/** * @file Read-only panel displaying goddess quests grouped by zone. * @copyright nhcarrigan * @license Naomi's Public License * @author Naomi Carrigan */ /* eslint-disable max-lines-per-function -- Complex component with many render paths */ /* eslint-disable react/no-multi-comp -- QuestCard sub-component is tightly coupled */ import { useState, type JSX } from "react"; import { useGame } from "../../context/gameContext.js"; import type { GoddessQuest, GoddessQuestReward, GoddessZone, } from "@elysium/types"; /** * Formats a duration in seconds to a human-readable string. * @param seconds - The total number of seconds to format. * @returns The formatted duration string. */ const formatDuration = (seconds: number): string => { const secondsPerHour = 3600; const secondsPerMinute = 60; if (seconds >= secondsPerHour) { const hours = Math.floor(seconds / secondsPerHour); const remainderSeconds = seconds % secondsPerHour; const minutes = Math.floor(remainderSeconds / secondsPerMinute); return `${String(hours)}h ${String(minutes)}m`; } if (seconds >= secondsPerMinute) { const minutes = Math.floor(seconds / secondsPerMinute); const secs = seconds % secondsPerMinute; return `${String(minutes)}m ${String(secs)}s`; } return `${String(seconds)}s`; }; /** * Returns a human-readable label string for a goddess quest reward. * @param reward - The reward to describe. * @param formatNumber - The number formatter function. * @returns The label string, or an empty string for unknown types. */ const getRewardLabel = ( reward: GoddessQuestReward, formatNumber: (value: number)=> string, ): string => { if (reward.type === "prayers") { return `🙏 ${formatNumber(reward.amount ?? 0)} Prayers`; } if (reward.type === "divinity") { return `✨ ${formatNumber(reward.amount ?? 0)} Divinity`; } if (reward.type === "stardust") { return `⭐ ${formatNumber(reward.amount ?? 0)} Stardust`; } if (reward.type === "upgrade") { return "🔓 Upgrade Unlocked"; } if (reward.type === "disciple") { return "👤 New Disciple Tier"; } return "🛡️ Equipment Unlocked"; }; interface GoddessQuestCardProperties { readonly quest: GoddessQuest; readonly unlockHint: string | undefined; readonly zoneIsOpen: boolean; } /** * Renders a single goddess quest card (read-only). * @param props - The component properties. * @param props.quest - The goddess quest to display. * @param props.unlockHint - The name of the prerequisite quest, if locked. * @param props.zoneIsOpen - Whether the quest's zone is currently unlocked. * @returns The JSX element. */ const GoddessQuestCard = ({ quest, unlockHint, zoneIsOpen, }: GoddessQuestCardProperties): JSX.Element => { const { formatNumber } = useGame(); return (
{quest.description}
{"⏱ "} {formatDuration(quest.durationSeconds)}
{"📜 Complete: "} {unlockHint}
} > : null } {quest.status === "available" && {"📋 Available"} } {quest.status === "active" && {"⏳ In Progress"} } {quest.status === "completed" && {"✅ Completed"} }{"Loading..."}
{"Goddess expansion not yet unlocked."}
{activeZone.description}
{String(completedCount)} {" / "} {String(zoneQuests.length)} {" quests completed"}
{activeZone.status === "locked" &&{"🔒 This zone is locked. Defeat the required goddess boss"} {" to unlock it."}
}{"No quests in this zone."}
: zoneQuests.map((quest: GoddessQuest) => { return