import {useEffect, useState} from "react"; import {createUser, fetchAllUsers, fetchCurrentUser, updateUser,} from "../../api/points/UserPoint"; import type {UserDto} from "../../api/dtos/UserDto"; import ContentBody from "../basics/ContentBody"; import StickyHeader from "../basics/StickyHeader"; import Button from "../basics/Button"; import {ButtonType} from "../basics/BasicButtonDefinitions"; import PageContainer from "../basics/PageContainer"; import {ChangePasswordModal} from "./ChangePasswordModal"; import ButtonGroupLayout from "../basics/ButtonGroupLayout"; import {Plus, X} from "lucide-react"; import ButtonLink from "../basics/ButtonLink"; import {getRecipeListUrl} from "../../routes"; import type {CreateUserResponse} from "../../api/dtos/CreateUserResponse"; import type {UserListResponse} from "../../api/dtos/UserListResponse"; import UserList from "./UserList"; import UserEditForm from "./UserEditForm"; import ErrorPopup from "../basics/ErrorPopup"; import {UserRole} from "../../api/enums/UserRole.ts"; import PageContentLayout from "../basics/PageContentLayout.tsx"; /** * UserManagementPage * ------------------- * Displays a two-column layout: * - Left: list of all users * - Right: edit form for selected or new user * * Allows: * - Admins to manage all users (add/edit) * - Regular users to edit their own profile * - Password changes via modal */ export default function UserManagementPage() { const [users, setUsers] = useState([]); const [selectedUser, setSelectedUser] = useState(null); const [currentUser, setCurrentUser] = useState(null); const [isPasswordModalOpen, setIsPasswordModalOpen] = useState(false); const [isSaving, setIsSaving] = useState(false); const [error, setError] = useState(null); const isAdmin = currentUser?.role === UserRole.ADMIN; // Load current user and user list (if admin) useEffect(() => { loadData(); }, []); /** * Load data for user management page * * An admin can see all users while a normal user can only see his own user data. * Initially, the current user is selected. */ const loadData = async () => { try { const me = await fetchCurrentUser(); setCurrentUser(me); if (me.role === UserRole.ADMIN) { const userResponse: UserListResponse = await fetchAllUsers(); // Sort users alphabetically by last name, then first name const sortedUsers = userResponse.valueList.sort((a, b) => { const lastNameCompare = (a.lastName || "").localeCompare( b.lastName || "" ); if (lastNameCompare !== 0) { return lastNameCompare; } return (a.firstName || "").localeCompare(b.firstName || ""); }); setUsers(sortedUsers); setSelectedUser(me); } else { setUsers([me]); setSelectedUser(me); } } catch (err) { setError( err instanceof Error ? err.message : "Fehler beim Laden der Benutzerdaten" ); } }; /** Handles selecting a user from the list */ const handleSelectUser = (user: UserDto) => { setSelectedUser({...user}); }; /** Handles saving user (create or update) */ const handleSave = async (user: UserDto, password?: string) => { setIsSaving(true); setError(null); try { if (!user.id) { // New user const response: CreateUserResponse = await createUser({ userData: user, password: password || "", }); const userDto = response.userData; if (userDto) { const newUsers = [...users, userDto].sort((a, b) => { const lastNameCompare = (a.lastName || "").localeCompare( b.lastName || "" ); if (lastNameCompare !== 0) { return lastNameCompare; } return (a.firstName || "").localeCompare(b.firstName || ""); }); setUsers(newUsers); setSelectedUser(userDto); } } else { // Existing user const updated = await updateUser(user); setUsers(users.map((u) => (u.id === updated.id ? updated : u))); setSelectedUser(updated); } } catch (err) { setError( err instanceof Error ? err.message : "Fehler beim Speichern der Benutzerdaten" ); } finally { setIsSaving(false); } }; /** Opens password modal */ const openPasswordModal = () => { setIsPasswordModalOpen(true); }; /** Add new empty user */ const handleAddUser = () => { setSelectedUser({ userName: "", firstName: "", lastName: "", email: "", role: UserRole.USER, }); }; return (

Benutzerverwaltung

{isAdmin && (