import { useState } from "react"; import type { CodexEntry } from "@elysium/types"; import { CODEX_ENTRIES, ZONE_LABELS } from "../../data/codex.js"; import { useGame } from "../../context/GameContext.js"; const SOURCE_BADGE: Record = { boss: "⚔️", quest: "📜", equipment: "🛡️", adventurer: "👥", upgrade: "🔧", prestige: "🔮", zone: "🗺️", }; export const CodexPanel = (): React.JSX.Element => { const { state } = useGame(); const [expandedId, setExpandedId] = useState(null); if (!state) return

Loading...

; const unlockedIds = new Set(state.codex?.unlockedEntryIds ?? []); const totalEntries = CODEX_ENTRIES.length; const unlockedCount = CODEX_ENTRIES.filter((e) => unlockedIds.has(e.id)).length; const progressPercent = totalEntries > 0 ? (unlockedCount / totalEntries) * 100 : 0; const entriesByZone = Object.entries(ZONE_LABELS).map(([zoneId, zoneName]) => { const zoneEntries = CODEX_ENTRIES.filter((e) => e.zoneId === zoneId); const unlockedZoneEntries = zoneEntries.filter((e) => unlockedIds.has(e.id)); return { zoneId, zoneName, entries: zoneEntries, unlockedEntries: unlockedZoneEntries }; }).filter(({ entries }) => entries.length > 0); return (

📖 Codex

Lore discovered: {unlockedCount} / {totalEntries}

{entriesByZone.map(({ zoneId, zoneName, entries, unlockedEntries }) => (

{zoneName} {unlockedEntries.length}/{entries.length}

{entries.map((entry) => { const isUnlocked = unlockedIds.has(entry.id); const isExpanded = expandedId === entry.id; if (!isUnlocked) { return (
🔒 ???
); } return (
{ setExpandedId(isExpanded ? null : entry.id); }} >
{SOURCE_BADGE[entry.sourceType]} {entry.title} {isExpanded ? "▲" : "▼"}
{isExpanded && (

{entry.content}

)}
); })}
))}
); };