add option to create a report via the admin panel
All checks were successful
delpoy / build-and-deploy (push) Successful in 47s
All checks were successful
delpoy / build-and-deploy (push) Successful in 47s
This commit is contained in:
parent
61ea07d371
commit
3713c7eaba
78
src/lib/components/Input/Search.svelte
Normal file
78
src/lib/components/Input/Search.svelte
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let id: string | null = null;
|
||||||
|
export let value = '';
|
||||||
|
export let suggestionRequired = false;
|
||||||
|
export let searchSuggestionFunc: (
|
||||||
|
input: string
|
||||||
|
) => Promise<{ name: string; value: string }[]> = () => Promise.resolve([]);
|
||||||
|
export let size: 'xs' | 'sm' | 'md' | 'lg' = 'md';
|
||||||
|
export let label: string | null = null;
|
||||||
|
export let required = false;
|
||||||
|
|
||||||
|
let inputValue: string;
|
||||||
|
let searchSuggestions: { name: string; value: string }[] = [];
|
||||||
|
$: if (!suggestionRequired) value = inputValue;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="relative">
|
||||||
|
<div>
|
||||||
|
{#if label}
|
||||||
|
<label class="label" for={id}>
|
||||||
|
<span class="label-text">
|
||||||
|
{label}
|
||||||
|
{#if required}
|
||||||
|
<span class="text-red-700">*</span>
|
||||||
|
{/if}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
{/if}
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
class="input input-bordered w-full"
|
||||||
|
class:input-xs={size === 'xs'}
|
||||||
|
class:input-sm={size === 'sm'}
|
||||||
|
class:input-md={size === 'md'}
|
||||||
|
class:input-lg={size === 'md'}
|
||||||
|
{id}
|
||||||
|
{required}
|
||||||
|
bind:value={inputValue}
|
||||||
|
on:input={() => {
|
||||||
|
value = '';
|
||||||
|
searchSuggestionFunc(inputValue).then((v) => {
|
||||||
|
searchSuggestions = v;
|
||||||
|
let searchSuggestionValue = v.find((v) => v.name === inputValue);
|
||||||
|
if (searchSuggestionValue !== undefined) {
|
||||||
|
value = searchSuggestionValue.value;
|
||||||
|
searchSuggestions = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
pattern={suggestionRequired ? `${value ? inputValue : 'a^'}` : null}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if inputValue && searchSuggestions.length !== 0}
|
||||||
|
<ul class="absolute bg-base-200 w-full z-20 menu menu-sm rounded-box">
|
||||||
|
{#each searchSuggestions as searchSuggestion}
|
||||||
|
<li class="w-full text-left">
|
||||||
|
<button
|
||||||
|
class="block w-full overflow-hidden text-ellipsis whitespace-nowrap"
|
||||||
|
title="{searchSuggestion.name} ({searchSuggestion.value})"
|
||||||
|
on:click|preventDefault={() => {
|
||||||
|
inputValue = searchSuggestion.name;
|
||||||
|
value = searchSuggestion.value;
|
||||||
|
searchSuggestions = [];
|
||||||
|
}}>{searchSuggestion.name}</button
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if inputValue && searchSuggestions.length !== 0}
|
||||||
|
<button
|
||||||
|
class="absolute top-0 left-0 z-10 w-full h-full cursor-default"
|
||||||
|
on:click={() => (searchSuggestions = [])}
|
||||||
|
/>
|
||||||
|
{/if}
|
@ -8,6 +8,9 @@
|
|||||||
import Input from '$lib/components/Input/Input.svelte';
|
import Input from '$lib/components/Input/Input.svelte';
|
||||||
import Textarea from '$lib/components/Input/Textarea.svelte';
|
import Textarea from '$lib/components/Input/Textarea.svelte';
|
||||||
import { reportCount } from '$lib/stores';
|
import { reportCount } from '$lib/stores';
|
||||||
|
import HeaderBar from './HeaderBar.svelte';
|
||||||
|
import { IconOutline } from 'svelte-heros-v2';
|
||||||
|
import NewReportModal from './NewReportModal.svelte';
|
||||||
|
|
||||||
export let data: PageData;
|
export let data: PageData;
|
||||||
|
|
||||||
@ -47,29 +50,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let saveActiveReportChangesModal: HTMLDialogElement;
|
let saveActiveReportChangesModal: HTMLDialogElement;
|
||||||
|
let newReportModal: HTMLDialogElement;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="h-screen flex flex-row">
|
<div class="h-screen flex flex-row">
|
||||||
<div class="w-full flex flex-col">
|
<div class="w-full flex flex-col">
|
||||||
<form class="flex flex-row justify-center space-x-4 mx-4 my-2">
|
<HeaderBar bind:reportFilter />
|
||||||
<Input size="sm" placeholder="Alle" bind:value={reportFilter.reporter}>
|
|
||||||
<span slot="label">Report Ersteller</span>
|
|
||||||
</Input>
|
|
||||||
<Input size="sm" placeholder="Alle" bind:value={reportFilter.reported}>
|
|
||||||
<span slot="label">Reportete Spieler</span>
|
|
||||||
</Input>
|
|
||||||
<Select label="Bearbeitungsstatus" size="sm" bind:value={reportFilter.status}>
|
|
||||||
<option value="none">Unbearbeitet</option>
|
|
||||||
<option value="review">In Bearbeitung</option>
|
|
||||||
<option value={null}>Unbearbeitet & In Bearbeitung</option>
|
|
||||||
<option value="reviewed">Bearbeitet</option>
|
|
||||||
</Select>
|
|
||||||
<Select label="Reportstatus" size="sm" bind:value={reportFilter.draft}>
|
|
||||||
<option value={false}>Erstellt</option>
|
|
||||||
<option value={true}>Entwurf</option>
|
|
||||||
<option value={null}>Erstellt & Entwurf</option>
|
|
||||||
</Select>
|
|
||||||
</form>
|
|
||||||
<hr class="divider my-1 mx-8 border-none" />
|
<hr class="divider my-1 mx-8 border-none" />
|
||||||
<table class="table table-fixed h-fit">
|
<table class="table table-fixed h-fit">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
@ -124,6 +110,16 @@
|
|||||||
<td>{report.draft ? 'Entwurf' : 'Erstellt'}</td>
|
<td>{report.draft ? 'Entwurf' : 'Erstellt'}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
|
<tr>
|
||||||
|
<td colspan="100">
|
||||||
|
<div class="flex justify-center items-center">
|
||||||
|
<button class="btn btn-sm" on:click={() => newReportModal.show()}>
|
||||||
|
<IconOutline name="plus-outline" />
|
||||||
|
<span>Neuer Report</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -162,7 +158,7 @@
|
|||||||
>
|
>
|
||||||
<Textarea
|
<Textarea
|
||||||
label="Interne Notizen"
|
label="Interne Notizen"
|
||||||
readonly={activeReport.auditor === null && activeReport.notice === null}
|
readonly={activeReport.status === 'none'}
|
||||||
rows={1}
|
rows={1}
|
||||||
bind:value={activeReport.notice}
|
bind:value={activeReport.notice}
|
||||||
/>
|
/>
|
||||||
@ -175,13 +171,15 @@
|
|||||||
>
|
>
|
||||||
<Textarea
|
<Textarea
|
||||||
label="(Öffentliche) Report Antwort"
|
label="(Öffentliche) Report Antwort"
|
||||||
readonly={activeReport.auditor === null && activeReport.notice === null}
|
readonly={activeReport.status === 'none'}
|
||||||
rows={3}
|
rows={3}
|
||||||
bind:value={activeReport.statement}
|
bind:value={activeReport.statement}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Select label="Bearbeitungsstatus" size="sm" bind:value={activeReport.status}>
|
<Select label="Bearbeitungsstatus" size="sm" bind:value={activeReport.status}>
|
||||||
<option value="none" disabled={activeReport.auditor != null || activeReport.notice}
|
<option
|
||||||
|
value="none"
|
||||||
|
disabled={activeReport.auditor != null || activeReport.notice || activeReport.statement}
|
||||||
>Unbearbeitet</option
|
>Unbearbeitet</option
|
||||||
>
|
>
|
||||||
<option value="review">In Bearbeitung</option>
|
<option value="review">In Bearbeitung</option>
|
||||||
@ -227,3 +225,13 @@
|
|||||||
<button>close</button>
|
<button>close</button>
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
|
<dialog class="modal" bind:this={newReportModal}>
|
||||||
|
<NewReportModal
|
||||||
|
on:submit={(e) => {
|
||||||
|
if (!e.detail.draft) $reportCount += 1;
|
||||||
|
currentPageReports = [e.detail, ...currentPageReports];
|
||||||
|
activeReport = currentPageReports[0];
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</dialog>
|
||||||
|
@ -5,6 +5,7 @@ import { Admin, Report, User } from '$lib/server/database';
|
|||||||
import type { Attributes } from 'sequelize';
|
import type { Attributes } from 'sequelize';
|
||||||
import { Op } from 'sequelize';
|
import { Op } from 'sequelize';
|
||||||
import { env } from '$env/dynamic/private';
|
import { env } from '$env/dynamic/private';
|
||||||
|
import crypto from 'crypto';
|
||||||
|
|
||||||
export const POST = (async ({ request, cookies }) => {
|
export const POST = (async ({ request, cookies }) => {
|
||||||
if (getSession(cookies, { permissions: [Permissions.ReportRead] }) == null) {
|
if (getSession(cookies, { permissions: [Permissions.ReportRead] }) == null) {
|
||||||
@ -104,3 +105,49 @@ export const PATCH = (async ({ request, cookies }) => {
|
|||||||
|
|
||||||
return new Response();
|
return new Response();
|
||||||
}) satisfies RequestHandler;
|
}) satisfies RequestHandler;
|
||||||
|
|
||||||
|
export const PUT = (async ({ request, cookies, url }) => {
|
||||||
|
if (getSession(cookies, { permissions: [Permissions.ReportWrite] }) == null) {
|
||||||
|
return new Response(null, {
|
||||||
|
status: 401
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const data: {
|
||||||
|
reporter: string;
|
||||||
|
reported: string;
|
||||||
|
reason: string;
|
||||||
|
body: string | null;
|
||||||
|
} = await request.json();
|
||||||
|
|
||||||
|
if (
|
||||||
|
data.reporter == null ||
|
||||||
|
data.reported == null ||
|
||||||
|
data.reason == null ||
|
||||||
|
data.body === undefined
|
||||||
|
)
|
||||||
|
return new Response(null, { status: 400 });
|
||||||
|
|
||||||
|
const reporter = await User.findOne({ where: { uuid: data.reporter } });
|
||||||
|
const reported = await User.findOne({ where: { uuid: data.reported } });
|
||||||
|
|
||||||
|
if (reporter == null || reported == null) return new Response(null, { status: 400 });
|
||||||
|
|
||||||
|
const report = await Report.create({
|
||||||
|
subject: data.reason,
|
||||||
|
body: data.body,
|
||||||
|
draft: data.body === null,
|
||||||
|
status: 'none',
|
||||||
|
url_hash: crypto.randomBytes(18).toString('hex'),
|
||||||
|
completed: false,
|
||||||
|
reporter_id: reporter.id,
|
||||||
|
reported_id: reported.id
|
||||||
|
});
|
||||||
|
report.dataValues.reporter = await User.findOne({ where: { id: report.reporter_id } });
|
||||||
|
report.dataValues.reported = await User.findOne({ where: { id: report.reported_id } });
|
||||||
|
report.dataValues.auditor = null;
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(report), {
|
||||||
|
status: 201
|
||||||
|
});
|
||||||
|
}) satisfies RequestHandler;
|
||||||
|
33
src/routes/admin/reports/HeaderBar.svelte
Normal file
33
src/routes/admin/reports/HeaderBar.svelte
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Select from '$lib/components/Input/Select.svelte';
|
||||||
|
import Input from '$lib/components/Input/Input.svelte';
|
||||||
|
|
||||||
|
export let reportFilter = {
|
||||||
|
reporter: null,
|
||||||
|
reported: null,
|
||||||
|
status: null,
|
||||||
|
draft: false
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="flex flex-row justify-center items-end">
|
||||||
|
<form class="flex flex-row justify-center space-x-4 mx-4 my-2">
|
||||||
|
<Input size="sm" placeholder="Alle" bind:value={reportFilter.reporter}>
|
||||||
|
<span slot="label">Report Ersteller</span>
|
||||||
|
</Input>
|
||||||
|
<Input size="sm" placeholder="Alle" bind:value={reportFilter.reported}>
|
||||||
|
<span slot="label">Reportete Spieler</span>
|
||||||
|
</Input>
|
||||||
|
<Select label="Bearbeitungsstatus" size="sm" bind:value={reportFilter.status}>
|
||||||
|
<option value="none">Unbearbeitet</option>
|
||||||
|
<option value="review">In Bearbeitung</option>
|
||||||
|
<option value={null}>Unbearbeitet & In Bearbeitung</option>
|
||||||
|
<option value="reviewed">Bearbeitet</option>
|
||||||
|
</Select>
|
||||||
|
<Select label="Reportstatus" size="sm" bind:value={reportFilter.draft}>
|
||||||
|
<option value={false}>Erstellt</option>
|
||||||
|
<option value={true}>Entwurf</option>
|
||||||
|
<option value={null}>Erstellt & Entwurf</option>
|
||||||
|
</Select>
|
||||||
|
</form>
|
||||||
|
</div>
|
137
src/routes/admin/reports/NewReportModal.svelte
Normal file
137
src/routes/admin/reports/NewReportModal.svelte
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Input from '$lib/components/Input/Input.svelte';
|
||||||
|
import { env } from '$env/dynamic/public';
|
||||||
|
import Textarea from '$lib/components/Input/Textarea.svelte';
|
||||||
|
import Search from '$lib/components/Input/Search.svelte';
|
||||||
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
let reporter: string;
|
||||||
|
let reported: string;
|
||||||
|
let reason = '';
|
||||||
|
let body = '';
|
||||||
|
|
||||||
|
async function usernameSuggestions(username: string): Promise<{ name: string; value: string }[]> {
|
||||||
|
const response = await fetch(`${env.PUBLIC_BASE_PATH}/admin/users`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
limit: 6,
|
||||||
|
search: username,
|
||||||
|
slim: true
|
||||||
|
})
|
||||||
|
});
|
||||||
|
const json: { username: string; uuid: string }[] = await response.json();
|
||||||
|
return json.map((v) => {
|
||||||
|
return { name: v.username, value: v.uuid };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function newReport() {
|
||||||
|
const response = await fetch(`${env.PUBLIC_BASE_PATH}/admin/reports`, {
|
||||||
|
method: 'PUT',
|
||||||
|
body: JSON.stringify({
|
||||||
|
reporter: reporter,
|
||||||
|
reported: reported,
|
||||||
|
reason: reason,
|
||||||
|
body: body || null
|
||||||
|
})
|
||||||
|
});
|
||||||
|
if (response.ok) dispatch('submit', await response.json());
|
||||||
|
}
|
||||||
|
|
||||||
|
let globalCloseForm: HTMLFormElement;
|
||||||
|
|
||||||
|
let reportForm: HTMLFormElement;
|
||||||
|
let confirmDialog: HTMLDialogElement;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<form method="dialog" class="modal-box" bind:this={reportForm}>
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-circle btn-ghost absolute right-2 top-2"
|
||||||
|
on:click|preventDefault={() => globalCloseForm.submit()}>✕</button
|
||||||
|
>
|
||||||
|
<h3 class="font-roboto text-xl">Neuer Report</h3>
|
||||||
|
<div class="space-y-2 mt-2 px-1 max-h-[70vh] overflow-y-scroll">
|
||||||
|
<div>
|
||||||
|
<Search
|
||||||
|
size="sm"
|
||||||
|
suggestionRequired={true}
|
||||||
|
searchSuggestionFunc={usernameSuggestions}
|
||||||
|
label="Reporter"
|
||||||
|
required={true}
|
||||||
|
bind:value={reporter}
|
||||||
|
/>
|
||||||
|
<Search
|
||||||
|
size="sm"
|
||||||
|
suggestionRequired={true}
|
||||||
|
searchSuggestionFunc={usernameSuggestions}
|
||||||
|
label="Reporteter User"
|
||||||
|
required={true}
|
||||||
|
bind:value={reported}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="divider mx-4 pt-3" />
|
||||||
|
<Input type="text" bind:value={reason} required={true} pickyWidth={false}>
|
||||||
|
<span slot="label">Report Grund</span>
|
||||||
|
</Input>
|
||||||
|
<div>
|
||||||
|
<Textarea rows={4} label="Details über den Report Grund" bind:value={body} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex flex-row space-x-2 mt-6">
|
||||||
|
<Input
|
||||||
|
type="submit"
|
||||||
|
value="Erstellen"
|
||||||
|
on:click={(e) => {
|
||||||
|
if (reportForm.checkValidity()) {
|
||||||
|
e.detail.preventDefault();
|
||||||
|
confirmDialog.show();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type="submit"
|
||||||
|
value="Abbrechen"
|
||||||
|
on:click={(e) => {
|
||||||
|
e.detail.preventDefault();
|
||||||
|
globalCloseForm.submit();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<form method="dialog" class="modal-backdrop bg-[rgba(0,0,0,.3)]" bind:this={globalCloseForm}>
|
||||||
|
<button>close</button>
|
||||||
|
</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"
|
||||||
|
on:click={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>
|
@ -1,7 +1,8 @@
|
|||||||
import { getSession } from '$lib/server/session';
|
import { getSession } from '$lib/server/session';
|
||||||
import { Permissions } from '$lib/permissions';
|
import { Permissions } from '$lib/permissions';
|
||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import { Admin, User } from '$lib/server/database';
|
import { User } from '$lib/server/database';
|
||||||
|
import { type Attributes, Op } from 'sequelize';
|
||||||
|
|
||||||
export const POST = (async ({ request, cookies }) => {
|
export const POST = (async ({ request, cookies }) => {
|
||||||
if (getSession(cookies, { permissions: [Permissions.UserRead] }) == null) {
|
if (getSession(cookies, { permissions: [Permissions.UserRead] }) == null) {
|
||||||
@ -10,11 +11,28 @@ export const POST = (async ({ request, cookies }) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await request.json();
|
const data: {
|
||||||
const limit = data['limit'] || 100;
|
limit: number | null;
|
||||||
const from = data['from'] || 0;
|
from: number | null;
|
||||||
|
search: string | null;
|
||||||
|
slim: boolean | null;
|
||||||
|
} = await request.json();
|
||||||
|
|
||||||
const users = await User.findAll({ offset: from, limit: limit });
|
const usersFindOptions: Attributes<User> = {};
|
||||||
|
if (data.search) {
|
||||||
|
Object.assign(usersFindOptions, {
|
||||||
|
[Op.or]: {
|
||||||
|
username: { [Op.like]: `%${data.search}%` },
|
||||||
|
uuid: { [Op.like]: `%${data.search}%` }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const users = await User.findAll({
|
||||||
|
where: usersFindOptions,
|
||||||
|
attributes: data.slim ? ['username', 'uuid'] : undefined,
|
||||||
|
offset: data.from || 0,
|
||||||
|
limit: data.limit || 100
|
||||||
|
});
|
||||||
|
|
||||||
return new Response(JSON.stringify(users));
|
return new Response(JSON.stringify(users));
|
||||||
}) satisfies RequestHandler;
|
}) satisfies RequestHandler;
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
import type { RequestHandler } from '@sveltejs/kit';
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
import { Report, User } from '$lib/server/database';
|
import { Report, User } from '$lib/server/database';
|
||||||
import * as crypto from 'crypto';
|
import * as crypto from 'crypto';
|
||||||
|
import { env } from '$env/dynamic/public';
|
||||||
|
|
||||||
export const POST = (async ({ request, url }) => {
|
export const POST = (async ({ request, url }) => {
|
||||||
const data: { reporter: string; reported: string; reason: string } = await request.json();
|
const data: { reporter: string; reported: string; reason: string } = await request.json();
|
||||||
|
|
||||||
if (data.reporter == undefined || data.reported == undefined || data.reason == undefined)
|
if (data.reporter == null || data.reported == null || data.reason == null)
|
||||||
return new Response(null, { status: 400 });
|
return new Response(null, { status: 400 });
|
||||||
|
|
||||||
const reporter = await User.findOne({ where: { uuid: data.reporter } });
|
const reporter = await User.findOne({ where: { uuid: data.reporter } });
|
||||||
@ -25,7 +26,9 @@ export const POST = (async ({ request, url }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return new Response(
|
return new Response(
|
||||||
JSON.stringify({ url: `${url.toString().replace(/\/$/, '')}/${report.url_hash}` }),
|
JSON.stringify({
|
||||||
|
url: `${url.protocol}//${url.host}${env.PUBLIC_BASE_PATH || ''}/report/${report.url_hash}`
|
||||||
|
}),
|
||||||
{
|
{
|
||||||
status: 201
|
status: 201
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user