import { html, css, LitElement } from 'lit' import { customElement, state } from 'lit/decorators.js' import { client } from '@operato/graphql' import gql from 'graphql-tag' @customElement('kpi-alert-panel') export class KpiAlertPanel extends LitElement { static styles = css` .alert-container { background: #fff; border-radius: 16px; padding: 32px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); margin-bottom: 16px; } .alert-title { font-size: 1.5rem; font-weight: bold; margin-bottom: 16px; } .alert-list { list-style: none; padding: 0; margin: 0; } .alert-item { padding: 10px 0; border-bottom: 1px solid #eee; font-size: 1.1rem; color: #d32f2f; display: flex; align-items: center; gap: 8px; } .alert-icon { font-size: 1.3rem; color: #d32f2f; } ` @state() alerts: Array<{ level: string; message: string; kpi?: { name: string }; createdAt: string }> = [] @state() loading = true @state() error = '' connectedCallback() { super.connectedCallback() this.fetchAlerts() } async fetchAlerts() { this.loading = true this.error = '' try { const response = await client.query({ query: gql` query { kpiAlerts { id message level createdAt kpi { name } } } ` }) this.alerts = response.data.kpiAlerts || [] } catch (e) { this.error = 'KPI 알림 데이터를 불러오지 못했습니다.' } finally { this.loading = false } } getIcon(level: string) { switch (level) { case 'critical': return '❗' case 'warning': return '⚠️' case 'info': default: return 'ℹ️' } } render() { if (this.loading) { return html`