import { Component, inject, input, output, signal } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { firstValueFrom } from 'rxjs'; import { apiError } from '../core/api-error'; interface Preview { name: string; dancers: number; groups: number; shows: number; existingId: number | null; existingName: string | null; existingRevision: number | null; } @Component({ selector: 'app-school-transfer', template: `
@if (schoolId() !== undefined) { }
@if (error()) { } @if (notice()) {

{{ notice() }}

} @if (preview(); as p) {

{{ p.name }}

{{ p.dancers }} dansers · {{ p.groups }} dansgroepen · {{ p.shows }} shows

@if (p.existingId !== null) {

De bestaande school {{ p.existingName }} wordt volledig vervangen. Alle huidige gegevens van deze school verdwijnen.

} @else { }
} `, }) export class SchoolTransfer { readonly schoolId = input(); readonly imported = output(); private readonly http = inject(HttpClient); readonly preview = signal(null); readonly busy = signal(false); readonly error = signal(''); readonly notice = signal(''); private json = ''; private readonly base = '/api/dance-schools'; cancel(): void { this.preview.set(null); this.json = ''; this.notice.set(''); } async select(event: Event): Promise { const input = event.target as HTMLInputElement; const file = input.files?.[0]; input.value = ''; this.cancel(); this.error.set(''); if (!file) return; this.busy.set(true); try { this.json = await file.text(); this.preview.set( await firstValueFrom( this.http.post(`${this.base}/import/preview`, this.json, { headers: { 'Content-Type': 'application/json' }, }), ), ); } catch (e) { this.error.set( `Import niet gelukt: ${e instanceof Error && !('status' in e) ? e.message : apiError(e)}`, ); } finally { this.busy.set(false); } } async confirm(): Promise { const p = this.preview(); if (!p || this.busy()) return; this.busy.set(true); this.error.set(''); try { const query = p.existingId === null ? '' : `?replaceId=${p.existingId}`; await firstValueFrom( this.http.post(`${this.base}/import${query}`, this.json, { headers: { 'Content-Type': 'application/json', ...(p.existingRevision === null ? {} : { 'X-School-Revision': String(p.existingRevision) }), }, }), ); this.cancel(); this.notice.set('School geïmporteerd.'); this.imported.emit(); } catch (e) { this.error.set(`Import niet gelukt: ${apiError(e)}`); this.preview.set(null); } finally { this.busy.set(false); } } async download(): Promise { this.error.set(''); this.busy.set(true); try { const blob = await firstValueFrom( this.http.get(`${this.base}/${this.schoolId()}/export`, { responseType: 'blob' }), ); const url = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = url; link.download = `school-${this.schoolId()}.json`; link.click(); setTimeout(() => URL.revokeObjectURL(url), 1000); } catch (e) { this.error.set(`Export niet gelukt: ${apiError(e)}`); } finally { this.busy.set(false); } } }