import { DeesElement, customElement, html, css, cssManager, property, type TemplateResult, } from '@design.estate/dees-element'; declare global { interface HTMLElementTagNameMap { 'sz-domain-detail-view': SzDomainDetailView; } } export interface IDomainDetail { id: string; name: string; status: 'active' | 'pending' | 'error'; verified: boolean; createdAt: string; proxyRoutes?: string[]; } export interface ICertificateDetail { id: string; domain: string; issuer: string; validFrom: string; validUntil: string; daysRemaining: number; status: 'valid' | 'expiring' | 'expired'; autoRenew: boolean; chain?: string[]; } export interface IDnsRecordDetail { id: string; type: 'A' | 'AAAA' | 'CNAME' | 'MX' | 'TXT' | 'NS' | 'SRV'; name: string; value: string; ttl: number; priority?: number; } @customElement('sz-domain-detail-view') export class SzDomainDetailView extends DeesElement { public static demo = () => html`
`; public static demoGroups = ['Network']; @property({ type: Object }) public accessor domain: IDomainDetail | null = null; @property({ type: Object }) public accessor certificate: ICertificateDetail | null = null; @property({ type: Array }) public accessor dnsRecords: IDnsRecordDetail[] = []; @property({ type: Boolean }) public accessor actionLoading: boolean = false; public static styles = [ cssManager.defaultStyles, css` :host { display: block; } .header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 24px; } .header-info { display: flex; flex-direction: column; gap: 8px; } .domain-name { font-size: 24px; font-weight: 700; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; display: flex; align-items: center; gap: 12px; } .status-badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 9999px; font-size: 12px; font-weight: 500; } .status-badge.active { background: ${cssManager.bdTheme('#dcfce7', 'rgba(34, 197, 94, 0.2)')}; color: ${cssManager.bdTheme('#16a34a', '#22c55e')}; } .status-badge.pending { background: ${cssManager.bdTheme('#fef3c7', 'rgba(245, 158, 11, 0.2)')}; color: ${cssManager.bdTheme('#d97706', '#f59e0b')}; } .status-badge.error { background: ${cssManager.bdTheme('#fee2e2', 'rgba(239, 68, 68, 0.2)')}; color: ${cssManager.bdTheme('#dc2626', '#ef4444')}; } .status-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; } .domain-meta { display: flex; align-items: center; gap: 16px; font-size: 14px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; } .verified-badge { display: inline-flex; align-items: center; gap: 4px; color: ${cssManager.bdTheme('#16a34a', '#22c55e')}; } .verified-badge svg { width: 16px; height: 16px; } .header-actions { display: flex; gap: 8px; } .action-button { display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; background: ${cssManager.bdTheme('#ffffff', '#09090b')}; border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')}; border-radius: 6px; font-size: 13px; font-weight: 500; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; cursor: pointer; transition: all 200ms ease; } .action-button:hover:not(:disabled) { background: ${cssManager.bdTheme('#f4f4f5', '#18181b')}; } .action-button:disabled { opacity: 0.6; cursor: not-allowed; } .action-button svg { width: 14px; height: 14px; } .action-button.danger { color: ${cssManager.bdTheme('#dc2626', '#ef4444')}; border-color: ${cssManager.bdTheme('#fee2e2', 'rgba(239, 68, 68, 0.3)')}; } .action-button.danger:hover:not(:disabled) { background: ${cssManager.bdTheme('#fee2e2', 'rgba(239, 68, 68, 0.2)')}; } .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-bottom: 16px; } @media (max-width: 768px) { .grid { grid-template-columns: 1fr; } } .section { background: ${cssManager.bdTheme('#ffffff', '#09090b')}; border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')}; border-radius: 8px; overflow: hidden; } .section.full-width { grid-column: 1 / -1; } .section-header { display: flex; justify-content: space-between; align-items: center; padding: 14px 16px; border-bottom: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')}; background: ${cssManager.bdTheme('#f4f4f5', '#18181b')}; } .section-title { font-size: 14px; font-weight: 600; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; display: flex; align-items: center; gap: 8px; } .section-title svg { width: 16px; height: 16px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; } .section-action { padding: 6px 10px; background: transparent; border: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')}; border-radius: 4px; font-size: 12px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; cursor: pointer; transition: all 200ms ease; } .section-action:hover { background: ${cssManager.bdTheme('#ffffff', '#09090b')}; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .section-content { padding: 16px; } .cert-status { display: flex; align-items: center; gap: 12px; padding: 16px; background: ${cssManager.bdTheme('#f0fdf4', 'rgba(34, 197, 94, 0.1)')}; border-radius: 8px; margin-bottom: 16px; } .cert-status.expiring { background: ${cssManager.bdTheme('#fffbeb', 'rgba(245, 158, 11, 0.1)')}; } .cert-status.expired { background: ${cssManager.bdTheme('#fef2f2', 'rgba(239, 68, 68, 0.1)')}; } .cert-icon { width: 40px; height: 40px; border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; } .cert-icon.valid { background: ${cssManager.bdTheme('#dcfce7', 'rgba(34, 197, 94, 0.2)')}; color: ${cssManager.bdTheme('#16a34a', '#22c55e')}; } .cert-icon.expiring { background: ${cssManager.bdTheme('#fef3c7', 'rgba(245, 158, 11, 0.2)')}; color: ${cssManager.bdTheme('#d97706', '#f59e0b')}; } .cert-icon.expired { background: ${cssManager.bdTheme('#fee2e2', 'rgba(239, 68, 68, 0.2)')}; color: ${cssManager.bdTheme('#dc2626', '#ef4444')}; } .cert-icon svg { width: 20px; height: 20px; } .cert-info { flex: 1; } .cert-title { font-size: 14px; font-weight: 600; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .cert-subtitle { font-size: 13px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; margin-top: 2px; } .cert-days { font-size: 24px; font-weight: 700; text-align: center; } .cert-days.valid { color: ${cssManager.bdTheme('#16a34a', '#22c55e')}; } .cert-days.expiring { color: ${cssManager.bdTheme('#d97706', '#f59e0b')}; } .cert-days.expired { color: ${cssManager.bdTheme('#dc2626', '#ef4444')}; } .cert-days-label { font-size: 11px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; text-align: center; margin-top: 2px; } .info-row { display: flex; justify-content: space-between; align-items: center; padding: 10px 0; border-bottom: 1px solid ${cssManager.bdTheme('#f4f4f5', '#27272a')}; } .info-row:last-child { border-bottom: none; } .info-label { font-size: 13px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; } .info-value { font-size: 13px; font-weight: 500; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .info-value.enabled { color: ${cssManager.bdTheme('#16a34a', '#22c55e')}; } .chain-list { display: flex; flex-wrap: wrap; gap: 8px; } .chain-badge { padding: 4px 8px; background: ${cssManager.bdTheme('#f4f4f5', '#27272a')}; border-radius: 4px; font-size: 12px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; } .dns-table { width: 100%; } .dns-header { display: grid; grid-template-columns: 80px 1fr 2fr 80px 60px; gap: 12px; padding: 10px 0; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; border-bottom: 1px solid ${cssManager.bdTheme('#e4e4e7', '#27272a')}; } .dns-row { display: grid; grid-template-columns: 80px 1fr 2fr 80px 60px; gap: 12px; padding: 12px 0; font-size: 13px; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; border-bottom: 1px solid ${cssManager.bdTheme('#f4f4f5', '#27272a')}; align-items: center; } .dns-row:last-child { border-bottom: none; } .dns-row:hover { background: ${cssManager.bdTheme('#f4f4f5', '#18181b')}; margin: 0 -16px; padding-left: 16px; padding-right: 16px; } .dns-type { padding: 2px 8px; background: ${cssManager.bdTheme('#dbeafe', 'rgba(59, 130, 246, 0.2)')}; color: ${cssManager.bdTheme('#2563eb', '#60a5fa')}; border-radius: 4px; font-size: 11px; font-weight: 600; text-align: center; } .dns-name { font-family: monospace; } .dns-value { font-family: monospace; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .dns-ttl { color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; } .dns-actions { display: flex; gap: 4px; } .icon-button { padding: 4px; background: transparent; border: none; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; cursor: pointer; border-radius: 4px; transition: all 200ms ease; } .icon-button:hover { background: ${cssManager.bdTheme('#e4e4e7', '#27272a')}; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .icon-button.danger:hover { background: ${cssManager.bdTheme('#fee2e2', 'rgba(239, 68, 68, 0.2)')}; color: ${cssManager.bdTheme('#dc2626', '#ef4444')}; } .icon-button svg { width: 14px; height: 14px; } .routes-list { display: flex; flex-wrap: wrap; gap: 8px; } .route-badge { padding: 6px 10px; background: ${cssManager.bdTheme('#f4f4f5', '#27272a')}; border-radius: 4px; font-size: 13px; font-family: monospace; color: ${cssManager.bdTheme('#18181b', '#fafafa')}; } .empty-state { text-align: center; padding: 24px; color: ${cssManager.bdTheme('#71717a', '#a1a1aa')}; font-size: 14px; } `, ]; public render(): TemplateResult { if (!this.domain) { return html`
No domain selected
`; } return html`
${this.domain.name} ${this.domain.status.charAt(0).toUpperCase() + this.domain.status.slice(1)}
${this.domain.verified ? html` Verified ` : html`Not verified`} Added ${this.domain.createdAt}
${!this.domain.verified ? html` ` : ''}
SSL Certificate
${this.certificate ? html` ` : ''}
${this.certificate ? html`
${this.certificate.status === 'valid' ? html` ` : this.certificate.status === 'expiring' ? html` ` : html` `}
${this.certificate.status === 'valid' ? 'Certificate Valid' : this.certificate.status === 'expiring' ? 'Certificate Expiring Soon' : 'Certificate Expired'}
Issued by ${this.certificate.issuer}
${Math.abs(this.certificate.daysRemaining)}
${this.certificate.daysRemaining >= 0 ? 'days left' : 'days ago'}
Valid From ${this.certificate.validFrom}
Valid Until ${this.certificate.validUntil}
Auto-Renew ${this.certificate.autoRenew ? 'Enabled' : 'Disabled'}
${this.certificate.chain && this.certificate.chain.length > 0 ? html`
Certificate Chain
${this.certificate.chain.map(cert => html`${cert}`)}
` : ''} ` : html`
No certificate configured
`}
Proxy Routes
${this.domain.proxyRoutes && this.domain.proxyRoutes.length > 0 ? html`
${this.domain.proxyRoutes.map(route => html` ${route} `)}
` : html`
No proxy routes configured
`}
DNS Records
${this.dnsRecords.length > 0 ? html`
Type Name Value TTL
${this.dnsRecords.map(record => html`
${record.type} ${record.name} ${record.priority ? `${record.priority} ` : ''}${record.value} ${record.ttl}s
`)}
` : html`
No DNS records configured
`}
`; } private handleVerify() { this.dispatchEvent(new CustomEvent('verify-domain', { detail: this.domain, bubbles: true, composed: true })); } private handleDelete() { this.dispatchEvent(new CustomEvent('delete-domain', { detail: this.domain, bubbles: true, composed: true })); } private handleRenewCertificate() { this.dispatchEvent(new CustomEvent('renew-certificate', { detail: this.certificate, bubbles: true, composed: true })); } private handleAddDnsRecord() { this.dispatchEvent(new CustomEvent('add-dns-record', { detail: this.domain, bubbles: true, composed: true })); } private handleEditDnsRecord(record: IDnsRecordDetail) { this.dispatchEvent(new CustomEvent('edit-dns-record', { detail: record, bubbles: true, composed: true })); } private handleDeleteDnsRecord(record: IDnsRecordDetail) { this.dispatchEvent(new CustomEvent('delete-dns-record', { detail: record, bubbles: true, composed: true })); } }