gitscope
← marzneshin / v0.5.6 / 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 { useGithubRepoStatsQuery, 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";
 27
 28export const DashboardLayout = () => {
 29    const isDesktop = useScreenBreakpoint("md");
 30    const {
 31        collapsed,
 32        panelRef,
 33        setCollapsed,
 34        toggleCollapse,
 35    } = usePanelToggle(isDesktop);
 36    const { isSudo } = useAuth();
 37    const { data: stats } = useGithubRepoStatsQuery()
 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 {...stats} variant={isDesktop ? "full" : "mini"} />
 60                        <HeaderMenu />
 61                    </>
 62                }
 63            />
 64            <div className="flex flex-1 overflow-hidden">
 65                {isDesktop ? (
 66                    <ResizablePanelGroup direction="horizontal" className="flex h-full w-full">
 67                        <ResizablePanel
 68                            collapsible
 69                            collapsedSize={2}
 70                            onCollapse={() => setCollapsed(true)}
 71                            onExpand={() => setCollapsed(false)}
 72                            minSize={15}
 73                            className={cn("w-[120px] min-w-[70px]")}
 74                            defaultSize={20}
 75                            ref={panelRef}
 76                            maxSize={30}
 77                        >
 78                            <DashboardSidebar
 79                                collapsed={collapsed}
 80                                setCollapsed={setCollapsed}
 81                            />
 82                        </ResizablePanel>
 83                        <ResizableHandle withHandle className="w-[2px]" />
 84                        <ResizablePanel className="flex-col flex justify-between">
 85                            <main className="flex flex-col h-full">
 86                                <Suspense fallback={<Loading />}>
 87                                    <Outlet />
 88                                </Suspense>
 89                            </main>
 90                            <footer className="h-10 py-2">
 91                                <VersionIndicator />
 92                            </footer>
 93                        </ResizablePanel>
 94                    </ResizablePanelGroup>
 95                ) : (
 96                    <div className="flex flex-col h-full w-full">
 97                        <main className="flex flex-col h-full overflow-y-auto">
 98                            <Suspense fallback={<Loading />}>
 99                                <Outlet />
100                            </Suspense>
101                            <footer className="h-30 border-t-3 py-2 px-5">
102                                <DashboardBottomMenu variant={isSudo() ? "sudo-admin" : "admin"} />
103                            </footer>
104                        </main>
105                    </div>
106                )}
107            </div>
108            <Toaster position="top-center" />
109        </div>
110    );
111};
112
113export const Route = createFileRoute("/_dashboard")({
114    component: () => <DashboardLayout />,
115    beforeLoad: async () => {
116        const loggedIn = await useAuth.getState().isLoggedIn();
117        if (!loggedIn) {
118            throw redirect({
119                to: "/login",
120            });
121        }
122    },
123});