generated from nhcarrigan/template
feat: add codex / lore book with 364 entries
Implements a full in-game Codex panel that tracks lore discovery across seven categories: bosses (72), quests (95), zones (18), equipment (65), adventurer tiers (32), upgrades (57), and prestige upgrades (25). Lore entries unlock automatically as players progress — existing completions are retroactively and silently added on first load. New discoveries trigger a toast notification and badge counter on the Codex tab.
This commit is contained in:
@@ -8,6 +8,8 @@ import { AdventurerPanel } from "./AdventurerPanel.js";
|
||||
import { BattleModal } from "./BattleModal.js";
|
||||
import { BossPanel } from "./BossPanel.js";
|
||||
import { ClickArea } from "./ClickArea.js";
|
||||
import { CodexPanel } from "./CodexPanel.js";
|
||||
import { CodexToast } from "./CodexToast.js";
|
||||
import { EditProfileModal } from "./EditProfileModal.js";
|
||||
import { EquipmentPanel } from "./EquipmentPanel.js";
|
||||
import { OfflineModal } from "./OfflineModal.js";
|
||||
@@ -17,9 +19,9 @@ import { StatisticsPanel } from "./StatisticsPanel.js";
|
||||
import { UpgradePanel } from "./UpgradePanel.js";
|
||||
import { DailyChallengePanel } from "./DailyChallengePanel.js";
|
||||
|
||||
type Tab = "adventurers" | "upgrades" | "quests" | "bosses" | "equipment" | "achievements" | "prestige" | "statistics" | "daily" | "about";
|
||||
type Tab = "adventurers" | "upgrades" | "quests" | "bosses" | "equipment" | "achievements" | "prestige" | "statistics" | "daily" | "codex" | "about";
|
||||
|
||||
const TABS: { id: Tab; label: string }[] = [
|
||||
const BASE_TABS: { id: Tab; label: string }[] = [
|
||||
{ id: "adventurers", label: "⚔️ Adventurers" },
|
||||
{ id: "upgrades", label: "🔧 Upgrades" },
|
||||
{ id: "quests", label: "📜 Quests" },
|
||||
@@ -29,11 +31,12 @@ const TABS: { id: Tab; label: string }[] = [
|
||||
{ id: "prestige", label: "⭐ Prestige" },
|
||||
{ id: "statistics", label: "📊 Statistics" },
|
||||
{ id: "daily", label: "📅 Daily" },
|
||||
{ id: "codex", label: "📖 Codex" },
|
||||
{ id: "about", label: "ℹ️ About" },
|
||||
];
|
||||
|
||||
export const GameLayout = (): React.JSX.Element => {
|
||||
const { state, isLoading, error, battleResult, dismissBattle, lastSavedAt, isSyncing, forceSync } = useGame();
|
||||
const { state, isLoading, error, battleResult, dismissBattle, lastSavedAt, isSyncing, forceSync, newCodexEntryIds } = useGame();
|
||||
const [activeTab, setActiveTab] = useState<Tab>("adventurers");
|
||||
const [editingProfile, setEditingProfile] = useState(false);
|
||||
|
||||
@@ -71,6 +74,7 @@ export const GameLayout = (): React.JSX.Element => {
|
||||
/>
|
||||
<OfflineModal />
|
||||
<AchievementToast />
|
||||
<CodexToast />
|
||||
{battleResult && (
|
||||
<BattleModal battle={battleResult} onDismiss={dismissBattle} />
|
||||
)}
|
||||
@@ -85,7 +89,7 @@ export const GameLayout = (): React.JSX.Element => {
|
||||
|
||||
<main className="game-content">
|
||||
<nav className="tab-bar">
|
||||
{TABS.map((tab) => (
|
||||
{BASE_TABS.map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
className={`tab-button ${activeTab === tab.id ? "active" : ""}`}
|
||||
@@ -93,6 +97,9 @@ export const GameLayout = (): React.JSX.Element => {
|
||||
type="button"
|
||||
>
|
||||
{tab.label}
|
||||
{tab.id === "codex" && newCodexEntryIds.length > 0 && (
|
||||
<span className="tab-badge">{newCodexEntryIds.length}</span>
|
||||
)}
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
@@ -107,6 +114,7 @@ export const GameLayout = (): React.JSX.Element => {
|
||||
{activeTab === "prestige" && <PrestigePanel />}
|
||||
{activeTab === "statistics" && <StatisticsPanel />}
|
||||
{activeTab === "daily" && <DailyChallengePanel />}
|
||||
{activeTab === "codex" && <CodexPanel />}
|
||||
{activeTab === "about" && <AboutPanel />}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user