Spaces:
Configuration error
Configuration error
File size: 3,514 Bytes
78013c4 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | "use client";
import React, { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { Menu, LogOut, Calendar } from "lucide-react";
import { useAuthStore } from "@/store/authStore";
import api from "@/lib/api";
import toast from "react-hot-toast";
import GlassBadge from "./GlassBadge";
const ROLE_BADGE_VARIANT: Record<string, "info" | "success"> = {
ADMIN: "info",
TEACHER: "success",
};
interface HeaderProps {
onMenuToggle: () => void;
}
export default function Header({ onMenuToggle }: HeaderProps): React.ReactElement {
const router = useRouter();
const { user, logout } = useAuthStore();
const [timeStr, setTimeStr] = useState("");
useEffect(() => {
const updateTime = () => {
const now = new Date();
setTimeStr(
now.toLocaleDateString("en-US", {
weekday: "short",
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
})
);
};
updateTime();
const interval = setInterval(updateTime, 60_000);
return () => clearInterval(interval);
}, []);
async function handleLogout(): Promise<void> {
try {
await api.post("/auth/logout");
} catch {
}
logout();
toast.success("Logged out successfully");
router.push("/login");
}
const roleBadge = ROLE_BADGE_VARIANT[user?.role ?? ""] ?? "success";
return (
<header
className="sticky top-0 z-20 flex items-center justify-between px-5 m-4 md:my-4 md:mr-4 md:ml-0 rounded-2xl border border-white/[0.06] shadow-xl animate-fade-in-up"
style={{
height: "calc(var(--header-height) - 8px)",
background: "rgba(3, 4, 12, 0.45)",
backdropFilter: "blur(28px)",
WebkitBackdropFilter: "blur(28px)",
}}
>
<button
onClick={onMenuToggle}
className="glass-btn glass-btn-ghost p-2 md:hidden hover:bg-white/5 rounded-xl transition-all duration-300"
aria-label="Toggle menu"
>
<Menu size={18} className="text-slate-300" />
</button>
{}
<div className="hidden md:flex items-center gap-2.5 text-xs font-semibold text-slate-400">
<Calendar size={13} className="text-emerald-400" />
<span className="w-1.5 h-1.5 rounded-full bg-emerald-500 animate-ping inline-block" />
<span className="tracking-wide text-slate-300">{timeStr || "Loading..."}</span>
</div>
{}
<div className="flex items-center gap-4">
<div className="flex items-center gap-3">
<GlassBadge variant={roleBadge} className="shadow-[0_4px_12px_rgba(0,0,0,0.5)] py-0.5 px-2.5 font-bold tracking-wider text-[10px]">
{user?.role || "—"}
</GlassBadge>
<span className="text-xs font-bold text-slate-300 hidden sm:inline tracking-wide">
{user?.email || "—"}
</span>
</div>
<div className="w-px h-5 bg-white/10" />
<button
onClick={handleLogout}
className="glass-btn glass-btn-ghost glass-btn-sm text-slate-400 hover:text-slate-200 hover:bg-white/5 hover:border-white/10 rounded-xl px-3 py-1.5 transition-all duration-300 flex items-center gap-1.5"
title="Logout"
>
<LogOut size={13} className="transition-transform duration-300 group-hover:translate-x-1" />
<span className="hidden sm:inline text-xs font-bold tracking-wide">Logout</span>
</button>
</div>
</header>
);
}
|