ente_nazionale_frontend/components/layout/app-header.tsx
Linas 5c50f28f7e Add Modelli (templates) admin section
New /dashboard/templates page (MANAGER/ADMIN, matches backend access):
lists document templates, lets MANAGER/ADMIN download the current
file and ADMIN replace it. Nav link added to the header. Also renamed
"Genera Attestato" to "Genera Certificato di Adesione" and the
downloaded file's name prefix to match, for consistency with the
document's real name.

Verified live: nav link navigates to the page, download round-trips
the file, and uploading a new file updates the listed filename and
timestamp immediately.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017hQcuUQFue2bFvrYw2UQhK
2026-08-24 19:22:18 +03:00

89 lines
3.0 KiB
TypeScript

"use client";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { LogOut } from "lucide-react";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { clearStoredUser, useStoredUser } from "@/lib/auth";
const ROLE_LABELS: Record<string, string> = {
ADMIN: "Amministratore",
MANAGER: "Gestore",
CLIENT: "Associazione",
};
export function AppHeader() {
const router = useRouter();
const { user } = useStoredUser();
const handleLogout = () => {
clearStoredUser();
router.push("/login");
};
const homeHref = user?.role === "CLIENT" ? "/client-portal" : "/dashboard";
return (
<header className="sticky top-0 z-20 border-b bg-background/95 backdrop-blur supports-backdrop-filter:bg-background/80">
<div className="mx-auto flex h-14 max-w-7xl items-center justify-between px-6">
<div className="flex items-center gap-6">
<Link href={homeHref} className="flex items-center gap-2.5">
<Image
src="/logo-encap.jpg"
alt="ENCAP"
width={28}
height={28}
className="rounded-md"
/>
<span className="text-sm font-semibold tracking-wide">ENCAP</span>
</Link>
{user && (user.role === "ADMIN" || user.role === "MANAGER") && (
<Link
href="/dashboard/templates"
className="text-sm text-muted-foreground transition-colors hover:text-foreground"
>
Modelli
</Link>
)}
</div>
{user && (
<DropdownMenu>
<DropdownMenuTrigger className="flex items-center gap-2.5 rounded-full outline-none focus-visible:ring-2 focus-visible:ring-ring">
<span className="hidden text-sm text-muted-foreground sm:inline">
{user.email}
</span>
<Avatar size="sm">
<AvatarFallback>{user.email.slice(0, 2).toUpperCase()}</AvatarFallback>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-56">
<DropdownMenuLabel className="flex flex-col gap-1.5 font-normal">
<span className="text-sm font-medium">{user.email}</span>
<Badge variant="secondary" className="w-fit">
{ROLE_LABELS[user.role] ?? user.role}
</Badge>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem variant="destructive" onClick={handleLogout}>
<LogOut />
Esci
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)}
</div>
</header>
);
}