import { FiArrowUp, FiArrowDown } from 'react-icons/fi'; import { TbRipple } from 'react-icons/tb'; import { type Language, t } from '../translations'; import { useState, useEffect } from 'react'; import { CircularProgress } from './CircularProgress'; interface KpiData { level: number; levelDiff24h?: number; levelDiff7d?: number; levelDiff30d?: number; inflow: number; outflow: number; volume: number; currentVolume?: number; fullness: number; storageDiff?: number; minDiff?: number; minDiffLabelCs?: string; minDiffLabelEn?: string; avgInflow24h?: number; avgOutflow24h?: number; } interface Props { data: KpiData; language: Language; lakeName?: string; isRiver?: boolean; } const KpiCards = ({ data, language, lakeName = 'Lipno 1', isRiver = false }: Props) => { const [showTooltip, setShowTooltip] = useState(false); const [showMinTooltip, setShowMinTooltip] = useState(false); const dict = t[language].kpi; const flowDiff = data.inflow - data.outflow; // Graf: pokud přibývá → přítok vs průměr přítoku; pokud ubývá → odtok vs průměr odtoku let visualFlowValue = 0; if (flowDiff >= 0) { // Voda přibývá → jak velký je přítok vůči průměru if (data.avgInflow24h && data.avgInflow24h > 0) { visualFlowValue = Math.min(100, (data.inflow / data.avgInflow24h) * 100); } else if (data.inflow > 0) { visualFlowValue = 50; } } else { // Voda ubývá → jak velký je odtok vůči průměru if (data.avgOutflow24h && data.avgOutflow24h > 0) { visualFlowValue = Math.min(100, (data.outflow / data.avgOutflow24h) * 100); } else if (data.outflow > 0) { visualFlowValue = 50; } } useEffect(() => { if (showTooltip) { const timer = setTimeout(() => { setShowTooltip(false); }, 3500); return () => clearTimeout(timer); } }, [showTooltip]); useEffect(() => { if (showMinTooltip) { const timer = setTimeout(() => { setShowMinTooltip(false); }, 3500); return () => clearTimeout(timer); } }, [showMinTooltip]); if (isRiver) { return ( <> {/* CARD 1: WATER LEVEL */}
{dict.waterLevel} {lakeName}
{data.level.toFixed(0)} cm
1D = 0 ? 'var(--color-green)' : 'var(--color-red)' }}> {(data.levelDiff24h ?? 0) > 0 ? '+' : ''}{(data.levelDiff24h ?? 0).toFixed(0)} cm
7D = 0 ? 'var(--color-green)' : 'var(--color-red)' }}> {(data.levelDiff7d ?? 0) > 0 ? '+' : ''}{(data.levelDiff7d ?? 0).toFixed(0)} cm
30D = 0 ? 'var(--color-green)' : 'var(--color-red)' }}> {(data.levelDiff30d ?? 0) > 0 ? '+' : ''}{(data.levelDiff30d ?? 0).toFixed(0)} cm
{/* CARD 2: FLOW */}
{dict.currentFlow}
{data.outflow.toFixed(1)} m³/s
{data.avgOutflow24h !== undefined && (
Ø 24h: {data.avgOutflow24h.toFixed(1)} m³/s
)}
); } return ( <> {/* CARD 1: WATER LEVEL */}
{dict.level} {lakeName}
{data.level.toFixed(2)} m n. m.
1D = 0 ? 'var(--color-green)' : 'var(--color-red)' }}> {(data.levelDiff24h ?? 0) > 0 ? '+' : ''}{((data.levelDiff24h ?? 0) * 100).toFixed(1)} cm
7D = 0 ? 'var(--color-green)' : 'var(--color-red)' }}> {(data.levelDiff7d ?? 0) > 0 ? '+' : ''}{((data.levelDiff7d ?? 0) * 100).toFixed(1)} cm
30D = 0 ? 'var(--color-green)' : 'var(--color-red)' }}> {(data.levelDiff30d ?? 0) > 0 ? '+' : ''}{((data.levelDiff30d ?? 0) * 100).toFixed(1)} cm
{/* CARD 2: FLOW */}
{dict.flow}
{dict.inflow}: {data.inflow.toFixed(1)} m³/s
{data.avgInflow24h !== undefined && (
Ø 24h: {data.avgInflow24h.toFixed(1)} m³/s
)}
{dict.outflow}: {data.outflow.toFixed(1)} m³/s {flowDiff > 0 ? : flowDiff < 0 ? : null}
{data.avgOutflow24h !== undefined && (
Ø 24h: {data.avgOutflow24h.toFixed(1)} m³/s
)}
{/* Flow Gauge using CircularProgress */}
= 0 ? 'var(--color-green)' : 'var(--color-red)'} />
= 0 ? 'var(--color-green)' : 'var(--color-red)', fontWeight: 'bold', lineHeight: 1.2 }}> {flowDiff > 0 ? '+' : ''}{flowDiff.toFixed(1)} m³/s
{/* CARD 3: CAPACITY */}
{dict.fullness} setShowTooltip(!showTooltip)} style={{ cursor: 'pointer', fontSize: '0.85rem', opacity: 0.6, padding: '0 4px' }} > ⓘ {showTooltip && (
setShowTooltip(false)} style={{ position: 'absolute', bottom: '100%', left: '50%', transform: 'translateX(-50%)', marginBottom: '8px', backgroundColor: 'var(--bg-card)', border: '1px solid var(--border-color)', padding: '0.75rem', borderRadius: '8px', width: '250px', zIndex: 100, boxShadow: '0 4px 12px rgba(0,0,0,0.5)', color: 'var(--text-main)', fontSize: '0.85rem', lineHeight: 1.4, cursor: 'pointer' }}> {language === 'cs' ? "Rozdíl mezi aktuální hladinou a hladinou zásobního prostoru (důležité pro jachtaře a rekreaci)." : "Difference between current water level and storage space level (important for sailing and recreation)."}
)}
{/* Circular Progress Ring */}
{/* Percentage Text */}
{data.fullness > 0 ? `${data.fullness.toFixed(1)}%` : 'N/A'}
{/* Center Data: Main Level Difference */}
{data.storageDiff !== undefined && data.storageDiff !== 0 ? (data.storageDiff > 0 ? `+${data.storageDiff.toFixed(2)}` : `${data.storageDiff.toFixed(2)}`) : ''} m
{/* Bottom Inside Data: Min Diff */} {data.minDiff !== undefined && (
setShowMinTooltip(!showMinTooltip)} > {data.minDiff.toFixed(2)} m {showMinTooltip && (
{ e.stopPropagation(); setShowMinTooltip(false); }} style={{ position: 'absolute', top: '100%', left: '50%', transform: 'translateX(-50%)', marginTop: '8px', backgroundColor: 'var(--bg-card)', border: '1px solid var(--border-color)', padding: '0.75rem', borderRadius: '8px', width: '220px', zIndex: 100, boxShadow: '0 4px 12px rgba(0,0,0,0.5)', color: 'var(--text-main)', fontSize: '0.85rem', lineHeight: 1.4, cursor: 'pointer', whiteSpace: 'normal', textAlign: 'center', fontWeight: 'normal', textShadow: 'none' }}> {language === 'cs' ? (data.minDiffLabelCs || 'K minimu') : (data.minDiffLabelEn || 'To min')}
)}
)}
{/* Bottom Elements */}
{dict.volume}: {data.currentVolume !== undefined && data.volume > 0 ? `${data.currentVolume.toFixed(1)} / ` : ''}{data.volume.toFixed(1)} mil. m³
); }; export default KpiCards;