| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- "use client";
- import React from "react";
- import Link from "next/link";
- import { usePathname } from "next/navigation";
- import { LifeBuoy, LogOut, User } from "lucide-react";
- import { cn } from "@/lib/utils";
- import { useAuth } from "@/components/auth/authContext";
- import { logout } from "@/lib/frontend/apiClient";
- import { buildLoginUrl, LOGIN_REASONS } from "@/lib/frontend/authRedirect";
- import { Button } from "@/components/ui/button";
- import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuLabel,
- DropdownMenuSeparator,
- DropdownMenuTrigger,
- } from "@/components/ui/dropdown-menu";
- import {
- Tooltip,
- TooltipContent,
- TooltipTrigger,
- } from "@/components/ui/tooltip";
- function formatRole(role) {
- if (role === "branch") return "Niederlassung";
- if (role === "admin") return "Admin";
- if (role === "dev") return "Entwicklung";
- return role ? String(role) : "Unbekannt";
- }
- function buildSupportMailto({ user, currentUrl, pathname, userAgent }) {
- const to = "info@attus.de";
- const roleLabel = user ? formatRole(user.role) : "Unbekannt";
- const userLabel = user?.branchId
- ? `${roleLabel} (${user.branchId})`
- : roleLabel;
- const now = new Date();
- const tz =
- typeof Intl !== "undefined"
- ? Intl.DateTimeFormat().resolvedOptions().timeZone
- : "";
- const timestampLocal = now.toLocaleString("de-DE");
- const timestampIso = now.toISOString();
- const routeLine = pathname ? `Route: ${pathname}` : "Route: (unbekannt)";
- const urlLine = currentUrl ? `URL: ${currentUrl}` : "URL: (bitte einfügen)";
- const uaLine = userAgent
- ? `User-Agent: ${userAgent}`
- : "User-Agent: (unbekannt)";
- const timeLine = tz
- ? `Zeitpunkt: ${timestampLocal} (${tz})`
- : `Zeitpunkt: ${timestampLocal}`;
- const isoLine = `ISO: ${timestampIso}`;
- const subject = user?.branchId
- ? `Support – RHL Lieferscheine (${user.branchId})`
- : "Support – RHL Lieferscheine";
- const body = [
- "Hallo attus Support,",
- "",
- "bitte beschreibt hier kurz das Anliegen:",
- "",
- "- Was wollten Sie tun?",
- "- Was ist passiert?",
- "- (Optional) Screenshot / Zeitpunkt",
- "",
- "--- Kontext (bitte drin lassen) ---",
- `Benutzer: ${userLabel}`,
- routeLine,
- urlLine,
- timeLine,
- isoLine,
- uaLine,
- "----------------------------------",
- "",
- "Vielen Dank.",
- ].join("\r\n");
- return `mailto:${to}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(
- body,
- )}`;
- }
- export default function UserStatus() {
- const pathname = usePathname() || "/";
- const { status, user } = useAuth();
- const isAuthenticated = status === "authenticated" && user;
- let text = "Nicht geladen";
- if (status === "loading") text = "Lädt…";
- if (isAuthenticated) {
- const roleLabel = formatRole(user.role);
- text = user.branchId ? `${roleLabel} (${user.branchId})` : roleLabel;
- }
- if (status === "unauthenticated") text = "Abgemeldet";
- if (status === "error") text = "Fehler";
- const currentUrl = typeof window !== "undefined" ? window.location.href : "";
- const userAgent = typeof navigator !== "undefined" ? navigator.userAgent : "";
- const supportMailto = buildSupportMailto({
- user,
- currentUrl,
- pathname,
- userAgent,
- });
- const isProfileActive =
- pathname === "/profile" || pathname.startsWith("/profile/");
- async function handleLogout() {
- try {
- await logout();
- } catch (err) {
- console.error("[UserStatus] logout failed:", err);
- }
- const loginUrl = buildLoginUrl({ reason: LOGIN_REASONS.LOGGED_OUT });
- window.location.replace(loginUrl);
- }
- return (
- <DropdownMenu>
- <Tooltip>
- <TooltipTrigger asChild>
- <DropdownMenuTrigger asChild>
- <Button
- type="button"
- variant="ghost"
- size="sm"
- aria-label="Benutzermenü öffnen"
- className={cn(
- "gap-2",
- "px-2 md:px-3",
- isProfileActive ? "bg-accent" : "",
- )}
- >
- <User className="h-4 w-4" aria-hidden="true" />
- <span className="hidden text-xs md:inline">{text}</span>
- </Button>
- </DropdownMenuTrigger>
- </TooltipTrigger>
- <TooltipContent side="bottom">Benutzermenü</TooltipContent>
- </Tooltip>
- <DropdownMenuContent align="end" className="min-w-56">
- <DropdownMenuLabel>Benutzer</DropdownMenuLabel>
- <div className="px-2 pb-2 text-xs text-muted-foreground">
- {isAuthenticated
- ? `Angemeldet als: ${text}`
- : "Keine aktive Sitzung."}
- </div>
- <DropdownMenuSeparator />
- <DropdownMenuItem asChild disabled={!isAuthenticated}>
- <Link href="/profile" className="flex w-full items-center gap-2">
- <User className="h-4 w-4" aria-hidden="true" />
- Profil
- </Link>
- </DropdownMenuItem>
- <DropdownMenuItem asChild>
- <a href={supportMailto} className="flex w-full items-center gap-2">
- <LifeBuoy className="h-4 w-4" aria-hidden="true" />
- Support
- </a>
- </DropdownMenuItem>
- <DropdownMenuSeparator />
- <DropdownMenuItem
- variant="destructive"
- disabled={!isAuthenticated}
- onSelect={(e) => {
- e.preventDefault();
- handleLogout();
- }}
- >
- <LogOut className="h-4 w-4" aria-hidden="true" />
- Abmelden
- </DropdownMenuItem>
- </DropdownMenuContent>
- </DropdownMenu>
- );
- }
|