ProfilePage.jsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. "use client";
  2. import React from "react";
  3. import { usePathname } from "next/navigation";
  4. import { LifeBuoy } from "lucide-react";
  5. import { useAuth } from "@/components/auth/authContext";
  6. import ChangePasswordCard from "@/components/profile/ChangePasswordCard";
  7. import { buildSupportMailto } from "@/lib/frontend/support/supportMailto";
  8. import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert";
  9. import { Button } from "@/components/ui/button";
  10. import {
  11. Card,
  12. CardHeader,
  13. CardTitle,
  14. CardDescription,
  15. CardContent,
  16. } from "@/components/ui/card";
  17. function formatRole(role) {
  18. if (role === "branch") return "Niederlassung";
  19. if (role === "admin") return "Admin";
  20. if (role === "superadmin") return "Superadmin";
  21. if (role === "dev") return "Entwicklung";
  22. return role ? String(role) : "Unbekannt";
  23. }
  24. export default function ProfilePage() {
  25. const pathname = usePathname() || "/profile";
  26. const { status, user } = useAuth();
  27. const [passwordChangedSuccess, setPasswordChangedSuccess] =
  28. React.useState(false);
  29. const isAuthenticated = status === "authenticated" && user;
  30. const roleLabel = isAuthenticated ? formatRole(user.role) : "—";
  31. const branchLabel = isAuthenticated ? user.branchId || "—" : "—";
  32. const emailLabel = isAuthenticated ? user.email || "—" : "—";
  33. const userIdLabel = isAuthenticated ? user.userId || "—" : "—";
  34. const mustChangePassword =
  35. isAuthenticated && user.mustChangePassword === true;
  36. const currentUrl = typeof window !== "undefined" ? window.location.href : "";
  37. const userAgent = typeof navigator !== "undefined" ? navigator.userAgent : "";
  38. const supportMailto = React.useMemo(() => {
  39. return buildSupportMailto({
  40. user: isAuthenticated ? user : null,
  41. pathname,
  42. currentUrl,
  43. userAgent,
  44. });
  45. }, [isAuthenticated, user, pathname, currentUrl, userAgent]);
  46. React.useEffect(() => {
  47. if (mustChangePassword) {
  48. setPasswordChangedSuccess(false);
  49. }
  50. }, [mustChangePassword]);
  51. return (
  52. <div className="space-y-4 w-1/2 mx-auto">
  53. <div className="space-y-1">
  54. <h1 className="text-2xl font-semibold tracking-tight">Profil</h1>
  55. <p className="text-sm text-muted-foreground">
  56. Konto- und Zugangseinstellungen.
  57. </p>
  58. </div>
  59. {mustChangePassword ? (
  60. <Alert variant="destructive">
  61. <AlertTitle>Passwortänderung erforderlich</AlertTitle>
  62. <AlertDescription>
  63. Sie müssen Ihr Passwort ändern, bevor Sie fortfahren können.
  64. </AlertDescription>
  65. </Alert>
  66. ) : null}
  67. {!mustChangePassword && passwordChangedSuccess ? (
  68. <Alert className="border-emerald-500/40 bg-emerald-50 text-emerald-900 dark:border-emerald-400/40 dark:bg-emerald-950/40 dark:text-emerald-100">
  69. <AlertTitle>Passwort erfolgreich geändert</AlertTitle>
  70. <AlertDescription className="text-emerald-800 dark:text-emerald-200">
  71. Ihr Passwort wurde erfolgreich aktualisiert. Sie können jetzt normal
  72. weiterarbeiten.
  73. </AlertDescription>
  74. </Alert>
  75. ) : null}
  76. <Card>
  77. <CardHeader>
  78. <CardTitle>Konto</CardTitle>
  79. <CardDescription>Aktuelle Sitzungsinformationen.</CardDescription>
  80. </CardHeader>
  81. <CardContent className="grid gap-3 text-sm">
  82. <div className="flex items-center justify-between gap-4">
  83. <span className="text-muted-foreground">Rolle</span>
  84. <span>{roleLabel}</span>
  85. </div>
  86. <div className="flex items-center justify-between gap-4">
  87. <span className="text-muted-foreground">Niederlassung</span>
  88. <span>{branchLabel}</span>
  89. </div>
  90. <div className="flex items-center justify-between gap-4">
  91. <span className="text-muted-foreground">E-Mail</span>
  92. <span className="truncate">{emailLabel}</span>
  93. </div>
  94. <div className="flex items-center justify-between gap-4">
  95. <span className="text-muted-foreground">User ID</span>
  96. <span className="truncate">{userIdLabel}</span>
  97. </div>
  98. <p className="pt-1 text-xs text-muted-foreground">
  99. Die E-Mail wird zentral verwaltet. Für Änderungen wenden Sie sich an
  100. die IT.
  101. </p>
  102. </CardContent>
  103. </Card>
  104. <ChangePasswordCard
  105. onPasswordChangeSuccess={() => setPasswordChangedSuccess(true)}
  106. />
  107. <Card>
  108. <CardHeader>
  109. <CardTitle>Support</CardTitle>
  110. <CardDescription>
  111. Bei Fragen oder Problemen können Sie direkt den Support
  112. kontaktieren.
  113. </CardDescription>
  114. </CardHeader>
  115. <CardContent>
  116. <div className="flex justify-start">
  117. <Button variant="outline" asChild>
  118. <a href={supportMailto}>
  119. <LifeBuoy className="h-4 w-4" aria-hidden="true" />
  120. Support kontaktieren
  121. </a>
  122. </Button>
  123. </div>
  124. </CardContent>
  125. </Card>
  126. {!isAuthenticated ? (
  127. <p className="text-xs text-muted-foreground">
  128. Hinweis: Profilfunktionen sind nur verfügbar, wenn Sie angemeldet
  129. sind.
  130. </p>
  131. ) : null}
  132. </div>
  133. );
  134. }