346 lines
14 KiB
TypeScript
346 lines
14 KiB
TypeScript
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import { ThemeToggle } from '@/components/theme-toggle';
|
|
import { Menu, ChevronDown, School, GraduationCap, Clock, BookOpen, Award, Home, LogOut, User } from 'lucide-react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Sheet, SheetContent, SheetTrigger } from '@/components/ui/sheet';
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from '@/components/ui/dropdown-menu';
|
|
import Link from 'next/link';
|
|
import LoginDialog from './login-dialog';
|
|
import { useToast } from '@/components/ui/use-toast';
|
|
|
|
interface UserData {
|
|
id_user: number;
|
|
username?: string;
|
|
nip?: string;
|
|
role_user: string;
|
|
}
|
|
|
|
const Navbar = () => {
|
|
const [user, setUser] = useState<UserData | null>(null);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const { toast } = useToast();
|
|
const router = useRouter();
|
|
|
|
// Check for existing user session on mount
|
|
useEffect(() => {
|
|
checkUserSession();
|
|
}, []);
|
|
|
|
const checkUserSession = async () => {
|
|
try {
|
|
const response = await fetch('/api/auth/user');
|
|
if (response.ok) {
|
|
const data = await response.json();
|
|
setUser(data.user);
|
|
}
|
|
} catch (error) {
|
|
console.error('Error checking session:', error);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
|
|
const handleLoginSuccess = (userData: any) => {
|
|
setUser(userData.user);
|
|
};
|
|
|
|
const handleLogout = async () => {
|
|
try {
|
|
const response = await fetch('/api/auth/logout', {
|
|
method: 'POST',
|
|
});
|
|
|
|
if (response.ok) {
|
|
setUser(null);
|
|
toast({
|
|
title: "Logout Berhasil",
|
|
description: "Anda telah keluar dari sistem",
|
|
});
|
|
// Redirect to root page after successful logout
|
|
router.push('/');
|
|
}
|
|
} catch (error) {
|
|
console.error('Logout error:', error);
|
|
toast({
|
|
variant: "destructive",
|
|
title: "Error",
|
|
description: "Terjadi kesalahan saat logout",
|
|
});
|
|
}
|
|
};
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className="bg-background/95 border-b py-2 sticky top-0 z-30">
|
|
<div className="container mx-auto px-4 flex justify-between items-center">
|
|
<div className="flex items-center">
|
|
<Link href="/" className="flex items-center text-lg font-semibold hover:text-primary transition-colors">
|
|
<img src="/podif-icon.png" alt="PODIF Logo" className="h-6 w-auto mr-2" />
|
|
PODIF
|
|
</Link>
|
|
</div>
|
|
<div className="flex items-center gap-4">
|
|
<ThemeToggle />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="bg-background/95 border-b py-2 sticky top-0 z-30">
|
|
<div className="container mx-auto px-4 flex justify-between items-center">
|
|
{/* Logo */}
|
|
<div className="flex items-center">
|
|
<Link href="/" className="flex items-center text-lg font-semibold hover:text-primary transition-colors">
|
|
<img src="/podif-icon.png" alt="PODIF Logo" className="h-6 w-auto mr-2" />
|
|
PODIF
|
|
</Link>
|
|
</div>
|
|
|
|
{/* Desktop Navigation - Centered */}
|
|
<div className="hidden md:flex items-center gap-4">
|
|
{/* Beranda - Always visible */}
|
|
<Link href="/" className="flex items-center gap-2 px-3 py-2 text-sm font-medium hover:text-primary transition-colors">
|
|
<Home className="h-4 w-4" />
|
|
Beranda
|
|
</Link>
|
|
|
|
{/* Visualisasi Dropdown - Only when logged in */}
|
|
{user && (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button variant="ghost" className="flex items-center gap-2 px-3 py-2 text-sm font-medium">
|
|
<School className="h-4 w-4" />
|
|
Visualisasi
|
|
<ChevronDown className="h-4 w-4" />
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="center" className="w-48">
|
|
<DropdownMenuItem asChild>
|
|
<Link href="/visualisasi/mahasiswa" className="flex items-center gap-2 w-full">
|
|
<GraduationCap className="h-4 w-4" />
|
|
Mahasiswa
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem asChild>
|
|
<Link href="/visualisasi/status" className="flex items-center gap-2 w-full">
|
|
<GraduationCap className="h-4 w-4" />
|
|
Status Kuliah
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem asChild>
|
|
<Link href="/visualisasi/tipekelulusan" className="flex items-center gap-2 w-full">
|
|
<Clock className="h-4 w-4" />
|
|
Tipe Kelulusan
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem asChild>
|
|
<Link href="/visualisasi/beasiswa" className="flex items-center gap-2 w-full">
|
|
<BookOpen className="h-4 w-4" />
|
|
Beasiswa
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem asChild>
|
|
<Link href="/visualisasi/prestasi" className="flex items-center gap-2 w-full">
|
|
<Award className="h-4 w-4" />
|
|
Prestasi
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)}
|
|
|
|
{/* Kelola Data Dropdown - Only for Admin */}
|
|
{user && user.role_user === 'admin' && (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button variant="ghost" className="flex items-center gap-2 px-3 py-2 text-sm font-medium">
|
|
<School className="h-4 w-4" />
|
|
Kelola Data
|
|
<ChevronDown className="h-4 w-4" />
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="center" className="w-48">
|
|
<DropdownMenuItem asChild>
|
|
<Link href="/keloladata/mahasiswa" className="flex items-center gap-2 w-full">
|
|
<GraduationCap className="h-4 w-4" />
|
|
Mahasiswa
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem asChild>
|
|
<Link href="/keloladata/beasiswa" className="flex items-center gap-2 w-full">
|
|
<BookOpen className="h-4 w-4" />
|
|
Beasiswa
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem asChild>
|
|
<Link href="/keloladata/prestasi" className="flex items-center gap-2 w-full">
|
|
<Award className="h-4 w-4" />
|
|
Prestasi
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem asChild>
|
|
<Link href="/keloladata/kelompokkeahlian" className="flex items-center gap-2 w-full">
|
|
<Award className="h-4 w-4" />
|
|
Kelompok Keahlian
|
|
</Link>
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
)}
|
|
</div>
|
|
|
|
{/* Right Side - Theme Toggle, Login/User Menu, and Mobile Menu */}
|
|
<div className="flex items-center gap-4">
|
|
<ThemeToggle />
|
|
|
|
{user ? (
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button variant="ghost" className="flex items-center gap-2">
|
|
<User className="h-4 w-4" />
|
|
{user.role_user === 'ketuajurusan' ? 'Ketua Jurusan' : 'Admin'}
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end">
|
|
<DropdownMenuItem disabled>
|
|
<User className="h-4 w-4 mr-2" />
|
|
{user.role_user === 'ketuajurusan' ? user.nip : user.username}
|
|
</DropdownMenuItem>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuItem onClick={handleLogout}>
|
|
<LogOut className="h-4 w-4 mr-2" />
|
|
Logout
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
) : (
|
|
<LoginDialog onLoginSuccess={handleLoginSuccess} />
|
|
)}
|
|
|
|
{/* Mobile Menu Button */}
|
|
<div className="md:hidden">
|
|
<Sheet>
|
|
<SheetTrigger asChild>
|
|
<Button variant="outline" size="icon">
|
|
<Menu className="h-5 w-5" />
|
|
<span className="sr-only">Toggle menu</span>
|
|
</Button>
|
|
</SheetTrigger>
|
|
<SheetContent side="left" className="p-0 w-[250px] overflow-y-auto">
|
|
<MobileNavContent user={user} onLogout={handleLogout} />
|
|
</SheetContent>
|
|
</Sheet>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
// Mobile Navigation Content Component
|
|
interface MobileNavContentProps {
|
|
user: UserData | null;
|
|
onLogout: () => void;
|
|
}
|
|
|
|
const MobileNavContent = ({ user, onLogout }: MobileNavContentProps) => {
|
|
return (
|
|
<div className="p-4 space-y-4">
|
|
<div className="space-y-2">
|
|
<h3 className="text-sm font-semibold text-muted-foreground">Dashboard PODIF</h3>
|
|
<Link href="/" className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors">
|
|
<Home className="h-4 w-4" />
|
|
Beranda
|
|
</Link>
|
|
</div>
|
|
|
|
{user ? (
|
|
<div className="space-y-2">
|
|
<h3 className="text-sm font-semibold text-muted-foreground">Menu Utama</h3>
|
|
|
|
<div className="space-y-1">
|
|
<h4 className="text-xs font-medium text-muted-foreground px-3">Visualisasi</h4>
|
|
<Link href="/visualisasi/mahasiswa" className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors">
|
|
<GraduationCap className="h-4 w-4" />
|
|
Mahasiswa
|
|
</Link>
|
|
<Link href="/visualisasi/status" className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors">
|
|
<GraduationCap className="h-4 w-4" />
|
|
Status Kuliah
|
|
</Link>
|
|
<Link href="/visualisasi/tipekelulusan" className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors">
|
|
<Clock className="h-4 w-4" />
|
|
Tipe Kelulusan
|
|
</Link>
|
|
<Link href="/visualisasi/beasiswa" className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors">
|
|
<BookOpen className="h-4 w-4" />
|
|
Beasiswa
|
|
</Link>
|
|
<Link href="/visualisasi/prestasi" className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors">
|
|
<Award className="h-4 w-4" />
|
|
Prestasi
|
|
</Link>
|
|
</div>
|
|
|
|
{/* Kelola Data - Only for Admin */}
|
|
{user.role_user === 'admin' && (
|
|
<div className="space-y-1">
|
|
<h4 className="text-xs font-medium text-muted-foreground px-3">Kelola Data</h4>
|
|
<Link href="/keloladata/mahasiswa" className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors">
|
|
<GraduationCap className="h-4 w-4" />
|
|
Mahasiswa
|
|
</Link>
|
|
<Link href="/keloladata/beasiswa" className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors">
|
|
<BookOpen className="h-4 w-4" />
|
|
Beasiswa
|
|
</Link>
|
|
<Link href="/keloladata/prestasi" className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors">
|
|
<Award className="h-4 w-4" />
|
|
Prestasi
|
|
</Link>
|
|
<Link href="/keloladata/kelompokkeahlian" className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors">
|
|
<Award className="h-4 w-4" />
|
|
Kelompok Keahlian
|
|
</Link>
|
|
</div>
|
|
)}
|
|
|
|
<div className="pt-4 border-t">
|
|
<div className="flex items-center gap-2 px-3 py-2 text-sm text-muted-foreground">
|
|
<User className="h-4 w-4" />
|
|
{user.role_user === 'ketuajurusan' ? 'Ketua Jurusan' : 'Admin'}
|
|
</div>
|
|
<button
|
|
onClick={onLogout}
|
|
className="flex items-center gap-2 px-3 py-2 text-sm hover:bg-accent hover:text-accent-foreground rounded-md transition-colors w-full text-left"
|
|
>
|
|
<LogOut className="h-4 w-4" />
|
|
Logout
|
|
</button>
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="space-y-2">
|
|
<h3 className="text-sm font-semibold text-muted-foreground">Login</h3>
|
|
<p className="text-sm text-muted-foreground px-3">
|
|
Silakan login untuk mengakses menu Visualisasi dan Kelola Data
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Navbar;
|