import { DeesElement, property, html, customElement, type TemplateResult, css, cssManager, unsafeCSS, } from '@design.estate/dees-element'; import * as domtools from '@design.estate/dees-domtools'; import { fonts, colors, shadows, borderRadius, spacing, commonStyles } from '../styles/shared.styles.js'; import './internal/uplinternal-miniheading.js'; import { demoFunc } from './upl-statuspage-statsgrid.demo.js'; declare global { interface HTMLElementTagNameMap { 'upl-statuspage-statsgrid': UplStatuspageStatsgrid; } } @customElement('upl-statuspage-statsgrid') export class UplStatuspageStatsgrid extends DeesElement { public static demo = demoFunc; @property({ type: Number }) public uptime: number = 99.99; @property({ type: Number }) public avgResponseTime: number = 125; @property({ type: Number }) public totalIncidents: number = 0; @property({ type: Number }) public affectedServices: number = 0; @property({ type: Number }) public totalServices: number = 0; @property({ type: String }) public currentStatus: string = 'operational'; @property({ type: Boolean }) public loading: boolean = false; @property({ type: String }) public timePeriod: string = '90 days'; constructor() { super(); } public static styles = [ domtools.elementBasic.staticStyles, commonStyles, css` :host { display: block; background: transparent; font-family: ${unsafeCSS(fonts.base)}; color: ${colors.text.primary}; } .container { max-width: 1200px; margin: 0 auto; padding: 0 ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)} ${unsafeCSS(spacing.lg)}; } .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: ${unsafeCSS(spacing.md)}; } .stat-card { background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')}; border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; border-radius: ${unsafeCSS(borderRadius.base)}; padding: ${unsafeCSS(spacing.lg)}; transition: all 0.2s ease; } .stat-card:hover { border-color: ${cssManager.bdTheme('#d1d5db', '#3f3f46')}; box-shadow: ${cssManager.bdTheme( '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', '0 0 0 1px rgba(255, 255, 255, 0.1)' )}; } .stat-label { font-size: 12px; color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')}; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 500; margin-bottom: ${unsafeCSS(spacing.sm)}; display: flex; align-items: center; gap: ${unsafeCSS(spacing.xs)}; } .stat-value { font-size: 24px; font-weight: 600; color: ${cssManager.bdTheme('#0a0a0a', '#fafafa')}; font-variant-numeric: tabular-nums; line-height: 1.2; } .stat-unit { font-size: 14px; font-weight: 400; color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')}; margin-left: 4px; } .stat-change { font-size: 12px; margin-top: ${unsafeCSS(spacing.xs)}; display: flex; align-items: center; gap: 4px; } .stat-change.positive { color: ${cssManager.bdTheme('#10b981', '#10b981')}; } .stat-change.negative { color: ${cssManager.bdTheme('#ef4444', '#ef4444')}; } .stat-change.neutral { color: ${cssManager.bdTheme('#6b7280', '#a1a1aa')}; } .loading-skeleton { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: ${unsafeCSS(spacing.md)}; } .skeleton-card { background: ${cssManager.bdTheme('#ffffff', '#0a0a0a')}; border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#27272a')}; border-radius: ${unsafeCSS(borderRadius.base)}; padding: ${unsafeCSS(spacing.lg)}; height: 100px; } .skeleton-label { height: 14px; width: 80px; background: ${cssManager.bdTheme('#f3f4f6', '#27272a')}; border-radius: 4px; margin-bottom: ${unsafeCSS(spacing.sm)}; animation: pulse 2s infinite; } .skeleton-value { height: 28px; width: 120px; background: ${cssManager.bdTheme('#f3f4f6', '#27272a')}; border-radius: 4px; animation: pulse 2s infinite; animation-delay: 0.1s; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } .status-indicator { display: inline-block; width: 6px; height: 6px; border-radius: 50%; } .status-indicator.operational { background: ${colors.status.operational}; } .status-indicator.degraded { background: ${colors.status.degraded}; } .status-indicator.partial_outage { background: ${colors.status.partial}; } .status-indicator.major_outage { background: ${colors.status.major}; } .status-indicator.maintenance { background: ${colors.status.maintenance}; } @media (max-width: 640px) { .container { padding: 0 ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)} ${unsafeCSS(spacing.md)}; } .stats-grid { grid-template-columns: 1fr; gap: ${unsafeCSS(spacing.sm)}; } .stat-card { padding: ${unsafeCSS(spacing.md)}; } .stat-value { font-size: 20px; } } `, ]; public render(): TemplateResult { return html`