feat: sidebar navigation to dedicated detail views
- Sidebar icons now navigate to full-screen views for each tool - Dashboard bento cards have 'Expand' buttons that open the detail view - Back arrow (←) in title bar returns to dashboard - Detail views wrapped in a glass-card with max-w-2xl layout - Settings page gets its own full layout with heading - World Map, Quest Designer, Soundboard show placeholder screens with icons - All nav items in sidebar: World, NPCs, Encounter, Dice, Session, Sound, Initiative, Random Tables, Calendar, Settings
This commit is contained in:
+156
-67
@@ -8,78 +8,167 @@ import {
|
||||
Timer,
|
||||
Volume2,
|
||||
Calendar,
|
||||
Maximize2,
|
||||
} 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-4 gap-3 p-4 h-full bg-[var(--color-bg-deep)]">
|
||||
{/* World Map — 2×2 */}
|
||||
<BentoCard title="World Map" icon={<Map size={16} />} span="col-span-2 row-span-2">
|
||||
<div className="flex flex-col items-center justify-center h-full text-[var(--color-text-dim)] text-sm gap-2">
|
||||
<Map size={48} className="opacity-30" />
|
||||
<p>Map canvas coming soon</p>
|
||||
<button
|
||||
onClick={() => onNavigate("world")}
|
||||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center gap-1 cursor-pointer transition-colors"
|
||||
>
|
||||
<Maximize2 size={12} /> Open full view
|
||||
</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 items-center justify-center h-full text-[var(--color-text-dim)] text-sm gap-2">
|
||||
<Sparkles size={32} className="opacity-30" />
|
||||
<p>Quest flowchart coming soon</p>
|
||||
<button
|
||||
onClick={() => onNavigate("quest")}
|
||||
className="text-[var(--color-gold-bright)] hover:text-[var(--color-gold-muted)] text-xs flex items-center gap-1 cursor-pointer transition-colors"
|
||||
>
|
||||
<Maximize2 size={12} /> Open
|
||||
</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>
|
||||
</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";
|
||||
|
||||
export function Dashboard() {
|
||||
return (
|
||||
<div className="grid grid-cols-4 grid-rows-4 gap-3 p-4 h-full bg-[var(--color-bg-deep)]">
|
||||
{/* World Map — 2×2 */}
|
||||
<BentoCard title="World Map" icon={<Map size={16} />} span="col-span-2 row-span-2">
|
||||
<div className="flex items-center justify-center h-full text-[var(--color-text-dim)] text-sm">
|
||||
<div className="text-center">
|
||||
<Map size={48} className="mx-auto mb-2 opacity-30" />
|
||||
<p>Map canvas coming soon</p>
|
||||
<p className="text-xs mt-1">react-konva integration pending</p>
|
||||
</div>
|
||||
</div>
|
||||
</BentoCard>
|
||||
|
||||
{/* NPC Sheet — 1×1 */}
|
||||
<BentoCard title="NPC Sheet" icon={<User size={16} />} span="col-span-1 row-span-1">
|
||||
<NpcGenerator />
|
||||
</BentoCard>
|
||||
|
||||
{/* Dice Roller — 1×1 */}
|
||||
<BentoCard title="Dice Roller" icon={<Dice5 size={16} />} span="col-span-1 row-span-1">
|
||||
<DiceRoller />
|
||||
</BentoCard>
|
||||
|
||||
{/* Encounter Builder — 1×1 */}
|
||||
<BentoCard title="Encounter" icon={<Swords size={16} />} span="col-span-1 row-span-1">
|
||||
<EncounterBuilder />
|
||||
</BentoCard>
|
||||
|
||||
{/* Session Log — 2×1 */}
|
||||
<BentoCard title="Session Log" icon={<ScrollText size={16} />} span="col-span-2 row-span-1">
|
||||
<SessionLogger />
|
||||
</BentoCard>
|
||||
|
||||
{/* Quest Designer — 2×1 */}
|
||||
<BentoCard title="Quest Designer" icon={<Sparkles size={16} />} span="col-span-2 row-span-1">
|
||||
<div className="flex items-center justify-center h-full text-[var(--color-text-dim)] text-sm">
|
||||
Quest flowchart coming soon — react-flow integration pending
|
||||
</div>
|
||||
</BentoCard>
|
||||
|
||||
{/* Initiative Tracker — 1×1 */}
|
||||
<BentoCard title="Initiative" icon={<Timer size={16} />} span="col-span-1 row-span-1">
|
||||
<InitiativeTracker />
|
||||
</BentoCard>
|
||||
|
||||
{/* Random Tables — 1×1 */}
|
||||
<BentoCard title="Random Tables" icon={<Sparkles size={16} />} span="col-span-1 row-span-1">
|
||||
<RandomTables />
|
||||
</BentoCard>
|
||||
|
||||
{/* Calendar — 1×1 */}
|
||||
<BentoCard title="Calendar" icon={<Calendar size={16} />} span="col-span-1 row-span-1">
|
||||
<CalendarWidget />
|
||||
</BentoCard>
|
||||
|
||||
{/* Soundboard — 1×1 */}
|
||||
<BentoCard title="Soundboard" icon={<Volume2 size={16} />} span="col-span-1 row-span-1">
|
||||
<div className="flex items-center justify-center h-full text-[var(--color-text-dim)] text-sm">
|
||||
Soundboard coming soon
|
||||
</div>
|
||||
</BentoCard>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
import { CalendarWidget } from "./CalendarWidget";
|
||||
Reference in New Issue
Block a user