import { useState, PropsWithChildren, ReactNode, useEffect } from 'react';
import ApplicationLogo from '@/Components/ApplicationLogo';
import Dropdown from '@/Components/Dropdown';
import NavLink from '@/Components/NavLink';
import ResponsiveNavLink from '@/Components/ResponsiveNavLink';
import { Link, router, usePage } from '@inertiajs/react';
import { PageProps, User } from '@/types';
import { cn } from '@/lib/utils';
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from "@/Components/ui/collapsible";
import {
LayoutDashboard,
GraduationCap,
Award,
UserCircle,
LogOut,
ChevronDown,
Bell,
Menu,
X,
ChevronRight,
BookOpen,
Calendar,
ClipboardList,
Settings,
Users,
FileText,
Briefcase,
Cloud,
CreditCard,
Github,
Keyboard,
LifeBuoy,
Mail,
MessageSquare,
Plus,
PlusCircle,
UserPlus,
UserIcon,
SearchCode,
} from "lucide-react";
import { ScrollArea } from '@/Components/ui/scroll-area';
import { Button } from "@/Components/ui/button";
import { Separator } from "@/Components/ui/separator";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuPortal,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubContent,
DropdownMenuSubTrigger,
DropdownMenuTrigger,
} from "@/Components/ui/dropdown-menu"
import { toast } from '@/hooks/use-toast';
import { Toaster } from '@/Components/ui/toaster';
export default function AuthenticatedLayout({ user, header, children }: PropsWithChildren<{ user: User, header?: ReactNode }>) {
const [showingNavigationDropdown, setShowingNavigationDropdown] = useState(false);
const [sidebarOpen, setSidebarOpen] = useState(false);
const [openMenus, setOpenMenus] = useState<Record<string, boolean>>({
training: false,
certificates: false,
profile: false
});
const flash = usePage<PageProps>().props.flash;
useEffect(() => {
if (flash && flash.success) {
toast({
title: 'Success',
description: flash.success,
})
}
if (flash && flash.error) {
toast({
variant: "destructive",
title: 'Error',
description: flash.error,
})
}
}, [flash]);
const logOut = () => {
router.post('/logout');
}
const toggleMenu = (menu: string) => {
setOpenMenus(prev => ({
...prev,
[menu]: !prev[menu]
}));
};
return (
<div className="min-h-screen bg-gray-50/95">
{/* Mobile Overlay */}
{sidebarOpen && (
<div
className="fixed inset-0 bg-black/50 z-40 lg:hidden"
onClick={() => setSidebarOpen(false)}
/>
)}
{/* Sidebar */}
<aside className={`
fixed left-0 top-0 h-full bg-white border-r shadow-sm z-50
w-[280px] lg:w-64
transition-transform duration-200
${sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'}
`}>
<div className="flex items-center justify-between p-6 border-b">
<div className="flex items-center gap-2">
<LayoutDashboard className="w-6 h-6 text-blue-600" />
<span className="font-semibold text-lg">Talent Peserta</span>
</div>
<Button
variant="ghost"
size="icon"
className="lg:hidden"
onClick={() => setSidebarOpen(false)}
>
<X className="w-5 h-5" />
</Button>
</div>
<ScrollArea className="h-[calc(100vh-5rem)]">
<nav className="p-4 space-y-2">
<Link href={route('dashboard')}>
<Button variant="ghost" className="w-full justify-start gap-2">
<LayoutDashboard className="w-5 h-5" /> Dashboard
</Button>
</Link>
{/* Training Dropdown */}
<Collapsible open={openMenus.training} onOpenChange={() => toggleMenu('training')}>
<CollapsibleTrigger asChild>
<Button variant="ghost" className="w-full justify-between">
<div className="flex items-center gap-2">
<GraduationCap className="w-5 h-5" />
<span>Pelatihan</span>
</div>
<ChevronRight className={cn(
"w-4 h-4 transition-transform",
openMenus.training && "rotate-90"
)} />
</Button>
</CollapsibleTrigger>
<CollapsibleContent className="pl-6 space-y-1">
<Link href={route('course.index')}>
<Button variant="ghost" size="sm" className="w-full justify-start gap-2">
<SearchCode className="w-4 h-4" /> Cari
</Button>
</Link>
<Link href={route('pelatihan.index')}>
<Button variant="ghost" size="sm" className="w-full justify-start gap-2">
<BookOpen className="w-4 h-4" /> Terdaftar
</Button>
</Link>
<Link href={route('jadwal.index')}>
<Button variant="ghost" size="sm" className="w-full justify-start gap-2">
<Calendar className="w-4 h-4" /> Jadwal
</Button>
</Link>
<Link href={route('tugas.index')}>
<Button variant="ghost" size="sm" className="w-full justify-start gap-2">
<ClipboardList className="w-4 h-4" /> Tugas
</Button>
</Link>
</CollapsibleContent>
</Collapsible>
<Link href={route('sertifikat.index')}>
<Button variant="ghost" className="w-full justify-start gap-2">
<Award className="w-5 h-5" /> Sertifikat
</Button>
</Link>
<Link href={route('profile.edit')}>
<Button variant="ghost" className="w-full justify-start gap-2">
<UserCircle className="w-5 h-5" /> Profil
</Button>
</Link>
<Separator />
<Button onClick={logOut} variant="ghost" className="w-full justify-start gap-2 text-red-600 hover:text-red-700 hover:bg-red-50">
<LogOut className="w-5 h-5" /> Log out
</Button>
</nav>
</ScrollArea>
</aside>
{/* Main Content */}
<main className="lg:ml-64 p-4 lg:p-8">
<header className="flex flex-row justify-end mb:justify-start items-start sm:items-center gap-4 mb-4">
<div className="flex items-center gap-4 lg:hidden">
<Button
variant="outline"
size="icon"
onClick={() => setSidebarOpen(true)}
>
<Menu className="w-5 h-5" />
</Button>
</div>
{/* <div>
<h1 className="text-2xl font-bold">Hello, John Wick</h1>
<p className="text-gray-500">Track your training progress here</p>
</div> */}
<div className="flex items-center gap-4 w-full justify-end">
<Button variant="ghost" size="icon">
<Bell className="w-5 h-5" />
</Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" className="gap-2">
<img
src={route('my-avatar')}
alt="Profile"
className="w-6 h-6 rounded-full"
/>
<span className="hidden sm:inline">{user.nama}</span>
<ChevronDown className="w-4 h-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuSeparator />
{/* <DropdownMenuGroup>
<DropdownMenuItem>
<UserIcon />
<span>Profile</span>
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<CreditCard />
<span>Billing</span>
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<Settings />
<span>Settings</span>
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
<Keyboard />
<span>Keyboard shortcuts</span>
<DropdownMenuShortcut>⌘K</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<Users />
<span>Team</span>
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
<UserPlus />
<span>Invite users</span>
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>
<Mail />
<span>Email</span>
</DropdownMenuItem>
<DropdownMenuItem>
<MessageSquare />
<span>Message</span>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
<PlusCircle />
<span>More...</span>
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuItem>
<Plus />
<span>New Team</span>
<DropdownMenuShortcut>⌘+T</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem>
<Github />
<span>GitHub</span>
</DropdownMenuItem>
<DropdownMenuItem>
<LifeBuoy />
<span>Support</span>
</DropdownMenuItem>
<DropdownMenuItem disabled>
<Cloud />
<span>API</span>
</DropdownMenuItem>
<DropdownMenuSeparator /> */}
<DropdownMenuItem onClick={logOut}>
<LogOut />
<span>Log out</span>
<DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</header>
{children}
<Toaster />
</main>
</div>
);
}
Anons79 File Manager Version 1.0, Coded By Anons79
Email: [email protected]