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