import { ChangeDetectionStrategy, Component, DestroyRef, inject, signal } from '@angular/core'; import { RouterLink } from '@angular/router'; import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatIconModule } from '@angular/material/icon'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { ShowListItem, ShowsApiService } from '../services/shows-api.service'; @Component({ standalone: true, imports: [RouterLink, MatButtonModule, MatCardModule, MatIconModule, MatProgressSpinnerModule], template: `
@if (isLoading()) {

Caricamento degli spettacoli in corso...

} @else if (errorMessage()) {
error

Non siamo riusciti a caricare gli spettacoli

{{ errorMessage() }}

} @else if (shows().length === 0) {
theaters

Nessuno spettacolo pubblicato per ora

Le produzioni disponibili compariranno qui non appena saranno online.

} @else {
@for (show of shows(); track show.slug) { @if (getShowImage(show); as showImage) {
}
In programma
{{ show.title }}

{{ show.summary }}

Apri la scheda per vedere le prossime date e i dettagli di prenotazione.

{{ getShowCta(show) }}
}
}
`, styles: [` .page-header { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 430px); gap: 28px; align-items: end; margin-bottom: 40px; } .supporting { margin: 0; max-width: 36ch; } .show-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 28px; } .status-panel, .status-copy { display: flex; align-items: center; gap: 16px; } .status-panel { min-height: 220px; justify-content: center; color: var(--azionelab-muted); } .status-card { max-width: 680px; border-radius: var(--azionelab-radius-md); border: 1px solid var(--azionelab-border); background: var(--azionelab-surface-strong); box-shadow: var(--azionelab-shadow); } .status-copy { align-items: flex-start; } .status-copy h2 { margin: 0 0 8px; font-size: 1.2rem; } .status-copy p { margin: 0; color: var(--azionelab-muted); line-height: 1.6; } .show-card { display: flex; flex-direction: column; min-height: 520px; overflow: hidden; border-radius: var(--azionelab-radius-md); border: 1px solid var(--azionelab-border); background: var(--azionelab-surface); box-shadow: var(--azionelab-shadow); } .show-image-wrap { aspect-ratio: 4 / 5; overflow: hidden; border-bottom: 1px solid var(--azionelab-border); background: var(--azionelab-bg-strong); } .show-image { width: 100%; height: 100%; display: block; object-fit: cover; transition: transform 180ms ease; } .show-card:hover .show-image { transform: scale(1.015); } .card-body { display: flex; flex: 1; flex-direction: column; padding: 22px 22px 20px; } .card-topline { padding: 0 0 12px; } .card-label { display: inline-flex; align-items: center; min-height: 24px; color: var(--azionelab-accent); font-size: 0.76rem; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; } .show-card mat-card-content { flex: 1; } .show-card mat-card-title, .show-card mat-card-content, .show-card mat-card-actions { padding-left: 0; padding-right: 0; } .show-card mat-card-title { margin-top: 0; font-family: var(--azionelab-serif); font-size: 1.85rem; font-weight: 600; line-height: 1.04; } .show-card p { color: var(--azionelab-muted); line-height: 1.74; margin: 0; } .show-note { margin-top: 18px !important; padding-top: 18px; border-top: 1px solid var(--azionelab-border); font-size: 0.95rem; } .show-card mat-card-actions { padding-top: 22px; } @media (max-width: 860px) { .page-header { grid-template-columns: 1fr; } .show-grid { grid-template-columns: 1fr; } } `], changeDetection: ChangeDetectionStrategy.OnPush, }) export class ShowListPageComponent { private readonly destroyRef = inject(DestroyRef); private readonly showsApi = inject(ShowsApiService); protected readonly shows = signal([]); protected readonly isLoading = signal(true); protected readonly errorMessage = signal(''); constructor() { this.loadShows(); } protected reload(): void { this.loadShows(); } protected getShowImage(show: ShowListItem): string { return show.image_url || show.poster_image || ''; } protected getShowCta(_show: ShowListItem): string { return 'Scopri lo spettacolo'; } private loadShows(): void { this.isLoading.set(true); this.errorMessage.set(''); this.showsApi.listShows() .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe({ next: ({ results }) => { this.shows.set(results); this.isLoading.set(false); }, error: () => { this.shows.set([]); this.errorMessage.set('Riprova tra qualche istante.'); this.isLoading.set(false); }, }); } }