瀏覽代碼

RHL-029 feat(profile): add email display to ProfilePage and remove deprecated email card

Code_Uwe 4 天之前
父節點
當前提交
411747da16
共有 3 個文件被更改,包括 11 次插入96 次删除
  1. 0 61
      components/auth/LogoutButton.jsx
  2. 1 0
      components/auth/authContext.jsx
  3. 10 35
      components/profile/ProfilePage.jsx

+ 0 - 61
components/auth/LogoutButton.jsx

@@ -1,61 +0,0 @@
-"use client";
-
-import React from "react";
-
-import { logout } from "@/lib/frontend/apiClient";
-import { buildLoginUrl, LOGIN_REASONS } from "@/lib/frontend/authRedirect";
-import { Button } from "@/components/ui/button";
-
-/**
- * LogoutButton (RHL-020)
- *
- * Responsibilities:
- * - Call apiClient.logout() to clear the HTTP-only session cookie.
- * - Then redirect to /login?reason=logged-out.
- *
- * Important test/runtime note:
- * - We intentionally avoid next/navigation hooks here.
- * - Some unit tests render AppShell via react-dom/server without Next.js runtime.
- * - Using window.location inside the click handler avoids needing router context
- *   during server rendering (handler is not invoked in SSR tests).
- *
- * UX rule:
- * - All user-facing text must be German.
- */
-export default function LogoutButton() {
-	const [isLoggingOut, setIsLoggingOut] = React.useState(false);
-
-	async function handleLogout() {
-		if (isLoggingOut) return;
-
-		setIsLoggingOut(true);
-
-		try {
-			// Backend endpoint is idempotent; even if no cookie exists it returns ok.
-			await logout();
-		} catch (err) {
-			// If logout fails due to network issues, we still redirect to login.
-			// This keeps UX predictable; user can log in again if needed.
-			console.error("[LogoutButton] logout failed:", err);
-		}
-
-		const loginUrl = buildLoginUrl({ reason: LOGIN_REASONS.LOGGED_OUT });
-
-		// Replace so "Back" won't bring the user into a protected page.
-		window.location.replace(loginUrl);
-	}
-
-	return (
-		<Button
-			variant="outline"
-			size="sm"
-			type="button"
-			disabled={isLoggingOut}
-			aria-disabled={isLoggingOut ? "true" : "false"}
-			onClick={handleLogout}
-			title={isLoggingOut ? "Abmeldung läuft…" : "Abmelden"}
-		>
-			{isLoggingOut ? "Abmeldung…" : "Abmelden"}
-		</Button>
-	);
-}

+ 1 - 0
components/auth/authContext.jsx

@@ -23,6 +23,7 @@ import React from "react";
  * @property {string} userId
  * @property {string} role
  * @property {string|null} branchId
+ * @property {string|null} email
  */
 
 /**

+ 10 - 35
components/profile/ProfilePage.jsx

@@ -5,16 +5,12 @@ import { useAuth } from "@/components/auth/authContext";
 
 import ChangePasswordCard from "@/components/profile/ChangePasswordCard";
 
-import { Button } from "@/components/ui/button";
-import { Input } from "@/components/ui/input";
-import { Label } from "@/components/ui/label";
 import {
 	Card,
 	CardHeader,
 	CardTitle,
 	CardDescription,
 	CardContent,
-	CardFooter,
 } from "@/components/ui/card";
 
 function formatRole(role) {
@@ -31,6 +27,7 @@ export default function ProfilePage() {
 
 	const roleLabel = isAuthenticated ? formatRole(user.role) : "—";
 	const branchLabel = isAuthenticated ? user.branchId || "—" : "—";
+	const emailLabel = isAuthenticated ? user.email || "—" : "—";
 	const userIdLabel = isAuthenticated ? user.userId || "—" : "—";
 
 	return (
@@ -59,43 +56,21 @@ export default function ProfilePage() {
 						<span>{branchLabel}</span>
 					</div>
 
+					<div className="flex items-center justify-between gap-4">
+						<span className="text-muted-foreground">E-Mail</span>
+						<span className="truncate">{emailLabel}</span>
+					</div>
+
 					<div className="flex items-center justify-between gap-4">
 						<span className="text-muted-foreground">User ID</span>
 						<span className="truncate">{userIdLabel}</span>
 					</div>
-				</CardContent>
-			</Card>
 
-			<Card>
-				<CardHeader>
-					<CardTitle>E-Mail</CardTitle>
-					<CardDescription>
-						Die Änderung der E-Mail-Adresse wird in einem späteren Ticket
-						aktiviert.
-					</CardDescription>
-				</CardHeader>
-
-				<CardContent className="grid gap-2">
-					<Label htmlFor="email">E-Mail-Adresse</Label>
-					<Input
-						id="email"
-						type="email"
-						placeholder="name@firma.de"
-						disabled
-						aria-disabled="true"
-					/>
+					<p className="pt-1 text-xs text-muted-foreground">
+						Die E-Mail wird zentral verwaltet. Für Änderungen wenden Sie sich an
+						die IT.
+					</p>
 				</CardContent>
-
-				<CardFooter className="flex justify-end">
-					<Button
-						type="button"
-						disabled
-						aria-disabled="true"
-						title="Kommt später"
-					>
-						Speichern
-					</Button>
-				</CardFooter>
 			</Card>
 
 			<ChangePasswordCard />