Files
personel/src/components/layout/Sidebar.tsx
T

185 lines
8.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import { useState, useEffect } from 'react'
import Link from 'next/link'
import Image from 'next/image'
import { usePathname } from 'next/navigation'
import {
HomeIcon,
UsersIcon,
CalendarDaysIcon,
BuildingOfficeIcon,
Cog6ToothIcon,
ArrowRightOnRectangleIcon,
Bars3Icon,
XMarkIcon,
} from '@heroicons/react/24/outline'
const navigation = [
{ name: 'Dashboard', href: '/', icon: HomeIcon },
{ name: 'Personeller', href: '/employees', icon: UsersIcon },
{ name: 'İzinler', href: '/leave-requests', icon: CalendarDaysIcon },
{ name: 'Şirketler', href: '/companies', icon: BuildingOfficeIcon },
{ name: 'Ayarlar', href: '/settings', icon: Cog6ToothIcon },
]
interface SidebarProps {
isAdmin?: boolean
}
export function Sidebar({ isAdmin = false }: SidebarProps) {
const pathname = usePathname()
const [sidebarOpen, setSidebarOpen] = useState(false)
const filteredNavigation = navigation.filter(item => {
if (item.href === '/companies') return isAdmin
return true
})
// Listen for mobile menu open event from Header
useEffect(() => {
const handleOpen = () => setSidebarOpen(true);
window.addEventListener('open-mobile-menu', handleOpen);
return () => window.removeEventListener('open-mobile-menu', handleOpen);
}, []);
return (
<>
{/* Drawer logic is below, Mobile Header is now in Header.tsx */}
{/* Mobile Sidebar Overlay (Drawer) */}
{sidebarOpen && (
<div className="relative z-50 lg:hidden" aria-modal="true">
<div className="fixed inset-0 bg-slate-900/60 backdrop-blur-sm transition-opacity" onClick={() => setSidebarOpen(false)} />
<div className="fixed inset-0 flex">
<div className="relative flex w-full max-w-xs flex-1 transform transition duration-300 ease-in-out">
<div className="absolute right-0 top-0 -mr-12 pt-4">
<button
type="button"
className="ml-1 flex h-10 w-10 items-center justify-center rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white"
onClick={() => setSidebarOpen(false)}
>
<span className="sr-only">Menüyü Kapat</span>
<XMarkIcon className="h-6 w-6 text-white" aria-hidden="true" />
</button>
</div>
{/* Mobile Sidebar Content - Reusing Desktop Style */}
<div className="flex grow flex-col gap-y-5 overflow-y-auto bg-[#173363] px-6 pb-4 shadow-2xl">
<div className="flex h-24 shrink-0 items-center mt-4 border-b border-white/10">
<div className="flex flex-col gap-1">
<Image src="/logo.png" alt="Abisena Logo" width={140} height={45} className="h-10 w-auto object-contain" />
<span className="text-[9px] font-black text-slate-400 tracking-[0.3em] uppercase ml-1">Personel Takip Sistemi</span>
</div>
</div>
<nav className="flex flex-1 flex-col">
<ul role="list" className="flex flex-1 flex-col gap-y-7">
<li>
<ul role="list" className="-mx-2 space-y-2">
{filteredNavigation.map((item) => (
<li key={item.name}>
<Link
href={item.href}
onClick={() => setSidebarOpen(false)}
className={`
group flex items-center gap-x-3 rounded-xl p-3 text-sm leading-6 font-semibold transition-all
${pathname === item.href
? 'bg-[#CE0515] text-white'
: 'text-slate-300 hover:text-white hover:bg-white/5'
}
`}
>
<item.icon
className={`h-5 w-5 shrink-0 ${pathname === item.href ? 'text-white' : 'text-slate-400 group-hover:text-white'}`}
aria-hidden="true"
/>
{item.name}
</Link>
</li>
))}
</ul>
</li>
<li className="mt-auto">
<form action="/auth/signout" method="post" className="-mx-2 pb-4">
<button type="submit" className="group flex w-full items-center gap-x-3 rounded-xl p-3 text-sm font-bold text-slate-400 hover:text-white transition-all">
<ArrowRightOnRectangleIcon className="h-5 w-5 shrink-0" />
Güvenli Çıkış
</button>
</form>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
)}
{/* Desktop Sidebar */}
<div className="hidden lg:fixed lg:inset-y-0 lg:z-50 lg:flex lg:w-72 lg:flex-col">
<div className="flex grow flex-col gap-y-5 overflow-y-auto bg-[#173363] px-6 pb-4 shadow-xl">
<div className="flex h-24 shrink-0 items-center mt-6 mb-2 border-b border-gray-100/50 dark:border-zinc-900/50">
<div className="flex flex-col items-start gap-2 group cursor-pointer w-full">
<div className="p-2 transition-all duration-300 group-hover:brightness-110">
<Image src="/logo.png" alt="Abisena Logo" width={180} height={60} className="h-12 w-auto object-contain" priority />
</div>
<div className="px-2 w-full">
<div className="h-px w-full bg-gradient-to-r from-gray-200 via-gray-100 to-transparent dark:from-zinc-800 dark:via-zinc-900 dark:to-transparent mb-2" />
<span className="text-[10px] font-black text-gray-400 dark:text-zinc-500 tracking-[0.3em] uppercase ml-1 block">Personel Takip Sistemi</span>
</div>
</div>
</div>
<nav className="flex flex-1 flex-col">
<ul role="list" className="flex flex-1 flex-col gap-y-7">
<li>
<div className="text-[10px] font-bold tracking-widest leading-6 text-slate-400 mb-4 uppercase">YÖNETİM PANELİ</div>
<ul role="list" className="-mx-2 space-y-2">
{filteredNavigation.map((item) => (
<li key={item.name}>
<Link
href={item.href}
className={`
group flex items-center gap-x-3 rounded-xl p-3 text-sm leading-6 font-semibold transition-all duration-300 relative overflow-hidden
${pathname === item.href
? 'bg-[#CE0515] text-white shadow-lg shadow-red-900/20'
: 'text-slate-300 hover:text-white hover:bg-white/5'
}
`}
>
<item.icon
className={`h-5 w-5 shrink-0 transition-colors duration-200 ${pathname === item.href ? 'text-white' : 'text-slate-400 group-hover:text-white'}`}
aria-hidden="true"
/>
{item.name}
{pathname === item.href && (
<div className="ml-auto w-1.5 h-1.5 rounded-full bg-white animate-pulse" />
)}
</Link>
</li>
))}
</ul>
</li>
<li className="mt-auto">
<form action="/auth/signout" method="post" className="-mx-2 pb-4">
<button
type="submit"
className="group flex w-full items-center gap-x-3 rounded-2xl p-3 text-sm font-bold leading-6 text-slate-500 hover:text-rose-600 dark:text-zinc-400 dark:hover:text-rose-400 hover:bg-rose-50 dark:hover:bg-rose-500/5 transition-all duration-300 active:scale-95"
>
<ArrowRightOnRectangleIcon
className="h-5 w-5 shrink-0 text-slate-400 group-hover:text-rose-500 transition-colors duration-300"
aria-hidden="true"
/>
Güvenli Çıkış
</button>
</form>
</li>
</ul>
</nav>
</div>
</div>
</>
)
}