gitscope
← marzneshin / v0.4.1 / dashboard/src/components/nav-dir/index.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/components/nav-dir/index.tsx · TypeScript
Blame Raw
  1
  2import { Link, useRouterState } from "@tanstack/react-router";
  3import React, { FC } from 'react'
  4import {
  5    BreadcrumbPage,
  6    Drawer,
  7    DrawerClose,
  8    DrawerContent,
  9    DrawerDescription,
 10    DrawerTrigger,
 11    Breadcrumb,
 12    BreadcrumbEllipsis,
 13    BreadcrumbItem,
 14    BreadcrumbLink,
 15    BreadcrumbList,
 16    BreadcrumbSeparator,
 17    DrawerFooter,
 18    DrawerHeader,
 19    DrawerTitle,
 20    DropdownMenu,
 21    DropdownMenuContent,
 22    DropdownMenuItem,
 23    DropdownMenuTrigger,
 24    Button,
 25    SidebarObject,
 26} from "@marzneshin/components"
 27import { useScreenBreakpoint } from "@marzneshin/hooks/use-screen-breakpoint";
 28import { AppRouterPaths } from "@marzneshin/types";
 29import i18n from "@marzneshin/features/i18n";
 30
 31interface Dir {
 32    href: AppRouterPaths;
 33    label: string;
 34}
 35
 36interface NavigationDirectoryProps {
 37    sidebar: SidebarObject;
 38}
 39
 40
 41function getPathDirs(currentPath: string, sidebar: SidebarObject): Dir[] {
 42    const dirs: Dir[] = [];
 43    const pathArray = currentPath.split('/').filter(Boolean); // Split path and remove empty strings
 44    let fullPath = '/';
 45    for (let i = 0; i < pathArray.length; i++) {
 46        const dir = pathArray[i];
 47        fullPath += `/${dir}`;
 48        if (sidebar[dir]) {
 49            dirs.push({ href: sidebar[dir][0].to, label: sidebar[dir][0].title });
 50        } else {
 51            dirs.push({ href: fullPath as AppRouterPaths, label: i18n.t(dir) });
 52        }
 53    }
 54    return dirs;
 55}
 56
 57const ITEMS_TO_DISPLAY = 3
 58
 59export const NavigationDirectory: FC<NavigationDirectoryProps> = ({ sidebar }) => {
 60    const [open, setOpen] = React.useState(false)
 61    const currentPath = useRouterState().location.pathname;
 62    const items = getPathDirs(currentPath, sidebar);
 63    const isDesktop = !useScreenBreakpoint("sm");
 64    return (
 65        <Breadcrumb>
 66            <BreadcrumbList>
 67                {items.length > ITEMS_TO_DISPLAY ? (
 68                    <>
 69                        <BreadcrumbItem>
 70                            {isDesktop ? (
 71                                <DropdownMenu open={open} onOpenChange={setOpen}>
 72                                    <DropdownMenuTrigger
 73                                        className="flex gap-1 items-center"
 74                                        aria-label="Toggle menu"
 75                                    >
 76                                        <BreadcrumbEllipsis className="w-4 h-4" />
 77                                    </DropdownMenuTrigger>
 78                                    <DropdownMenuContent align="start">
 79                                        {items.slice(1, -2).map((item, index) => (
 80                                            <DropdownMenuItem key={index}>
 81                                                <Link to={item.href} className="capitalize">
 82                                                    {item.label}
 83                                                </Link>
 84                                            </DropdownMenuItem>
 85                                        ))}
 86                                    </DropdownMenuContent>
 87                                </DropdownMenu>
 88                            ) : (
 89                                <Drawer open={open} onOpenChange={setOpen}>
 90                                    <DrawerTrigger aria-label="Toggle Menu">
 91                                        <BreadcrumbEllipsis className="w-4 h-4" />
 92                                    </DrawerTrigger>
 93                                    <DrawerContent>
 94                                        <DrawerHeader className="text-left">
 95                                            <DrawerTitle>Navigate to</DrawerTitle>
 96                                            <DrawerDescription>
 97                                                Select a page to navigate to.
 98                                            </DrawerDescription>
 99                                        </DrawerHeader>
100                                        <div className="grid gap-1 px-4">
101                                            {items.slice(1, -2).map((item, index) => (
102                                                <Link
103                                                    key={index}
104                                                    to="/"
105                                                    className="py-1 text-sm"
106                                                >
107                                                    {item.label}
108                                                </Link>
109                                            ))}
110                                        </div>
111                                        <DrawerFooter className="pt-4">
112                                            <DrawerClose asChild>
113                                                <Button variant="outline">Close</Button>
114                                            </DrawerClose>
115                                        </DrawerFooter>
116                                    </DrawerContent>
117                                </Drawer>
118                            )}
119                        </BreadcrumbItem>
120                    </>
121                ) : null}
122                {items.slice(-ITEMS_TO_DISPLAY + 1).map((item, index) => (
123                    <BreadcrumbItem key={index}>
124                        {item.href ? (
125                            <>
126                                <BreadcrumbLink
127                                    asChild
128                                    className="md:max-w-none max-w-20 truncate text-accent dark:text-accent-foreground hover:text-primary-foreground"
129                                >
130                                    <Link to={item.href}>{item.label}</Link>
131                                </BreadcrumbLink>
132                                {index !== items.slice(-ITEMS_TO_DISPLAY + 1).length - 1 && <BreadcrumbSeparator />}
133                            </>
134                        ) : (
135                            <BreadcrumbPage className="md:max-w-none max-w-20 truncate">
136                                {item.label}
137                            </BreadcrumbPage>
138                        )}
139                    </BreadcrumbItem>
140                ))}
141            </BreadcrumbList>
142        </Breadcrumb>
143    )
144}