feat: World Builder, Item Forge, Quest Designer + sidebar navigation

- World Builder: AI-generated worlds with regions, landmarks, conflicts, cultures
- Item Forge: AI magic item generator with rarity-colored headers, mechanical/lore sections
- Quest Designer: AI quest generator with step-through navigation, choices, twist, reward
- Sidebar now navigates to dedicated full-screen views for every tool
- Bento dashboard cards have 'Expand' buttons opening detail views
- Back arrow (←) in title bar returns to dashboard
- Dashboard grid expanded to 5 rows to accommodate Item Forge
- All three new tools also work in compact dashboard mode
- Full production build clean
This commit is contained in:
itsamejms
2026-06-28 22:50:50 +01:00
parent a44de0e4bb
commit ea827ff20e
5 changed files with 559 additions and 33 deletions
+21 -20
View File
@@ -11,6 +11,7 @@ import {
Sparkles,
Timer,
Calendar,
Wand2,
} from "lucide-react";
import { useState } from "react";
import { Dashboard } from "./components/Dashboard";
@@ -22,6 +23,9 @@ import { EncounterBuilder } from "./components/EncounterBuilder";
import { InitiativeTracker } from "./components/InitiativeTracker";
import { RandomTables } from "./components/RandomTables";
import { CalendarWidget } from "./components/CalendarWidget";
import { WorldBuilder } from "./components/WorldBuilder";
import { ItemForge } from "./components/ItemForge";
import { QuestDesigner } from "./components/QuestDesigner";
export type View =
| "dashboard"
@@ -35,11 +39,13 @@ export type View =
| "tables"
| "calendar"
| "quest"
| "items"
| "settings";
const navItems: { icon: typeof Map; label: string; view: View }[] = [
{ icon: Map, label: "World", view: "world" },
{ icon: User, label: "NPCs", view: "npcs" },
{ icon: Wand2, label: "Items", view: "items" },
{ icon: Swords, label: "Encounter", view: "encounter" },
{ icon: Dice5, label: "Dice", view: "dice" },
{ icon: ScrollText, label: "Session", view: "session" },
@@ -65,27 +71,11 @@ function renderView(view: View): React.ReactNode {
case "settings":
return <SettingsPanel />;
case "world":
return (
<div className="flex items-center justify-center h-full text-[var(--color-text-dim)]">
<div className="text-center">
<Map size={64} className="mx-auto mb-4 opacity-30" />
<p className="text-lg font-heading">World Map</p>
<p className="text-sm mt-2">Interactive map canvas coming soon</p>
<p className="text-xs mt-1 opacity-60">react-konva integration pending</p>
</div>
</div>
);
return <WorldBuilder />;
case "quest":
return (
<div className="flex items-center justify-center h-full text-[var(--color-text-dim)]">
<div className="text-center">
<Sparkles size={64} className="mx-auto mb-4 opacity-30" />
<p className="text-lg font-heading">Quest Designer</p>
<p className="text-sm mt-2">Branching flowchart coming soon</p>
<p className="text-xs mt-1 opacity-60">react-flow integration pending</p>
</div>
</div>
);
return <QuestDesigner />;
case "items":
return <ItemForge />;
case "sound":
return (
<div className="flex items-center justify-center h-full text-[var(--color-text-dim)]">
@@ -165,6 +155,17 @@ export default function App() {
>
<Sparkles size={18} />
</button>
<button
onClick={() => setView("quest")}
className={`w-10 h-10 rounded-lg flex items-center justify-center transition-colors cursor-pointer ${
view === "quest"
? "bg-[var(--color-bg-card)] text-[var(--color-gold-bright)]"
: "text-[var(--color-text-dim)] hover:text-[var(--color-text-secondary)] hover:bg-[var(--color-bg-card)]"
}`}
title="Quest Designer"
>
<Sparkles size={16} />
</button>
<button
onClick={() => setView("calendar")}
className={`w-10 h-10 rounded-lg flex items-center justify-center transition-colors cursor-pointer ${