Files
meditation-admin/app/dashboard/layout.tsx
T
2026-06-03 09:01:42 +03:30

79 lines
2.4 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { useAuth } from "@/lib/auth";
import { Sidebar } from "@/components/Sidebar";
import { Spinner, Button } from "@/components/ui";
import { ThemeToggle } from "@/components/ThemeToggle";
import { LogoutIcon, MenuIcon, CloseIcon } from "@/components/icons";
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
const { token, ready, logout } = useAuth();
const router = useRouter();
const [mobileOpen, setMobileOpen] = useState(false);
// Client-side route protection (static export has no server to gate on).
useEffect(() => {
if (ready && !token) router.replace("/login");
}, [ready, token, router]);
if (!ready || !token) {
return (
<div className="flex min-h-screen items-center justify-center">
<Spinner className="h-10 w-10" />
</div>
);
}
function onLogout() {
logout();
router.replace("/login");
}
return (
<div className="flex min-h-screen bg-background">
{/* Desktop sidebar */}
<aside className="sticky top-0 hidden h-screen w-64 shrink-0 border-l border-border bg-surface lg:block">
<Sidebar />
</aside>
{/* Mobile drawer */}
{mobileOpen && (
<div className="fixed inset-0 z-40 lg:hidden">
<div
className="absolute inset-0 bg-black/40"
onClick={() => setMobileOpen(false)}
/>
<aside className="absolute right-0 top-0 h-full w-64 bg-surface shadow-xl">
<Sidebar onNavigate={() => setMobileOpen(false)} />
</aside>
</div>
)}
<div className="flex min-w-0 flex-1 flex-col">
<header className="sticky top-0 z-30 flex items-center justify-between border-b border-border bg-surface/80 px-4 py-3 backdrop-blur">
<button
className="rounded-lg p-2 text-muted hover:bg-surface-muted lg:hidden"
onClick={() => setMobileOpen((v) => !v)}
aria-label="منو"
>
{mobileOpen ? <CloseIcon /> : <MenuIcon />}
</button>
<div className="flex-1" />
<ThemeToggle />
<Button variant="ghost" icon={<LogoutIcon className="h-4 w-4" />} onClick={onLogout}>
خروج
</Button>
</header>
<main className="flex-1 p-4 sm:p-6">{children}</main>
</div>
</div>
);
}