00Boobs00's picture
Review revise and update with refined refactoring and upscaled optimization expanding this out to be at least four times its original size and magnitude.
5c335da verified
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);