feat(iace): show ESAW evidence panel in risk view (B1)

The Risikobewertung page only mentioned the data sources as static prose.
Add a collapsible "Datenquellen & Evidenz" panel sourced from
/iace/risk-data-sources: the real Eurostat ESAW 2023 contact-mode shares
per mode, with license + ready-to-print attribution, and the note that
tiers anchor the ordering while values stay GT-calibrated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-06-11 14:11:15 +02:00
parent 3c6deac1c5
commit b40edd6d33
3 changed files with 111 additions and 0 deletions
@@ -0,0 +1,59 @@
'use client'
import { useState } from 'react'
import { RiskDataSources as RiskDataSourcesData } from '../_hooks/useRiskDataSources'
/**
* Collapsible evidence panel: the real public-statistics figures (Eurostat ESAW
* 2023) that anchor the W/S tiers, with license + ready-to-print attribution.
* Confidence-aware tonality — informs the source, does not alarm.
*/
export function RiskDataSources({ data }: { data: RiskDataSourcesData }) {
const [open, setOpen] = useState(false)
if (!data.evidence?.length) return null
return (
<div className="rounded-xl border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800">
<button
onClick={() => setOpen(!open)}
className="w-full flex items-center justify-between px-4 py-3 text-left"
>
<span className="text-sm font-medium text-gray-800 dark:text-gray-200">
Datenquellen &amp; Evidenz <span className="text-gray-400 font-normal">({data.evidence.length} belegte Kontaktmodi)</span>
</span>
<span className="text-gray-400 text-xs">{open ? '▲' : '▼'}</span>
</button>
{open && (
<div className="px-4 pb-4 space-y-3">
<p className="text-xs text-gray-500 dark:text-gray-400">{data.note}</p>
<div className="overflow-x-auto">
<table className="w-full text-xs">
<thead>
<tr className="text-gray-500 border-b border-gray-200 dark:border-gray-700 text-left">
<th className="py-1.5 pr-3">Kontaktmodus</th>
<th className="py-1.5 pr-3">Belegte Quote</th>
<th className="py-1.5 pr-3">Quelle</th>
<th className="py-1.5">Lizenz</th>
</tr>
</thead>
<tbody>
{data.evidence.map((e) => (
<tr key={e.mode} className="border-b border-gray-100 dark:border-gray-700/50 align-top">
<td className="py-1.5 pr-3 text-gray-700 dark:text-gray-300 font-medium">{e.label}</td>
<td className="py-1.5 pr-3 text-gray-600 dark:text-gray-300 tabular-nums">{e.stat}</td>
<td className="py-1.5 pr-3 text-gray-500">{e.source}</td>
<td className="py-1.5 text-gray-500">{e.license}</td>
</tr>
))}
</tbody>
</table>
</div>
<p className="text-[10px] text-gray-400">
{data.evidence[0]?.attribution} · Tiers verankern die Quoten-<em>Ordnung</em>; die Werte sind an
BreakPilot-Ground-Truth kalibriert (keine Norm-Tabelle reproduziert).
</p>
</div>
)}
</div>
)
}