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()) {

Loading shows...

} @else if (errorMessage()) {
error

Could not load shows

{{ errorMessage() }}

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

No shows published yet

Published productions will appear here as soon as they are available.

} @else {
@for (show of shows(); track show.slug) { {{ show.title }}

{{ show.summary }}

Open detail
}
}
`, styles: [` .page { max-width: 1180px; margin: 0 auto; } .page-header { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 380px); gap: 24px; align-items: end; margin-bottom: 24px; } .eyebrow { margin: 0 0 10px; color: var(--azionelab-accent); text-transform: uppercase; font-size: 0.78rem; font-weight: 700; } h1 { margin: 0; font-size: clamp(2rem, 4vw, 3rem); } .supporting { margin: 0; color: var(--azionelab-muted); line-height: 1.6; } .show-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; } .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: 8px; border: 1px solid var(--azionelab-border); background: var(--azionelab-surface); 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: 220px; border-radius: 8px; border: 1px solid var(--azionelab-border); background: var(--azionelab-surface); box-shadow: var(--azionelab-shadow); } .show-card mat-card-content { flex: 1; } .show-card p { color: var(--azionelab-muted); line-height: 1.6; } @media (max-width: 860px) { .page-header { 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(); } 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('Please try again in a moment.'); this.isLoading.set(false); }, }); } }