diff --git a/src/actions/admin.ts b/src/actions/admin.ts index 5e32bf9..46bf852 100644 --- a/src/actions/admin.ts +++ b/src/actions/admin.ts @@ -33,6 +33,16 @@ export const admin = { await db.editAdmin(input); } }), + deleteAdmin: defineAction({ + input: z.object({ + id: z.number() + }), + handler: async (input, context) => { + Session.actionSessionFromCookies(context.cookies, Permissions.Admin); + + await db.deleteAdmin(input); + } + }), admins: defineAction({ handler: async (_, context) => { Session.actionSessionFromCookies(context.cookies, Permissions.Admin); diff --git a/src/actions/team.ts b/src/actions/team.ts index ab63660..f50ed22 100644 --- a/src/actions/team.ts +++ b/src/actions/team.ts @@ -105,6 +105,16 @@ export const team = { }); } }), + deleteTeam: defineAction({ + input: z.object({ + id: z.number() + }), + handler: async (input, context) => { + Session.actionSessionFromCookies(context.cookies, Permissions.Users); + + await db.deleteTeam(input); + } + }), teams: defineAction({ input: z.object({ name: z.string().nullish(), diff --git a/src/actions/user.ts b/src/actions/user.ts index a91eab6..0926118 100644 --- a/src/actions/user.ts +++ b/src/actions/user.ts @@ -70,6 +70,16 @@ export const user = { }); } }), + deleteUser: defineAction({ + input: z.object({ + id: z.number() + }), + handler: async (input, context) => { + Session.actionSessionFromCookies(context.cookies, Permissions.Users); + + await db.deleteUser(input); + } + }), users: defineAction({ input: z.object({ username: z.string().nullish(), @@ -112,6 +122,16 @@ export const user = { await db.editBlockedUser(input); } }), + deleteBlocked: defineAction({ + input: z.object({ + id: z.number() + }), + handler: async (input, context) => { + Session.actionSessionFromCookies(context.cookies, Permissions.Users); + + await db.deleteBlockedUser(input); + } + }), blocked: defineAction({ handler: async (_, context) => { Session.actionSessionFromCookies(context.cookies, Permissions.Users); diff --git a/src/app/admin/admins/Admins.svelte b/src/app/admin/admins/Admins.svelte index 181ebc6..77dc506 100644 --- a/src/app/admin/admins/Admins.svelte +++ b/src/app/admin/admins/Admins.svelte @@ -1,13 +1,23 @@ {#snippet permissionsBadge(permissions: number)} @@ -22,6 +32,7 @@ { key: 'permissions', label: 'Berechtigungen', width: 60, transform: permissionsBadge } ]} onEdit={(admin) => (editPopupAdmin = admin)} + onDelete={onAdminDelete} /> ['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); } diff --git a/src/app/admin/teams/Teams.svelte b/src/app/admin/teams/Teams.svelte index f3a7857..0034c58 100644 --- a/src/app/admin/teams/Teams.svelte +++ b/src/app/admin/teams/Teams.svelte @@ -1,7 +1,8 @@ {#snippet color(value: string)} @@ -27,6 +37,7 @@ { key: 'memberTwo.username', label: 'Spieler 2', width: 30 } ]} onEdit={(team) => (editPopupTeam = team)} + onDelete={onTeamDelete} /> ['data'], undefined>['teams']; export type Team = Teams[0]; -export type Users = Exclude['data'], undefined>['users']; - // state export const teams = writable([]); @@ -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); } diff --git a/src/app/admin/users/Users.svelte b/src/app/admin/users/Users.svelte index 1d88601..60ca586 100644 --- a/src/app/admin/users/Users.svelte +++ b/src/app/admin/users/Users.svelte @@ -1,7 +1,8 @@ (editPopupUser = user)} + onDelete={onUserDelete} /> ['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); } diff --git a/src/app/admin/usersBlocked/UsersBlocked.svelte b/src/app/admin/usersBlocked/UsersBlocked.svelte index 5547de0..357fd31 100644 --- a/src/app/admin/usersBlocked/UsersBlocked.svelte +++ b/src/app/admin/usersBlocked/UsersBlocked.svelte @@ -1,7 +1,13 @@ (blockedUserEditPopupBlockedUser = blockedUser)} + onDelete={onBlockedUserDelete} /> ['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); } diff --git a/src/components/admin/table/DataTable.svelte b/src/components/admin/table/DataTable.svelte index dfcc6f8..c8513f8 100644 --- a/src/components/admin/table/DataTable.svelte +++ b/src/components/admin/table/DataTable.svelte @@ -21,10 +21,11 @@ onClick?: (t: T) => void; onEdit?: (t: T) => void; + onDelete?: (t: T) => void; } // input - let { data, count, keys, onClick, onEdit }: Props = $props(); + let { data, count, keys, onClick, onEdit, onDelete }: Props = $props();
@@ -39,7 +40,7 @@ >{key.label} {/each} - {#if onEdit} + {#if onEdit || onDelete} {/if} @@ -59,11 +60,18 @@ {/if} {/each} - {#if onEdit} + {#if onEdit || onDelete} - + {#if onEdit} + + {/if} + {#if onDelete} + + {/if} {/if} diff --git a/src/db/database.ts b/src/db/database.ts index 78eda4f..7f01769 100644 --- a/src/db/database.ts +++ b/src/db/database.ts @@ -9,7 +9,9 @@ import { type AddAdminReq, addAdmin, type EditAdminReq, - editAdmin + editAdmin, + type DeleteAdminReq, + deleteAdmin } from './schema/admin'; import { addTeam, @@ -114,7 +116,9 @@ import { type GetBlockedUserByUuidReq, getBlockedUserByUuid, type EditBlockedUserReq, - editBlockedUser + editBlockedUser, + type DeleteBlockedUserReq, + deleteBlockedUser } from '@db/schema/blockedUser.ts'; export class Database { @@ -173,6 +177,7 @@ export class Database { /* admins */ addAdmin = (values: AddAdminReq) => addAdmin(this.db, values); editAdmin = (values: EditAdminReq) => editAdmin(this.db, values); + deleteAdmin = (values: DeleteAdminReq) => deleteAdmin(this.db, values); getAdmins = (values: GetAdminReq) => getAdmins(this.db, values); existsAdmin = (values: ExistsAdminReq) => existsAdmin(this.db, values); @@ -189,6 +194,7 @@ export class Database { /* user blocks */ addBlockedUser = (values: AddBlockedUserReq) => addBlockedUser(this.db, values); editBlockedUser = (values: EditBlockedUserReq) => editBlockedUser(this.db, values); + deleteBlockedUser = (values: DeleteBlockedUserReq) => deleteBlockedUser(this.db, values); getBlockedUserByUuid = (values: GetBlockedUserByUuidReq) => getBlockedUserByUuid(this.db, values); getBlockedUsers = (values: GetBlockedUsersReq) => getBlockedUsers(this.db, values); diff --git a/src/db/schema/admin.ts b/src/db/schema/admin.ts index ad5a946..f6ee9a9 100644 --- a/src/db/schema/admin.ts +++ b/src/db/schema/admin.ts @@ -22,6 +22,10 @@ export type EditAdminReq = { permissions: number; }; +export type DeleteAdminReq = { + id: number; +}; + export type GetAdminReq = {}; export type GetAdminRes = Omit[]; @@ -55,6 +59,10 @@ export async function editAdmin(db: Database, values: EditAdminReq) { .where(eq(admin.id, values.id)); } +export async function deleteAdmin(db: Database, values: DeleteAdminReq) { + return db.delete(admin).where(eq(admin.id, values.id)); +} + export async function getAdmins(db: Database, _values: GetAdminReq): Promise { return db.select({ id: admin.id, username: admin.username, permissions: admin.permissions }).from(admin); } diff --git a/src/db/schema/blockedUser.ts b/src/db/schema/blockedUser.ts index 19e51b7..5994182 100644 --- a/src/db/schema/blockedUser.ts +++ b/src/db/schema/blockedUser.ts @@ -21,6 +21,10 @@ export type EditBlockedUserReq = { comment?: string | null; }; +export type DeleteBlockedUserReq = { + id: number; +}; + export type GetBlockedUserByUuidReq = { uuid: string; }; @@ -37,6 +41,10 @@ export async function editBlockedUser(db: Database, values: EditBlockedUserReq) await db.update(blockedUser).set(values).where(eq(blockedUser.id, values.id)); } +export async function deleteBlockedUser(db: Database, values: DeleteBlockedUserReq) { + return db.delete(blockedUser).where(eq(blockedUser.id, values.id)); +} + export async function getBlockedUserByUuid(db: Database, values: GetBlockedUserByUuidReq) { const bu = await db.query.blockedUser.findFirst({ where: eq(blockedUser.uuid, values.uuid) diff --git a/src/util/state.ts b/src/util/state.ts new file mode 100644 index 0000000..a709583 --- /dev/null +++ b/src/util/state.ts @@ -0,0 +1,24 @@ +import type { Writable } from 'svelte/store'; + +export function addToWritableArray(writable: Writable, t: T) { + writable.update((old) => { + old.push(t); + return old; + }); +} + +export function updateWritableArray(writable: Writable, t: T, cmp: (t: T) => boolean) { + writable.update((old) => { + const index = old.findIndex(cmp); + old[index] = t; + return old; + }); +} + +export function deleteFromWritableArray(writable: Writable, cmp: (t: T) => boolean) { + writable.update((old) => { + const index = old.findIndex(cmp); + old.splice(index, 1); + return old; + }); +}