use global modal for popup messages
All checks were successful
delpoy / build-and-deploy (push) Successful in 51s
All checks were successful
delpoy / build-and-deploy (push) Successful in 51s
This commit is contained in:
parent
a1965c62e2
commit
e30446598c
@ -32,8 +32,6 @@ export default ts.config(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
rules: {
|
rules: {
|
||||||
// expressions are often used to check if a props function is defined before calling it
|
|
||||||
'@typescript-eslint/no-unused-expressions': 'off',
|
|
||||||
'@typescript-eslint/no-explicit-any': 'off'
|
'@typescript-eslint/no-explicit-any': 'off'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
required = false,
|
required = false,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
readonly = false,
|
readonly = false,
|
||||||
checked = false,
|
checked = $bindable(false),
|
||||||
size = 'md',
|
size = 'md',
|
||||||
pickyWidth = true,
|
pickyWidth = true,
|
||||||
containerClass = '',
|
containerClass = '',
|
||||||
@ -109,10 +109,15 @@
|
|||||||
{readonly}
|
{readonly}
|
||||||
bind:this={inputElement}
|
bind:this={inputElement}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
|
onchange={() => {
|
||||||
|
if (type === 'checkbox') {
|
||||||
|
checked = !checked;
|
||||||
|
}
|
||||||
|
}}
|
||||||
oninput={(e: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
|
oninput={(e: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
|
||||||
value = e.currentTarget.value;
|
value = e.currentTarget.value;
|
||||||
if (pattern && !pattern.test(value)) return;
|
if (pattern && !pattern.test(value)) return;
|
||||||
oninput && oninput(e);
|
oninput?.(e);
|
||||||
}}
|
}}
|
||||||
onpaste={(e) => {
|
onpaste={(e) => {
|
||||||
if (pattern && e.clipboardData && !pattern.test(e.clipboardData.getData('text'))) {
|
if (pattern && e.clipboardData && !pattern.test(e.clipboardData.getData('text'))) {
|
||||||
|
@ -63,14 +63,14 @@
|
|||||||
value = searchSuggestion.value;
|
value = searchSuggestion.value;
|
||||||
searchSuggestions = [];
|
searchSuggestions = [];
|
||||||
e.currentTarget.setCustomValidity('');
|
e.currentTarget.setCustomValidity('');
|
||||||
onsubmit && onsubmit(Object.assign(e, { input: inputValue, value: value }));
|
onsubmit?.(Object.assign(e, { input: inputValue, value: value }));
|
||||||
} else if (inputValue === '' && emptyAllowed) {
|
} else if (inputValue === '' && emptyAllowed) {
|
||||||
onsubmit && onsubmit(Object.assign(e, { input: '', value: '' }));
|
onsubmit?.(Object.assign(e, { input: '', value: '' }));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
oninvalid={(e: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
|
oninvalid={(e: Event & { currentTarget: EventTarget & HTMLInputElement }) => {
|
||||||
invalidMessage && e.currentTarget.setCustomValidity(invalidMessage);
|
if (invalidMessage) e.currentTarget.setCustomValidity(invalidMessage);
|
||||||
}}
|
}}
|
||||||
pattern={suggestionRequired
|
pattern={suggestionRequired
|
||||||
? `${value ? inputValue : 'a^' + (emptyAllowed ? '|$^' : '')}`
|
? `${value ? inputValue : 'a^' + (emptyAllowed ? '|$^' : '')}`
|
||||||
@ -89,7 +89,7 @@
|
|||||||
inputValue = searchSuggestion.name;
|
inputValue = searchSuggestion.name;
|
||||||
value = searchSuggestion.value;
|
value = searchSuggestion.value;
|
||||||
searchSuggestions = [];
|
searchSuggestions = [];
|
||||||
onsubmit && onsubmit(Object.assign(e, { input: inputValue, value: value }));
|
onsubmit?.(Object.assign(e, { input: inputValue, value: value }));
|
||||||
}}>{searchSuggestion.name}</button
|
}}>{searchSuggestion.name}</button
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
|
18
src/lib/context.ts
Normal file
18
src/lib/context.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { getContext } from 'svelte';
|
||||||
|
|
||||||
|
export type PopupModalContextArgs = {
|
||||||
|
title: string;
|
||||||
|
text?: string;
|
||||||
|
actions?: { text: string; action?: (modal: Event) => void }[];
|
||||||
|
onClose?: () => void;
|
||||||
|
};
|
||||||
|
export function getPopupModalShowFn(): ({
|
||||||
|
title,
|
||||||
|
text,
|
||||||
|
actions,
|
||||||
|
onClose
|
||||||
|
}: PopupModalContextArgs) => void {
|
||||||
|
const { set }: { set: ({ title, text, actions, onClose }: PopupModalContextArgs) => void } =
|
||||||
|
getContext('globalPopupModal');
|
||||||
|
return set;
|
||||||
|
}
|
@ -3,6 +3,9 @@
|
|||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
|
import Input from '$lib/components/Input/Input.svelte';
|
||||||
|
import { setContext, tick } from 'svelte';
|
||||||
|
import type { PopupModalContextArgs } from '$lib/context';
|
||||||
|
|
||||||
let { children } = $props();
|
let { children } = $props();
|
||||||
|
|
||||||
@ -60,7 +63,20 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let popupModalState: PopupModalContextArgs | null = $state(null);
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
let popupModalNullTimeout: number | NodeJS.Timeout | null = null;
|
||||||
|
setContext('globalPopupModal', {
|
||||||
|
set: async ({ title, text, actions, onClose }: PopupModalContextArgs) => {
|
||||||
|
if (popupModalNullTimeout) clearTimeout(popupModalNullTimeout);
|
||||||
|
popupModalState = { title, text, actions, onClose };
|
||||||
|
await tick();
|
||||||
|
popupModalElem.showModal();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let navElem: HTMLDivElement;
|
let navElem: HTMLDivElement;
|
||||||
|
let popupModalElem: HTMLDialogElement;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window bind:innerHeight={windowHeight} />
|
<svelte:window bind:innerHeight={windowHeight} />
|
||||||
@ -179,6 +195,48 @@
|
|||||||
</footer>
|
</footer>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<dialog class="modal" bind:this={popupModalElem}>
|
||||||
|
{#if popupModalState}
|
||||||
|
<form
|
||||||
|
method="dialog"
|
||||||
|
class="modal-box z-50"
|
||||||
|
onsubmit={() => {
|
||||||
|
popupModalNullTimeout = setTimeout(() => {
|
||||||
|
popupModalState = null;
|
||||||
|
popupModalNullTimeout = null;
|
||||||
|
}, 200);
|
||||||
|
popupModalState?.onClose?.();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
||||||
|
<h3 class="font-bold text-2xl">{popupModalState.title}</h3>
|
||||||
|
{#if popupModalState.text}
|
||||||
|
<p class="py-4 whitespace-pre-line">{popupModalState.text}</p>
|
||||||
|
{/if}
|
||||||
|
{#if popupModalState.actions}
|
||||||
|
<div class="flex flex-row space-x-1 mt-4">
|
||||||
|
{#each popupModalState.actions as action}
|
||||||
|
<Input type="submit" value={action.text} onclick={(e) => action.action?.(e)} />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</form>
|
||||||
|
<form
|
||||||
|
method="dialog"
|
||||||
|
class="modal-backdrop bg-[rgba(0,0,0,.2)]"
|
||||||
|
onsubmit={() => {
|
||||||
|
popupModalNullTimeout = setTimeout(() => {
|
||||||
|
popupModalState = null;
|
||||||
|
popupModalNullTimeout = null;
|
||||||
|
}, 200);
|
||||||
|
popupModalState?.onClose?.();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<button>close</button>
|
||||||
|
</form>
|
||||||
|
{/if}
|
||||||
|
</dialog>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@media (max-height: 450px) {
|
@media (max-height: 450px) {
|
||||||
.main-menu {
|
.main-menu {
|
||||||
|
@ -16,9 +16,12 @@
|
|||||||
import Search from '$lib/components/Input/Search.svelte';
|
import Search from '$lib/components/Input/Search.svelte';
|
||||||
import { usernameSuggestions } from '$lib/utils';
|
import { usernameSuggestions } from '$lib/utils';
|
||||||
import PaginationTableBody from '$lib/components/PaginationTable/PaginationTableBody.svelte';
|
import PaginationTableBody from '$lib/components/PaginationTable/PaginationTableBody.svelte';
|
||||||
|
import { getPopupModalShowFn } from '$lib/context';
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
|
let showPopupModal = getPopupModalShowFn();
|
||||||
|
|
||||||
let reports: (typeof Report.prototype.dataValues)[] = $state([]);
|
let reports: (typeof Report.prototype.dataValues)[] = $state([]);
|
||||||
let reportsPerRequest = 25;
|
let reportsPerRequest = 25;
|
||||||
let reportFilter = $state({ draft: false, status: null, reporter: null, reported: null });
|
let reportFilter = $state({ draft: false, status: null, reporter: null, reported: null });
|
||||||
@ -91,7 +94,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let saveActiveReportChangesModal: HTMLDialogElement;
|
|
||||||
let newReportModal: HTMLDialogElement;
|
let newReportModal: HTMLDialogElement;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -327,22 +329,13 @@
|
|||||||
<Input
|
<Input
|
||||||
type="submit"
|
type="submit"
|
||||||
value="Speichern"
|
value="Speichern"
|
||||||
onclick={() => saveActiveReportChangesModal.show()}
|
onclick={() => {
|
||||||
/>
|
showPopupModal({
|
||||||
</div>
|
title: 'Änderungen Speichern?',
|
||||||
</div>
|
actions: [
|
||||||
{/if}
|
{
|
||||||
</div>
|
text: 'Speichern',
|
||||||
|
action: async () => {
|
||||||
<dialog class="modal" bind:this={saveActiveReportChangesModal}>
|
|
||||||
<form method="dialog" class="modal-box">
|
|
||||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
||||||
<h3 class="font-roboto text-xl">Änderungen Speichern?</h3>
|
|
||||||
<div class="flex flex-row space-x-2 mt-6">
|
|
||||||
<Input
|
|
||||||
type="submit"
|
|
||||||
value="Speichern"
|
|
||||||
onclick={async () => {
|
|
||||||
await updateActiveReport();
|
await updateActiveReport();
|
||||||
if (activeReport.reported?.username) {
|
if (activeReport.reported?.username) {
|
||||||
if (activeReport.reported?.id === undefined) {
|
if (activeReport.reported?.id === undefined) {
|
||||||
@ -352,7 +345,10 @@
|
|||||||
activeReport.reported = undefined;
|
activeReport.reported = undefined;
|
||||||
}
|
}
|
||||||
reports = [...reports];
|
reports = [...reports];
|
||||||
if (activeReport.originalStatus !== 'reviewed' && activeReport.status === 'reviewed') {
|
if (
|
||||||
|
activeReport.originalStatus !== 'reviewed' &&
|
||||||
|
activeReport.status === 'reviewed'
|
||||||
|
) {
|
||||||
$reportCount -= 1;
|
$reportCount -= 1;
|
||||||
} else if (
|
} else if (
|
||||||
activeReport.originalStatus === 'reviewed' &&
|
activeReport.originalStatus === 'reviewed' &&
|
||||||
@ -360,15 +356,17 @@
|
|||||||
) {
|
) {
|
||||||
$reportCount += 1;
|
$reportCount += 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ text: 'Abbrechen' }
|
||||||
|
]
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Input type="submit" value="Abbrechen" />
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]">
|
{/if}
|
||||||
<button>close</button>
|
</div>
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
|
|
||||||
<dialog class="modal" bind:this={newReportModal}>
|
<dialog class="modal" bind:this={newReportModal}>
|
||||||
<NewReportModal
|
<NewReportModal
|
||||||
|
@ -5,9 +5,12 @@
|
|||||||
import Search from '$lib/components/Input/Search.svelte';
|
import Search from '$lib/components/Input/Search.svelte';
|
||||||
import { usernameSuggestions } from '$lib/utils';
|
import { usernameSuggestions } from '$lib/utils';
|
||||||
import type { Report } from '$lib/server/database';
|
import type { Report } from '$lib/server/database';
|
||||||
|
import { getPopupModalShowFn } from '$lib/context';
|
||||||
|
|
||||||
let { onSubmit }: { onSubmit: (data: typeof Report.prototype.dataValues) => void } = $props();
|
let { onSubmit }: { onSubmit: (data: typeof Report.prototype.dataValues) => void } = $props();
|
||||||
|
|
||||||
|
let showPopupModal = getPopupModalShowFn();
|
||||||
|
|
||||||
let reporter: string | undefined = $state();
|
let reporter: string | undefined = $state();
|
||||||
let reported: string | undefined = $state();
|
let reported: string | undefined = $state();
|
||||||
let reason = $state('');
|
let reason = $state('');
|
||||||
@ -29,7 +32,6 @@
|
|||||||
let globalCloseForm: HTMLFormElement;
|
let globalCloseForm: HTMLFormElement;
|
||||||
|
|
||||||
let reportForm: HTMLFormElement;
|
let reportForm: HTMLFormElement;
|
||||||
let confirmDialog: HTMLDialogElement;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form method="dialog" class="modal-box" bind:this={reportForm}>
|
<form method="dialog" class="modal-box" bind:this={reportForm}>
|
||||||
@ -79,7 +81,22 @@
|
|||||||
onclick={(e) => {
|
onclick={(e) => {
|
||||||
if (reportForm.checkValidity()) {
|
if (reportForm.checkValidity()) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
confirmDialog.show();
|
showPopupModal({
|
||||||
|
title: 'Report Erstellen?',
|
||||||
|
text: body
|
||||||
|
? 'Dadurch, dass bereits Details über den Report Grund hinzugefügt wurden, ist es nach dem Erstellen nicht mehr möglich, den Report Inhalt zu ändern'
|
||||||
|
: 'Der Report wird als Entwurf gespeichert und kann nach dem Erstellen über den Report-Link bearbeitet werden',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
text: 'Erstellen',
|
||||||
|
action: async () => {
|
||||||
|
await newReport();
|
||||||
|
globalCloseForm.submit();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ text: 'Abbrechen' }
|
||||||
|
]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -96,35 +113,3 @@
|
|||||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]" bind:this={globalCloseForm}>
|
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]" bind:this={globalCloseForm}>
|
||||||
<button>close</button>
|
<button>close</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<dialog class="modal" bind:this={confirmDialog}>
|
|
||||||
<form method="dialog" class="modal-box">
|
|
||||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
||||||
<h3 class="font-roboto text-xl mb-2">Report Erstellen?</h3>
|
|
||||||
{#if body}
|
|
||||||
<p>
|
|
||||||
Dadurch, dass bereits Details über den Report Grund hinzugefügt wurden, ist es nach dem
|
|
||||||
Erstellen nicht mehr möglich, den Report Inhalt zu ändern
|
|
||||||
</p>
|
|
||||||
{:else}
|
|
||||||
<p>
|
|
||||||
Der Report wird als Entwurf gespeichert und kann nach dem Erstellen über den Report-Link
|
|
||||||
bearbeitet werden
|
|
||||||
</p>
|
|
||||||
{/if}
|
|
||||||
<div class="flex flex-row space-x-2 mt-6">
|
|
||||||
<Input
|
|
||||||
type="submit"
|
|
||||||
value="Erstellen"
|
|
||||||
onclick={async () => {
|
|
||||||
await newReport();
|
|
||||||
globalCloseForm.submit();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Input type="submit" value="Abbrechen" />
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]">
|
|
||||||
<button>close</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
|
@ -64,6 +64,7 @@
|
|||||||
|
|
||||||
let userFilterEffectAlreadyRan = false;
|
let userFilterEffectAlreadyRan = false;
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
||||||
userFilter;
|
userFilter;
|
||||||
|
|
||||||
if (!userFilterEffectAlreadyRan) {
|
if (!userFilterEffectAlreadyRan) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
import Select from '$lib/components/Input/Select.svelte';
|
import Select from '$lib/components/Input/Select.svelte';
|
||||||
import { errorMessage } from '$lib/stores';
|
import { errorMessage } from '$lib/stores';
|
||||||
|
import { getPopupModalShowFn } from '$lib/context';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
onSubmit
|
onSubmit
|
||||||
@ -24,6 +25,8 @@
|
|||||||
}) => void;
|
}) => void;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
|
let showPopupModal = getPopupModalShowFn();
|
||||||
|
|
||||||
let firstname: string = $state('');
|
let firstname: string = $state('');
|
||||||
let lastname: string = $state('');
|
let lastname: string = $state('');
|
||||||
let birthday: string = $state('');
|
let birthday: string = $state('');
|
||||||
@ -61,7 +64,6 @@
|
|||||||
let globalCloseForm: HTMLFormElement;
|
let globalCloseForm: HTMLFormElement;
|
||||||
|
|
||||||
let reportForm: HTMLFormElement;
|
let reportForm: HTMLFormElement;
|
||||||
let confirmDialog: HTMLDialogElement;
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form method="dialog" class="modal-box" bind:this={reportForm}>
|
<form method="dialog" class="modal-box" bind:this={reportForm}>
|
||||||
@ -111,7 +113,10 @@
|
|||||||
onclick={(e) => {
|
onclick={(e) => {
|
||||||
if (reportForm.checkValidity()) {
|
if (reportForm.checkValidity()) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
confirmDialog.show();
|
showPopupModal({
|
||||||
|
title: 'Spieler hinzufügen?',
|
||||||
|
actions: [{ text: 'Hinzufügen', action: newUser }, { text: 'Abbrechen' }]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -128,17 +133,3 @@
|
|||||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]" bind:this={globalCloseForm}>
|
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]" bind:this={globalCloseForm}>
|
||||||
<button>close</button>
|
<button>close</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<dialog class="modal" bind:this={confirmDialog}>
|
|
||||||
<form method="dialog" class="modal-box">
|
|
||||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
||||||
<h3 class="font-roboto text-xl mb-2">Spieler hinzufügen?</h3>
|
|
||||||
<div class="flex flex-row space-x-2 mt-6">
|
|
||||||
<Input type="submit" value="Hinzufügen" onclick={newUser} />
|
|
||||||
<Input type="submit" value="Abbrechen" />
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]">
|
|
||||||
<button>close</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
import Textarea from '$lib/components/Input/Textarea.svelte';
|
import Textarea from '$lib/components/Input/Textarea.svelte';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
import Select from '$lib/components/Input/Select.svelte';
|
import Select from '$lib/components/Input/Select.svelte';
|
||||||
|
import { getPopupModalShowFn } from '$lib/context';
|
||||||
|
|
||||||
|
let showPopupModal = getPopupModalShowFn();
|
||||||
|
|
||||||
let content = $state('');
|
let content = $state('');
|
||||||
let type = $state('feedback');
|
let type = $state('feedback');
|
||||||
|
|
||||||
let submitModal: HTMLDialogElement;
|
|
||||||
let sentModal: HTMLDialogElement;
|
|
||||||
|
|
||||||
async function submitFeedback() {
|
async function submitFeedback() {
|
||||||
await fetch(`${env.PUBLIC_BASE_PATH}/feedback`, {
|
await fetch(`${env.PUBLIC_BASE_PATH}/feedback`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -30,7 +30,37 @@
|
|||||||
<form
|
<form
|
||||||
onsubmit={(e) => {
|
onsubmit={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
submitModal.show();
|
|
||||||
|
showPopupModal({
|
||||||
|
title: `${type === 'feedback' ? 'Feedback' : 'Kontaktanfrage'} abschicken?`,
|
||||||
|
text:
|
||||||
|
type === 'feedback'
|
||||||
|
? 'Nach dem Abschicken des Feedbacks lässt es sich nicht mehr bearbeiten.'
|
||||||
|
: 'Bitte hinterlege eine Rückmeldemöglichkeit in deiner Anfrage. Nachdem sie abgeschickt wurde, kannst du die Nachricht nicht mehr bearbeiten.',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
text: 'Abschicken',
|
||||||
|
action: () =>
|
||||||
|
setTimeout(async () => {
|
||||||
|
await submitFeedback();
|
||||||
|
|
||||||
|
showPopupModal({
|
||||||
|
title: `${type === 'feedback' ? 'Feedback' : 'Kontaktanfrage'} abgeschickt`,
|
||||||
|
text:
|
||||||
|
type === 'feedback'
|
||||||
|
? 'Dein Feedback wurde abgeschickt.'
|
||||||
|
: 'Deine Kontaktanfrage wurde abgeschickt. Jemand aus dem Team wird sich nächstmöglich bei Dir melden.',
|
||||||
|
actions: [{ text: 'Schließen' }],
|
||||||
|
onClose: () => {
|
||||||
|
content = '';
|
||||||
|
type = 'feedback';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 200)
|
||||||
|
},
|
||||||
|
{ text: 'Abbrechen' }
|
||||||
|
]
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="space-y-4 mt-6 mb-4">
|
<div class="space-y-4 mt-6 mb-4">
|
||||||
@ -50,77 +80,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<dialog class="modal" bind:this={submitModal}>
|
|
||||||
<form method="dialog" class="modal-box">
|
|
||||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
||||||
<div>
|
|
||||||
<h3 class="font-roboto font-medium text-xl">
|
|
||||||
{type === 'feedback' ? 'Feedback' : 'Kontaktanfrage'} abschicken?
|
|
||||||
</h3>
|
|
||||||
<div class="my-4">
|
|
||||||
{#if type === 'feedback'}
|
|
||||||
<p>Nach dem Abschicken des Feedbacks lässt es sich nicht mehr bearbeiten.</p>
|
|
||||||
{:else}
|
|
||||||
<p>
|
|
||||||
Bitte hinterlege eine Rückmeldemöglichkeit in deiner Anfrage. Nachdem sie abgeschickt
|
|
||||||
wurde, kannst du die Nachricht nicht mehr bearbeiten.
|
|
||||||
</p>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-row space-x-1">
|
|
||||||
<Input
|
|
||||||
type="submit"
|
|
||||||
value="Abschicken"
|
|
||||||
onclick={async () => {
|
|
||||||
await submitFeedback();
|
|
||||||
sentModal.show();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Input type="submit" value="Abbrechen" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]">
|
|
||||||
<button>close</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
|
|
||||||
<dialog class="modal" bind:this={sentModal}>
|
|
||||||
<form
|
|
||||||
method="dialog"
|
|
||||||
class="modal-box"
|
|
||||||
onsubmit={() => {
|
|
||||||
content = '';
|
|
||||||
type = 'feedback';
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
||||||
<div>
|
|
||||||
<h3 class="font-roboto font-medium text-xl">
|
|
||||||
{type === 'feedback' ? 'Feedback' : 'Kontaktanfrage'} abgeschickt
|
|
||||||
</h3>
|
|
||||||
<div class="my-4">
|
|
||||||
{#if type === 'feedback'}
|
|
||||||
<p>Dein Feedback wurde abgeschickt.</p>
|
|
||||||
{:else}
|
|
||||||
<p>
|
|
||||||
Deine Kontaktanfrage wurde abgeschickt. Jemand aus dem Team wird sich nächstmöglich bei
|
|
||||||
Dir melden.
|
|
||||||
</p>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<Input type="submit" value="Schließen" />
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<form
|
|
||||||
method="dialog"
|
|
||||||
class="modal-backdrop bg-[rgba(0,0,0,.3)]"
|
|
||||||
onsubmit={() => {
|
|
||||||
content = '';
|
|
||||||
type = 'feedback';
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<button>close</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
import FeedbackSent from './FeedbackSent.svelte';
|
import FeedbackSent from './FeedbackSent.svelte';
|
||||||
|
|
||||||
let { data } = $props();
|
let { data } = $props();
|
||||||
|
|
||||||
|
let draft = $state(data.draft);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@ -12,13 +14,9 @@
|
|||||||
<meta name="robots" content="noindex" />
|
<meta name="robots" content="noindex" />
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
{#if data.draft}
|
{#if draft}
|
||||||
<div class="col-[1] row-[1]" transition:fly={{ x: -200, duration: 300 }}>
|
<div class="col-[1] row-[1]" transition:fly={{ x: -200, duration: 300 }}>
|
||||||
<FeedbackDraft
|
<FeedbackDraft event={data.event} anonymous={data.anonymous} onSubmit={() => (draft = false)} />
|
||||||
event={data.event}
|
|
||||||
anonymous={data.anonymous}
|
|
||||||
on:submit={() => (data.draft = false)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="col-[1] row-[1]" transition:fly={{ x: 200, duration: 300 }}>
|
<div class="col-[1] row-[1]" transition:fly={{ x: 200, duration: 300 }}>
|
||||||
|
@ -3,14 +3,15 @@
|
|||||||
import Textarea from '$lib/components/Input/Textarea.svelte';
|
import Textarea from '$lib/components/Input/Textarea.svelte';
|
||||||
import { env } from '$env/dynamic/public';
|
import { env } from '$env/dynamic/public';
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
|
import { getPopupModalShowFn } from '$lib/context';
|
||||||
|
|
||||||
let { event, anonymous, onSubmit }: { event: string; anonymous: false; onSubmit?: () => void } =
|
let { event, anonymous, onSubmit }: { event: string; anonymous: boolean; onSubmit?: () => void } =
|
||||||
$props();
|
$props();
|
||||||
|
|
||||||
let content = $state('');
|
let showPopupModal = getPopupModalShowFn();
|
||||||
let sendAnonymous = $state(true);
|
|
||||||
|
|
||||||
let submitModal: HTMLDialogElement;
|
let content = $state('');
|
||||||
|
let sendAnonymous = $state(false);
|
||||||
|
|
||||||
async function submitFeedback() {
|
async function submitFeedback() {
|
||||||
await fetch(`${env.PUBLIC_BASE_PATH}/feedback/${$page.params.url_hash}`, {
|
await fetch(`${env.PUBLIC_BASE_PATH}/feedback/${$page.params.url_hash}`, {
|
||||||
@ -28,7 +29,21 @@
|
|||||||
<form
|
<form
|
||||||
onsubmit={(e) => {
|
onsubmit={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
submitModal.show();
|
|
||||||
|
showPopupModal({
|
||||||
|
title: 'Feedback abschicken?',
|
||||||
|
text: 'Nach dem Abschicken des Feedbacks lässt es sich nicht mehr bearbeiten.',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
text: 'Abschicken',
|
||||||
|
action: async () => {
|
||||||
|
await submitFeedback();
|
||||||
|
onSubmit?.();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ text: 'Abbrechen' }
|
||||||
|
]
|
||||||
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div class="space-y-4 my-4">
|
<div class="space-y-4 my-4">
|
||||||
@ -38,23 +53,9 @@
|
|||||||
{/snippet}
|
{/snippet}
|
||||||
</Input>
|
</Input>
|
||||||
<Textarea required={true} rows={4} label="Feedback" bind:value={content} />
|
<Textarea required={true} rows={4} label="Feedback" bind:value={content} />
|
||||||
<div>
|
|
||||||
<Input type="submit" disabled={content === ''} value="Feedback senden" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<dialog class="modal" bind:this={submitModal}>
|
|
||||||
<form method="dialog" class="modal-box">
|
|
||||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
||||||
<div>
|
|
||||||
<h3 class="font-roboto font-medium text-xl">Feedback abschicken?</h3>
|
|
||||||
<div class="my-4">
|
|
||||||
<p>Nach dem Abschicken des Feedbacks lässt es sich nicht mehr bearbeiten.</p>
|
|
||||||
{#if !anonymous}
|
{#if !anonymous}
|
||||||
<div class="flex items-center gap-2 mt-2">
|
<div class="flex items-center gap-2 mt-2">
|
||||||
<Input type="checkbox" id="anonymous" size="xs" checked />
|
<Input type="checkbox" id="anonymous" size="xs" bind:checked={sendAnonymous} />
|
||||||
<label
|
<label
|
||||||
for="anonymous"
|
for="anonymous"
|
||||||
title="Dein Spielername wird nach dem Abschicken nicht mit dem Feedback zusammen gespeichert"
|
title="Dein Spielername wird nach dem Abschicken nicht mit dem Feedback zusammen gespeichert"
|
||||||
@ -62,21 +63,9 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
<div>
|
||||||
<div class="flex flex-row space-x-1">
|
<Input type="submit" disabled={content === ''} value="Feedback senden" />
|
||||||
<Input
|
|
||||||
type="submit"
|
|
||||||
value="Abschicken"
|
|
||||||
onclick={async () => {
|
|
||||||
await submitFeedback();
|
|
||||||
onSubmit && onSubmit();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Input type="submit" value="Abbrechen" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]">
|
</div>
|
||||||
<button>close</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
import { rulesShort } from '$lib/rules';
|
import { rulesShort } from '$lib/rules';
|
||||||
import { RegisterSchema } from './schema';
|
import { RegisterSchema } from './schema';
|
||||||
import { dev } from '$app/environment';
|
import { dev } from '$app/environment';
|
||||||
|
import { getPopupModalShowFn } from '$lib/context';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
submit
|
submit
|
||||||
@ -27,6 +28,8 @@
|
|||||||
}) => void;
|
}) => void;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
|
let showPopupModal = getPopupModalShowFn();
|
||||||
|
|
||||||
const modalTimeoutSeconds = dev ? 0 : 30;
|
const modalTimeoutSeconds = dev ? 0 : 30;
|
||||||
|
|
||||||
let checkInputs = $state(() => {});
|
let checkInputs = $state(() => {});
|
||||||
@ -76,7 +79,7 @@
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!parseResult.success) {
|
if (!parseResult.success) {
|
||||||
reject(Error(parseResult.error.issues.map((i) => i.message).join('\n\n')));
|
reject(Error(parseResult.error.issues.map((i) => i.message).join('\n')));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +117,14 @@
|
|||||||
let inputsInvalidMessage: string | null = $state('Bitte fülle alle erforderlichen Felder aus');
|
let inputsInvalidMessage: string | null = $state('Bitte fülle alle erforderlichen Felder aus');
|
||||||
let registerRequest: Promise<void> | null = $state(null);
|
let registerRequest: Promise<void> | null = $state(null);
|
||||||
let errorMessage: string = $state('');
|
let errorMessage: string = $state('');
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (!errorMessage) return;
|
||||||
|
showPopupModal({
|
||||||
|
title: 'Fehler',
|
||||||
|
text: errorMessage
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1 class="text-center text-3xl lg:text-5xl">Anmeldung</h1>
|
<h1 class="text-center text-3xl lg:text-5xl">Anmeldung</h1>
|
||||||
@ -371,16 +382,3 @@
|
|||||||
<button>close</button>
|
<button>close</button>
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
{#if errorMessage}
|
|
||||||
<dialog class="modal" onclose={() => setTimeout(() => (errorMessage = ''), 200)} open>
|
|
||||||
<form method="dialog" class="modal-box z-50">
|
|
||||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
||||||
<h3 class="font-bold text-2xl">Achtung</h3>
|
|
||||||
<p class="py-4 whitespace-pre-line">{errorMessage}</p>
|
|
||||||
</form>
|
|
||||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.2)]">
|
|
||||||
<button>close</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
{/if}
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import Search from '$lib/components/Input/Search.svelte';
|
import Search from '$lib/components/Input/Search.svelte';
|
||||||
import Select from '$lib/components/Input/Select.svelte';
|
import Select from '$lib/components/Input/Select.svelte';
|
||||||
|
import { getPopupModalShowFn } from '$lib/context';
|
||||||
|
|
||||||
let {
|
let {
|
||||||
reporterName,
|
reporterName,
|
||||||
@ -20,12 +21,11 @@
|
|||||||
onsubmit: () => void;
|
onsubmit: () => void;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
|
let showPopupModal = getPopupModalShowFn();
|
||||||
|
|
||||||
let reported = $state(reportedName);
|
let reported = $state(reportedName);
|
||||||
let content = $state('');
|
let content = $state('');
|
||||||
|
|
||||||
let userErrorModal: HTMLDialogElement;
|
|
||||||
let submitModal: HTMLDialogElement;
|
|
||||||
|
|
||||||
async function submitReport() {
|
async function submitReport() {
|
||||||
await fetch(`${env.PUBLIC_BASE_PATH}/report/${$page.params.url_hash}`, {
|
await fetch(`${env.PUBLIC_BASE_PATH}/report/${$page.params.url_hash}`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
@ -56,9 +56,26 @@
|
|||||||
onsubmit={(e) => {
|
onsubmit={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (reported != null && users.findIndex((u) => u === reported) === -1) {
|
if (reported != null && users.findIndex((u) => u === reported) === -1) {
|
||||||
userErrorModal.show();
|
showPopupModal({
|
||||||
|
title: 'Fehler',
|
||||||
|
text: 'Der zu reportende Spieler existiert nicht.',
|
||||||
|
actions: [{ text: 'Schließen' }]
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
submitModal.show();
|
showPopupModal({
|
||||||
|
title: 'Report abschicken?',
|
||||||
|
text: 'Nach dem Abschicken des Reports wird sich ein Admin schnellstmöglich darum kümmern.',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
text: 'Abschicken',
|
||||||
|
action: async () => {
|
||||||
|
await submitReport();
|
||||||
|
onsubmit();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ text: 'Abbrechen' }
|
||||||
|
]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@ -100,47 +117,3 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<dialog class="modal" bind:this={userErrorModal}>
|
|
||||||
<form method="dialog" class="modal-box">
|
|
||||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
||||||
<div>
|
|
||||||
<h3 class="font-roboto font-medium text-xl">Fehler</h3>
|
|
||||||
<div class="my-4">
|
|
||||||
<p>Der zu reportende Spieler existiert nicht</p>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-row space-x-1">
|
|
||||||
<Input type="submit" value="Schließen" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]">
|
|
||||||
<button>close</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
|
|
||||||
<dialog class="modal" bind:this={submitModal}>
|
|
||||||
<form method="dialog" class="modal-box">
|
|
||||||
<button class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">✕</button>
|
|
||||||
<div>
|
|
||||||
<h3 class="font-roboto font-medium text-xl">Report abschicken?</h3>
|
|
||||||
<div class="my-4">
|
|
||||||
<p>Nach dem Abschicken des Reports wird sich ein Admin schnellstmöglich darum kümmern.</p>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-row space-x-1">
|
|
||||||
<Input
|
|
||||||
type="submit"
|
|
||||||
value="Abschicken"
|
|
||||||
onclick={async () => {
|
|
||||||
await submitReport();
|
|
||||||
onsubmit();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Input type="submit" value="Abbrechen" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]">
|
|
||||||
<button>close</button>
|
|
||||||
</form>
|
|
||||||
</dialog>
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user