Enum for user role - somehow user page is currently unresponsive. Probably because of previous layout changes
This commit is contained in:
parent
bd6ee25910
commit
e6fd6d7d6f
5 changed files with 94 additions and 21 deletions
|
|
@ -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;
|
||||
}
|
||||
52
frontend/src/api/enums/UserRole.ts
Normal file
52
frontend/src/api/enums/UserRole.ts
Normal file
|
|
@ -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, string> = {
|
||||
[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);
|
||||
},
|
||||
};
|
||||
|
|
@ -1,18 +1,40 @@
|
|||
type SelectFieldProps = {
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
options: { value: string; label: string }[];
|
||||
type SelectFieldProps<T extends string> = {
|
||||
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
|
||||
* <SelectField<UserRole>
|
||||
* value={user.role}
|
||||
* onChange={(role) => setUser({...user, role})}
|
||||
* options={UserRoleHelper.getRoleOptions()}
|
||||
* />
|
||||
*
|
||||
* @example
|
||||
* // With plain strings
|
||||
* <SelectField<string>
|
||||
* 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<T extends string>({
|
||||
value,
|
||||
onChange,
|
||||
options,
|
||||
className = ''
|
||||
}: SelectFieldProps<T>) {
|
||||
return (
|
||||
<select
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
onChange={(e) => onChange(e.target.value as T)}
|
||||
className={`p-2 w-full border rounded-md bg-white border-gray-600 hover:border-blue-800 transition-colors text-gray-600 focus:outline-none focus:border-blue-900 cursor-pointer ${className}`}
|
||||
>
|
||||
{options.map((option) => (
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import PasswordField from "../basics/PasswordField";
|
|||
import ButtonGroupLayout from "../basics/ButtonGroupLayout";
|
||||
import TextLinkButton from "../basics/TextLinkButton";
|
||||
import SelectField from "../basics/SelectField";
|
||||
import {UserRole, UserRoleHelper} from "../../api/enums/UserRole.ts";
|
||||
|
||||
type UserEditFormProps = {
|
||||
user: UserDto;
|
||||
|
|
@ -52,10 +53,7 @@ export default function UserEditForm({
|
|||
};
|
||||
|
||||
// @todo API string
|
||||
const roleOptions = [
|
||||
{value: "user", label: "Benutzer"},
|
||||
{value: "admin", label: "Administrator"},
|
||||
];
|
||||
const roleOptions = UserRoleHelper.getRoleOptions();
|
||||
|
||||
return (
|
||||
<div className="px-6 py-2">
|
||||
|
|
@ -104,8 +102,8 @@ export default function UserEditForm({
|
|||
{isAdmin && (
|
||||
<>
|
||||
<label>Benutzergruppe</label>
|
||||
<SelectField
|
||||
value={editedUser.role ?? "user"}
|
||||
<SelectField<UserRole>
|
||||
value={editedUser.role ?? UserRole.USER}
|
||||
onChange={(value) =>
|
||||
setEditedUser({...editedUser, role: value})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ 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";
|
||||
|
||||
/**
|
||||
* UserManagementPage
|
||||
|
|
@ -39,8 +40,7 @@ export default function UserManagementPage() {
|
|||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
//@todo API enum
|
||||
const adminRole: string = "admin";
|
||||
const isAdmin = currentUser?.role === adminRole;
|
||||
const isAdmin = currentUser?.role === UserRole.ADMIN;
|
||||
|
||||
// Load current user and user list (if admin)
|
||||
useEffect(() => {
|
||||
|
|
@ -52,7 +52,7 @@ export default function UserManagementPage() {
|
|||
const me = await fetchCurrentUser();
|
||||
setCurrentUser(me);
|
||||
|
||||
if (me.role === adminRole) {
|
||||
if (me.role === UserRole.ADMIN) {
|
||||
const userResponse: UserListResponse = await fetchAllUsers();
|
||||
|
||||
// Sort users alphabetically by last name, then first name
|
||||
|
|
@ -140,7 +140,7 @@ export default function UserManagementPage() {
|
|||
firstName: "",
|
||||
lastName: "",
|
||||
email: "",
|
||||
role: "user",
|
||||
role: UserRole.USER,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue