gitscope
← marzneshin / v0.3.2 / dashboard/src/routes/_dashboard.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/routes/_dashboard.tsx · TypeScript
Blame Raw
  1import {
  2    Header,
  3    ResizableHandle,
  4    ResizablePanel,
  5    ResizablePanelGroup,
  6    Toaster,
  7    Loading,
  8    HeaderLogo,
  9    HeaderMenu,
 10} from "@marzneshin/components";
 11import { useAuth } from "@marzneshin/features/auth";
 12import { DashboardSidebar, ToggleButton } 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 { Suspense } from "react";
 17import {
 18    Outlet,
 19    Link,
 20    createFileRoute,
 21    redirect
 22} from "@tanstack/react-router";
 23import { GithubRepo } from "@marzneshin/features/github-repo";
 24import { CommandBox } from "@marzneshin/features/search-command";
 25import { DashboardBottomMenu } from "@marzneshin/features/bottom-menu";
 26import { VersionIndicator } from "@marzneshin/features/version-indicator";
 27import { Settings } from "lucide-react";
 28
 29export const DashboardLayout = () => {
 30    const isDesktop = useScreenBreakpoint("md");
 31    const {
 32        collapsed,
 33        panelRef,
 34        setCollapsed,
 35        toggleCollapse,
 36    } = usePanelToggle(isDesktop);
 37    const { isSudo } = useAuth();
 38
 39    return (
 40        <div className="flex flex-col w-screen h-screen">
 41            <Header
 42                start={
 43                    <>
 44                        <Link to="/">
 45                            <HeaderLogo />
 46                        </Link>
 47                        {isDesktop && (
 48
 49                            <ToggleButton
 50                                collapsed={collapsed}
 51                                onToggle={toggleCollapse}
 52                            />
 53                        )}
 54                    </>
 55                }
 56                center={<CommandBox />}
 57                end={
 58                    <>
 59                        <GithubRepo variant={isDesktop ? "full" : "mini"} />
 60                        {(!isDesktop && isSudo()) && (<Link to="/settings">
 61                            <Settings className="bg-gray-800 text-secondary dark:hover:bg-secondary-foreground dark:hover:text-secondary dark:text-secondary-foreground size-10 rounded-md text-2xl p-2" />
 62                        </Link>
 63                        )}
 64                        <HeaderMenu />
 65                    </>
 66                }
 67            />
 68            <div className="flex flex-1 overflow-hidden">
 69                {isDesktop ? (
 70                    <ResizablePanelGroup direction="horizontal" className="flex h-full w-full">
 71                        <ResizablePanel
 72                            collapsible
 73                            collapsedSize={2}
 74                            onCollapse={() => setCollapsed(true)}
 75                            onExpand={() => setCollapsed(false)}
 76                            minSize={15}
 77                            className={cn("w-[120px] min-w-[70px]")}
 78                            defaultSize={20}
 79                            ref={panelRef}
 80                            maxSize={30}
 81                        >
 82                            <DashboardSidebar
 83                                collapsed={collapsed}
 84                                setCollapsed={setCollapsed}
 85                            />
 86                        </ResizablePanel>
 87                        <ResizableHandle withHandle className="w-[2px]" />
 88                        <ResizablePanel className="flex-col flex justify-between">
 89                            <main className="flex flex-col h-full">
 90                                <Suspense fallback={<Loading />}>
 91                                    <Outlet />
 92                                </Suspense>
 93                            </main>
 94                            <footer className="h-10 py-2">
 95                                <VersionIndicator />
 96                            </footer>
 97                        </ResizablePanel>
 98                    </ResizablePanelGroup>
 99                ) : (
100                    <div className="flex flex-col h-full w-full">
101                        <main className="flex flex-col h-full overflow-y-auto">
102                            <Suspense fallback={<Loading />}>
103                                <Outlet />
104                            </Suspense>
105                            <footer className="h-30 border-t-3 py-2 px-5">
106                                <DashboardBottomMenu variant={isSudo() ? "sudo-admin" : "admin"} />
107                            </footer>
108                        </main>
109                    </div>
110                )}
111            </div>
112            <Toaster position="top-center" />
113        </div>
114    );
115};
116
117export const Route = createFileRoute("/_dashboard")({
118    component: () => <DashboardLayout />,
119    beforeLoad: async () => {
120        const loggedIn = await useAuth.getState().isLoggedIn();
121        if (!loggedIn) {
122            throw redirect({
123                to: "/login",
124            });
125        }
126    },
127});