From e6fd6d7d6f9a9fb87ba5d19d4420f6b2b031419c Mon Sep 17 00:00:00 2001 From: araemer Date: Sun, 30 Nov 2025 08:42:07 +0100 Subject: [PATCH] Enum for user role - somehow user page is currently unresponsive. Probably because of previous layout changes --- frontend/src/api/dtos/UserDto.ts | 11 ++-- frontend/src/api/enums/UserRole.ts | 52 +++++++++++++++++++ .../src/components/basics/SelectField.tsx | 34 +++++++++--- .../src/components/users/UserEditForm.tsx | 10 ++-- .../components/users/UserManagementPage.tsx | 8 +-- 5 files changed, 94 insertions(+), 21 deletions(-) create mode 100644 frontend/src/api/enums/UserRole.ts diff --git a/frontend/src/api/dtos/UserDto.ts b/frontend/src/api/dtos/UserDto.ts index 972cad6..3aaa4c6 100644 --- a/frontend/src/api/dtos/UserDto.ts +++ b/frontend/src/api/dtos/UserDto.ts @@ -1,9 +1,10 @@ -import { AbstractDto } from "./AbstractDto.ts"; +import {AbstractDto} from "./AbstractDto"; +import {UserRole} from "../enums/UserRole"; -export class UserDto extends AbstractDto { +export interface UserDto extends AbstractDto { firstName?: string; lastName?: string; - userName!: string; - email!: string; - role?: string; + userName: string; + email: string; + role?: UserRole; } \ No newline at end of file diff --git a/frontend/src/api/enums/UserRole.ts b/frontend/src/api/enums/UserRole.ts new file mode 100644 index 0000000..d4f5f53 --- /dev/null +++ b/frontend/src/api/enums/UserRole.ts @@ -0,0 +1,52 @@ +/** + * User roles - Frontend version + * Content should match backend enum exactly + * However, we cannot use a basic enum here as we're using erasableSyntaxOnly. + */ +export const UserRole = { + USER: "user", + ADMIN: "admin", +} as const; + +// Create a type from the values +export type UserRole = typeof UserRole[keyof typeof UserRole]; + +/** + * Helper functions for UserRole in frontend + */ +export const UserRoleHelper = { + /** + * Get display name for role (German) + */ + getDisplayName(role: UserRole): string { + const displayNames: Record = { + [UserRole.USER]: "Benutzer", + [UserRole.ADMIN]: "Administrator", + }; + return displayNames[role]; + }, + + /** + * Get all roles with display names for dropdowns + */ + getRoleOptions(): Array<{ value: UserRole; label: string }> { + return Object.values(UserRole).map((role) => ({ + value: role, + label: this.getDisplayName(role), + })); + }, + + /** + * Check if a string is a valid role + */ + isValidRole(value: string): value is UserRole { + return Object.values(UserRole).includes(value as UserRole); + }, + + /** + * Get all role values + */ + getAllRoles(): UserRole[] { + return Object.values(UserRole); + }, +}; \ No newline at end of file diff --git a/frontend/src/components/basics/SelectField.tsx b/frontend/src/components/basics/SelectField.tsx index 1dc0ecb..e8c560a 100644 --- a/frontend/src/components/basics/SelectField.tsx +++ b/frontend/src/components/basics/SelectField.tsx @@ -1,18 +1,40 @@ -type SelectFieldProps = { - value: string; - onChange: (value: string) => void; - options: { value: string; label: string }[]; +type SelectFieldProps = { + value: T; + onChange: (value: T) => void; + options: { value: T; label: string }[]; className?: string; }; /** * SelectField - A dropdown styled consistently with input fields + * Generic component that works with any string-based type (including string literals and enums) + * + * @example + * // With UserRole type + * + * value={user.role} + * onChange={(role) => setUser({...user, role})} + * options={UserRoleHelper.getRoleOptions()} + * /> + * + * @example + * // With plain strings + * + * value={status} + * onChange={setStatus} + * options={[{value: "active", label: "Active"}, {value: "inactive", label: "Inactive"}]} + * /> */ -export default function SelectField({value, onChange, options, className = ''}: SelectFieldProps) { +export default function SelectField({ + value, + onChange, + options, + className = '' + }: SelectFieldProps) { return (