import { CommonModule, isPlatformBrowser } from '@angular/common'; import { Component, PLATFORM_ID, inject, OnInit } from '@angular/core'; import { AdminOperationsService, AdminQuoteSession, AdminQuoteSessionDetail, } from '../services/admin-operations.service'; import { CopyOnClickDirective } from '../../../shared/directives/copy-on-click.directive'; @Component({ selector: 'app-admin-sessions', standalone: true, imports: [CommonModule, CopyOnClickDirective], templateUrl: './admin-sessions.component.html', styleUrl: './admin-sessions.component.scss', }) export class AdminSessionsComponent implements OnInit { private readonly isBrowser = isPlatformBrowser(inject(PLATFORM_ID)); private readonly adminOperationsService = inject(AdminOperationsService); sessions: AdminQuoteSession[] = []; sessionDetailsById: Record = {}; loading = false; deletingSessionIds = new Set(); loadingDetailSessionIds = new Set(); expandedSessionId: string | null = null; errorMessage: string | null = null; successMessage: string | null = null; ngOnInit(): void { this.loadSessions(); } loadSessions(): void { this.loading = true; this.errorMessage = null; this.successMessage = null; this.adminOperationsService.getSessions().subscribe({ next: (sessions) => { this.sessions = sessions; this.loading = false; }, error: () => { this.loading = false; this.errorMessage = 'Impossibile caricare le sessioni.'; }, }); } deleteSession(session: AdminQuoteSession): void { if (this.deletingSessionIds.has(session.id)) { return; } const confirmed = this.isBrowser && window.confirm( `Vuoi eliminare la sessione ${session.id}? Questa azione non si puo annullare.`, ); if (!confirmed) { return; } this.errorMessage = null; this.successMessage = null; this.deletingSessionIds.add(session.id); this.adminOperationsService.deleteSession(session.id).subscribe({ next: () => { this.sessions = this.sessions.filter((item) => item.id !== session.id); this.deletingSessionIds.delete(session.id); this.successMessage = 'Sessione eliminata.'; }, error: (err) => { this.deletingSessionIds.delete(session.id); this.errorMessage = this.extractErrorMessage( err, 'Impossibile eliminare la sessione.', ); }, }); } isDeletingSession(sessionId: string): boolean { return this.deletingSessionIds.has(sessionId); } toggleSessionDetail(session: AdminQuoteSession): void { if (this.expandedSessionId === session.id) { this.expandedSessionId = null; return; } this.expandedSessionId = session.id; if ( this.sessionDetailsById[session.id] || this.loadingDetailSessionIds.has(session.id) ) { return; } this.loadingDetailSessionIds.add(session.id); this.adminOperationsService.getSessionDetail(session.id).subscribe({ next: (detail) => { this.sessionDetailsById = { ...this.sessionDetailsById, [session.id]: detail, }; this.loadingDetailSessionIds.delete(session.id); }, error: (err) => { this.loadingDetailSessionIds.delete(session.id); this.errorMessage = this.extractErrorMessage( err, 'Impossibile caricare il dettaglio sessione.', ); }, }); } isDetailOpen(sessionId: string): boolean { return this.expandedSessionId === sessionId; } isLoadingDetail(sessionId: string): boolean { return this.loadingDetailSessionIds.has(sessionId); } getSessionDetail(sessionId: string): AdminQuoteSessionDetail | undefined { return this.sessionDetailsById[sessionId]; } formatPrintTime(seconds?: number): string { if (!seconds || seconds <= 0) { return '-'; } const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); return `${hours}h ${minutes}m`; } private extractErrorMessage(error: unknown, fallback: string): string { const err = error as { error?: { message?: string } }; return err?.error?.message || fallback; } }