generated from nhcarrigan/template
11e97325cb
## Summary - Adds `apps/web/src/utils/cdn.ts` with a `cdnImage(folder, id)` helper that builds URLs from `https://cdn.nhcarrigan.com/elysium/` - Wires CDN art into all 13 game panels (bosses, quests, adventurers, companions, equipment, upgrades, prestige, transcendence, achievements, explorations, crafting, story, codex) - Zone selector tabs now display 16:9 zone art thumbnails in place of emoji icons - Adds a fixed background image at 15% opacity via `body::before` - Documents the art generation and CDN upload process in `CLAUDE.md` for future expansions Resolves #15 ✨ This PR was created with help from Hikari~ 🌸 Reviewed-on: #43 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>
62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
/**
|
|
* @file Zone selector component for choosing the active zone.
|
|
* @copyright nhcarrigan
|
|
* @license Naomi's Public License
|
|
* @author Naomi Carrigan
|
|
*/
|
|
import { cdnImage } from "../../utils/cdn.js";
|
|
import type { Zone } from "@elysium/types";
|
|
import type { JSX } from "react";
|
|
|
|
interface ZoneSelectorProperties {
|
|
readonly zones: Array<Zone>;
|
|
readonly activeZoneId: string;
|
|
readonly onSelectZone: (zoneId: string)=> void;
|
|
}
|
|
|
|
/**
|
|
* Renders a zone selector with buttons for each available zone.
|
|
* @param props - The zone selector properties.
|
|
* @param props.zones - The list of zones to display.
|
|
* @param props.activeZoneId - The currently active zone ID.
|
|
* @param props.onSelectZone - Callback when a zone is selected.
|
|
* @returns The JSX element.
|
|
*/
|
|
const ZoneSelector = ({
|
|
zones,
|
|
activeZoneId,
|
|
onSelectZone,
|
|
}: ZoneSelectorProperties): JSX.Element => {
|
|
return (
|
|
<div className="zone-selector">
|
|
{zones.map((zone) => {
|
|
function handleSelect(): void {
|
|
onSelectZone(zone.id);
|
|
}
|
|
return (
|
|
<button
|
|
className={`zone-tab ${
|
|
zone.id === activeZoneId
|
|
? "zone-tab-active"
|
|
: ""
|
|
}`}
|
|
key={zone.id}
|
|
onClick={handleSelect}
|
|
title={zone.description}
|
|
type="button"
|
|
>
|
|
<img
|
|
alt={zone.name}
|
|
className="zone-tab-image"
|
|
src={cdnImage("zones", zone.id)}
|
|
/>
|
|
<span className="zone-name">{zone.name}</span>
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export { ZoneSelector };
|