f44d57629f
- GET /api/eterra/counties — distinct county list from GisUat - POST /api/eterra/sync-county — background sync all UATs in a county (TERENURI + CLADIRI + INTRAVILAN), magic mode for enriched UATs, concurrency guard, creates notification on completion - In-app notification service (KeyValueStore, CRUD, unread count) - GET/PATCH /api/notifications/app — list and mark-read endpoints - NotificationBell component in header with popover + polling - Monitor page: county select dropdown + SyncTestButton with customBody Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
87 lines
2.8 KiB
TypeScript
87 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import { PanelLeft, User as UserIcon, LogOut, LogIn } from "lucide-react";
|
|
import { Button } from "@/shared/components/ui/button";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuTrigger,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuLabel,
|
|
} from "@/shared/components/ui/dropdown-menu";
|
|
import { useAuth } from "@/core/auth";
|
|
import { signIn, signOut } from "next-auth/react";
|
|
import { ThemeToggle } from "@/shared/components/common/theme-toggle";
|
|
import { NotificationBell } from "./notification-bell";
|
|
|
|
interface HeaderProps {
|
|
onToggleSidebar?: () => void;
|
|
}
|
|
|
|
export function Header({ onToggleSidebar }: HeaderProps) {
|
|
const { user, isAuthenticated } = useAuth();
|
|
|
|
return (
|
|
<header className="flex h-14 items-center justify-between border-b bg-card px-4">
|
|
<div className="flex items-center gap-2">
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="lg:hidden"
|
|
onClick={onToggleSidebar}
|
|
>
|
|
<PanelLeft className="h-5 w-5" />
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-3">
|
|
<NotificationBell />
|
|
<ThemeToggle />
|
|
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="rounded-full bg-muted"
|
|
>
|
|
<UserIcon className="h-4 w-4" />
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end" className="w-56">
|
|
{isAuthenticated && user ? (
|
|
<>
|
|
<DropdownMenuLabel className="font-normal">
|
|
<div className="flex flex-col space-y-1">
|
|
<p className="text-sm font-medium leading-none">
|
|
{user.name}
|
|
</p>
|
|
<p className="text-xs leading-none text-muted-foreground">
|
|
{user.email}
|
|
</p>
|
|
</div>
|
|
</DropdownMenuLabel>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuItem onClick={() => signOut()}>
|
|
<LogOut className="mr-2 h-4 w-4" />
|
|
<span>Deconectare</span>
|
|
</DropdownMenuItem>
|
|
</>
|
|
) : (
|
|
<>
|
|
<DropdownMenuLabel>Neautentificat</DropdownMenuLabel>
|
|
<DropdownMenuSeparator />
|
|
<DropdownMenuItem onClick={() => signIn("authentik")}>
|
|
<LogIn className="mr-2 h-4 w-4" />
|
|
<span>Autentificare (Authentik)</span>
|
|
</DropdownMenuItem>
|
|
</>
|
|
)}
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</div>
|
|
</header>
|
|
);
|
|
}
|