File size: 4,241 Bytes
5c335da
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
class CustomStatCard extends HTMLElement {
    constructor() {
        super();
    }

    connectedCallback() {
        this.attachShadow({ mode: 'open' });
        
        const title = this.getAttribute('title') || 'Metric';
        const value = this.getAttribute('value') || '0';
        const color = this.getAttribute('color') || 'green';
        const icon = this.getAttribute('icon') || 'activity';
        const trend = this.getAttribute('trend') || '';
        
        const colorMap = {
            green: '#22c55e',
            orange: '#f97316',
            gold: '#ffd700',
            red: '#ef4444',
            blue: '#3b82f6',
            purple: '#a855f7'
        };
        
        const accentColor = colorMap[color] || colorMap.green;
        
        let trendHtml = '';
        if (trend) {
            const isPositive = trend.includes('+') || trend === 'record';
            const isNegative = trend.includes('-');
            const isNeutral = trend === 'stable';
            
            if (isPositive) {
                trendHtml = `<div class="text-xs text-neon-green mt-1 flex items-center">
                    <svg class="w-3 h-3 mr-1" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"></polyline><polyline points="17 6 23 6 23 12"></polyline></svg>
                    ${trend}
                </div>`;
            } else if (isNegative) {
                trendHtml = `<div class="text-xs text-neon-red mt-1 flex items-center">
                    <svg class="w-3 h-3 mr-1" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="23 18 13.5 8.5 8.5 13.5 1 6"></polyline><polyline points="17 18 23 18 23 12"></polyline></svg>
                    ${trend}
                </div>`;
            } else {
                trendHtml = `<div class="text-xs text-gray-400 mt-1">${trend}</div>`;
            }
        }
        
        this.shadowRoot.innerHTML = `
            <style>
                :host {
                    display: block;
                }
                .card {
                    background-color: #0a0a0a;
                    border: 1px solid #1f2937;
                    border-radius: 0.5rem;
                    padding: 1rem;
                    position: relative;
                    overflow: hidden;
                    transition: all 0.2s;
                }
                .card:hover {
                    border-color: ${accentColor};
                    box-shadow: 0 0 20px rgba(${parseInt(accentColor.slice(1,3),16)}, ${parseInt(accentColor.slice(3,5),16)}, ${parseInt(accentColor.slice(5,7),16)}, 0.15);
                }
                .icon-bg {
                    position: absolute;
                    right: 8px;
                    top: 8px;
                    opacity: 0.1;
                    transition: opacity 0.2s;
                }
                .card:hover .icon-bg {
                    opacity: 0.2;
                }
                .title {
                    color: #9ca3af;
                    font-size: 0.65rem;
                    text-transform: uppercase;
                    letter-spacing: 0.1em;
                    font-weight: 700;
                }
                .value {
                    color: #fff;
                    font-size: 1.25rem;
                    font-weight: 700;
                    margin-top: 0.5rem;
                    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
                }
            </style>
            <div class="card">
                <div class="icon-bg">
                    <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="${accentColor}" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-feather="${icon}"></svg>
                </div>
                <div class="title">${title}</div>
                <div class="value">${value}</div>
                ${trendHtml}
            </div>
        `;
        
        // Load feather icons for this component
        if (typeof feather !== 'undefined') {
            feather.replace();
        }
    }
}

customElements.define('custom-stat-card', CustomStatCard);