From b7804e10eafa15134182180536bb51bfe6840855 Mon Sep 17 00:00:00 2001 From: AzuTear Date: Thu, 25 Jun 2026 20:14:47 +0200 Subject: [PATCH] Polish team role and login UI --- Backend/Endpoints/AdminTeamEndpoints.cs | 10 ++++++++++ frontend/src/components/admin/useAdminTeamManager.ts | 4 ++++ frontend/src/views/LoginView.vue | 2 +- frontend/src/views/admin/AdminTeamView.vue | 6 +++--- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/Backend/Endpoints/AdminTeamEndpoints.cs b/Backend/Endpoints/AdminTeamEndpoints.cs index c301779..007333a 100644 --- a/Backend/Endpoints/AdminTeamEndpoints.cs +++ b/Backend/Endpoints/AdminTeamEndpoints.cs @@ -105,6 +105,11 @@ public static class AdminTeamEndpoints return validationError; } + if (normalizedRole == AdminRoles.Creator) + { + return Results.Json(new { message = "Creator-Konten werden fest vorkonfiguriert und können nicht manuell angelegt werden." }, statusCode: StatusCodes.Status403Forbidden); + } + if (AdminRoles.IsPrivilegedFullControlRole(normalizedRole) && !AdminRoles.CanResetTeamPasswords(session.Role)) { return Results.Json(new { message = "Owner- und Creator-Konten können nur von Owner oder Creator angelegt werden." }, statusCode: StatusCodes.Status403Forbidden); @@ -185,6 +190,11 @@ public static class AdminTeamEndpoints return Results.Conflict(new { message = "Dieser Login existiert bereits." }); } + if (normalizedRole == AdminRoles.Creator && member.Role != AdminRoles.Creator) + { + return Results.Json(new { message = "Creator-Konten werden fest vorkonfiguriert und können nicht manuell zugewiesen werden." }, statusCode: StatusCodes.Status403Forbidden); + } + if ((AdminRoles.IsPrivilegedFullControlRole(member.Role) || AdminRoles.IsPrivilegedFullControlRole(normalizedRole)) && !AdminRoles.CanResetTeamPasswords(session.Role)) { return Results.Json(new { message = "Owner- und Creator-Konten können nur von Owner oder Creator bearbeitet werden." }, statusCode: StatusCodes.Status403Forbidden); diff --git a/frontend/src/components/admin/useAdminTeamManager.ts b/frontend/src/components/admin/useAdminTeamManager.ts index 154ddaf..0420ba7 100644 --- a/frontend/src/components/admin/useAdminTeamManager.ts +++ b/frontend/src/components/admin/useAdminTeamManager.ts @@ -38,6 +38,9 @@ export function useAdminTeamManager() { const pendingPasswordChanges = computed(() => members.value.filter((member) => member.mustChangePassword).length) const roleOptions = computed(() => roles.value.map((role) => ({ value: role.key, label: role.label }))) const selectedMember = computed(() => members.value.find((member) => member.id === editingMemberId.value) ?? null) + const assignableRoleOptions = computed(() => roleOptions.value.filter((role) => + role.value !== 'creator' || selectedMember.value?.role === 'creator', + )) const hasRoleChanges = computed(() => Boolean(savedRoleSnapshot.value) && JSON.stringify(rolePermissionDrafts.value) !== savedRoleSnapshot.value, ) @@ -260,6 +263,7 @@ export function useAdminTeamManager() { activeMembers, pendingPasswordChanges, roleOptions, + assignableRoleOptions, hasRoleChanges, loadTeam, startCreateMember, diff --git a/frontend/src/views/LoginView.vue b/frontend/src/views/LoginView.vue index fd0e254..7d5a3d6 100644 --- a/frontend/src/views/LoginView.vue +++ b/frontend/src/views/LoginView.vue @@ -11,7 +11,7 @@ const route = useRoute() const router = useRouter() const form = reactive({ - login: 'jayuhime_admin', + login: '', password: '', }) diff --git a/frontend/src/views/admin/AdminTeamView.vue b/frontend/src/views/admin/AdminTeamView.vue index d9ecd58..108d326 100644 --- a/frontend/src/views/admin/AdminTeamView.vue +++ b/frontend/src/views/admin/AdminTeamView.vue @@ -41,7 +41,7 @@ const { selectedMember, activeMembers, pendingPasswordChanges, - roleOptions, + assignableRoleOptions, hasRoleChanges, startCreateMember, startEditMember, @@ -343,7 +343,7 @@ async function changeOwnPassword() { @@ -433,7 +433,7 @@ async function changeOwnPassword() { v-model="memberForm.role" class="h-12 rounded-2xl border border-violet-100 bg-white px-4 text-base font-bold text-slate-900 outline-none transition focus:border-violet-300 focus:ring-4 focus:ring-violet-100" > -