Files
landingpage_ljn/src/layouts/AdminLayout.tsx
T
2026-08-24 13:38:25 +07:00

113 lines
3.7 KiB
TypeScript

import { useState } from "react"
import { Link, Outlet, useLocation } from "react-router-dom"
import {
LayoutDashboard,
Package,
Zap,
Info,
Phone,
Share2,
Gift,
Menu,
X,
Home,
Image,
LogOut,
} from "lucide-react"
import { Button } from "@/components/ui/button"
import { cn } from "@/utils/helpers"
import { useAuth } from "@/context/AuthContext"
const menuItems = [
{ href: "/admin", icon: LayoutDashboard, label: "Dashboard" },
{ href: "/admin/hero", icon: Home, label: "Konten" },
{ href: "/admin/packages", icon: Package, label: "Paket Internet" },
{ href: "/admin/benefits", icon: Zap, label: "Keunggulan" },
{ href: "/admin/about", icon: Info, label: "Tentang Kami" },
{ href: "/admin/gallery", icon: Image, label: "Galeri" },
{ href: "/admin/contact", icon: Phone, label: "Kontak" },
{ href: "/admin/social", icon: Share2, label: "Media Sosial" },
{ href: "/admin/promo", icon: Gift, label: "Promo Pop-up" },
]
export default function AdminLayout() {
const [sidebarOpen, setSidebarOpen] = useState(false)
const location = useLocation()
const { logout } = useAuth()
const handleSignOut = async () => {
await logout()
}
return (
<div className="min-h-screen bg-gray-100">
<div className="bg-yellow-300 border-b-4 border-black px-4 h-14 flex items-center justify-between lg:hidden">
<span className="font-black">Admin Panel</span>
<div className="flex items-center gap-2">
<Button variant="brutal" size="icon" onClick={handleSignOut} aria-label="Logout">
<LogOut className="h-4 w-4" />
</Button>
<Button variant="brutal" size="icon" onClick={() => setSidebarOpen(!sidebarOpen)}>
{sidebarOpen ? <X className="h-4 w-4" /> : <Menu className="h-4 w-4" />}
</Button>
</div>
</div>
<div className="flex">
<aside
className={cn(
"fixed inset-y-0 left-0 z-40 w-64 bg-white border-r-4 border-black transform transition-transform lg:translate-x-0 lg:static lg:inset-auto",
sidebarOpen ? "translate-x-0" : "-translate-x-full"
)}
>
<div className="h-14 flex items-center justify-between px-4 border-b-4 border-black bg-yellow-300">
<Link to="/" className="font-black text-lg">
LJN Admin
</Link>
<Button
variant="brutal"
size="icon"
onClick={handleSignOut}
aria-label="Logout"
className="hidden lg:inline-flex"
>
<LogOut className="h-4 w-4" />
</Button>
</div>
<nav className="p-2 space-y-1">
{menuItems.map((item) => {
const isActive = location.pathname === item.href
return (
<Link
key={item.href}
to={item.href}
onClick={() => setSidebarOpen(false)}
className={cn(
"flex items-center gap-3 px-3 py-2.5 rounded-md font-bold text-sm transition-colors",
isActive
? "bg-black text-yellow-300"
: "hover:bg-gray-100 text-gray-700"
)}
>
<item.icon className="h-4 w-4" />
{item.label}
</Link>
)
})}
</nav>
</aside>
{sidebarOpen && (
<div
className="fixed inset-0 z-30 bg-black/50 lg:hidden"
onClick={() => setSidebarOpen(false)}
/>
)}
<main className="flex-1 min-h-screen p-4 sm:p-6 lg:p-8">
<Outlet />
</main>
</div>
</div>
)
}