import { useEffect, useState } from 'react'; import { Maximize2 } from 'lucide-react'; import SourceLink, { DataSource } from './SourceLink'; import { DrillDownModal, DrillDownData } from './DrillDownModal'; interface DataPanelProps { title: string; value: string | number; subtitle?: string; trend?: 'up' | 'down' | 'stable'; animate?: boolean; source?: DataSource; /** Enable drill-down capability */ drillDown?: DrillDownData; /** Backend endpoint for fetching detailed data */ drillDownEndpoint?: string; } const DataPanel = ({ title, value, subtitle, trend, animate = true, source, drillDown, drillDownEndpoint }: DataPanelProps) => { const [displayValue, setDisplayValue] = useState(animate ? '---' : value); const [showDrillDown, setShowDrillDown] = useState(false); // Build drill-down data from props const drillDownData: DrillDownData = drillDown || { id: title.toLowerCase().replace(/\s+/g, '-'), title: title, description: subtitle, endpoint: drillDownEndpoint, metrics: [ { label: 'Nuværende værdi', value: String(value), trend } ], details: { title, value, subtitle, trend, source: source?.name } }; const hasDrillDown = drillDown || drillDownEndpoint; useEffect(() => { if (!animate) return; const chars = '0123456789ABCDEF'; let iterations = 0; const maxIterations = 10; const interval = setInterval(() => { if (iterations >= maxIterations) { setDisplayValue(value); clearInterval(interval); return; } setDisplayValue( String(value) .split('') .map((char, index) => { if (index < iterations) return char; return chars[Math.floor(Math.random() * chars.length)]; }) .join('') ); iterations++; }, 50); return () => clearInterval(interval); }, [value, animate]); return ( <>
setShowDrillDown(true) : undefined} >
{title}
{hasDrillDown && ( )} {source && } {trend && ( {trend === 'up' ? '▲' : trend === 'down' ? '▼' : '●'} )}
{displayValue}
{subtitle && (

{subtitle}

{source && }
)} {/* Scan line on hover */}
{/* Drill-Down Modal */} {hasDrillDown && ( setShowDrillDown(false)} data={drillDownData} /> )} ); }; export default DataPanel;