[rewrite] Updated frontend structure and played with custom routes

This commit is contained in:
Thastertyn committed 2025-02-21 14:51:17 +01:00
1 parent 43063dcf4e
commit 073f01d070
243 files changed
+11778 -11940

No files matched your search

+151 -156
View File
@@ -1,180 +1,175 @@
import { ReactNode } from 'react'
import { Link, useLocation } from '@tanstack/react-router'
import { ChevronRight } from 'lucide-react'
import { ReactNode } from "react";
import { Link, useLocation } from "@tanstack/react-router";
import { ChevronRight } from "lucide-react";
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from '@/components/ui/collapsible'
Collapsible,
CollapsibleContent,
CollapsibleTrigger
} from "@/components/ui/collapsible";
import {
SidebarGroup,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarMenuSub,
SidebarMenuSubButton,
SidebarMenuSubItem,
useSidebar,
} from '@/components/ui/sidebar'
import { Badge } from '../ui/badge'
SidebarGroup,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarMenuSub,
SidebarMenuSubButton,
SidebarMenuSubItem,
useSidebar
} from "@/components/ui/sidebar";
import { Badge } from "../ui/badge";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '../ui/dropdown-menu'
import { NavCollapsible, NavItem, NavLink, type NavGroup } from './types'
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger
} from "../ui/dropdown-menu";
import { NavCollapsible, NavItem, NavLink, type NavGroup } from "./types";
export function NavGroup({ title, items }: NavGroup) {
const { state } = useSidebar()
const href = useLocation({ select: (location) => location.href })
return (
<SidebarGroup>
<SidebarGroupLabel>{title}</SidebarGroupLabel>
<SidebarMenu>
{items.map((item) => {
const key = `${item.title}-${item.url}`
const { state } = useSidebar();
const href = useLocation({ select: (location) => location.href });
return (
<SidebarGroup>
<SidebarGroupLabel>{title}</SidebarGroupLabel>
<SidebarMenu>
{items.map((item) => {
const key = `${item.title}-${item.url}`;
if (!item.items)
return <SidebarMenuLink key={key} item={item} href={href} />
if (!item.items)
return <SidebarMenuLink key={key} item={item} href={href} />;
if (state === 'collapsed')
return (
<SidebarMenuCollapsedDropdown key={key} item={item} href={href} />
)
if (state === "collapsed")
return (
<SidebarMenuCollapsedDropdown key={key} item={item} href={href} />
);
return <SidebarMenuCollapsible key={key} item={item} href={href} />
})}
</SidebarMenu>
</SidebarGroup>
)
return <SidebarMenuCollapsible key={key} item={item} href={href} />;
})}
</SidebarMenu>
</SidebarGroup>
);
}
const NavBadge = ({ children }: { children: ReactNode }) => (
<Badge className='rounded-full px-1 py-0 text-xs'>{children}</Badge>
)
<Badge className="rounded-full px-1 py-0 text-xs">{children}</Badge>
);
const SidebarMenuLink = ({ item, href }: { item: NavLink; href: string }) => {
const { setOpenMobile } = useSidebar()
return (
<SidebarMenuItem>
<SidebarMenuButton
asChild
isActive={checkIsActive(href, item)}
tooltip={item.title}
>
<Link to={item.url} onClick={() => setOpenMobile(false)}>
{item.icon && <item.icon />}
<span>{item.title}</span>
{item.badge && <NavBadge>{item.badge}</NavBadge>}
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
)
}
const { setOpenMobile } = useSidebar();
return (
<SidebarMenuItem>
<SidebarMenuButton
asChild
isActive={checkIsActive(href, item)}
tooltip={item.title}>
<Link to={item.url} onClick={() => setOpenMobile(false)}>
{item.icon && <item.icon />}
<span>{item.title}</span>
{item.badge && <NavBadge>{item.badge}</NavBadge>}
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
);
};
const SidebarMenuCollapsible = ({
item,
href,
item,
href
}: {
item: NavCollapsible
href: string
item: NavCollapsible;
href: string;
}) => {
const { setOpenMobile } = useSidebar()
return (
<Collapsible
asChild
defaultOpen={checkIsActive(href, item, true)}
className='group/collapsible'
>
<SidebarMenuItem>
<CollapsibleTrigger asChild>
<SidebarMenuButton tooltip={item.title}>
{item.icon && <item.icon />}
<span>{item.title}</span>
{item.badge && <NavBadge>{item.badge}</NavBadge>}
<ChevronRight className='ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90' />
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent className='CollapsibleContent'>
<SidebarMenuSub>
{item.items.map((subItem) => (
<SidebarMenuSubItem key={subItem.title}>
<SidebarMenuSubButton
asChild
isActive={checkIsActive(href, subItem)}
>
<Link to={subItem.url} onClick={() => setOpenMobile(false)}>
{subItem.icon && <subItem.icon />}
<span>{subItem.title}</span>
{subItem.badge && <NavBadge>{subItem.badge}</NavBadge>}
</Link>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
))}
</SidebarMenuSub>
</CollapsibleContent>
</SidebarMenuItem>
</Collapsible>
)
}
const { setOpenMobile } = useSidebar();
return (
<Collapsible
asChild
defaultOpen={checkIsActive(href, item, true)}
className="group/collapsible">
<SidebarMenuItem>
<CollapsibleTrigger asChild>
<SidebarMenuButton tooltip={item.title}>
{item.icon && <item.icon />}
<span>{item.title}</span>
{item.badge && <NavBadge>{item.badge}</NavBadge>}
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
</SidebarMenuButton>
</CollapsibleTrigger>
<CollapsibleContent className="CollapsibleContent">
<SidebarMenuSub>
{item.items.map((subItem) => (
<SidebarMenuSubItem key={subItem.title}>
<SidebarMenuSubButton
asChild
isActive={checkIsActive(href, subItem)}>
<Link to={subItem.url} onClick={() => setOpenMobile(false)}>
{subItem.icon && <subItem.icon />}
<span>{subItem.title}</span>
{subItem.badge && <NavBadge>{subItem.badge}</NavBadge>}
</Link>
</SidebarMenuSubButton>
</SidebarMenuSubItem>
))}
</SidebarMenuSub>
</CollapsibleContent>
</SidebarMenuItem>
</Collapsible>
);
};
const SidebarMenuCollapsedDropdown = ({
item,
href,
item,
href
}: {
item: NavCollapsible
href: string
item: NavCollapsible;
href: string;
}) => {
return (
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuButton
tooltip={item.title}
isActive={checkIsActive(href, item)}
>
{item.icon && <item.icon />}
<span>{item.title}</span>
{item.badge && <NavBadge>{item.badge}</NavBadge>}
<ChevronRight className='ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90' />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent side='right' align='start' sideOffset={4}>
<DropdownMenuLabel>
{item.title} {item.badge ? `(${item.badge})` : ''}
</DropdownMenuLabel>
<DropdownMenuSeparator />
{item.items.map((sub) => (
<DropdownMenuItem key={`${sub.title}-${sub.url}`} asChild>
<Link
to={sub.url}
className={`${checkIsActive(href, sub) ? 'bg-secondary' : ''}`}
>
{sub.icon && <sub.icon />}
<span className='max-w-52 text-wrap'>{sub.title}</span>
{sub.badge && (
<span className='ml-auto text-xs'>{sub.badge}</span>
)}
</Link>
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
)
}
return (
<SidebarMenuItem>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuButton
tooltip={item.title}
isActive={checkIsActive(href, item)}>
{item.icon && <item.icon />}
<span>{item.title}</span>
{item.badge && <NavBadge>{item.badge}</NavBadge>}
<ChevronRight className="ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90" />
</SidebarMenuButton>
</DropdownMenuTrigger>
<DropdownMenuContent side="right" align="start" sideOffset={4}>
<DropdownMenuLabel>
{item.title} {item.badge ? `(${item.badge})` : ""}
</DropdownMenuLabel>
<DropdownMenuSeparator />
{item.items.map((sub) => (
<DropdownMenuItem key={`${sub.title}-${sub.url}`} asChild>
<Link
to={sub.url}
className={`${checkIsActive(href, sub) ? "bg-secondary" : ""}`}>
{sub.icon && <sub.icon />}
<span className="max-w-52 text-wrap">{sub.title}</span>
{sub.badge && (
<span className="ml-auto text-xs">{sub.badge}</span>
)}
</Link>
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
</SidebarMenuItem>
);
};
function checkIsActive(href: string, item: NavItem, mainNav = false) {
return (
href === item.url || // /endpint?search=param
href.split('?')[0] === item.url || // endpoint
!!item?.items?.filter((i) => i.url === href).length || // if child nav is active
(mainNav &&
href.split('/')[1] !== '' &&
href.split('/')[1] === item?.url?.split('/')[1])
)
return (
href === item.url || // /endpint?search=param
href.split("?")[0] === item.url || // endpoint
!!item?.items?.filter((i) => i.url === href).length || // if child nav is active
(mainNav &&
href.split("/")[1] !== "" &&
href.split("/")[1] === item?.url?.split("/")[1])
);
}