forked from 77media/video-flow
103 lines
3.0 KiB
TypeScript
103 lines
3.0 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from 'react';
|
|
import Link from 'next/link';
|
|
import { usePathname } from 'next/navigation';
|
|
import { cn } from '@/public/lib/utils';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Separator } from '@/components/ui/separator';
|
|
import { GradientText } from '@/components/ui/gradient-text';
|
|
import {
|
|
Home,
|
|
FolderOpen,
|
|
Users,
|
|
Type,
|
|
Image,
|
|
History,
|
|
ChevronLeft,
|
|
ChevronRight,
|
|
Video,
|
|
PanelsLeftBottom,
|
|
ArrowLeftToLine,
|
|
BookHeart,
|
|
PanelRightClose,
|
|
Gift
|
|
} from 'lucide-react';
|
|
|
|
interface SidebarProps {
|
|
collapsed: boolean;
|
|
onToggle: (collapsed: boolean) => void;
|
|
}
|
|
|
|
const navigationItems = [
|
|
{
|
|
title: 'Main',
|
|
items: [
|
|
{ name: 'My Portfolio', href: '/movies', icon: BookHeart },
|
|
{ name: 'Share', href: '/share', icon: Gift },
|
|
],
|
|
}
|
|
];
|
|
|
|
export function Sidebar({ collapsed, onToggle }: SidebarProps) {
|
|
const pathname = usePathname();
|
|
|
|
return (
|
|
<>
|
|
{/* Sidebar */}
|
|
<div
|
|
data-alt="sidebar-container"
|
|
className={cn(
|
|
'fixed left-0 top-0 z-[999] h-full bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60',
|
|
'border-r border-r-[#ffffff14] transition-all duration-300 ease-in-out',
|
|
collapsed ? 'w-[3rem]' : 'w-[16rem]'
|
|
)}
|
|
>
|
|
<div className="flex h-full flex-col">
|
|
{/* Toggle Button */}
|
|
<div className="flex h-16 items-center px-4">
|
|
<Button
|
|
data-alt="toggle-sidebar"
|
|
variant="ghost"
|
|
size="icon"
|
|
className={cn(
|
|
'h-4 w-4 rounded-full transition-transform duration-300 text-gray-300',
|
|
!collapsed && 'rotate-180'
|
|
)}
|
|
onClick={() => onToggle(!collapsed)}
|
|
>
|
|
<PanelRightClose className="h-4 w-4" />
|
|
</Button>
|
|
</div>
|
|
|
|
{/* Navigation */}
|
|
<div className="flex-1 space-y-1 px-1">
|
|
{navigationItems.map((section) => (
|
|
<div key={section.title} className="space-y-1">
|
|
{section.items.map((item) => {
|
|
const isActive = pathname === item.href;
|
|
return (
|
|
<Link key={item.name} href={item.href}>
|
|
<Button
|
|
data-alt={`nav-item-${item.name}`}
|
|
variant={isActive ? 'secondary' : 'ghost'}
|
|
className={cn(
|
|
'w-full justify-start',
|
|
collapsed ? 'px-3' : 'px-4',
|
|
isActive && 'bg-primary/10 text-primary hover:bg-primary/20'
|
|
)}
|
|
>
|
|
<item.icon className={cn('h-4 w-4 shrink-0 text-gray-300', !collapsed && 'mr-2')} />
|
|
{!collapsed && <span>{item.name}</span>}
|
|
</Button>
|
|
</Link>
|
|
);
|
|
})}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
} |