add death to admin ui
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
import TeamSearch from '@components/admin/search/TeamSearch.svelte';
|
||||
import { editReportStatus, getReportStatus } from '@app/admin/reports/reports.ts';
|
||||
import { confirmPopupState } from '@components/popup/ConfirmPopup.ts';
|
||||
import Icon from "@iconify/svelte";
|
||||
import Icon from '@iconify/svelte';
|
||||
|
||||
// html bindings
|
||||
let previewDialogElem: HTMLDialogElement;
|
||||
|
||||
49
src/app/admin/teamDeaths/SidebarActions.svelte
Normal file
49
src/app/admin/teamDeaths/SidebarActions.svelte
Normal file
@@ -0,0 +1,49 @@
|
||||
<script lang="ts">
|
||||
import { addDeath, fetchDeaths } from '@app/admin/teamDeaths/teamDeaths.ts';
|
||||
import Icon from '@iconify/svelte';
|
||||
import CrudPopup from '@components/admin/popup/CrudPopup.svelte';
|
||||
|
||||
// states
|
||||
let createPopupOpen = $state(false);
|
||||
|
||||
// lifecycle
|
||||
$effect(() => {
|
||||
fetchDeaths();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<button class="btn btn-soft w-full" onclick={() => (createPopupOpen = true)}>
|
||||
<Icon icon="heroicons:plus-16-solid" />
|
||||
<span>Neuer Spielertod</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<CrudPopup
|
||||
texts={{
|
||||
title: 'Spielertod erstellen',
|
||||
submitButtonTitle: 'Erstellen',
|
||||
confirmPopupTitle: 'Spielertod erstellen?',
|
||||
confirmPopupMessage: 'Soll der neue Spielertod erstellt werden?'
|
||||
}}
|
||||
target={null}
|
||||
keys={[
|
||||
[
|
||||
{
|
||||
key: 'killed',
|
||||
type: 'user-search',
|
||||
label: 'Getöteter Spieler',
|
||||
options: { required: true, validate: (user) => !!user?.id }
|
||||
},
|
||||
{
|
||||
key: 'killer',
|
||||
type: 'user-search',
|
||||
label: 'Killer',
|
||||
options: { validate: (user) => (user?.username ? !!user?.id : true) }
|
||||
}
|
||||
],
|
||||
[{ key: 'message', type: 'textarea', label: 'Todesnachricht', options: { required: true, dynamicWidth: true } }]
|
||||
]}
|
||||
onSubmit={addDeath}
|
||||
bind:open={createPopupOpen}
|
||||
/>
|
||||
69
src/app/admin/teamDeaths/TeamDeaths.svelte
Normal file
69
src/app/admin/teamDeaths/TeamDeaths.svelte
Normal file
@@ -0,0 +1,69 @@
|
||||
<script lang="ts">
|
||||
// state
|
||||
import { type Death, deaths, deleteDeath, editDeath } from '@app/admin/teamDeaths/teamDeaths.ts';
|
||||
import { confirmPopupState } from '@components/popup/ConfirmPopup.ts';
|
||||
import DataTable from '@components/admin/table/DataTable.svelte';
|
||||
import CrudPopup from '@components/admin/popup/CrudPopup.svelte';
|
||||
|
||||
let editPopupDeath = $state(null);
|
||||
let editPopupOpen = $derived(!!editPopupDeath);
|
||||
|
||||
// lifecycle
|
||||
$effect(() => {
|
||||
if (!editPopupOpen) editPopupDeath = null;
|
||||
});
|
||||
|
||||
// callbacks
|
||||
function onDeathDelete(death: Death) {
|
||||
$confirmPopupState = {
|
||||
title: 'Tod löschen?',
|
||||
message: 'Soll der Tod wirklich gelöscht werden?',
|
||||
onConfirm: () => deleteDeath(death)
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
{#snippet username(user?: { id: number; username: string })}
|
||||
{user?.username}
|
||||
{/snippet}
|
||||
|
||||
<DataTable
|
||||
data={deaths}
|
||||
count={true}
|
||||
keys={[
|
||||
{ key: 'killed', label: 'Getöteter Spieler', width: 20, transform: username },
|
||||
{ key: 'killer', label: 'Killer', width: 20, transform: username },
|
||||
{ key: 'message', label: 'Todesnachricht', width: 50 }
|
||||
]}
|
||||
onEdit={(death) => (editPopupDeath = death)}
|
||||
onDelete={onDeathDelete}
|
||||
/>
|
||||
|
||||
<CrudPopup
|
||||
texts={{
|
||||
title: 'Tod bearbeiten',
|
||||
submitButtonTitle: 'Speichern',
|
||||
confirmPopupTitle: 'Änderungen speichern?',
|
||||
confirmPopupMessage: 'Sollen die Änderungen gespeichert werden?'
|
||||
}}
|
||||
target={editPopupDeath}
|
||||
keys={[
|
||||
[
|
||||
{
|
||||
key: 'killed',
|
||||
type: 'user-search',
|
||||
label: 'Getöteter Spieler',
|
||||
options: { required: true, validate: (user) => !!user?.id }
|
||||
},
|
||||
{
|
||||
key: 'killer',
|
||||
type: 'user-search',
|
||||
label: 'Killer',
|
||||
options: { validate: (user) => (user?.username ? !!user?.id : true) }
|
||||
}
|
||||
],
|
||||
[{ key: 'message', type: 'textarea', label: 'Todesnachricht', options: { required: true, dynamicWidth: true } }]
|
||||
]}
|
||||
onSubmit={editDeath}
|
||||
bind:open={editPopupDeath}
|
||||
/>
|
||||
61
src/app/admin/teamDeaths/teamDeaths.ts
Normal file
61
src/app/admin/teamDeaths/teamDeaths.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
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 Deaths = Exclude<ActionReturnType<typeof actions.team.deaths>['data'], undefined>['deaths'];
|
||||
export type Death = Deaths[0];
|
||||
|
||||
// state
|
||||
export const deaths = writable<Deaths>([]);
|
||||
|
||||
// actions
|
||||
export async function fetchDeaths() {
|
||||
const { data, error } = await actions.team.deaths();
|
||||
if (error) {
|
||||
actionErrorPopup(error);
|
||||
return;
|
||||
}
|
||||
|
||||
deaths.set(data.deaths);
|
||||
}
|
||||
|
||||
export async function addDeath(death: Death) {
|
||||
const { data, error } = await actions.team.addDeath({
|
||||
deadUserId: death.killed.id,
|
||||
killerUserId: death.killer?.id,
|
||||
message: death.message
|
||||
});
|
||||
if (error) {
|
||||
actionErrorPopup(error);
|
||||
return;
|
||||
}
|
||||
|
||||
addToWritableArray(deaths, Object.assign(death, { id: data.id }));
|
||||
}
|
||||
|
||||
export async function editDeath(death: Death) {
|
||||
const { error } = await actions.team.editDeath({
|
||||
id: death.id,
|
||||
deadUserId: death.killed.id,
|
||||
killerUserId: death.killer?.id,
|
||||
message: death.message
|
||||
});
|
||||
if (error) {
|
||||
actionErrorPopup(error);
|
||||
return;
|
||||
}
|
||||
|
||||
updateWritableArray(deaths, death, (d) => d.id == death.id);
|
||||
}
|
||||
|
||||
export async function deleteDeath(death: Death) {
|
||||
const { error } = await actions.team.deleteDeath({ id: death.id });
|
||||
if (error) {
|
||||
actionErrorPopup(error);
|
||||
return;
|
||||
}
|
||||
|
||||
deleteFromWritableArray(deaths, (d) => d.id == death.id);
|
||||
}
|
||||
Reference in New Issue
Block a user