import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core'; import { RouterLink } from '@angular/router'; import { TranslatePipe } from '../../../../i18n/translate.pipe'; import { TranslateService } from '../../../../i18n/translate.service'; import { LanguageService } from '../../../../services/language.service'; import { AdminDashboardFacade } from '../facade/admin-dashboard.facade'; import { DashboardSectionComponent } from '../components/dashboard-section.component'; import { DashboardCardComponent } from '../components/dashboard-card.component'; import { DashboardMetricComponent } from '../components/dashboard-metric.component'; import { DashboardStatusRowComponent } from '../components/dashboard-status-row.component'; import { DashboardShortcutCardComponent } from '../components/dashboard-shortcut-card.component'; import { DashboardTimelineComponent, DashboardTimelineEntry, DashboardTimelineStatus } from '../components/dashboard-timeline.component'; import { ButtonComponent } from '../../../../shared/ui/button/button.component'; import { IconComponent } from '../../../../shared/ui/icon/icon.component'; import { AdminDashboardQuickAction, AdminDashboardShortcut } from '../models/admin-dashboard.model'; import { AppIconName } from '../../../../shared/ui/icon/icon-registry'; interface LinkedAction { icon: AppIconName; labelKey: string; descriptionKey?: string; route: string[]; comingSoon: boolean; } const ACTIVITY_ICON: Record = { 'draft-saved': 'save', published: 'upload', }; const ACTIVITY_LABEL_KEY: Record = { 'draft-saved': 'dashboard.activityDraftSaved', published: 'dashboard.activityPublished', }; const DOCUMENTATION_LINKS: Array<{ id: string; icon: AppIconName; labelKey: string }> = [ { id: 'documentation', icon: 'book', labelKey: 'dashboard.docDocumentation' }, { id: 'shortcuts', icon: 'zap', labelKey: 'dashboard.docKeyboardShortcuts' }, { id: 'report-issue', icon: 'flag', labelKey: 'dashboard.docReportIssue' }, { id: 'release-notes', icon: 'megaphone', labelKey: 'dashboard.docReleaseNotes' }, ]; @Component({ selector: 'app-admin-dashboard-page', standalone: true, imports: [ RouterLink, TranslatePipe, DashboardSectionComponent, DashboardCardComponent, DashboardMetricComponent, DashboardStatusRowComponent, DashboardShortcutCardComponent, DashboardTimelineComponent, ButtonComponent, IconComponent, ], templateUrl: './admin-dashboard-page.component.html', styleUrls: ['./admin-dashboard-page.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, }) export class AdminDashboardPageComponent { readonly facade = inject(AdminDashboardFacade); private readonly translate = inject(TranslateService); private readonly languageService = inject(LanguageService); readonly documentationLinks = DOCUMENTATION_LINKS; private toLinkedAction(action: AdminDashboardQuickAction | AdminDashboardShortcut): LinkedAction { const lang = this.languageService.currentLanguage(); const comingSoon = 'comingSoon' in action ? !!action.comingSoon : action.route.length === 0; return { icon: action.icon, labelKey: action.labelKey, descriptionKey: 'descriptionKey' in action ? action.descriptionKey : undefined, route: comingSoon ? [] : ['/', lang, ...action.route], comingSoon, }; } readonly quickActions = computed(() => this.facade.quickActions.map(action => this.toLinkedAction(action)), ); readonly shortcuts = computed(() => this.facade.shortcuts.map(action => this.toLinkedAction(action)), ); readonly previewRoute = computed(() => ['/', this.languageService.currentLanguage()]); readonly tenantName = computed(() => this.facade.bootstrap()?.tenant.name ?? null); readonly bootstrapLoading = computed(() => !this.facade.bootstrap()); readonly lastPublishedText = computed(() => this.formatTimestamp(this.facade.lastPublishedAt())); readonly lastSavedText = computed(() => this.formatTimestamp(this.facade.lastSavedAt())); readonly activityStatus = computed(() => (this.bootstrapLoading() ? 'loading' : 'ready')); readonly activityTimelineEntries = computed(() => this.facade.activityEntries().map(entry => ({ id: entry.id, labelKey: ACTIVITY_LABEL_KEY[entry.type] ?? entry.type, timeText: new Date(entry.timestamp).toLocaleString(this.languageService.currentLanguage()), icon: ACTIVITY_ICON[entry.type] ?? 'circle', })), ); constructor() { this.facade.ensureLoaded(); } private formatTimestamp(timestamp: number | null): string | null { return timestamp ? new Date(timestamp).toLocaleString(this.languageService.currentLanguage()) : null; } publishDraft(): void { this.facade.publishDraft(); } discardDraft(): void { this.facade.discardDraft(); } }