rewrite website
This commit is contained in:
23
src/pages/report/[urlHash].astro
Normal file
23
src/pages/report/[urlHash].astro
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
import WebsiteLayout from '@layouts/website/WebsiteLayout.astro';
|
||||
import { db } from '@db/database.ts';
|
||||
import Draft from './_draft.astro';
|
||||
import Submitted from './_submitted.astro';
|
||||
import Popup from '@components/popup/Popup.svelte';
|
||||
import ConfirmPopup from '@components/popup/ConfirmPopup.svelte';
|
||||
|
||||
const { urlHash } = Astro.params;
|
||||
|
||||
const report = urlHash ? await db.getReportByUrlHash({ urlHash: urlHash }) : null;
|
||||
|
||||
if (!report) {
|
||||
return new Response(null, { status: 404 });
|
||||
}
|
||||
---
|
||||
|
||||
<WebsiteLayout title="Report">
|
||||
{report.createdAt === null ? <Draft report={report} /> : <Submitted report={report} />}
|
||||
</WebsiteLayout>
|
||||
|
||||
<Popup client:idle />
|
||||
<ConfirmPopup client:idle />
|
||||
106
src/pages/report/_draft.astro
Normal file
106
src/pages/report/_draft.astro
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
import type { db } from '@db/database.ts';
|
||||
import AdversarySearch from '@app/website/report/AdversarySearch.svelte';
|
||||
import Dropzone from '@app/website/report/Dropzone.svelte';
|
||||
import Input from '@components/input/Input.svelte';
|
||||
import Textarea from '@components/input/Textarea.svelte';
|
||||
import { MAX_UPLOAD_BYTES } from 'astro:env/server';
|
||||
|
||||
interface Props {
|
||||
report: Awaited<ReturnType<db.getReportByUrlHash>>;
|
||||
}
|
||||
|
||||
const { report } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="flex justify-center items-center">
|
||||
<div class="mt-12 grid card w-11/12 xl:w-2/3 2xl:w-1/2 p-6 shadow-lg">
|
||||
<h2 class="text-3xl text-center">
|
||||
Report von <span class="underline">{report.reporter.username}</span> gegen <span
|
||||
id="adversary-username"
|
||||
class="underline">{report.reported?.username ?? 'unbekannt'}</span
|
||||
>
|
||||
</h2>
|
||||
<form id="report" data-url-hash={report.urlHash} data-adversary-username={report.reported?.username}>
|
||||
<div class="space-y-4 my-4">
|
||||
<div class="flex flex-col gap-4">
|
||||
<AdversarySearch client:load />
|
||||
<Input id="reason" value={report.reason} label="Report Grund" dynamicWidth required />
|
||||
<Textarea id="body" value={report.body} label="Details" rows={10} dynamicWidth required />
|
||||
<Dropzone maxFilesBytes={MAX_UPLOAD_BYTES} client:load />
|
||||
</div>
|
||||
<button id="send" class="btn" disabled={report.body}>Report senden</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
import { actions } from 'astro:actions';
|
||||
import { actionErrorPopup } from '@util/action';
|
||||
import { popupState } from '@components/popup/Popup';
|
||||
|
||||
document.addEventListener('astro:page-load', () => {
|
||||
const eventCancelController = new AbortController();
|
||||
document.addEventListener('astro:after-swap', () => eventCancelController.abort());
|
||||
|
||||
const adversary = document.getElementById('adversary-username') as HTMLSpanElement;
|
||||
const form = document.getElementById('report') as HTMLFormElement;
|
||||
const reason = document.getElementById('reason') as HTMLInputElement;
|
||||
const body = document.getElementById('body') as HTMLTextAreaElement;
|
||||
const sendButton = document.getElementById('send') as HTMLButtonElement;
|
||||
|
||||
let adversaryUsername = form.dataset.adversaryUsername ?? null;
|
||||
let attachments: File[] = [];
|
||||
|
||||
body.addEventListener('change', () => {
|
||||
sendButton.disabled = !body.value;
|
||||
});
|
||||
|
||||
document.addEventListener(
|
||||
'adversaryInput',
|
||||
(e: any & { detail: { adversaryUsername: string | null } }) => {
|
||||
adversaryUsername = e.detail.adversaryUsername;
|
||||
adversary.textContent = e.detail.adversaryUsername ?? 'unbekannt';
|
||||
},
|
||||
{ signal: eventCancelController.signal }
|
||||
);
|
||||
document.addEventListener(
|
||||
'dropzoneInput',
|
||||
(e: any & { detail: { files: File[] } }) => {
|
||||
attachments = e.detail.files;
|
||||
},
|
||||
{ signal: eventCancelController.signal }
|
||||
);
|
||||
|
||||
form.addEventListener(
|
||||
'submit',
|
||||
async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData();
|
||||
formData.set('urlHash', form.dataset.urlHash!);
|
||||
if (adversaryUsername != null) formData.set('reported', adversaryUsername);
|
||||
formData.set('reason', reason.value);
|
||||
formData.set('body', body.value);
|
||||
for (const attachment of attachments) {
|
||||
formData.append('files', attachment);
|
||||
}
|
||||
|
||||
const { error } = await actions.report.submitReport(formData);
|
||||
if (error) {
|
||||
actionErrorPopup(error);
|
||||
return;
|
||||
}
|
||||
|
||||
popupState.set({
|
||||
type: 'info',
|
||||
title: 'Report abgeschickt',
|
||||
message: 'Der Report wurde abgeschickt. Ein Admin wird sich schnellstmöglich darum kümmern.',
|
||||
onClose: () => location.reload()
|
||||
});
|
||||
},
|
||||
{ signal: eventCancelController.signal }
|
||||
);
|
||||
});
|
||||
</script>
|
||||
33
src/pages/report/_submitted.astro
Normal file
33
src/pages/report/_submitted.astro
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
import type { db } from '@db/database.ts';
|
||||
import Textarea from '@components/input/Textarea.svelte';
|
||||
|
||||
interface Props {
|
||||
report: Awaited<ReturnType<db.getReportByUrlHash>>;
|
||||
}
|
||||
|
||||
const { report } = Astro.props;
|
||||
---
|
||||
|
||||
<div class="flex justify-center items-center">
|
||||
<div class="mt-12 grid card w-11/12 xl:w-2/3 2xl:w-1/2 p-6 shadow-lg">
|
||||
{
|
||||
report.status?.status == null ? (
|
||||
<p>Dein Report wird in kürze bearbeitet</p>
|
||||
) : report.status?.status === 'open' ? (
|
||||
<p>Dein Report befindet sich in Bearbeitung</p>
|
||||
) : (
|
||||
<>
|
||||
<p>Dein Report wurde bearbeitet</p>
|
||||
<Textarea
|
||||
value={report.status?.statement}
|
||||
label="Antwort vom Admin Team (optional)"
|
||||
rows={5}
|
||||
dynamicWidth
|
||||
readonly
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user