This commit is contained in:
102
src/app/admin/teams/CreateOrEditPopup.svelte
Normal file
102
src/app/admin/teams/CreateOrEditPopup.svelte
Normal file
@ -0,0 +1,102 @@
|
||||
<script lang="ts">
|
||||
import UserSearch from '@components/admin/search/UserSearch.svelte';
|
||||
import Input from '@components/input/Input.svelte';
|
||||
import type { Team } from '@app/admin/teams/types.ts';
|
||||
import { confirmPopupState } from '@components/popup/ConfirmPopup.ts';
|
||||
|
||||
// html bindings
|
||||
let modal: HTMLDialogElement;
|
||||
let modalForm: HTMLFormElement;
|
||||
|
||||
// types
|
||||
interface Props {
|
||||
popupTitle: string;
|
||||
submitButtonTitle: string;
|
||||
confirmPopupTitle: string;
|
||||
confirmPopupMessage: string;
|
||||
|
||||
team: Team | null;
|
||||
|
||||
open: boolean;
|
||||
|
||||
onSubmit: (team: Team) => void;
|
||||
onClose?: () => void;
|
||||
}
|
||||
|
||||
// inputs
|
||||
let { popupTitle, submitButtonTitle, confirmPopupTitle, confirmPopupMessage, team, open, onSubmit, onClose }: Props =
|
||||
$props();
|
||||
|
||||
// states
|
||||
let name = $state<string | null>(team?.name ?? null);
|
||||
let color = $state<string | null>(team?.color ?? null);
|
||||
let lastJoined = $state<string | null>(team?.lastJoined ?? null);
|
||||
let memberOne = $state<Team['memberOne']>(team?.memberOne ?? ({ username: null } as unknown as Team['memberOne']));
|
||||
let memberTwo = $state<Team['memberOne']>(team?.memberTwo ?? ({ username: null } as unknown as Team['memberOne']));
|
||||
|
||||
let submitEnabled = $derived(!!(name && color && memberOne.username && memberTwo.username));
|
||||
|
||||
// lifecycle
|
||||
$effect(() => {
|
||||
if (open) modal.show();
|
||||
});
|
||||
|
||||
// callbacks
|
||||
async function onSaveButtonClick(e: Event) {
|
||||
e.preventDefault();
|
||||
$confirmPopupState = {
|
||||
title: confirmPopupTitle,
|
||||
message: confirmPopupMessage,
|
||||
onConfirm: () => {
|
||||
modalForm.submit();
|
||||
onSubmit({
|
||||
id: team?.id ?? -1,
|
||||
name: name!,
|
||||
color: color!,
|
||||
lastJoined: lastJoined!,
|
||||
memberOne: memberOne!,
|
||||
memberTwo: memberTwo!
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function onCancelButtonClick(e: Event) {
|
||||
e.preventDefault();
|
||||
modalForm.submit();
|
||||
}
|
||||
</script>
|
||||
|
||||
<dialog class="modal" bind:this={modal} onclose={() => setTimeout(() => onClose?.(), 300)}>
|
||||
<form method="dialog" class="modal-box overflow-visible" bind:this={modalForm}>
|
||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2" onclick={onCancelButtonClick}>✕</button>
|
||||
<div class="space-y-5">
|
||||
<h3 class="text-xl font-geist font-bold">{popupTitle}</h3>
|
||||
<div class="w-full flex flex-col">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<Input type="color" label="Farbe" bind:value={color} />
|
||||
<Input type="text" label="Name" bind:value={name} />
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<UserSearch label="Spieler 1" bind:value={memberOne.username} required mustMatch />
|
||||
<UserSearch label="Spieler 2" bind:value={memberTwo.username} required />
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<Input type="date" label="Zuletzt gejoined" bind:value={lastJoined}></Input>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="btn btn-success"
|
||||
class:disabled={!submitEnabled}
|
||||
disabled={!submitEnabled}
|
||||
onclick={onSaveButtonClick}>{submitButtonTitle}</button
|
||||
>
|
||||
<button class="btn btn-error" type="button" onclick={onCancelButtonClick}>Abbrechen</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]">
|
||||
<button class="!cursor-default">close</button>
|
||||
</form>
|
||||
</dialog>
|
Reference in New Issue
Block a user