"use client"; import Link from "next/link"; import { usePathname, useRouter } from "next/navigation"; import { useEffect, useRef, useState, useTransition } from "react"; import type { PopiartUser } from "@/lib/popiart-api"; import type { Locale } from "@/lib/site-content"; function replaceLocale(pathname: string, locale: Locale) { const parts = pathname.split("/"); if (parts[1] === "zh" || parts[1] === "en") { parts[1] = locale; return parts.join("/") || `/${locale}`; } return `/${locale}${pathname.startsWith("/") ? pathname : `/${pathname}`}`; } function userLabel(user: PopiartUser) { return user.name || user.email || user.id; } function initials(user: PopiartUser) { const source = user.name || user.email || user.id || "PA"; return source.slice(0, 2).toUpperCase(); } export function HeaderControls({ locale, user, labels, loginHref, }: { locale: Locale; user: PopiartUser | null; labels: { zh: string; en: string; logout: string; loggingOut: string; loginHint: string; login: string; }; loginHref: string; }) { const pathname = usePathname(); const router = useRouter(); const [isPending, startTransition] = useTransition(); const [menuOpen, setMenuOpen] = useState(false); const menuRef = useRef(null); useEffect(() => { function handlePointerDown(event: MouseEvent) { if (!menuRef.current?.contains(event.target as Node)) { setMenuOpen(false); } } function handleEscape(event: KeyboardEvent) { if (event.key === "Escape") { setMenuOpen(false); } } window.addEventListener("mousedown", handlePointerDown); window.addEventListener("keydown", handleEscape); return () => { window.removeEventListener("mousedown", handlePointerDown); window.removeEventListener("keydown", handleEscape); }; }, []); function switchLocale(target: Locale) { setMenuOpen(false); router.push(replaceLocale(pathname, target)); } function logout() { startTransition(async () => { await fetch("/api/auth/logout", { method: "POST", }); router.refresh(); }); } return (
{menuOpen ? (
) : null}
{user ? (
{initials(user)} {userLabel(user)}
) : (
{labels.login}
)}
); }