import { Component, inject, signal, OnInit } from '@angular/core'; import { RouterLink } from '@angular/router'; import { ApiService } from '../../core/services/api.service'; import { ToastService } from '../../core/services/toast.service'; import { IDomainDetail } from '../../core/types/api.types'; import { CardComponent, CardHeaderComponent, CardTitleComponent, CardContentComponent, } from '../../ui/card/card.component'; import { ButtonComponent } from '../../ui/button/button.component'; import { BadgeComponent } from '../../ui/badge/badge.component'; import { TableComponent, TableHeaderComponent, TableBodyComponent, TableRowComponent, TableHeadComponent, TableCellComponent, } from '../../ui/table/table.component'; import { SkeletonComponent } from '../../ui/skeleton/skeleton.component'; @Component({ selector: 'app-domains-content', standalone: true, imports: [ RouterLink, CardComponent, CardHeaderComponent, CardTitleComponent, CardContentComponent, ButtonComponent, BadgeComponent, TableComponent, TableHeaderComponent, TableBodyComponent, TableRowComponent, TableHeadComponent, TableCellComponent, SkeletonComponent, ], template: `

Manage domains and SSL certificates

Total Domains
{{ domains().length }}
Valid Certificates
{{ countByStatus('valid') }}
Expiring Soon
{{ countByStatus('expiring-soon') }}
Expired/Pending
{{ countByStatus('expired') + countByStatus('pending') }}
@if (loading() && domains().length === 0) {
@for (_ of [1,2,3]; track $index) { }
} @else if (domains().length === 0) {

No domains found

Sync domains from Cloudflare to get started.

} @else { Domain Provider Services Certificate Expires Actions @for (d of domains(); track d.domain.id) {
{{ d.domain.domain }} @if (d.domain.isObsolete) { Obsolete }
{{ d.domain.dnsProvider || 'None' }} {{ d.serviceCount }} {{ d.certificateStatus }} @if (d.daysRemaining !== null) { {{ d.daysRemaining }} days } @else { - }
}
}
`, }) export class DomainsContentComponent implements OnInit { private api = inject(ApiService); private toast = inject(ToastService); domains = signal([]); loading = signal(false); syncing = signal(false); ngOnInit(): void { this.loadDomains(); } async loadDomains(): Promise { this.loading.set(true); try { const response = await this.api.getDomains(); if (response.success && response.data) { this.domains.set(response.data); } } catch { this.toast.error('Failed to load domains'); } finally { this.loading.set(false); } } async syncDomains(): Promise { this.syncing.set(true); try { const response = await this.api.syncCloudflareDomains(); if (response.success) { this.toast.success('Domains synced'); this.loadDomains(); } else { this.toast.error(response.error || 'Failed to sync domains'); } } catch { this.toast.error('Failed to sync domains'); } finally { this.syncing.set(false); } } countByStatus(status: string): number { return this.domains().filter(d => d.certificateStatus === status).length; } getCertStatusVariant(status: string): 'success' | 'warning' | 'destructive' | 'secondary' { switch (status) { case 'valid': return 'success'; case 'expiring-soon': return 'warning'; case 'expired': return 'destructive'; case 'pending': return 'secondary'; default: return 'secondary'; } } }