Übersicht: Vereins-Header mit Logo + nächste Termine statt redundanter Nav-Chips
This commit is contained in:
parent
f2906f5c60
commit
472979a91c
1 changed files with 117 additions and 43 deletions
|
|
@ -1,70 +1,144 @@
|
|||
<script lang="ts">
|
||||
import { pb } from '$lib/pb';
|
||||
import Icon from '$lib/components/Icon.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import type { Verein, Termin } from '$lib/types';
|
||||
|
||||
const vereinsname = pb.authStore.record?.name ?? 'Dein Verein';
|
||||
let verein = $state<Verein | null>(null);
|
||||
let termine = $state<Termin[]>([]);
|
||||
let loading = $state(true);
|
||||
|
||||
onMount(async () => {
|
||||
const vid = pb.authStore.record?.verein_id as string;
|
||||
const now = new Date().toISOString();
|
||||
[verein, termine] = await Promise.all([
|
||||
pb.collection('vereine').getOne<Verein>(vid),
|
||||
pb.collection('termine').getList<Termin>(1, 3, {
|
||||
filter: `beginn >= "${now}"`,
|
||||
sort: 'beginn',
|
||||
}).then(r => r.items),
|
||||
]);
|
||||
loading = false;
|
||||
});
|
||||
|
||||
function formatTermin(t: Termin): string {
|
||||
const d = new Date(t.beginn);
|
||||
return d.toLocaleDateString('de-DE', { weekday: 'short', day: '2-digit', month: 'long' })
|
||||
+ ' · ' + d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }) + ' Uhr'
|
||||
+ (t.ort ? ' · ' + t.ort : '');
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Übersicht — vereins.haus</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>Willkommen, {vereinsname}</h1>
|
||||
|
||||
<div class="cards">
|
||||
<a href="/mitglieder" class="card">
|
||||
<Icon name="users" size={40} />
|
||||
<span class="card-label">Mitglieder</span>
|
||||
</a>
|
||||
<a href="/termine" class="card">
|
||||
<Icon name="calendar" size={40} />
|
||||
<span class="card-label">Termine</span>
|
||||
</a>
|
||||
<a href="/beitraege" class="card">
|
||||
<Icon name="currency-eur" size={40} />
|
||||
<span class="card-label">Beiträge</span>
|
||||
</a>
|
||||
<a href="/nachrichten" class="card">
|
||||
<Icon name="envelope" size={40} />
|
||||
<span class="card-label">Nachrichten</span>
|
||||
</a>
|
||||
{#if !loading && verein}
|
||||
<div class="verein-header">
|
||||
<img src="/favicon.svg" alt="" class="verein-icon" />
|
||||
<div>
|
||||
<h1>{verein.name}</h1>
|
||||
{#if verein.ort}
|
||||
<span class="verein-ort">{verein.ort}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if termine.length > 0}
|
||||
<section>
|
||||
<h2>Nächste Termine</h2>
|
||||
<ul>
|
||||
{#each termine as t (t.id)}
|
||||
<li>
|
||||
<span class="termin-titel">{t.titel}</span>
|
||||
<span class="termin-wann">{formatTermin(t)}</span>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
<a href="/termine" class="alle-link">Alle Termine →</a>
|
||||
</section>
|
||||
{:else}
|
||||
<p class="hint">Noch keine Termine geplant.</p>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
font-size: 1.4rem;
|
||||
font-weight: 700;
|
||||
color: #1e293b;
|
||||
.verein-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding: 1.25rem;
|
||||
background: #0f172a;
|
||||
border-radius: 14px;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.75rem;
|
||||
.verein-icon {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
border-radius: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.card {
|
||||
h1 {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.verein-ort {
|
||||
font-size: 0.82rem;
|
||||
color: #94a3b8;
|
||||
}
|
||||
|
||||
section {
|
||||
background: #fff;
|
||||
border: 1.5px solid #e2e8f0;
|
||||
border: 1px solid #e2e8f0;
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem 1rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
color: #94a3b8;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
padding: 0.85rem 1rem 0.5rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
gap: 0.15rem;
|
||||
padding: 0.7rem 1rem;
|
||||
border-top: 1px solid #f1f5f9;
|
||||
}
|
||||
|
||||
.termin-titel { font-size: 0.92rem; font-weight: 600; color: #1e293b; }
|
||||
.termin-wann { font-size: 0.78rem; color: #64748b; }
|
||||
|
||||
.alle-link {
|
||||
display: block;
|
||||
padding: 0.7rem 1rem;
|
||||
border-top: 1px solid #f1f5f9;
|
||||
font-size: 0.85rem;
|
||||
color: #1e40af;
|
||||
transition: border-color .15s, box-shadow .15s;
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
border-color: #1e40af;
|
||||
box-shadow: 0 2px 8px rgba(30,64,175,.1);
|
||||
}
|
||||
|
||||
.card-label {
|
||||
.hint {
|
||||
color: #94a3b8;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
text-align: center;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue