Spaces:
Running
Running
| class StatCard extends HTMLElement { | |
| static get observedAttributes() { | |
| return ['icon', 'label', 'value', 'color']; | |
| } | |
| constructor() { | |
| super(); | |
| } | |
| connectedCallback() { | |
| this.render(); | |
| } | |
| attributeChangedCallback() { | |
| this.render(); | |
| } | |
| render() { | |
| const icon = this.getAttribute('icon') || 'activity'; | |
| const label = this.getAttribute('label') || 'Label'; | |
| const value = this.getAttribute('value') || '0'; | |
| const color = this.getAttribute('color') || 'primary'; | |
| const colorClasses = { | |
| primary: 'text-primary-400 bg-primary-500/10 border-primary-500/20', | |
| secondary: 'text-secondary-400 bg-secondary-500/10 border-secondary-500/20', | |
| green: 'text-emerald-400 bg-emerald-500/10 border-emerald-500/20', | |
| red: 'text-red-400 bg-red-500/10 border-red-500/20', | |
| slate: 'text-slate-400 bg-slate-500/10 border-slate-500/20' | |
| }; | |
| const colorClass = colorClasses[color] || colorClasses.primary; | |
| this.innerHTML = ` | |
| <div class="bg-slate-900/80 border border-slate-800 rounded-2xl p-5 shadow-lg backdrop-blur-sm hover:border-slate-700 transition-colors"> | |
| <div class="flex items-start justify-between"> | |
| <div> | |
| <p class="text-slate-500 text-xs font-medium uppercase tracking-wider mb-1">${label}</p> | |
| <h4 class="text-2xl font-bold text-slate-100">${value}</h4> | |
| </div> | |
| <div class="w-10 h-10 rounded-xl ${colorClass} flex items-center justify-center border"> | |
| <i data-feather="${icon}" class="w-5 h-5"></i> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| // Re-initialize feather icons for this component | |
| if (window.feather) { | |
| feather.replace(); | |
| } | |
| } | |
| } | |
| customElements.define('stat-card', StatCard); |