Release 0.6.0
This commit is contained in:
1 parent
fd47910d09
commit
b80dded55d
40 files changed
+4080
-856
No files matched your search
@@ -0,0 +1,141 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/state';
|
||||
import { formatDuration } from '#lib/format.js';
|
||||
import type { PageProps } from './$types';
|
||||
|
||||
let { data, form }: PageProps = $props();
|
||||
|
||||
function berlinDate(value: string | null) {
|
||||
if (!value) return 'Termin nicht angegeben';
|
||||
return new Intl.DateTimeFormat('de-DE', {
|
||||
timeZone: 'Europe/Berlin',
|
||||
dateStyle: 'full',
|
||||
timeStyle: 'short'
|
||||
}).format(new Date(value));
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head><title>Sendungsfreigabe | Sendewerk</title></svelte:head>
|
||||
|
||||
<main class="share-page">
|
||||
{#if data.status === 'unavailable'}
|
||||
<section class="quiet-panel share-gate">
|
||||
<p class="eyebrow">Lesefreigabe</p>
|
||||
<h1>Nicht verfügbar</h1>
|
||||
<p>Dieser Link ist ungültig, abgelaufen oder wurde widerrufen.</p>
|
||||
</section>
|
||||
{:else if data.status === 'password'}
|
||||
<section class="quiet-panel share-gate">
|
||||
<p class="eyebrow">Geschützte Lesefreigabe</p>
|
||||
<h1>Passwort erforderlich</h1>
|
||||
{#if form?.error}<div class="form-message error" role="alert">{form.error}</div>{/if}
|
||||
<form method="POST" action="?/password" class="compact-form">
|
||||
<label
|
||||
>Passwort<input
|
||||
name="password"
|
||||
type="password"
|
||||
required
|
||||
autocomplete="current-password"
|
||||
/></label
|
||||
>
|
||||
<button class="primary-button" type="submit">Sendung öffnen</button>
|
||||
</form>
|
||||
</section>
|
||||
{:else}
|
||||
<header class="share-heading">
|
||||
<p class="eyebrow">
|
||||
{data.share.isCompleted ? 'Abgeschlossene Sendung' : 'Aktuelle Sendungsplanung'} · Nur lesen
|
||||
</p>
|
||||
<h1>{data.share.title}</h1>
|
||||
<p>{berlinDate(data.share.startsAtUtc)} Uhr</p>
|
||||
</header>
|
||||
<div class="shared-rundown">
|
||||
{#each data.share.sections as section (section)}
|
||||
<section class="quiet-panel shared-section">
|
||||
<header>
|
||||
<div>
|
||||
{#if section.category}<small
|
||||
style={`--tax-color: ${section.categoryColor ?? '#67dde8'}`}
|
||||
>{section.category}</small
|
||||
>{/if}
|
||||
<h2>{section.name}</h2>
|
||||
</div>
|
||||
{#if section.explicitDurationSeconds !== null}<span
|
||||
>{formatDuration(section.explicitDurationSeconds)}</span
|
||||
>{/if}
|
||||
</header>
|
||||
{#each section.usages as usage (usage)}
|
||||
<article class="shared-usage">
|
||||
<div class="shared-usage-heading">
|
||||
<div>
|
||||
<small
|
||||
>{usage.status === 'done'
|
||||
? 'Gesendet'
|
||||
: usage.status === 'skipped'
|
||||
? 'Übersprungen'
|
||||
: 'Offen'}</small
|
||||
>
|
||||
<h3>{usage.title}</h3>
|
||||
</div>
|
||||
<span>{formatDuration(usage.actualDurationSeconds || usage.durationSeconds)}</span>
|
||||
</div>
|
||||
{#if usage.media}<img
|
||||
src={`${page.url.pathname}/media/${usage.media.id}`}
|
||||
alt={usage.media.alt_text}
|
||||
/>{/if}
|
||||
{#if 'introHtml' in usage && usage.introHtml}<div class="shared-copy">
|
||||
<strong>Einleitung</strong>
|
||||
<!-- HTML is produced exclusively by the server-side allowlist sanitizer. -->
|
||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||
<div>{@html usage.introHtml}</div>
|
||||
</div>{/if}
|
||||
{#if 'moderationHtml' in usage && usage.moderationHtml}<div class="shared-copy">
|
||||
<strong>Moderation</strong>
|
||||
<!-- HTML is produced exclusively by the server-side allowlist sanitizer. -->
|
||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||
<div>{@html usage.moderationHtml}</div>
|
||||
</div>{/if}
|
||||
{#if 'interactionHtml' in usage && usage.interactionHtml}<div class="shared-copy">
|
||||
<strong>Interaktion</strong>
|
||||
<!-- HTML is produced exclusively by the server-side allowlist sanitizer. -->
|
||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||
<div>{@html usage.interactionHtml}</div>
|
||||
</div>{/if}
|
||||
{#if 'transitionHtml' in usage && usage.transitionHtml}<div class="shared-copy">
|
||||
<strong>Überleitung</strong>
|
||||
<!-- HTML is produced exclusively by the server-side allowlist sanitizer. -->
|
||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||
<div>{@html usage.transitionHtml}</div>
|
||||
</div>{/if}
|
||||
{#if 'researchHtml' in usage && usage.researchHtml}<details>
|
||||
<summary>Recherche</summary>
|
||||
<!-- HTML is produced exclusively by the server-side allowlist sanitizer. -->
|
||||
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
||||
<div class="shared-copy">{@html usage.researchHtml}</div>
|
||||
</details>{/if}
|
||||
{#if 'sources' in usage && usage.sources?.length}<details>
|
||||
<summary>Quellen</summary>
|
||||
<ul>
|
||||
{#each usage.sources ?? [] as source (source)}<li>
|
||||
<!-- External source URLs are validated and stored server-side. -->
|
||||
<!-- eslint-disable-next-line svelte/no-navigation-without-resolve -->
|
||||
<a href={source.url} rel="noreferrer">{source.label || source.url}</a>
|
||||
</li>{/each}
|
||||
</ul>
|
||||
</details>{/if}
|
||||
{#if 'tools' in usage && usage.tools?.length}<details>
|
||||
<summary>Werkzeuge</summary>
|
||||
<ul>
|
||||
{#each usage.tools ?? [] as tool (tool)}<li>
|
||||
<strong>{tool.name}</strong>{#if tool.note}
|
||||
· {tool.note}{/if}
|
||||
</li>{/each}
|
||||
</ul>
|
||||
</details>{/if}
|
||||
</article>
|
||||
{/each}
|
||||
</section>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
Reference in new issue
Block a user