[Valentino Heman Budiarto] e210d2a424 .
2026-06-22 18:34:26 +07:00

140 lines
5.8 KiB
TypeScript

"use client";
import { useState, useEffect } from "react";
import { useRouter, usePathname } from "next/navigation";
import Link from "next/link";
import {
LogOut,
LayoutDashboard,
Activity,
ShieldCheck,
Settings2,
CalendarDays
} from "lucide-react";
export default function AdminLayout({ children }: { children: React.ReactNode }) {
const router = useRouter();
const pathname = usePathname();
const [user, setUser] = useState<any>(null);
// 1. TAMBAHAN BARU: Gembok Loading untuk mencegah glitch redirect
const [isAuthorized, setIsAuthorized] = useState(false);
useEffect(() => {
const userData = localStorage.getItem("user");
if (!userData) {
router.push("/login");
return;
}
try {
const parsed = JSON.parse(userData);
// 2. PERBAIKAN: Baca role dengan aman, ubah semua ke huruf kecil
const userRole = parsed.role || parsed.Role || "";
if (userRole.toLowerCase() !== 'admin') {
router.push("/dashboard");
} else {
setUser(parsed);
setIsAuthorized(true); // Buka gembok karena dia benar-benar admin!
}
} catch (error) {
console.error("Gagal membaca data user", error);
router.push("/login");
}
}, [router]);
const handleLogout = () => {
localStorage.clear();
router.push("/login");
};
// 3. CEGATAN RENDER: Jika belum divalidasi, jangan render apapun selain layar loading
if (!isAuthorized) {
return (
<div className="min-h-screen flex items-center justify-center bg-white">
<div className="text-blue-600 font-bold animate-pulse">Memverifikasi Otoritas Admin...</div>
</div>
);
}
return (
<div className="min-h-screen bg-white flex flex-col font-sans">
{/* HEADER ADMIN */}
<header className="bg-[#e5e7eb] flex items-center justify-between px-6 py-4 shadow-sm z-20 relative">
<div>
<h2 className="text-blue-600 text-sm font-medium mb-1">Admin Panel,</h2>
<h1 className="text-blue-600 text-3xl font-bold">S-CLASS</h1>
</div>
<div className="flex items-center gap-8">
<div className="flex items-center gap-3">
<div className="bg-slate-800 text-white rounded-full h-10 w-10 flex items-center justify-center text-lg font-bold shadow-sm">
{user?.full_name ? user.full_name.charAt(0).toUpperCase() : "A"}
</div>
<div className="hidden sm:flex flex-col">
<span className="font-semibold text-gray-800 text-sm">{user?.full_name || "Administrator"}</span>
<span className="font-medium text-blue-600 text-xs uppercase tracking-wider">System Controller</span>
</div>
</div>
<button onClick={handleLogout} className="flex items-center gap-2 text-red-500 font-medium hover:text-red-600 transition-colors">
Log Out <LogOut size={20} />
</button>
</div>
</header>
<div className="flex flex-1 overflow-hidden relative">
{/* SIDEBAR ADMIN (Lebar Permanen: w-64) */}
<aside className="bg-[#b0c4d9] w-64 flex flex-col py-10 shadow-inner z-10">
<nav className="flex flex-col gap-6 px-4">
<Link href="/admin" className={`flex items-center gap-4 font-semibold transition-colors group ${pathname === '/admin' ? 'text-blue-700' : 'text-gray-800 hover:text-blue-700'}`}>
<div className={`p-2 rounded-lg transition-colors ${pathname === '/admin' ? 'bg-white/60 shadow-sm' : 'bg-white/30 group-hover:bg-white/50'}`}>
<LayoutDashboard size={22} />
</div>
<span>Dashboard</span>
</Link>
<Link href="/admin/monitoring" className={`flex items-center gap-4 font-semibold transition-colors group ${pathname === '/admin/monitoring' ? 'text-blue-700' : 'text-gray-800 hover:text-blue-700'}`}>
<div className={`p-2 rounded-lg transition-colors ${pathname === '/admin/monitoring' ? 'bg-white/60 shadow-sm' : 'bg-white/30 group-hover:bg-white/50'}`}>
<Activity size={22} />
</div>
<span>Power Monitoring</span>
</Link>
<Link href="/admin/approvals" className={`flex items-center gap-4 font-semibold transition-colors group ${pathname === '/admin/approvals' ? 'text-blue-700' : 'text-gray-800 hover:text-blue-700'}`}>
<div className={`p-2 rounded-lg transition-colors ${pathname === '/admin/approvals' ? 'bg-white/60 shadow-sm' : 'bg-white/30 group-hover:bg-white/50'}`}>
<ShieldCheck size={22} />
</div>
<span>Approvals</span>
</Link>
<Link href="/admin/rooms" className={`flex items-center gap-4 font-semibold transition-colors group ${pathname === '/admin/rooms' ? 'text-blue-700' : 'text-gray-800 hover:text-blue-700'}`}>
<div className={`p-2 rounded-lg transition-colors ${pathname === '/admin/rooms' ? 'bg-white/60 shadow-sm' : 'bg-white/30 group-hover:bg-white/50'}`}>
<Settings2 size={22} />
</div>
<span>Manage Rooms</span>
</Link>
<Link href="/admin/schedules" className={`flex items-center gap-4 font-semibold transition-colors group ${pathname === '/admin/schedules' ? 'text-blue-700' : 'text-gray-800 hover:text-blue-700'}`}>
<div className={`p-2 rounded-lg transition-colors ${pathname === '/admin/schedules' ? 'bg-white/60 shadow-sm' : 'bg-white/30 group-hover:bg-white/50'}`}>
<CalendarDays size={22} />
</div>
<span>Edit Jadwal</span>
</Link>
</nav>
</aside>
{/* KONTEN UTAMA */}
<main className="flex-1 overflow-y-auto bg-[#f8fafc] p-8">
{children}
</main>
</div>
</div>
);
}