Ü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">
|
<script lang="ts">
|
||||||
import { pb } from '$lib/pb';
|
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>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>Übersicht — vereins.haus</title>
|
<title>Übersicht — vereins.haus</title>
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<h1>Willkommen, {vereinsname}</h1>
|
{#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>
|
||||||
|
|
||||||
<div class="cards">
|
{#if termine.length > 0}
|
||||||
<a href="/mitglieder" class="card">
|
<section>
|
||||||
<Icon name="users" size={40} />
|
<h2>Nächste Termine</h2>
|
||||||
<span class="card-label">Mitglieder</span>
|
<ul>
|
||||||
</a>
|
{#each termine as t (t.id)}
|
||||||
<a href="/termine" class="card">
|
<li>
|
||||||
<Icon name="calendar" size={40} />
|
<span class="termin-titel">{t.titel}</span>
|
||||||
<span class="card-label">Termine</span>
|
<span class="termin-wann">{formatTermin(t)}</span>
|
||||||
</a>
|
</li>
|
||||||
<a href="/beitraege" class="card">
|
{/each}
|
||||||
<Icon name="currency-eur" size={40} />
|
</ul>
|
||||||
<span class="card-label">Beiträge</span>
|
<a href="/termine" class="alle-link">Alle Termine →</a>
|
||||||
</a>
|
</section>
|
||||||
<a href="/nachrichten" class="card">
|
{:else}
|
||||||
<Icon name="envelope" size={40} />
|
<p class="hint">Noch keine Termine geplant.</p>
|
||||||
<span class="card-label">Nachrichten</span>
|
{/if}
|
||||||
</a>
|
{/if}
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
h1 {
|
.verein-header {
|
||||||
font-size: 1.4rem;
|
display: flex;
|
||||||
font-weight: 700;
|
align-items: center;
|
||||||
color: #1e293b;
|
gap: 1rem;
|
||||||
|
padding: 1.25rem;
|
||||||
|
background: #0f172a;
|
||||||
|
border-radius: 14px;
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cards {
|
.verein-icon {
|
||||||
display: grid;
|
width: 52px;
|
||||||
grid-template-columns: 1fr 1fr;
|
height: 52px;
|
||||||
gap: 0.75rem;
|
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;
|
background: #fff;
|
||||||
border: 1.5px solid #e2e8f0;
|
border: 1px solid #e2e8f0;
|
||||||
border-radius: 12px;
|
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;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
gap: 0.15rem;
|
||||||
gap: 0.5rem;
|
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;
|
color: #1e40af;
|
||||||
transition: border-color .15s, box-shadow .15s;
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card:hover {
|
.hint {
|
||||||
border-color: #1e40af;
|
color: #94a3b8;
|
||||||
box-shadow: 0 2px 8px rgba(30,64,175,.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-label {
|
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
font-weight: 600;
|
text-align: center;
|
||||||
color: #1e293b;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue