From 91f67f7dfc717ae435500b623d6d18ddd951ca9c Mon Sep 17 00:00:00 2001 From: Sven Carstensen Date: Tue, 17 Mar 2026 16:58:47 +0100 Subject: [PATCH] feat: Allow primary users to access user management and create sub-users Frontend: - Extend UserManagementPage for both ADMIN and primary users - Admins see all primary users (excluding other admins) - Primary users see only their sub-users - Add create sub-user form for primary users - Adjust UI text based on user role - Fix table columns (hide company column for primary users) --- frontend/src/pages/UserManagementPage.tsx | 212 ++++++++++++++++++---- 1 file changed, 178 insertions(+), 34 deletions(-) diff --git a/frontend/src/pages/UserManagementPage.tsx b/frontend/src/pages/UserManagementPage.tsx index 2d344be..ae3fdce 100644 --- a/frontend/src/pages/UserManagementPage.tsx +++ b/frontend/src/pages/UserManagementPage.tsx @@ -3,10 +3,9 @@ import { apiGet, apiPost } from "../lib/api"; import { useSession } from "../lib/session"; import type { UserRow } from "../lib/types"; -interface PrimaryUserRow { +interface SubUserRow { id: string; displayName: string; - companyName: string | null; email: string | null; active: boolean; updatedAt: string; @@ -14,27 +13,49 @@ interface PrimaryUserRow { export default function UserManagementPage() { const { user } = useSession(); - const [users, setUsers] = useState([]); + const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [message, setMessage] = useState(null); + const [showCreateForm, setShowCreateForm] = useState(false); const isAdmin = user?.role === "ADMIN"; + const isPrimaryUser = user?.primaryUser === true; + const canManageUsers = isAdmin || isPrimaryUser; + + // Form state for creating new sub-user + const [newUserName, setNewUserName] = useState(""); + const [newUserEmail, setNewUserEmail] = useState(""); + const [newUserPassword, setNewUserPassword] = useState(""); + const [creating, setCreating] = useState(false); useEffect(() => { async function loadUsers() { try { const response = await apiGet("/portal/users"); - // Nur Hauptnutzer (primaryUser=true) anzeigen, aber Admin ausblenden - const primaryUsers = response - .filter((u) => u.primaryUser && u.role !== "ADMIN") - .map((u) => ({ - id: u.id, - displayName: u.displayName, - companyName: u.companyName, - email: u.email, - active: u.active, - updatedAt: u.updatedAt, - })); - setUsers(primaryUsers); + if (isAdmin) { + // Admin sieht alle Hauptnutzer (außer andere Admins) + const primaryUsers = response + .filter((u) => u.primaryUser && u.role !== "ADMIN") + .map((u) => ({ + id: u.id, + displayName: u.displayName, + email: u.email, + active: u.active, + updatedAt: u.updatedAt, + })); + setUsers(primaryUsers); + } else { + // Hauptnutzer sieht alle seine Unterbenutzer (nicht-primary) + const subUsers = response + .filter((u) => !u.primaryUser) + .map((u) => ({ + id: u.id, + displayName: u.displayName, + email: u.email, + active: u.active, + updatedAt: u.updatedAt, + })); + setUsers(subUsers); + } } catch (error) { setMessage((error as Error).message); } finally { @@ -43,7 +64,7 @@ export default function UserManagementPage() { } void loadUsers(); - }, []); + }, [isAdmin]); async function toggleUserStatus(userId: string, newStatus: boolean) { try { @@ -65,14 +86,54 @@ export default function UserManagementPage() { }.` ); - // Nachricht nach 3 Sekunden ausblenden setTimeout(() => setMessage(null), 3000); } catch (error) { setMessage((error as Error).message); } } - // Formatierungsfunktion für das Datum + async function handleCreateUser(e: React.FormEvent) { + e.preventDefault(); + if (!newUserName.trim() || !newUserEmail.trim() || !newUserPassword.trim()) { + setMessage("Bitte alle Felder ausfüllen."); + return; + } + + setCreating(true); + try { + await apiPost("/portal/users", { + displayName: newUserName.trim(), + email: newUserEmail.trim(), + password: newUserPassword, + }); + + // Reload users + const response = await apiGet("/portal/users"); + const subUsers = response + .filter((u) => !u.primaryUser) + .map((u) => ({ + id: u.id, + displayName: u.displayName, + email: u.email, + active: u.active, + updatedAt: u.updatedAt, + })); + setUsers(subUsers); + + // Reset form + setNewUserName(""); + setNewUserEmail(""); + setNewUserPassword(""); + setShowCreateForm(false); + setMessage(`Benutzer "${newUserName}" wurde erstellt.`); + setTimeout(() => setMessage(null), 3000); + } catch (error) { + setMessage((error as Error).message); + } finally { + setCreating(false); + } + } + function formatDate(value: string) { return new Intl.DateTimeFormat("de-DE", { dateStyle: "medium", @@ -80,13 +141,12 @@ export default function UserManagementPage() { }).format(new Date(value)); } - // Nicht-Admin Ansicht (sollte nicht passieren, da Route geschützt ist) - if (!isAdmin) { + if (!canManageUsers) { return (
- Zugriff verweigert. Diese Seite ist nur für Administratoren. + Zugriff verweigert. Diese Seite ist nur für Administratoren und Hauptbenutzer.
@@ -99,10 +159,11 @@ export default function UserManagementPage() {

Benutzerverwaltung

-

Hauptnutzer freigeben oder sperren

+

{isAdmin ? "Hauptnutzer freigeben oder sperren" : "Unterbenutzer verwalten"}

- Verwalten Sie den Zugriff von Hauptnutzern auf das System. - Gesperrte Benutzer können sich nicht mehr anmelden. + {isAdmin + ? "Verwalten Sie den Zugriff von Hauptnutzern auf das System. Gesperrte Benutzer können sich nicht mehr anmelden." + : "Erstellen und verwalten Sie Unterbenutzer für Ihr Konto. Unterbenutzer können Proben registrieren und bearbeiten."}

@@ -111,7 +172,9 @@ export default function UserManagementPage() { {message ? (
) : null} - {/* Tabelle mit Hauptnutzern */} + {/* Create Sub-user Form (nur für Hauptnutzer) */} + {isPrimaryUser && !isAdmin && ( +
+ {!showCreateForm ? ( +
+
+

Neuer Unterbenutzer

+

Benutzer anlegen

+
+ +
+ ) : ( + <> +
+
+

Neuer Unterbenutzer

+

Benutzer anlegen

+
+ +
+
+ + + +
+ +
+
+ + )} +
+ )} + + {/* Tabelle mit Benutzern */}
-

Hauptnutzer

-

Registrierte Hauptnutzer

+

{isAdmin ? "Hauptnutzer" : "Unterbenutzer"}

+

{isAdmin ? "Registrierte Hauptnutzer" : "Ihre Unterbenutzer"}

{loading ? (
Benutzer werden geladen...
) : users.length === 0 ? ( -
Keine Hauptnutzer vorhanden.
+
+ {isAdmin ? "Keine Hauptnutzer vorhanden." : "Keine Unterbenutzer vorhanden."} +
) : (
- + {isAdmin && } @@ -152,7 +296,7 @@ export default function UserManagementPage() { - + {isAdmin && }
NameFirmaFirmaE-Mail Status Letzte Änderung {entry.displayName} {entry.companyName ?? "-"}{(entry as SubUserRow & { companyName?: string }).companyName ?? "-"}{entry.email ?? "-"} Hinweis

- Hauptnutzer sind die primären Kontoinhaber. Wenn Sie einen Hauptnutzer sperren, - können sich dieser und alle zugehörigen Nebennutzer nicht mehr anmelden. - Die Daten bleiben erhalten und können durch Freigabe wieder aktiviert werden. + {isAdmin + ? "Hauptnutzer sind die primären Kontoinhaber. Wenn Sie einen Hauptnutzer sperren, können sich dieser und alle zugehörigen Nebennutzer nicht mehr anmelden. Die Daten bleiben erhalten und können durch Freigabe wieder aktiviert werden." + : "Unterbenutzer können Proben registrieren und bearbeiten, aber keine neuen Benutzer anlegen. Wenn Sie einen Unterbenutzer sperren, kann sich dieser nicht mehr anmelden."}