import { ChangeDetectionStrategy, Component, HostListener, computed, input, output, } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ImportPreviewResponse, ImportResultResponse } from '../../../core/services/admin.service'; @Component({ selector: 'app-challenge-import-modal', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule], styles: [` .modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.4); display: flex; align-items: center; justify-content: center; z-index: 70; } .modal { background: var(--color-surface, #fff); padding: 16px; border-radius: 8px; width: min(520px, 90vw); } .actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; } .error { color: var(--color-danger, #f00); margin-top: 8px; } .warnings { color: var(--color-warning, #b45309); margin-top: 8px; } .result { color: var(--color-success, #065f46); margin-top: 8px; } ul { margin: 0; padding-left: 18px; } .spinner { display: inline-block; width: 12px; height: 12px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin 0.6s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } `], template: ` @if (open()) { } `, }) export class ChallengeImportModalComponent { readonly open = input(false); readonly document = input(null); readonly preview = input(null); readonly result = input(null); readonly submitting = input(false); readonly errorMessage = input(null); readonly cancel = output(); readonly confirm = output(); readonly summary = computed(() => this.preview()); @HostListener('document:keydown.escape') onEscape(): void { if (this.open() && !this.submitting() && !this.result()) this.onCancel(); } onCancel(): void { if (this.submitting()) return; this.cancel.emit(); } onConfirm(): void { if (this.submitting() || this.result()) return; this.confirm.emit(); } }