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