Files
GMW/services/frontend/src/widgets/DashboardLayout.tsx
T

73 lines
2.1 KiB
TypeScript
Raw Normal View History

import { motion } from "framer-motion";
import type { ReactNode } from "react";
import type { DashboardTab } from "../entities/ui/types";
2026-06-03 15:01:34 +07:00
import type { MessageRecord, VoiceStatus } from "../shared/api/client";
import { fadeSlideUp } from "../shared/hooks/useFramerStagger";
import { useMascotSummary } from "../shared/hooks/useMascotSummary";
import type { WsStatus } from "../shared/ws/socket";
import { Header } from "./Header";
import { ParticleBackground } from "./particles/ParticleBackground";
import { Sidebar } from "./Sidebar";
interface DashboardLayoutProps {
activeTab: DashboardTab;
wsStatus: WsStatus;
voiceStatus: VoiceStatus;
onTabChange: (tab: DashboardTab) => void;
children: ReactNode;
2026-06-03 15:01:34 +07:00
recentMessages?: MessageRecord[];
guildId?: string;
channelId?: string;
}
export function DashboardLayout({
activeTab,
wsStatus,
voiceStatus,
onTabChange,
children,
recentMessages = [],
2026-06-03 15:01:34 +07:00
guildId,
channelId,
}: DashboardLayoutProps) {
// Generate mascot summary from recent messages
const mascotSummary = useMascotSummary({
messages: recentMessages,
enabled: activeTab === "messages" && recentMessages.length > 0,
});
return (
<div className="relative min-h-screen bg-background text-foreground">
{/* Sakura particle layer */}
<ParticleBackground />
<div className="relative flex min-h-screen">
<Sidebar
activeTab={activeTab}
onTabChange={onTabChange}
mascotChatMessage={mascotSummary}
2026-06-03 15:01:34 +07:00
recentMessages={recentMessages}
guildId={guildId}
channelId={channelId}
/>
<main className="flex min-w-0 flex-1 flex-col">
<Header
activeTab={activeTab}
wsStatus={wsStatus}
voiceStatus={voiceStatus}
/>
<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"
>
{children}
</motion.main>
</main>
</div>
</div>
);
}