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 ;
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.
)}
);
};