2026-06-03 03:12:14 +07:00
|
|
|
import { motion } from "framer-motion";
|
2026-05-16 19:17:34 +07:00
|
|
|
import type { ReactNode } from "react";
|
2026-06-03 14:17:21 +07:00
|
|
|
import { useMemo } from "react";
|
2026-06-01 16:42:36 +07:00
|
|
|
import type { DashboardTab } from "../entities/ui/types";
|
|
|
|
|
import type { VoiceStatus } from "../shared/api/client";
|
2026-06-03 03:12:14 +07:00
|
|
|
import { fadeSlideUp } from "../shared/hooks/useFramerStagger";
|
2026-06-03 14:17:21 +07:00
|
|
|
import { useMascotSummary } from "../shared/hooks/useMascotSummary";
|
2026-06-01 21:44:29 +07:00
|
|
|
import type { WsStatus } from "../shared/ws/socket";
|
2026-05-16 19:17:34 +07:00
|
|
|
import { Header } from "./Header";
|
2026-06-03 03:12:14 +07:00
|
|
|
import { ParticleBackground } from "./particles/ParticleBackground";
|
2026-05-16 19:17:34 +07:00
|
|
|
import { Sidebar } from "./Sidebar";
|
|
|
|
|
|
|
|
|
|
interface DashboardLayoutProps {
|
|
|
|
|
activeTab: DashboardTab;
|
2026-06-01 16:42:36 +07:00
|
|
|
wsStatus: WsStatus;
|
2026-05-16 19:17:34 +07:00
|
|
|
voiceStatus: VoiceStatus;
|
|
|
|
|
onTabChange: (tab: DashboardTab) => void;
|
|
|
|
|
children: ReactNode;
|
2026-06-03 14:17:21 +07:00
|
|
|
recentMessages?: any[];
|
2026-05-16 19:17:34 +07:00
|
|
|
}
|
|
|
|
|
|
2026-06-01 21:44:29 +07:00
|
|
|
export function DashboardLayout({
|
|
|
|
|
activeTab,
|
|
|
|
|
wsStatus,
|
|
|
|
|
voiceStatus,
|
|
|
|
|
onTabChange,
|
|
|
|
|
children,
|
2026-06-03 14:17:21 +07:00
|
|
|
recentMessages = [],
|
2026-06-01 21:44:29 +07:00
|
|
|
}: DashboardLayoutProps) {
|
2026-06-03 14:17:21 +07:00
|
|
|
// Generate mascot summary from recent messages
|
|
|
|
|
const mascotSummary = useMascotSummary({
|
|
|
|
|
messages: recentMessages,
|
|
|
|
|
enabled: activeTab === "messages" && recentMessages.length > 0,
|
|
|
|
|
});
|
2026-05-16 19:17:34 +07:00
|
|
|
return (
|
2026-06-03 03:12:14 +07:00
|
|
|
<div className="relative min-h-screen bg-background text-foreground">
|
|
|
|
|
{/* Sakura particle layer */}
|
|
|
|
|
<ParticleBackground />
|
|
|
|
|
|
|
|
|
|
<div className="relative flex min-h-screen">
|
2026-06-03 14:17:21 +07:00
|
|
|
<Sidebar
|
|
|
|
|
activeTab={activeTab}
|
|
|
|
|
onTabChange={onTabChange}
|
|
|
|
|
mascotChatMessage={mascotSummary}
|
|
|
|
|
/>
|
2026-05-16 19:17:34 +07:00
|
|
|
<main className="flex min-w-0 flex-1 flex-col">
|
2026-06-01 21:44:29 +07:00
|
|
|
<Header
|
|
|
|
|
activeTab={activeTab}
|
|
|
|
|
wsStatus={wsStatus}
|
|
|
|
|
voiceStatus={voiceStatus}
|
|
|
|
|
/>
|
2026-06-03 03:12:14 +07:00
|
|
|
<motion.main
|
|
|
|
|
key={activeTab}
|
|
|
|
|
variants={fadeSlideUp}
|
|
|
|
|
initial="initial"
|
|
|
|
|
animate="animate"
|
|
|
|
|
exit="exit"
|
|
|
|
|
className="flex-1 overflow-auto p-4 md:p-6 lg:p-8"
|
|
|
|
|
>
|
2026-06-01 21:44:29 +07:00
|
|
|
{children}
|
2026-06-03 03:12:14 +07:00
|
|
|
</motion.main>
|
2026-05-16 19:17:34 +07:00
|
|
|
</main>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|