skl/resources/js/Components/Sidebar.tsx

117 lines
4.0 KiB
TypeScript

import { Link, usePage } from "@inertiajs/react";
import { AlignJustifyIcon, Home, Icon } from "lucide-react";
import { cn } from "@/lib/utils";
import { buttonVariants } from "@/Components/ui/button";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/Components/ui/tooltip";
import { MenuItemProp } from "@/types";
import ApplicationLogo from "@/Components/ApplicationLogo";
import { ReactNode } from "react";
type Props = {
links: MenuItemProp[];
isCollapsed?: boolean;
};
type MenuItemProps = {
link: MenuItemProp;
isActive?: boolean;
};
const CollapsedMenuItem = ({ link, isActive }: MenuItemProps) => {
const Icon = (link.icon ?? AlignJustifyIcon) as React.ElementType;
return (
<Tooltip delayDuration={0}>
<TooltipTrigger asChild>
<Link
href={link.href}
className={cn(
buttonVariants({
variant: isActive ? "default" : "ghost",
size: "icon",
}),
"h-9 w-9",
link.variant === "default" &&
"dark:bg-muted dark:text-muted-foreground dark:hover:bg-muted dark:hover:text-white"
)}
>
{<Icon className="h-4 w-4" />}
<span className="sr-only">{link.title}</span>
</Link>
</TooltipTrigger>
<TooltipContent side="right" className="flex items-center gap-4">
{link.title}
</TooltipContent>
</Tooltip>
);
};
const ExpandedMenuItem = ({ link, isActive }: MenuItemProps) => {
const Icon = (link.icon ?? AlignJustifyIcon) as React.ElementType;
return (
<Link
href={link.href}
className={cn(
buttonVariants({ variant: isActive ? "default" : "ghost" }),
"justify-start"
)}
>
{<Icon className="mr-2 h-4 w-4" />}
{link.title}
</Link>
);
};
const Sidebar = ({ links, isCollapsed }: Props) => {
const { url } = usePage();
return (
<TooltipProvider>
<nav className="hidden bg-muted/40 md:block h-full">
<div className="flex h-full max-h-screen flex-col gap-2">
<div className="flex h-14 items-center border-b px-4 lg:h-[60px] lg:px-6">
<Link
href="/"
className={cn("flex items-center font-semibold", {
"justify-center": isCollapsed,
})}
>
<ApplicationLogo className="h-6 w-6 fill-current text-gray-500" />
{!isCollapsed && (
<span className="pl-2">Acme Inc</span>
)}
</Link>
</div>
<div className="flex-1">
<nav className="grid items-start space-y-2 text-sm font-medium lg:px-4">
{links.map((link, index) =>
isCollapsed ? (
<CollapsedMenuItem
key={index}
link={link}
isActive={link.href.includes(url)}
/>
) : (
<ExpandedMenuItem
key={index}
link={link}
isActive={link.href.includes(url)}
/>
)
)}
</nav>
</div>
</div>
</nav>
</TooltipProvider>
);
};
export default Sidebar;