diff --git a/src/components/CountryDeepDivePanel.ts b/src/components/CountryDeepDivePanel.ts index 51d9589e6..c8af0373d 100644 --- a/src/components/CountryDeepDivePanel.ts +++ b/src/components/CountryDeepDivePanel.ts @@ -485,6 +485,7 @@ export class CountryDeepDivePanel implements CountryBriefPanel { public updateEnergyProfile(data: CountryEnergyProfileData): void { if (!this.energyBody) return; this.renderEnergyProfile(data); + this.resilienceWidget?.setEnergyMix(data); } private renderEnergyProfile(data: CountryEnergyProfileData): void { diff --git a/src/components/ResilienceWidget.ts b/src/components/ResilienceWidget.ts index 3a2c6487c..bc6b08f5c 100644 --- a/src/components/ResilienceWidget.ts +++ b/src/components/ResilienceWidget.ts @@ -14,6 +14,7 @@ import { getResilienceTrendArrow, getResilienceVisualLevel, } from './resilience-widget-utils'; +import type { CountryEnergyProfileData } from './CountryBriefPanel'; const LOCKED_PREVIEW: ResilienceScoreResponse = { countryCode: 'US', @@ -51,6 +52,7 @@ export class ResilienceWidget { private loading = false; private errorMessage: string | null = null; private requestVersion = 0; + private energyMixData: CountryEnergyProfileData | null = null; constructor(countryCode?: string | null) { this.element = document.createElement('section'); @@ -78,6 +80,7 @@ export class ResilienceWidget { this.currentCountryCode = normalized; this.currentData = null; + this.energyMixData = null; this.errorMessage = null; this.loading = false; this.requestVersion += 1; @@ -122,6 +125,11 @@ export class ResilienceWidget { } } + public setEnergyMix(data: CountryEnergyProfileData | null): void { + this.energyMixData = data; + this.render(); + } + public destroy(): void { this.requestVersion += 1; this.unsubscribeAuth?.(); @@ -257,7 +265,7 @@ export class ResilienceWidget { h( 'div', { className: 'resilience-widget__domains' }, - ...data.domains.map((domain) => this.renderDomainRow(domain)), + ...data.domains.map((domain) => this.renderDomainRow(domain, preview)), ), h( 'div', @@ -275,13 +283,27 @@ export class ResilienceWidget { ); } - private renderDomainRow(domain: ResilienceDomain): HTMLElement { + private renderDomainRow(domain: ResilienceDomain, preview = false): HTMLElement { const score = clampScore(domain.score); const levelColor = RESILIENCE_VISUAL_LEVEL_COLORS[getResilienceVisualLevel(score)]; + const attrs: Record = { className: 'resilience-widget__domain-row' }; + + if (!preview && domain.id === 'energy' && this.energyMixData?.mixAvailable) { + const d = this.energyMixData; + const parts = [ + `Import dep: ${d.importShare.toFixed(1)}%`, + `Gas: ${d.gasShare.toFixed(1)}%`, + `Coal: ${d.coalShare.toFixed(1)}%`, + `Renew: ${d.renewShare.toFixed(1)}%`, + ]; + if (d.gasStorageAvailable) parts.push(`EU storage: ${d.gasStorageFillPct.toFixed(1)}%`); + attrs['title'] = parts.join(' | '); + } + return h( 'div', - { className: 'resilience-widget__domain-row' }, + attrs, h('span', { className: 'resilience-widget__domain-label' }, getResilienceDomainLabel(domain.id)), this.renderBarBlock(score, levelColor), h('span', { className: 'resilience-widget__domain-score' }, String(Math.round(score))), diff --git a/tests/product-catalog-freshness.test.mjs b/tests/product-catalog-freshness.test.mjs index ef5166750..d0eae058d 100644 --- a/tests/product-catalog-freshness.test.mjs +++ b/tests/product-catalog-freshness.test.mjs @@ -160,6 +160,8 @@ describe('Product ID guard', () => { const result = execSync( `grep -rn 'pdt_' --include='*.ts' --include='*.tsx' --include='*.mjs' --include='*.js' . ` + `| grep -v node_modules ` + + `| grep -v '.claude/worktrees/' ` + + `| grep -v 'convex/_generated/' ` + `| grep -v 'convex/config/productCatalog' ` + `| grep -v 'api/product-catalog' ` + `| grep -v 'api/_product-fallback-prices' ` +