Release 0.2.0

This commit is contained in:
hnzio committed 2026-10-21 17:25:28 +02:00
1 parent 7a49e66c37
commit 08e8875cb5
38 files changed
+2645 -93

No files matched your search

+103 -4
View File
@@ -1,6 +1,6 @@
<script lang="ts">
import type { PageData } from './$types';
let { data }: { data: PageData } = $props();
import type { PageProps } from './$types';
let { data, form }: PageProps = $props();
</script>
<svelte:head><title>Verwaltung | Sendewerk</title></svelte:head>
@@ -8,8 +8,108 @@
<div class="page-wrap narrow-page">
<header class="page-heading">
<h1>Verwaltung</h1>
<p class="page-intro">Abschnittskategorien, Formate und Themen im Überblick.</p>
<p class="page-intro">Konten, Rollen und bestehende Taxonomie verwalten.</p>
</header>
{#if form?.error}<div class="form-message error" role="alert">{form.error}</div>{/if}
{#if form?.success}<div class="form-message success" role="status">{form.success}</div>{/if}
<section class="quiet-panel account-panel">
<div class="panel-heading">
<div>
<p class="eyebrow">Konten & Rollen</p>
<h2>Redaktionszugänge</h2>
</div>
<span class="mail-mode"
>Mail: {data.mailTransport === 'local' ? 'lokale Outbox' : 'SMTP'}</span
>
</div>
<div class="account-list">
{#each data.users as user (user.id)}
<article class="account-row">
<div><strong>{user.displayName}</strong><small>{user.email}</small></div>
<span class:locked={user.lockedAtUtc} class="account-status"
>{user.lockedAtUtc ? 'Gesperrt' : 'Aktiv'}</span
>
<form method="POST" action="?/role" class="inline-account-form">
<input type="hidden" name="userId" value={user.id} />
<label class="sr-only" for={`role-${user.id}`}>Rolle für {user.displayName}</label>
<select id={`role-${user.id}`} name="role">
<option value="barkeeper" selected={user.role === 'barkeeper'}>Barkeeper</option>
<option value="thekencrew" selected={user.role === 'thekencrew'}>Thekencrew</option>
</select>
<button class="text-button" type="submit">Rolle speichern</button>
</form>
<form method="POST" action={user.lockedAtUtc ? '?/unlock' : '?/lock'}>
<input type="hidden" name="userId" value={user.id} />
<button
class="secondary-button"
type="submit"
disabled={user.id === data.user?.id}
title={user.id === data.user?.id
? 'Das eigene Konto kann nicht gesperrt werden.'
: undefined}
>{user.lockedAtUtc
? 'Entsperren'
: user.id === data.user?.id
? 'Eigenes Konto'
: 'Sperren'}</button
>
</form>
</article>
{/each}
</div>
</section>
<div class="management-grid">
<section class="quiet-panel invite-panel">
<p class="eyebrow">Einladung</p>
<h2>Neues Konto einladen</h2>
<form class="compact-form" method="POST" action="?/invite">
<label
>E-Mail<input
name="email"
type="email"
required
maxlength="254"
value={form?.intent === 'invite' ? (form.email ?? '') : ''}
/></label
>
<label
>Rolle<select name="role"
><option value="thekencrew">Thekencrew</option><option value="barkeeper"
>Barkeeper</option
></select
></label
>
<button class="primary-button" type="submit">Einladung erstellen</button>
</form>
</section>
<section class="quiet-panel invite-panel">
<p class="eyebrow">Offene Einladungen</p>
<h2>Noch nicht angenommen</h2>
{#if data.invitations.length}
<div class="invitation-list">
{#each data.invitations as invitation (invitation.id)}
<div>
<span
><strong>{invitation.email}</strong><small
>{invitation.role === 'barkeeper' ? 'Barkeeper' : 'Thekencrew'}</small
></span
>
<form method="POST" action="?/revokeInvitation">
<input type="hidden" name="invitationId" value={invitation.id} /><button
class="text-button"
type="submit">Widerrufen</button
>
</form>
</div>
{/each}
</div>
{:else}<p class="quiet-copy">Keine offenen Einladungen.</p>{/if}
</section>
</div>
<h2 class="section-heading">Taxonomie</h2>
<div class="settings-grid">
<section class="quiet-panel taxonomy-panel">
<p class="eyebrow">Abschnittskategorien</p>
@@ -35,5 +135,4 @@
</div>
</section>
</div>
<p class="settings-footnote">Konten und Rollen sind noch nicht verfügbar.</p>
</div>