import type { Quest } from "@elysium/types"; import { useState } from "react"; import { useGame } from "../../context/GameContext.js"; import { LockToggle } from "../ui/LockToggle.js"; import { ZoneSelector } from "./ZoneSelector.js"; const formatDuration = (seconds: number): string => { if (seconds >= 3600) return `${Math.floor(seconds / 3600)}h ${Math.floor((seconds % 3600) / 60)}m`; if (seconds >= 60) return `${Math.floor(seconds / 60)}m ${seconds % 60}s`; return `${seconds}s`; }; const questTimeRemaining = (quest: Quest): number => { if (quest.status !== "active" || quest.startedAt == null) return 0; const elapsed = (Date.now() - quest.startedAt) / 1000; return Math.max(0, quest.durationSeconds - elapsed); }; interface QuestCardProps { quest: Quest; } const QuestCard = ({ quest }: QuestCardProps): React.JSX.Element => { const { startQuest } = useGame(); return (

{quest.name}

{quest.description}

{quest.rewards.map((reward, index) => ( // eslint-disable-next-line react/no-array-index-key -- rewards have no unique id {reward.type === "gold" && `🪙 ${reward.amount?.toLocaleString()}`} {reward.type === "essence" && `✨ ${reward.amount?.toLocaleString()}`} {reward.type === "crystals" && `💎 ${reward.amount?.toLocaleString()}`} {reward.type === "upgrade" && "🔓 Upgrade"} {reward.type === "adventurer" && "👥 New Adventurer"} ))}
{quest.status === "locked" && 🔒 Locked} {quest.status === "available" && ( )} {quest.status === "active" && ( ⏳ {formatDuration(Math.ceil(questTimeRemaining(quest)))} remaining )} {quest.status === "completed" && ✅ Complete}
); }; export const QuestPanel = (): React.JSX.Element => { const { state } = useGame(); const [activeZoneId, setActiveZoneId] = useState("verdant_vale"); const [showLocked, setShowLocked] = useState(true); if (!state) return

Loading...

; const zones = state.zones ?? []; const zoneQuests = state.quests.filter((q) => q.zoneId === activeZoneId); const lockedCount = zoneQuests.filter((q) => q.status === "locked").length; const visibleQuests = showLocked ? zoneQuests : zoneQuests.filter((q) => q.status !== "locked"); return (

Quests

{ setShowLocked((v) => !v); }} />
{visibleQuests.map((quest) => ( ))} {visibleQuests.length === 0 && (

No quests to show in this zone.

)}
); };