financefalconai / components /stat-meter.js
Ram2005's picture
User
9679277 verified
class StatMeter extends HTMLElement {
connectedCallback() {
this.attachShadow({ mode: 'open' });
document.addEventListener('state-update', () => this.update());
this.update();
}
update() {
const label = this.getAttribute('label');
const icon = this.getAttribute('icon');
const val = state.stats[label] || 0;
// Color logic based on value - "Invisible Future Meter" logic
let colorClass = '#22c55e'; // Green
let glowClass = '';
if (val < 30) {
colorClass = '#ef4444'; // Red - Danger
glowClass = 'box-shadow: 0 0 10px rgba(239, 68, 68, 0.5);';
} else if (val < 60) {
colorClass = '#eab308'; // Yellow - Caution
} else {
colorClass = '#3b82f6'; // Blue - Good (using blue for high stat instead of green for money)
}
// Icon mapping
const iconMap = {
'stability': 'shield',
'safety': 'activity',
'debt': 'arrow-down-circle',
'scamRisk': 'alert-triangle',
'wealth': 'trending-up'
};
this.shadowRoot.innerHTML = `
<style>
.stat-row { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; font-size: 0.8rem; }
.bar-bg { flex-grow: 1; height: 8px; background: #334155; border-radius: 4px; overflow: hidden; position: relative; }
.bar-fill {
height: 100%;
transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1), background-color 0.3s;
${glowClass}
}
.label { width: 70px; color: #cbd5e1; display: flex; align-items: center; gap: 6px; font-weight: 500; }
.value { width: 30px; text-align: right; color: #94a3b8; font-family: monospace; }
</style>
<div class="stat-row">
<div class="label">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
${label}
</div>
<div class="bar-bg">
<div class="bar-fill" style="width: ${val}%; background-color: ${colorClass};"></div>
</div>
<div class="value">${val}</div>
</div>
`;
}
}
customElements.define('stat-meter', StatMeter);