feat: report page, take action on reports
This commit is contained in:
parent
a0ba712632
commit
cacd3a30b7
14 changed files with 502 additions and 14 deletions
73
Foxnouns.Frontend/src/lib/components/admin/ActionForm.svelte
Normal file
73
Foxnouns.Frontend/src/lib/components/admin/ActionForm.svelte
Normal file
|
@ -0,0 +1,73 @@
|
|||
<script lang="ts">
|
||||
import { ClearableField } from "$api/models/moderation";
|
||||
import FormStatusMarker, { type FormError } from "$components/editor/FormStatusMarker.svelte";
|
||||
import { TabContent, TabPane } from "@sveltestrap/sveltestrap";
|
||||
|
||||
let {
|
||||
userId,
|
||||
reportId,
|
||||
memberId,
|
||||
form,
|
||||
}: { userId: string; reportId?: string; memberId?: string; form: FormError } = $props();
|
||||
|
||||
let fields = $derived.by(() => {
|
||||
const fields = [];
|
||||
for (const value of Object.values(ClearableField)) {
|
||||
fields.push({ value });
|
||||
}
|
||||
return fields;
|
||||
});
|
||||
</script>
|
||||
|
||||
<form method="POST">
|
||||
<input type="hidden" name="user" value={userId} />
|
||||
{#if memberId}
|
||||
<input type="hidden" name="member" value={memberId} />
|
||||
{/if}
|
||||
{#if reportId}
|
||||
<input type="hidden" name="report" value={reportId} />
|
||||
{/if}
|
||||
<FormStatusMarker {form} />
|
||||
<textarea name="reason" class="form-control" style="height: 200px;"></textarea>
|
||||
<TabContent>
|
||||
{#if reportId}
|
||||
<TabPane tabId="ignore" tab="Ignore">
|
||||
<button type="submit" formaction="?/ignore" class="btn btn-secondary">Ignore report</button>
|
||||
</TabPane>
|
||||
{/if}
|
||||
<TabPane tabId="warn" tab="Warn" active>
|
||||
<div class="row row-cols-1 row-cols-lg-2">
|
||||
{#each fields as field}
|
||||
<div class="form-check">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
name="clear-fields"
|
||||
value={field.value}
|
||||
id="reason-{field.value}"
|
||||
/>
|
||||
<label class="form-check-label" for="reason-{field.value}">
|
||||
<code>{field.value}</code>
|
||||
</label>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
<div>
|
||||
<button type="submit" formaction="?/warn" class="btn btn-danger">Warn user</button>
|
||||
</div>
|
||||
</TabPane>
|
||||
<TabPane tabId="suspend" tab="Suspend">
|
||||
<div class="form-check">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
value="yes"
|
||||
name="clear-profile"
|
||||
id="clear-profile"
|
||||
/>
|
||||
<label class="form-check-label" for="clear-profile">Clear the user's profile?</label>
|
||||
</div>
|
||||
<button type="submit" formaction="?/suspend" class="btn btn-danger">Suspend user</button>
|
||||
</TabPane>
|
||||
</TabContent>
|
||||
</form>
|
|
@ -0,0 +1,29 @@
|
|||
<script lang="ts">
|
||||
import type { PartialUser } from "$api/models";
|
||||
import Avatar from "$components/Avatar.svelte";
|
||||
import { idTimestamp } from "$lib";
|
||||
import { t } from "$lib/i18n";
|
||||
import { DateTime } from "luxon";
|
||||
|
||||
type Props = { user: PartialUser };
|
||||
let { user }: Props = $props();
|
||||
|
||||
let createdAt = $derived(idTimestamp(user.id).toLocaleString(DateTime.DATETIME_SHORT));
|
||||
</script>
|
||||
|
||||
<div class="text-center">
|
||||
<a href="/@{user.username}">
|
||||
<Avatar
|
||||
name={user.username}
|
||||
url={user.avatar_url}
|
||||
lazyLoad
|
||||
alt={$t("avatar-tooltip", { name: "@" + user.username })}
|
||||
/>
|
||||
</a>
|
||||
<p class="m-2">
|
||||
<a class="text-reset fs-5 text-break" href="/@{user.username}">
|
||||
@{user.username}
|
||||
</a>
|
||||
</p>
|
||||
<p>Created {createdAt}</p>
|
||||
</div>
|
|
@ -1,10 +1,14 @@
|
|||
<script module lang="ts">
|
||||
export type FormError = { error: RawApiError | null; ok: boolean } | null;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { Icon } from "@sveltestrap/sveltestrap";
|
||||
import { t } from "$lib/i18n";
|
||||
import type { RawApiError } from "$api/error";
|
||||
import ErrorAlert from "$components/ErrorAlert.svelte";
|
||||
|
||||
type Props = { form: { error: RawApiError | null; ok: boolean } | null; successMessage?: string };
|
||||
type Props = { form: FormError | null; successMessage?: string };
|
||||
let { form, successMessage }: Props = $props();
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue