Files
agiledancers/agiledancers-fe/src/app/schools/school-page.html

425 lines
15 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<a routerLink="/schools" class="back-link">← Alle dansscholen</a>
@if (loading()) {
<div class="loading-state" role="status"><span class="spinner"></span> Dansschool laden…</div>
} @else if (!data()) {
<div class="empty-state">
<h1>Dansschool niet beschikbaar</h1>
<p role="alert">{{ error() }}</p>
<button type="button" class="button secondary" (click)="retry()">Opnieuw proberen</button>
</div>
} @else if (data(); as context) {
<div class="page-heading school-heading">
<div class="school-title">
<span aria-hidden="true" class="avatar large">{{
context.school.name.charAt(0).toUpperCase()
}}</span>
<div>
<p class="eyebrow">MIJN DANSSCHOOL</p>
<h1>{{ context.school.name }}</h1>
<p class="lede">Jouw dansers. Jouw ritme. Jouw podium.</p>
</div>
</div>
<button
type="button"
class="button secondary"
(click)="editor.set({ kind: 'school', value: context.school })"
>
School bewerken
</button>
</div>
<app-school-transfer [schoolId]="context.school.id" (imported)="reload()" />
<nav class="tabs" aria-label="Dansschool onderdelen">
@for (tab of tabs; track tab.value) {
<a
[routerLink]="['/schools', context.school.id, tab.value]"
routerLinkActive="active"
ariaCurrentWhenActive="page"
>{{ tab.label }}
@switch (tab.value) {
@case ('dancers') {
<span>{{ context.dancers.length }}</span>
}
@case ('groups') {
<span>{{ context.groups.length }}</span>
}
@case ('shows') {
<span>{{ context.shows.length }}</span>
}
}
</a>
}
</nav>
@if (notice()) {
<div class="alert success" role="status">
{{ notice()
}}<button type="button" aria-label="Melding sluiten" (click)="notice.set('')">×</button>
</div>
}
@if (error()) {
<div class="alert error" role="alert">
{{ error()
}}<button type="button" class="button secondary" (click)="reload()">Vernieuwen</button>
</div>
}
@switch (section()) {
@case ('overview') {
<div class="stats-grid">
<a class="stat" [routerLink]="['/schools', context.school.id, 'dancers']"
><span class="stat-label">Dansers <span aria-hidden="true">↗</span></span
><strong>{{ context.dancers.length }}</strong
><span class="stat-caption">Alle talenten bij elkaar</span></a
>
<a class="stat" [routerLink]="['/schools', context.school.id, 'groups']"
><span class="stat-label">Dansgroepen <span aria-hidden="true">↗</span></span
><strong>{{ context.groups.length }}</strong
><span class="stat-caption">Samen de vloer op</span></a
>
<a class="stat" [routerLink]="['/schools', context.school.id, 'shows']"
><span class="stat-label">Shows <span aria-hidden="true">↗</span></span
><strong>{{ context.shows.length }}</strong
><span class="stat-caption">Momenten om naar uit te kijken</span></a
>
</div>
<div class="overview-grid">
<section class="panel">
<p class="eyebrow">DE VOLGENDE STAP</p>
<h2>Breng je school in beweging</h2>
<p class="muted">Een goede show begint in de studio. Zorg dat iedereen een plek heeft.</p>
<div class="quick-actions">
<button type="button" (click)="editor.set({ kind: 'dancer' })">
<span class="step-number">01</span
><span
><strong>Voeg een danser toe</strong
><small>Maak ruimte voor nieuw talent</small></span
><span aria-hidden="true">+</span>
</button>
<button type="button" (click)="editor.set({ kind: 'group' })">
<span class="step-number">02</span
><span
><strong>Stel een dansgroep samen</strong
><small>Verbind dansers met dezelfde passie</small></span
><span aria-hidden="true">+</span>
</button>
<button type="button" (click)="editor.set({ kind: 'show' })">
<span class="step-number">03</span
><span
><strong>Plan een show</strong
><small>Zet het volgende podium op de kalender</small></span
><span aria-hidden="true">+</span>
</button>
</div>
</section>
<section class="show-spotlight">
<div class="spotlight-decoration" aria-hidden="true">✳</div>
<p class="eyebrow">IN DE SPOTLIGHT</p>
@if (upcoming(); as show) {
<h2>{{ show.name }}</h2>
<p class="spotlight-date">{{ show.date | date: 'd MMMM yyyy' }}</p>
<p>Drie dagdelen. Eén gedeelde passie.</p>
<a class="button light" [routerLink]="['/schools', context.school.id, 'shows']"
>Shows bekijken <span aria-hidden="true">→</span></a
>
} @else {
<h2>Klaar voor<br />het grote podium?</h2>
<p>Maak een show aan en geef je dansers iets om naartoe te werken.</p>
<button type="button" class="button light" (click)="editor.set({ kind: 'show' })">
Eerste show plannen <span aria-hidden="true">→</span>
</button>
}
</section>
</div>
<section class="danger-zone">
<div>
<h3>Dansschool verwijderen</h3>
<p>Verwijdert ook alle dansers, groepen en shows van deze school.</p>
</div>
<button
class="button danger-outline"
type="button"
(click)="
askDelete({
kind: 'school',
id: context.school.id,
name: context.school.name,
explanation:
'Alle dansers, dansgroepen en shows van deze school worden ook definitief verwijderd.',
})
"
>
School verwijderen
</button>
</section>
}
@case ('dancers') {
<div class="section-heading">
<div>
<h2>Dansers</h2>
<p class="muted">De mensen die jouw school in beweging brengen.</p>
</div>
<button type="button" class="button primary" (click)="editor.set({ kind: 'dancer' })">
+ Danser toevoegen
</button>
</div>
@if (context.dancers.length) {
<label class="search-field"
><span aria-hidden="true">⌕</span
><input
type="search"
aria-label="Zoek een danser"
placeholder="Zoek op naam…"
[value]="search()"
(input)="search.set($any($event.target).value)"
/></label>
}
<div class="table-container">
<table>
<caption class="sr-only">
Dansers in
{{
context.school.name
}}
</caption>
<thead>
<tr>
<th>Danser</th>
<th>Geboortedatum</th>
<th>Dansgroepen</th>
<th><span class="sr-only">Acties</span></th>
</tr>
</thead>
<tbody>
@for (dancer of dancers(); track dancer.id) {
<tr>
<td>
<div class="person">
<span aria-hidden="true" class="avatar small">{{
dancer.name.charAt(0).toUpperCase()
}}</span
><strong>{{ dancer.name }}</strong>
</div>
</td>
<td class="nowrap">{{ dancer.birthDate | date: 'd MMM yyyy' }}</td>
<td class="muted">{{ groupNames(dancer.id) }}</td>
<td>
<div class="row-actions">
<button
class="text-button"
type="button"
[attr.aria-label]="dancer.name + ' bewerken'"
(click)="editor.set({ kind: 'dancer', value: dancer })"
>
Bewerken</button
><button
class="text-button destructive"
type="button"
[attr.aria-label]="dancer.name + ' verwijderen'"
(click)="
askDelete({
kind: 'dancer',
id: dancer.id,
name: dancer.name,
explanation:
'De danser wordt ook uit alle dansgroepen van deze school verwijderd.',
})
"
>
Verwijderen
</button>
</div>
</td>
</tr>
} @empty {
<tr>
<td colspan="4">
<div class="empty-state">
<h3>{{ search() ? 'Geen dansers gevonden' : 'De dansvloer is nog leeg' }}</h3>
<p>
{{
search()
? 'Probeer een andere naam.'
: 'Voeg je eerste danser toe. Daarna kun je die aan één of meerdere groepen koppelen.'
}}
</p>
@if (!search()) {
<button
class="button primary"
type="button"
(click)="editor.set({ kind: 'dancer' })"
>
Danser toevoegen
</button>
}
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
}
@case ('groups') {
<div class="section-heading">
<div>
<h2>Dansgroepen</h2>
<p class="muted">Iedere groep een eigen stijl. Iedere danser een plek.</p>
</div>
<button class="button primary" type="button" (click)="editor.set({ kind: 'group' })">
+ Dansgroep toevoegen
</button>
</div>
<div class="school-grid">
@for (group of context.groups; track group.id) {
<article class="group-card">
<div class="card-top">
<span class="group-symbol" aria-hidden="true">↗</span
><span class="tag">{{ groupType(group.type) }}</span>
</div>
<h3>{{ group.category }}</h3>
<p class="muted">
{{ group.startAge }}–{{ group.endAge }} jaar · {{ group.dancerIds.length }} dansers
</p>
<div class="tag-list">
@for (style of group.styles; track style) {
<span class="style-tag">{{ groupStyle(style) }}</span>
} @empty {
<span class="muted">Nog geen dansstijlen</span>
}
</div>
<button
class="button secondary full-width"
type="button"
[attr.aria-label]="'Dansers beheren voor ' + group.category"
(click)="members.set(group)"
>
Dansers beheren <span aria-hidden="true">→</span>
</button>
<div class="card-bottom">
<button
class="text-button"
type="button"
[attr.aria-label]="group.category + ' bewerken'"
(click)="editor.set({ kind: 'group', value: group })"
>
Bewerken</button
><button
class="text-button destructive"
type="button"
[attr.aria-label]="group.category + ' verwijderen'"
(click)="
askDelete({
kind: 'group',
id: group.id,
name: group.category,
explanation:
'De groep wordt verwijderd. De dansers blijven beschikbaar in de school.',
})
"
>
Verwijderen
</button>
</div>
</article>
} @empty {
<div class="empty-state full-width">
<span class="empty-symbol" aria-hidden="true">↗</span>
<h2>Samen vind je het ritme</h2>
<p>Maak een dansgroep aan en koppel er dansers aan.</p>
<button class="button primary" type="button" (click)="editor.set({ kind: 'group' })">
Eerste dansgroep aanmaken
</button>
</div>
}
</div>
}
@case ('shows') {
<div class="section-heading">
<div>
<h2>Shows</h2>
<p class="muted">Van maanden oefenen naar een onvergetelijk optreden.</p>
</div>
<button class="button primary" type="button" (click)="editor.set({ kind: 'show' })">
+ Show toevoegen
</button>
</div>
<div class="show-list">
@for (show of shows(); track show.id) {
<article class="show-card">
<div class="date-tile">
<strong>{{ show.date | date: 'dd' }}</strong
><span>{{ show.date | date: 'MMM yyyy' }}</span>
</div>
<div class="show-details">
<h3>{{ show.name }}</h3>
<div class="tag-list">
<span class="style-tag">Ochtend</span><span class="style-tag">Middag</span
><span class="style-tag">Avond</span>
</div>
<p class="muted">Groepen indelen over dagdelen is nog niet beschikbaar.</p>
</div>
<div class="row-actions">
<button
class="text-button"
type="button"
[attr.aria-label]="show.name + ' bewerken'"
(click)="editor.set({ kind: 'show', value: show })"
>
Bewerken</button
><button
class="text-button destructive"
type="button"
[attr.aria-label]="show.name + ' verwijderen'"
(click)="
askDelete({
kind: 'show',
id: show.id,
name: show.name,
explanation: 'Deze show wordt definitief verwijderd.',
})
"
>
Verwijderen
</button>
</div>
</article>
} @empty {
<div class="empty-state">
<span class="empty-symbol" aria-hidden="true">✦</span>
<h2>Het podium wacht op je</h2>
<p>Plan een show met een ochtend-, middag- en avonddeel.</p>
<button class="button primary" type="button" (click)="editor.set({ kind: 'show' })">
Eerste show plannen
</button>
</div>
}
</div>
}
}
@if (editor(); as target) {
<app-entity-editor
[target]="target"
[schoolId]="context.school.id"
(closed)="editor.set(null)"
(saved)="saved()"
/>
}
@if (members(); as group) {
<app-group-members
[group]="group"
[schoolId]="context.school.id"
[dancers]="context.dancers"
(closed)="members.set(null)"
(changed)="membershipChanged($event)"
/>
}
@if (deleting(); as target) {
<app-confirm-dialog
[name]="target.name"
[explanation]="target.explanation"
[busy]="deleteBusy()"
[error]="deleteError()"
(closed)="deleting.set(null)"
(confirmed)="confirmDelete()"
/>
}
}