add delete to admin panel
All checks were successful
deploy / build-and-deploy (push) Successful in 21s

This commit is contained in:
2025-05-21 20:53:53 +02:00
parent e47268111a
commit 45f984e4da
16 changed files with 207 additions and 50 deletions

View File

@ -1,13 +1,23 @@
<script lang="ts">
import BitBadge from '@components/input/BitBadge.svelte';
import { Permissions } from '@util/permissions.ts';
import { admins, editAdmin } from '@app/admin/admins/admins.ts';
import { type Admin, admins, deleteAdmin, editAdmin } from '@app/admin/admins/admins.ts';
import CrudPopup from '@components/admin/popup/CrudPopup.svelte';
import DataTable from '@components/admin/table/DataTable.svelte';
import { confirmPopupState } from '@components/popup/ConfirmPopup.ts';
// state
let editPopupAdmin = $state(null);
let editPopupOpen = $derived(!!editPopupAdmin);
// callback
function onAdminDelete(admin: Admin) {
$confirmPopupState = {
title: 'Admin löschen',
message: 'Soll der Admin wirklich gelöscht werden?',
onConfirm: () => deleteAdmin(admin)
};
}
</script>
{#snippet permissionsBadge(permissions: number)}
@ -22,6 +32,7 @@
{ key: 'permissions', label: 'Berechtigungen', width: 60, transform: permissionsBadge }
]}
onEdit={(admin) => (editPopupAdmin = admin)}
onDelete={onAdminDelete}
/>
<CrudPopup

View File

@ -1,6 +1,7 @@
import { type ActionReturnType, actions } from 'astro:actions';
import { writable } from 'svelte/store';
import { actionErrorPopup } from '@util/action.ts';
import { addToWritableArray, deleteFromWritableArray, updateWritableArray } from '@util/state.ts';
// types
export type Admins = Exclude<ActionReturnType<typeof actions.admin.admins>['data'], undefined>['admins'];
@ -27,10 +28,7 @@ export async function addAdmin(admin: Admin & { password: string }) {
return;
}
admins.update((old) => {
old.push(Object.assign(admin, { id: data.id }));
return old;
});
addToWritableArray(admins, Object.assign(admin, { id: data.id }));
}
export async function editAdmin(admin: Admin & { password: string }) {
@ -40,9 +38,15 @@ export async function editAdmin(admin: Admin & { password: string }) {
return;
}
admins.update((old) => {
const index = old.findIndex((a) => a.id == admin.id);
old[index] = admin;
return old;
});
updateWritableArray(admins, admin, (t) => t.id == admin.id);
}
export async function deleteAdmin(admin: Admin) {
const { error } = await actions.admin.deleteAdmin(admin);
if (error) {
actionErrorPopup(error);
return;
}
deleteFromWritableArray(admins, (t) => t.id == admin.id);
}

View File

@ -1,7 +1,8 @@
<script lang="ts">
import { addTeam, teams } from '@app/admin/teams/teams.ts';
import { addTeam, deleteTeam, type Team, teams } from '@app/admin/teams/teams.ts';
import DataTable from '@components/admin/table/DataTable.svelte';
import CrudPopup from '@components/admin/popup/CrudPopup.svelte';
import { confirmPopupState } from '@components/popup/ConfirmPopup.ts';
// state
let editPopupTeam = $state(null);
@ -11,6 +12,15 @@
$effect(() => {
if (!editPopupOpen) editPopupTeam = null;
});
// callback
function onTeamDelete(team: Team) {
$confirmPopupState = {
title: 'Team löschen?',
message: 'Soll das Team wirklich gelöscht werden?',
onConfirm: () => deleteTeam(team)
};
}
</script>
{#snippet color(value: string)}
@ -27,6 +37,7 @@
{ key: 'memberTwo.username', label: 'Spieler 2', width: 30 }
]}
onEdit={(team) => (editPopupTeam = team)}
onDelete={onTeamDelete}
/>
<CrudPopup

View File

@ -1,13 +1,12 @@
import { type ActionReturnType, actions } from 'astro:actions';
import { writable } from 'svelte/store';
import { actionErrorPopup } from '@util/action.ts';
import { addToWritableArray, deleteFromWritableArray, updateWritableArray } from '@util/state.ts';
// types
export type Teams = Exclude<ActionReturnType<typeof actions.team.teams>['data'], undefined>['teams'];
export type Team = Teams[0];
export type Users = Exclude<ActionReturnType<typeof actions.user.users>['data'], undefined>['users'];
// state
export const teams = writable<Teams>([]);
@ -29,10 +28,7 @@ export async function addTeam(team: Team) {
return;
}
teams.update((old) => {
old.push(Object.assign(team, { id: data.id }));
return old;
});
addToWritableArray(teams, Object.assign(team, { id: data.id }));
}
export async function editTeam(team: Team) {
@ -42,9 +38,15 @@ export async function editTeam(team: Team) {
return;
}
teams.update((old) => {
const index = old.findIndex((a) => a.id == team.id);
old[index] = team;
return old;
});
updateWritableArray(teams, team, (t) => t.id == team.id);
}
export async function deleteTeam(team: Team) {
const { error } = await actions.team.deleteTeam(team);
if (error) {
actionErrorPopup(error);
return;
}
deleteFromWritableArray(teams, (t) => t.id == team.id);
}

View File

@ -1,7 +1,8 @@
<script lang="ts">
import DataTable from '@components/admin/table/DataTable.svelte';
import { editUser, users } from '@app/admin/users/users.ts';
import { deleteUser, editUser, type User, users } from '@app/admin/users/users.ts';
import CrudPopup from '@components/admin/popup/CrudPopup.svelte';
import { confirmPopupState } from '@components/popup/ConfirmPopup.ts';
// state
let editPopupUser = $state(null);
@ -11,6 +12,15 @@
$effect(() => {
if (!editPopupOpen) editPopupUser = null;
});
// callback
function onUserDelete(user: User) {
$confirmPopupState = {
title: 'Nutzer löschen?',
message: 'Soll der Nutzer wirklich gelöscht werden?',
onConfirm: () => deleteUser(user)
};
}
</script>
<DataTable
@ -25,6 +35,7 @@
{ key: 'uuid', label: 'UUID', width: 23 }
]}
onEdit={(user) => (editPopupUser = user)}
onDelete={onUserDelete}
/>
<CrudPopup

View File

@ -1,6 +1,7 @@
import { writable } from 'svelte/store';
import { type ActionReturnType, actions } from 'astro:actions';
import { actionErrorPopup } from '@util/action.ts';
import { addToWritableArray, deleteFromWritableArray, updateWritableArray } from '@util/state.ts';
// types
export type Users = Exclude<ActionReturnType<typeof actions.user.users>['data'], undefined>['users'];
@ -34,10 +35,7 @@ export async function addUser(user: User) {
return;
}
users.update((old) => {
old.push(Object.assign(user, { id: data.id }));
return old;
});
addToWritableArray(users, user);
}
export async function editUser(user: User) {
@ -55,9 +53,15 @@ export async function editUser(user: User) {
return;
}
users.update((old) => {
const index = old.findIndex((a) => a.id == user.id);
old[index] = user;
return old;
});
updateWritableArray(users, user, (t) => t.id == user.id);
}
export async function deleteUser(user: User) {
const { error } = await actions.user.deleteUser({ id: user.id });
if (error) {
actionErrorPopup(error);
return;
}
deleteFromWritableArray(users, (t) => t.id == user.id);
}

View File

@ -1,7 +1,13 @@
<script lang="ts">
import { blockedUsers, editBlockedUser } from '@app/admin/usersBlocked/usersBlocked.ts';
import {
type BlockedUser,
blockedUsers,
deleteBlockedUser,
editBlockedUser
} from '@app/admin/usersBlocked/usersBlocked.ts';
import CrudPopup from '@components/admin/popup/CrudPopup.svelte';
import DataTable from '@components/admin/table/DataTable.svelte';
import { confirmPopupState } from '@components/popup/ConfirmPopup.ts';
// state
let blockedUserEditPopupBlockedUser = $state(null);
@ -11,6 +17,15 @@
$effect(() => {
if (!blockedUserEditPopupOpen) blockedUserEditPopupBlockedUser = null;
});
// callback
function onBlockedUserDelete(blockedUser: BlockedUser) {
$confirmPopupState = {
title: 'Nutzer entblockieren?',
message: 'Soll der Nutzer wirklich entblockiert werden?\nDieser kann sich danach wieder registrieren.',
onConfirm: () => deleteBlockedUser(blockedUser)
};
}
</script>
<DataTable
@ -21,6 +36,7 @@
{ key: 'comment', label: 'Kommentar', width: 70 }
]}
onEdit={(blockedUser) => (blockedUserEditPopupBlockedUser = blockedUser)}
onDelete={onBlockedUserDelete}
/>
<CrudPopup

View File

@ -1,6 +1,7 @@
import { type ActionReturnType, actions } from 'astro:actions';
import { writable } from 'svelte/store';
import { actionErrorPopup } from '@util/action.ts';
import { addToWritableArray, deleteFromWritableArray, updateWritableArray } from '@util/state.ts';
// types
export type BlockedUsers = Exclude<ActionReturnType<typeof actions.user.blocked>['data'], undefined>['blocked'];
@ -27,10 +28,7 @@ export async function addBlockedUser(blockedUser: BlockedUser) {
return;
}
blockedUsers.update((old) => {
old.push(Object.assign(blockedUser, { id: data.id }));
return old;
});
addToWritableArray(blockedUsers, Object.assign(blockedUser, { id: data.id }));
}
export async function editBlockedUser(blockedUser: BlockedUser) {
@ -40,9 +38,15 @@ export async function editBlockedUser(blockedUser: BlockedUser) {
return;
}
blockedUsers.update((old) => {
const index = old.findIndex((a) => a.id == blockedUser.id);
old[index] = blockedUser;
return old;
});
updateWritableArray(blockedUsers, blockedUser, (t) => t.id == blockedUser.id);
}
export async function deleteBlockedUser(blockedUser: BlockedUser) {
const { error } = await actions.user.deleteBlocked(blockedUser);
if (error) {
actionErrorPopup(error);
return;
}
deleteFromWritableArray(blockedUsers, (t) => t.id == blockedUser.id);
}