1import {
2 Drawer,
3 DrawerContent,
4 Header,
5 ResizableHandle,
6 ResizablePanel,
7 ResizablePanelGroup,
8 Toaster,
9} from "@marzneshin/components";
10import { useAuth } from "@marzneshin/features/auth";
11import { DashboardSidebar, ToggleButton } from "@marzneshin/features/sidebar";
12import { usePanelToggle } from "@marzneshin/features/sidebar/use-panel-toggle";
13import { useScreenBreakpoint } from "@marzneshin/hooks/use-screen-breakpoint";
14import { cn } from "@marzneshin/utils";
15import { Outlet, createFileRoute, redirect } from "@tanstack/react-router";
16
17export const DashboardLayout = () => {
18 const isDesktop = useScreenBreakpoint("md");
19 const {
20 collapsed,
21 panelRef,
22 open,
23 setCollapsed,
24 setOpen,
25 toggleCollapse,
26 toggleOpen,
27 } = usePanelToggle(isDesktop);
28
29 return (
30 <div className="flex flex-col w-screen h-screen">
31 <header className="h-[3.5rem]">
32 <Header>
33 <ToggleButton
34 isDesktop={isDesktop}
35 collapsed={collapsed}
36 open={open}
37 onToggle={isDesktop ? toggleCollapse : toggleOpen}
38 />
39 </Header>
40 </header>
41 {isDesktop ? (
42 <ResizablePanelGroup direction="horizontal" className="block sm:hidden">
43 <ResizablePanel
44 collapsible
45 collapsedSize={2}
46 onCollapse={() => setCollapsed(true)}
47 onExpand={() => setCollapsed(false)}
48 minSize={15}
49 className={cn("w-[120px] min-w-[70px]")}
50 defaultSize={20}
51 ref={panelRef}
52 maxSize={30}
53 >
54 <DashboardSidebar
55 collapsed={collapsed}
56 setCollapsed={setCollapsed}
57 />
58 </ResizablePanel>
59 <ResizableHandle withHandle className="w-[2px]" />
60 <ResizablePanel>
61 <main>
62 <Outlet />
63 <Toaster position="top-center" />
64 </main>
65 </ResizablePanel>
66 </ResizablePanelGroup>
67 ) : (
68 <div>
69 <aside>
70 <Drawer open={open} onOpenChange={setOpen}>
71 <DrawerContent>
72 <DashboardSidebar
73 collapsed={collapsed}
74 setCollapsed={setCollapsed}
75 setOpen={setOpen}
76 open={open}
77 />
78 </DrawerContent>
79 </Drawer>
80 </aside>
81 <main className="sm:block">
82 <Outlet />
83 <Toaster position="top-center" />
84 </main>
85 </div>
86 )}
87 </div>
88 );
89};
90
91export const Route = createFileRoute("/_dashboard")({
92 component: () => <DashboardLayout />,
93
94 beforeLoad: async () => {
95 const loggedIn = await useAuth.getState().isLoggedIn();
96 if (!loggedIn) {
97 throw redirect({
98 to: "/login",
99 });
100 }
101 },
102});