"use client"; import { useCallback, useEffect, useState } from "react"; import { useRouter } from "next/navigation"; import { AuthProvider, useAuth } from "@/hooks/use-auth"; import { Sidebar } from "@/components/layout/sidebar"; import { Header } from "@/components/layout/header"; import { PresenceHeartbeat } from "@/components/presence/presence-heartbeat"; // Auth-gated dashboard shell. Extracted from the layout so the layout // itself can stay a server component and export metadata (noindex) — // client components can't export Next's metadata object. function DashboardShellInner({ children }: { children: React.ReactNode }) { const { user, loading } = useAuth(); const router = useRouter(); // Sidebar drawer state — only used on mobile. On lg+ the sidebar is // always visible and this stays at `false` (ignored by the component). const [sidebarOpen, setSidebarOpen] = useState(false); const closeSidebar = useCallback(() => setSidebarOpen(false), []); useEffect(() => { if (!loading && !user) { router.push("/login"); } }, [user, loading, router]); if (loading) { return (

Loading...

); } if (!user) return null; return (
{/* Reports this tab's online/away presence once we know a user is signed in. Headless — renders nothing. */}
setSidebarOpen(true)} /> {/* Thinner horizontal padding on mobile so cards have room to breathe. */}
{children}
); } export function DashboardShell({ children }: { children: React.ReactNode }) { return ( {children} ); }