feat: backend for warnings, partial frontend for reports

This commit is contained in:
Sam 2023-03-23 14:54:43 +01:00
parent 29274287a2
commit a0bc39bcba
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
12 changed files with 479 additions and 79 deletions

View file

@ -1,9 +1,42 @@
<script lang="ts">
import { DateTime } from "luxon";
import { Button, Card, CardBody, CardFooter, CardHeader } from "sveltestrap";
import type { APIError } from "$lib/api/entities";
import { apiFetchClient } from "$lib/api/fetch";
import ErrorAlert from "$lib/components/ErrorAlert.svelte";
import { addToast } from "$lib/toast";
import { Button, FormGroup, Modal, ModalBody, ModalFooter } from "sveltestrap";
import type { PageData } from "./$types";
import ReportCard from "./ReportCard.svelte";
export let data: PageData;
let warnModalOpen = false;
const toggleWarnModal = () => (warnModalOpen = !warnModalOpen);
let reportIndex = -1;
let reason = "";
let deleteUser = false;
let error: APIError | null = null;
const openWarnModalFor = (index: number) => {
reportIndex = index;
toggleWarnModal();
};
const warnUser = async () => {
try {
await apiFetchClient<any>(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", {
warn: true,
reason: reason,
});
error = null;
addToast({ body: "Successfully warned user", header: "Warned user" });
toggleWarnModal();
reportIndex = -1;
} catch (e) {
error = e as APIError;
}
};
</script>
<svelte:head>
@ -14,27 +47,31 @@
<h1>Reports</h1>
<div>
{#each data.reports as report}
<Card>
<CardHeader>
<strong>#{report.id}</strong> on <a href="/@{report.user_name}">@{report.user_name}</a>
({report.user_id}) {#if report.member_id}
(member: <a href="/@{report.user_name}/{report.member_name}">{report.member_name}</a>,
{report.member_id})
{/if}
</CardHeader>
<CardBody>
<blockquote class="blockquote">{report.reason}</blockquote>
</CardBody>
<CardFooter>
Created {DateTime.fromISO(report.created_at)
.toLocal()
.toLocaleString(DateTime.DATETIME_MED)} &bull;
<Button outline color="warning" size="sm">Warn user</Button>
<Button outline color="danger" size="sm">Deactivate user</Button>
<Button outline color="secondary" size="sm">Ignore report</Button>
</CardFooter>
</Card>
{#each data.reports as report, index}
<ReportCard {report}>
&bull;
<Button outline color="warning" size="sm" on:click={() => openWarnModalFor(index)}
>Warn user</Button
>
<Button outline color="danger" size="sm">Deactivate user</Button>
<Button outline color="secondary" size="sm">Ignore report</Button>
</ReportCard>
{/each}
</div>
<Modal header="Warn user" isOpen={warnModalOpen} toggle={toggleWarnModal}>
<ModalBody>
{#if error}
<ErrorAlert {error} />
{/if}
<ReportCard report={data.reports[reportIndex]} />
<FormGroup floating label="Reason" class="mt-2">
<textarea style="min-height: 100px;" class="form-control" bind:value={reason} />
</FormGroup>
</ModalBody>
<ModalFooter>
<Button color="danger" on:click={warnUser} disabled={!reason}>Warn user</Button>
<Button color="secondary" on:click={toggleWarnModal}>Cancel</Button>
</ModalFooter>
</Modal>
</div>

View file

@ -0,0 +1,24 @@
<script lang="ts">
import type { Report } from "$lib/api/entities";
import { DateTime } from "luxon";
import { Button, Card, CardBody, CardFooter, CardHeader } from "sveltestrap";
export let report: Report;
</script>
<Card>
<CardHeader>
<strong>#{report.id}</strong> on <a href="/@{report.user_name}">@{report.user_name}</a>
({report.user_id}) {#if report.member_id}
(member: <a href="/@{report.user_name}/{report.member_name}">{report.member_name}</a>,
{report.member_id})
{/if}
</CardHeader>
<CardBody>
<blockquote class="blockquote">{report.reason}</blockquote>
</CardBody>
<CardFooter>
Created {DateTime.fromISO(report.created_at).toLocal().toLocaleString(DateTime.DATETIME_MED)}
<slot />
</CardFooter>
</Card>