2026-07-26 15:34:08 +07:00
|
|
|
"use client";
|
|
|
|
|
|
2026-07-26 16:55:20 +07:00
|
|
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
2026-07-26 15:34:08 +07:00
|
|
|
import { Suspense } from "react";
|
2026-07-28 08:53:54 +07:00
|
|
|
import { TopNav } from "@/components/layout/top-nav";
|
2026-07-26 16:14:32 +07:00
|
|
|
import { MobileNav } from "@/components/layout/mobile-nav";
|
2026-07-26 15:34:08 +07:00
|
|
|
import { WsProvider } from "@/lib/ws/context";
|
2026-07-28 08:53:54 +07:00
|
|
|
import { MascotProvider } from "@/components/mascot/mascot-context";
|
|
|
|
|
import { MascotContainer } from "@/components/mascot/mascot-container";
|
|
|
|
|
import { MiniPlayer } from "@/components/media/mini-player";
|
|
|
|
|
import { MediaPlayerProvider } from "@/lib/hooks/use-media-player";
|
|
|
|
|
import { HiddenSidebar } from "@/components/layout/hidden-sidebar";
|
|
|
|
|
import { useState } from "react";
|
2026-07-26 15:34:08 +07:00
|
|
|
|
2026-07-26 16:55:20 +07:00
|
|
|
const queryClient = new QueryClient({
|
|
|
|
|
defaultOptions: {
|
|
|
|
|
queries: {
|
2026-07-28 08:53:54 +07:00
|
|
|
staleTime: 10_000,
|
2026-07-26 16:55:20 +07:00
|
|
|
retry: 1,
|
|
|
|
|
refetchOnWindowFocus: false,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-26 15:34:08 +07:00
|
|
|
export default function DashboardLayout({
|
|
|
|
|
children,
|
|
|
|
|
}: {
|
|
|
|
|
children: React.ReactNode;
|
|
|
|
|
}) {
|
2026-07-28 08:53:54 +07:00
|
|
|
const [guildId, setGuildId] = useState("");
|
|
|
|
|
|
2026-07-26 15:34:08 +07:00
|
|
|
return (
|
2026-07-26 16:55:20 +07:00
|
|
|
<QueryClientProvider client={queryClient}>
|
|
|
|
|
<WsProvider>
|
2026-07-28 08:53:54 +07:00
|
|
|
<MediaPlayerProvider>
|
|
|
|
|
<MascotProvider>
|
|
|
|
|
<div className="min-h-screen bg-canvas">
|
|
|
|
|
<TopNav />
|
|
|
|
|
<HiddenSidebar guildId={guildId} onGuildChange={(g) => setGuildId(g ?? "")} />
|
|
|
|
|
|
|
|
|
|
{/* Sub-nav space — filled per-page */}
|
|
|
|
|
<div className="pt-11">
|
|
|
|
|
<main className="p-4 md:p-6 pb-24 md:pb-6 max-w-[1600px] mx-auto">
|
|
|
|
|
<Suspense
|
|
|
|
|
fallback={
|
|
|
|
|
<div className="flex h-[60vh] items-center justify-center">
|
|
|
|
|
<div className="size-8 rounded-full border-2 border-primary border-t-transparent animate-spin" />
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
{children}
|
|
|
|
|
</Suspense>
|
|
|
|
|
</main>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<MobileNav />
|
|
|
|
|
<MiniPlayer />
|
|
|
|
|
<MascotContainer />
|
|
|
|
|
</div>
|
|
|
|
|
</MascotProvider>
|
|
|
|
|
</MediaPlayerProvider>
|
2026-07-26 16:55:20 +07:00
|
|
|
</WsProvider>
|
|
|
|
|
</QueryClientProvider>
|
2026-07-26 15:34:08 +07:00
|
|
|
);
|
|
|
|
|
}
|