gitscope
← marzneshin / v0.7.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/common/components";
 11import { useAuth } from "@marzneshin/modules/auth";
 12import { DashboardSidebar, ToggleButton } from "@marzneshin/features/sidebar";
 13import { usePanelToggle } from "@marzneshin/features/sidebar/use-panel-toggle";
 14import { useScreenBreakpoint } from "@marzneshin/common/hooks/use-screen-breakpoint";
 15import { cn } from "@marzneshin/common/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";
 26
 27export const DashboardLayout = () => {
 28    const isDesktop = useScreenBreakpoint("md");
 29    const {
 30        collapsed,
 31        panelRef,
 32        setCollapsed,
 33        toggleCollapse,
 34    } = usePanelToggle(isDesktop);
 35    const { isSudo } = useAuth();
 36    const { data: stats } = useGithubRepoStatsQuery()
 37
 38    return (
 39        <div className="flex flex-col w-screen h-screen">
 40            <Header
 41                start={
 42                    <>
 43                        <Link to="/">
 44                            <HeaderLogo />
 45                        </Link>
 46                        {isDesktop && (
 47
 48                            <ToggleButton
 49                                collapsed={collapsed}
 50                                onToggle={toggleCollapse}
 51                            />
 52                        )}
 53                    </>
 54                }
 55                center={<CommandBox />}
 56                end={
 57                    <>
 58                        <GithubRepo {...stats} variant={isDesktop ? "full" : "mini"} />
 59                        <HeaderMenu />
 60                    </>
 61                }
 62            />
 63            <div className="flex flex-1 overflow-hidden">
 64                {isDesktop ? (
 65                    <ResizablePanelGroup direction="horizontal" className="flex h-full w-full">
 66                        <ResizablePanel
 67                            collapsible
 68                            collapsedSize={2}
 69                            onCollapse={() => setCollapsed(true)}
 70                            onExpand={() => setCollapsed(false)}
 71                            minSize={15}
 72                            className={cn("w-[120px] min-w-[70px]")}
 73                            defaultSize={20}
 74                            ref={panelRef}
 75                            maxSize={30}
 76                        >
 77                            <DashboardSidebar
 78                                collapsed={collapsed}
 79                                setCollapsed={setCollapsed}
 80                            />
 81                        </ResizablePanel>
 82                        <ResizableHandle withHandle className="w-[2px]" />
 83                        <ResizablePanel className="flex flex-col h-full">
 84                            <main className="flex-grow flex flex-col overflow-y-auto">
 85                                <Suspense fallback={<Loading />}>
 86                                    <Outlet />
 87                                </Suspense>
 88                            </main>
 89                        </ResizablePanel>
 90                    </ResizablePanelGroup>
 91                ) : (
 92                    <div className="flex flex-col h-full w-full">
 93                        <main className="flex flex-col h-full overflow-y-auto">
 94                            <Suspense fallback={<Loading />}>
 95                                <Outlet />
 96                            </Suspense>
 97                            <footer className="h-30 border-t-3 shrink-0 py-2 px-5">
 98                                <DashboardBottomMenu variant={isSudo() ? "sudo-admin" : "admin"} />
 99                            </footer>
100                        </main>
101                    </div>
102                )}
103            </div>
104            <Toaster position="top-center" />
105        </div>
106    );
107};
108
109export const Route = createFileRoute("/_dashboard")({
110    component: () => <DashboardLayout />,
111    beforeLoad: async () => {
112        const loggedIn = await useAuth.getState().isLoggedIn();
113        if (!loggedIn) {
114            throw redirect({
115                to: "/login",
116            });
117        }
118    },
119});