"use client"; import { useEffect, useState } from "react"; import { usePathname, useRouter } from "next/navigation"; import { useAuthStore } from "@/stores/authStore"; import { Sidebar } from "./Sidebar"; import { MobileHeader } from "./MobileHeader"; const NO_SHELL_PATHS = ["/login", "/register"]; const AUTH_REQUIRED = ["/following", "/notifications"]; export function AuthGuard({ children }: { children: React.ReactNode }) { const router = useRouter(); const pathname = usePathname(); const token = useAuthStore((s) => s.token); // Zustand persist hydrates asynchronously — wait for it before rendering const [hydrated, setHydrated] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false); useEffect(() => { setHydrated(true); }, []); useEffect(() => { if (!hydrated) return; const needsAuth = AUTH_REQUIRED.some((p) => pathname.startsWith(p)); if (!token && needsAuth) { router.replace("/login"); } }, [hydrated, token, pathname, router]); if (!hydrated) return null; // Login/register pages render without the app shell if (NO_SHELL_PATHS.includes(pathname)) { return <>{children}; } // Auth-required pages: blank while redirecting const needsAuth = AUTH_REQUIRED.some((p) => pathname.startsWith(p)); if (!token && needsAuth) return null; // Authenticated or guest browsing: render the full app shell return (
{/* Desktop sidebar — hidden on mobile */}
{/* Mobile slide-in drawer */} {drawerOpen && (
setDrawerOpen(false)} />
setDrawerOpen(false)} />
)} {/* Content column */}
setDrawerOpen(true)} />
{children}
); }