ea827ff20e
- 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
195 lines
8.0 KiB
TypeScript
195 lines
8.0 KiB
TypeScript
import {
|
||
Map,
|
||
User,
|
||
Swords,
|
||
ScrollText,
|
||
Dice5,
|
||
Sparkles,
|
||
Timer,
|
||
Volume2,
|
||
Calendar,
|
||
Maximize2,
|
||
Wand2,
|
||
} from "lucide-react";
|
||
import { BentoCard } from "./BentoCard";
|
||
import type { View } from "../App";
|
||
|
||
interface DashboardProps {
|
||
onNavigate: (view: View) => void;
|
||
}
|
||
|
||
export function Dashboard({ onNavigate }: DashboardProps) {
|
||
return (
|
||
<div className="grid grid-cols-4 grid-rows-5 gap-3 p-4 h-full bg-[var(--color-bg-deep)] overflow-y-auto">
|
||
{/* World Map — 2×2 */}
|
||
<BentoCard title="World Builder" icon={<Map size={16} />} span="col-span-2 row-span-2">
|
||
<div className="flex flex-col h-full">
|
||
<div className="flex-1 overflow-hidden">
|
||
<WorldBuilder />
|
||
</div>
|
||
<button
|
||
onClick={() => onNavigate("world")}
|
||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center justify-center gap-1 cursor-pointer transition-colors mt-1 pt-2 border-t border-[var(--color-border-subtle)]"
|
||
>
|
||
<Maximize2 size={12} /> Expand
|
||
</button>
|
||
</div>
|
||
</BentoCard>
|
||
|
||
{/* NPC Sheet — 1×1 */}
|
||
<BentoCard title="NPC Sheet" icon={<User size={16} />} span="col-span-1 row-span-1">
|
||
<div className="flex flex-col h-full">
|
||
<div className="flex-1 overflow-hidden">
|
||
<NpcGenerator />
|
||
</div>
|
||
<button
|
||
onClick={() => onNavigate("npcs")}
|
||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center justify-center gap-1 cursor-pointer transition-colors mt-1 pt-2 border-t border-[var(--color-border-subtle)]"
|
||
>
|
||
<Maximize2 size={12} /> Expand
|
||
</button>
|
||
</div>
|
||
</BentoCard>
|
||
|
||
{/* Dice Roller — 1×1 */}
|
||
<BentoCard title="Dice Roller" icon={<Dice5 size={16} />} span="col-span-1 row-span-1">
|
||
<div className="flex flex-col h-full">
|
||
<div className="flex-1 overflow-hidden">
|
||
<DiceRoller />
|
||
</div>
|
||
<button
|
||
onClick={() => onNavigate("dice")}
|
||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center justify-center gap-1 cursor-pointer transition-colors mt-1 pt-2 border-t border-[var(--color-border-subtle)]"
|
||
>
|
||
<Maximize2 size={12} /> Expand
|
||
</button>
|
||
</div>
|
||
</BentoCard>
|
||
|
||
{/* Encounter Builder — 1×1 */}
|
||
<BentoCard title="Encounter" icon={<Swords size={16} />} span="col-span-1 row-span-1">
|
||
<div className="flex flex-col h-full">
|
||
<div className="flex-1 overflow-hidden">
|
||
<EncounterBuilder />
|
||
</div>
|
||
<button
|
||
onClick={() => onNavigate("encounter")}
|
||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center justify-center gap-1 cursor-pointer transition-colors mt-1 pt-2 border-t border-[var(--color-border-subtle)]"
|
||
>
|
||
<Maximize2 size={12} /> Expand
|
||
</button>
|
||
</div>
|
||
</BentoCard>
|
||
|
||
{/* Session Log — 2×1 */}
|
||
<BentoCard title="Session Log" icon={<ScrollText size={16} />} span="col-span-2 row-span-1">
|
||
<div className="flex flex-col h-full">
|
||
<div className="flex-1 overflow-hidden">
|
||
<SessionLogger />
|
||
</div>
|
||
<button
|
||
onClick={() => onNavigate("session")}
|
||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center justify-center gap-1 cursor-pointer transition-colors mt-1 pt-2 border-t border-[var(--color-border-subtle)]"
|
||
>
|
||
<Maximize2 size={12} /> Expand
|
||
</button>
|
||
</div>
|
||
</BentoCard>
|
||
|
||
{/* Quest Designer — 2×1 */}
|
||
<BentoCard title="Quest Designer" icon={<Sparkles size={16} />} span="col-span-2 row-span-1">
|
||
<div className="flex flex-col h-full">
|
||
<div className="flex-1 overflow-hidden">
|
||
<QuestDesigner />
|
||
</div>
|
||
<button
|
||
onClick={() => onNavigate("quest")}
|
||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center justify-center gap-1 cursor-pointer transition-colors mt-1 pt-2 border-t border-[var(--color-border-subtle)]"
|
||
>
|
||
<Maximize2 size={12} /> Expand
|
||
</button>
|
||
</div>
|
||
</BentoCard>
|
||
|
||
{/* Initiative Tracker — 1×1 */}
|
||
<BentoCard title="Initiative" icon={<Timer size={16} />} span="col-span-1 row-span-1">
|
||
<div className="flex flex-col h-full">
|
||
<div className="flex-1 overflow-hidden">
|
||
<InitiativeTracker />
|
||
</div>
|
||
<button
|
||
onClick={() => onNavigate("initiative")}
|
||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center justify-center gap-1 cursor-pointer transition-colors mt-1 pt-2 border-t border-[var(--color-border-subtle)]"
|
||
>
|
||
<Maximize2 size={12} /> Expand
|
||
</button>
|
||
</div>
|
||
</BentoCard>
|
||
|
||
{/* Random Tables — 1×1 */}
|
||
<BentoCard title="Random Tables" icon={<Sparkles size={16} />} span="col-span-1 row-span-1">
|
||
<div className="flex flex-col h-full">
|
||
<div className="flex-1 overflow-hidden">
|
||
<RandomTables />
|
||
</div>
|
||
<button
|
||
onClick={() => onNavigate("tables")}
|
||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center justify-center gap-1 cursor-pointer transition-colors mt-1 pt-2 border-t border-[var(--color-border-subtle)]"
|
||
>
|
||
<Maximize2 size={12} /> Expand
|
||
</button>
|
||
</div>
|
||
</BentoCard>
|
||
|
||
{/* Calendar — 1×1 */}
|
||
<BentoCard title="Calendar" icon={<Calendar size={16} />} span="col-span-1 row-span-1">
|
||
<div className="flex flex-col h-full">
|
||
<div className="flex-1 overflow-hidden">
|
||
<CalendarWidget />
|
||
</div>
|
||
<button
|
||
onClick={() => onNavigate("calendar")}
|
||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center justify-center gap-1 cursor-pointer transition-colors mt-1 pt-2 border-t border-[var(--color-border-subtle)]"
|
||
>
|
||
<Maximize2 size={12} /> Expand
|
||
</button>
|
||
</div>
|
||
</BentoCard>
|
||
|
||
{/* Soundboard — 1×1 */}
|
||
<BentoCard title="Soundboard" icon={<Volume2 size={16} />} span="col-span-1 row-span-1">
|
||
<div className="flex flex-col items-center justify-center h-full text-[var(--color-text-dim)] text-sm gap-2">
|
||
<Volume2 size={32} className="opacity-30" />
|
||
<p>Soundboard coming soon</p>
|
||
</div>
|
||
</BentoCard>
|
||
|
||
{/* Item Forge — 2×1 */}
|
||
<BentoCard title="Item Forge" icon={<Wand2 size={16} />} span="col-span-2 row-span-1">
|
||
<div className="flex flex-col h-full">
|
||
<div className="flex-1 overflow-hidden">
|
||
<ItemForge />
|
||
</div>
|
||
<button
|
||
onClick={() => onNavigate("items")}
|
||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center justify-center gap-1 cursor-pointer transition-colors mt-1 pt-2 border-t border-[var(--color-border-subtle)]"
|
||
>
|
||
<Maximize2 size={12} /> Expand
|
||
</button>
|
||
</div>
|
||
</BentoCard>
|
||
</div>
|
||
);
|
||
}
|
||
|
||
// Inline imports for dashboard cards (compact versions)
|
||
import { NpcGenerator } from "./NpcGenerator";
|
||
import { DiceRoller } from "./DiceRoller";
|
||
import { SessionLogger } from "./SessionLogger";
|
||
import { EncounterBuilder } from "./EncounterBuilder";
|
||
import { InitiativeTracker } from "./InitiativeTracker";
|
||
import { RandomTables } from "./RandomTables";
|
||
import { CalendarWidget } from "./CalendarWidget";
|
||
import { WorldBuilder } from "./WorldBuilder";
|
||
import { QuestDesigner } from "./QuestDesigner";
|
||
import { ItemForge } from "./ItemForge"; |