Spaces:
Sleeping
Sleeping
| "use client"; | |
| import { useEffect, useState } from "react"; | |
| import { usePathname, useRouter } from "next/navigation"; | |
| import { DashboardLayout } from "./DashboardLayout"; | |
| import { useAuthStore } from "@/lib/stores/authStore"; | |
| import { useThemeStore } from "@/lib/stores/themeStore"; | |
| import { useLanguageStore } from "@/lib/stores/languageStore"; | |
| import { Loader2, Sparkles } from "lucide-react"; | |
| const PUBLIC_PATHS = ["/login"]; | |
| // Lang codes mapped to BCP-47 HTML lang values | |
| const LANG_MAP: Record<string, string> = { | |
| en: "en", | |
| hi: "hi", | |
| mr: "mr", | |
| }; | |
| function FullPageSpinner() { | |
| return ( | |
| <div className="flex min-h-screen items-center justify-center" style={{ background: "var(--bg, #050505)" }}> | |
| <div className="flex flex-col items-center gap-4"> | |
| <div className="flex h-14 w-14 items-center justify-center rounded-2xl bg-gradient-to-br from-emerald-400 to-cyan-500 shadow-2xl shadow-emerald-500/30"> | |
| <Sparkles className="h-7 w-7 text-white" /> | |
| </div> | |
| <Loader2 className="h-5 w-5 animate-spin text-emerald-400" /> | |
| <p className="text-xs text-zinc-500">Loading BankBot AI...</p> | |
| </div> | |
| </div> | |
| ); | |
| } | |
| export function AppShell({ children }: { children: React.ReactNode }) { | |
| const pathname = usePathname(); | |
| const router = useRouter(); | |
| const { isAuthenticated, restoreSession } = useAuthStore(); | |
| const { theme, setTheme } = useThemeStore(); | |
| const { language } = useLanguageStore(); | |
| const [hydrated, setHydrated] = useState(false); | |
| const isPublic = PUBLIC_PATHS.includes(pathname); | |
| // Apply persisted theme on mount | |
| useEffect(() => { | |
| setTheme(theme); | |
| restoreSession().finally(() => setHydrated(true)); | |
| }, []); // eslint-disable-line react-hooks/exhaustive-deps | |
| // Sync <html lang> whenever language changes | |
| useEffect(() => { | |
| if (typeof document !== "undefined") { | |
| document.documentElement.lang = LANG_MAP[language] ?? language; | |
| } | |
| }, [language]); | |
| if (!hydrated) return <FullPageSpinner />; | |
| if (isPublic) return <>{children}</>; | |
| if (!isAuthenticated) { | |
| router.replace("/login"); | |
| return <FullPageSpinner />; | |
| } | |
| return <DashboardLayout>{children}</DashboardLayout>; | |
| } | |