feat: update lake data and optimize weather widget rendering
This commit is contained in:
+2
-2
@@ -219,7 +219,7 @@
|
||||
.kpi-card {
|
||||
background-color: var(--bg-card);
|
||||
border-radius: 0.75rem;
|
||||
padding: 1.25rem 1.5rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border: 1px solid var(--border-color);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -440,7 +440,7 @@
|
||||
}
|
||||
|
||||
.kpi-card {
|
||||
padding: 1rem;
|
||||
padding: 0.6rem 1rem;
|
||||
}
|
||||
|
||||
.kpi-value {
|
||||
|
||||
+19
-19
@@ -75,14 +75,14 @@ const KpiCards = ({ data, language, lakeName = 'Lipno 1', isRiver = false }: Pro
|
||||
return (
|
||||
<>
|
||||
{/* CARD 1: WATER LEVEL */}
|
||||
<div className="kpi-card">
|
||||
<div className="kpi-card" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
|
||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '1rem' }}>
|
||||
{dict.waterLevel} {lakeName}
|
||||
</div>
|
||||
<div style={{ fontSize: '2.5rem', fontWeight: 'bold', color: 'var(--color-cyan)', lineHeight: 1, whiteSpace: 'nowrap' }}>
|
||||
{data.level.toFixed(0)} <span style={{ fontSize: '1rem', color: 'var(--text-muted)', fontWeight: 'normal' }}>cm</span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.3rem', alignContent: 'flex-start', marginTop: '0.5rem' }}>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.3rem', justifyContent: 'center', marginTop: '0.5rem' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.3rem', background: 'rgba(0,0,0,0.15)', padding: '0.2rem 0.4rem', borderRadius: '6px' }}>
|
||||
<span style={{ fontSize: '0.75rem', color: 'var(--text-muted)', fontWeight: 'bold' }}>1D</span>
|
||||
<span style={{ fontSize: '0.85rem', fontWeight: 'bold', color: (data.levelDiff24h ?? 0) >= 0 ? 'var(--color-green)' : 'var(--color-red)' }}>
|
||||
@@ -105,12 +105,12 @@ const KpiCards = ({ data, language, lakeName = 'Lipno 1', isRiver = false }: Pro
|
||||
</div>
|
||||
|
||||
{/* CARD 2: FLOW */}
|
||||
<div className="kpi-card">
|
||||
<div className="kpi-card" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
|
||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '1rem' }}>
|
||||
{dict.currentFlow}
|
||||
</div>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div>
|
||||
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '1.5rem', width: '100%' }}>
|
||||
<div style={{ textAlign: 'left' }}>
|
||||
<div style={{ fontSize: '2.5rem', fontWeight: 'bold', color: 'var(--color-cyan)', lineHeight: 1, whiteSpace: 'nowrap', marginBottom: '0.5rem' }}>
|
||||
{data.outflow.toFixed(1)} <span style={{ fontSize: '1.25rem', color: 'var(--text-muted)', fontWeight: 'normal' }}>m³/s</span>
|
||||
</div>
|
||||
@@ -138,14 +138,14 @@ const KpiCards = ({ data, language, lakeName = 'Lipno 1', isRiver = false }: Pro
|
||||
return (
|
||||
<>
|
||||
{/* CARD 1: WATER LEVEL */}
|
||||
<div className="kpi-card">
|
||||
<div className="kpi-card" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
|
||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '1rem' }}>
|
||||
{dict.level} {lakeName}
|
||||
</div>
|
||||
<div style={{ fontSize: '2.5rem', fontWeight: 'bold', color: 'var(--color-cyan)', lineHeight: 1, whiteSpace: 'nowrap' }}>
|
||||
{data.level.toFixed(2)} <span style={{ fontSize: '1rem', color: 'var(--text-muted)', fontWeight: 'normal' }}>m n. m.</span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.3rem', alignContent: 'flex-start' }}>
|
||||
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '0.3rem', justifyContent: 'center' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.3rem', background: 'rgba(0,0,0,0.15)', padding: '0.2rem 0.4rem', borderRadius: '6px' }}>
|
||||
<span style={{ fontSize: '0.75rem', color: 'var(--text-muted)', fontWeight: 'bold' }}>1D</span>
|
||||
<span style={{ fontSize: '0.85rem', fontWeight: 'bold', color: (data.levelDiff24h ?? 0) >= 0 ? 'var(--color-green)' : 'var(--color-red)' }}>
|
||||
@@ -168,12 +168,12 @@ const KpiCards = ({ data, language, lakeName = 'Lipno 1', isRiver = false }: Pro
|
||||
</div>
|
||||
|
||||
{/* CARD 2: FLOW */}
|
||||
<div className="kpi-card">
|
||||
<div className="kpi-card" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
|
||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '1rem' }}>
|
||||
{dict.flow}
|
||||
</div>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.85rem' }}>
|
||||
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', gap: '1.5rem', width: '100%' }}>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.85rem', textAlign: 'left' }}>
|
||||
<div style={{ fontSize: '0.85rem', color: 'var(--text-muted)', display: 'flex', alignItems: 'center', whiteSpace: 'nowrap' }}>
|
||||
<span style={{ display: 'inline-block', width: '8px', height: '8px', borderRadius: '50%', backgroundColor: 'var(--color-green)', marginRight: '6px', flexShrink: 0 }}></span>
|
||||
{dict.inflow}: <span style={{ fontWeight: 'bold', color: 'var(--text-main)', marginLeft: '4px' }}>{data.inflow.toFixed(1)} m³/s</span>
|
||||
@@ -196,27 +196,27 @@ const KpiCards = ({ data, language, lakeName = 'Lipno 1', isRiver = false }: Pro
|
||||
</div>
|
||||
|
||||
{/* Flow Gauge using CircularProgress */}
|
||||
<div style={{ position: 'relative', width: '70px', height: '70px', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<div style={{ position: 'relative', width: '90px', height: '90px', flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
||||
<div style={{ position: 'absolute', top: 0, left: 0 }}>
|
||||
<CircularProgress
|
||||
value={visualFlowValue || 0.1}
|
||||
size={70}
|
||||
strokeWidth={6}
|
||||
size={90}
|
||||
strokeWidth={7}
|
||||
hideText={true}
|
||||
color={flowDiff >= 0 ? 'var(--color-green)' : 'var(--color-red)'}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', color: flowDiff >= 0 ? 'var(--color-green)' : 'var(--color-red)', fontWeight: 'bold', lineHeight: 1.2 }}>
|
||||
<span style={{ fontSize: '0.85rem' }}>{flowDiff > 0 ? '+' : ''}{flowDiff.toFixed(1)}</span>
|
||||
<span style={{ fontSize: '0.6rem', opacity: 0.8 }}>m³/s</span>
|
||||
<span style={{ fontSize: '1rem' }}>{flowDiff > 0 ? '+' : ''}{flowDiff.toFixed(1)}</span>
|
||||
<span style={{ fontSize: '0.65rem', opacity: 0.8 }}>m³/s</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* CARD 3: CAPACITY */}
|
||||
<div className="kpi-card" style={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.4rem', position: 'relative' }}>
|
||||
<div className="kpi-card" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
|
||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '1rem', display: 'flex', alignItems: 'center', gap: '0.4rem', justifyContent: 'center', position: 'relative', width: '100%' }}>
|
||||
{dict.fullness}
|
||||
<span
|
||||
onClick={() => setShowTooltip(!showTooltip)}
|
||||
@@ -258,7 +258,7 @@ const KpiCards = ({ data, language, lakeName = 'Lipno 1', isRiver = false }: Pro
|
||||
</div>
|
||||
|
||||
{/* Percentage Text */}
|
||||
<div style={{ position: 'absolute', top: '24px', left: '50%', transform: 'translateX(-50%)', zIndex: 10, fontSize: '0.95rem', fontWeight: 'bold', color: 'var(--text-main)', textShadow: '0 2px 10px rgba(0,0,0,0.5)' }}>
|
||||
<div style={{ position: 'absolute', top: '18px', left: '50%', transform: 'translateX(-50%)', zIndex: 10, fontSize: '0.95rem', fontWeight: 'bold', color: 'var(--text-main)', textShadow: '0 2px 10px rgba(0,0,0,0.5)' }}>
|
||||
{data.fullness > 0 ? `${data.fullness.toFixed(1)}%` : 'N/A'}
|
||||
</div>
|
||||
|
||||
@@ -273,7 +273,7 @@ const KpiCards = ({ data, language, lakeName = 'Lipno 1', isRiver = false }: Pro
|
||||
{/* Bottom Inside Data: Min Diff */}
|
||||
{data.minDiff !== undefined && (
|
||||
<div
|
||||
style={{ position: 'absolute', bottom: '26px', left: '50%', transform: 'translateX(-50%)', zIndex: 20, fontSize: '0.9rem', fontWeight: 'bold', color: data.minDiff < 0.5 ? 'var(--color-red)' : 'var(--color-green)', cursor: 'pointer', textShadow: '0 2px 10px rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', gap: '0.25rem' }}
|
||||
style={{ position: 'absolute', bottom: '26px', left: '50%', transform: 'translateX(-50%)', zIndex: 20, fontSize: '0.9rem', fontWeight: 'bold', color: data.minDiff < 0.5 ? 'var(--color-red)' : 'var(--color-green)', cursor: 'pointer', textShadow: '0 2px 10px rgba(0,0,0,0.5)', display: 'flex', alignItems: 'center', gap: '0.25rem', whiteSpace: 'nowrap' }}
|
||||
onClick={() => setShowMinTooltip(!showMinTooltip)}
|
||||
>
|
||||
<span>{data.minDiff.toFixed(2)} m</span>
|
||||
|
||||
@@ -16,6 +16,7 @@ interface WeatherData {
|
||||
windDir: number; // degrees
|
||||
sunrise: string;
|
||||
sunset: string;
|
||||
time?: string;
|
||||
}
|
||||
|
||||
const getCompassDirection = (degrees: number, language: 'cs' | 'en') => {
|
||||
@@ -28,8 +29,17 @@ const getCompassDirection = (degrees: number, language: 'cs' | 'en') => {
|
||||
|
||||
const formatTime = (isoString: string) => {
|
||||
if (!isoString) return '--:--';
|
||||
const date = new Date(isoString);
|
||||
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||
try {
|
||||
const match = isoString.match(/T(\d{2}:\d{2})/);
|
||||
if (match) return match[1];
|
||||
const date = new Date(isoString);
|
||||
if (isNaN(date.getTime())) {
|
||||
return isoString;
|
||||
}
|
||||
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||
} catch (e) {
|
||||
return '--:--';
|
||||
}
|
||||
};
|
||||
|
||||
export const WeatherWidget = ({ lat, lng, language, sensorTemp, windUnit = 'kmh' }: WeatherProps) => {
|
||||
@@ -37,6 +47,12 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp, windUnit = 'kmh'
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
console.log("Weather data loaded:", data);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!lat || !lng) {
|
||||
setLoading(false);
|
||||
@@ -49,7 +65,7 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp, windUnit = 'kmh'
|
||||
setLoading(true);
|
||||
const res = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}¤t=temperature_2m,wind_speed_10m,wind_direction_10m,wind_gusts_10m&daily=sunrise,sunset&timezone=auto&wind_speed_unit=${windUnit}`);
|
||||
if (!res.ok) throw new Error('Failed to fetch weather');
|
||||
|
||||
|
||||
const json = await res.json();
|
||||
setData({
|
||||
temp: json.current.temperature_2m,
|
||||
@@ -57,7 +73,8 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp, windUnit = 'kmh'
|
||||
windGusts: json.current.wind_gusts_10m,
|
||||
windDir: json.current.wind_direction_10m,
|
||||
sunrise: json.daily.sunrise[0],
|
||||
sunset: json.daily.sunset[0]
|
||||
sunset: json.daily.sunset[0],
|
||||
time: json.current.time
|
||||
});
|
||||
setError(false);
|
||||
} catch (err) {
|
||||
@@ -69,15 +86,15 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp, windUnit = 'kmh'
|
||||
};
|
||||
|
||||
fetchWeather();
|
||||
|
||||
|
||||
// Refresh weather every 15 minutes
|
||||
const interval = setInterval(fetchWeather, 15 * 60 * 1000);
|
||||
return () => clearInterval(interval);
|
||||
}, [lat, lng, windUnit]);
|
||||
|
||||
const dict = {
|
||||
cs: { title: 'Počasí a Vítr (Aktuálně)', error: 'Data nedostupná', wind: 'Vítr', gusts: 'Nárazy', temp: 'Teplota' },
|
||||
en: { title: 'Weather & Wind (Current)', error: 'Data unavailable', wind: 'Wind', gusts: 'Gusts', temp: 'Temp' }
|
||||
cs: { title: 'POČASÍ A VÍTR', error: 'Data nedostupná', wind: 'Vítr', gusts: 'Nárazy', temp: 'Teplota' },
|
||||
en: { title: 'WEATHER & WIND', error: 'Data unavailable', wind: 'Wind', gusts: 'Gusts', temp: 'Temp' }
|
||||
}[language];
|
||||
|
||||
if (loading) {
|
||||
@@ -96,76 +113,81 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp, windUnit = 'kmh'
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="kpi-card" style={{ display: 'flex', flexDirection: 'column' }}>
|
||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '1rem' }}>{dict.title}</div>
|
||||
|
||||
<div style={{ position: 'relative', display: 'flex', justifyContent: 'center', alignItems: 'center', height: '170px', marginTop: '-1.5rem' }}>
|
||||
|
||||
{/* SVG Compass Ring */}
|
||||
<svg width="180" height="180" viewBox="0 0 260 260" style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)' }}>
|
||||
<circle cx="130" cy="130" r="100" fill="transparent" stroke="rgba(255,255,255,0.03)" strokeWidth="30" />
|
||||
|
||||
{/* Generate Ticks */}
|
||||
{Array.from({ length: 72 }).map((_, i) => {
|
||||
const angle = i * 5;
|
||||
const isMajor = angle % 90 === 0;
|
||||
const isMedium = angle % 45 === 0;
|
||||
const innerR = isMajor ? 90 : isMedium ? 100 : 105;
|
||||
const outerR = 115;
|
||||
const rad = (angle - 90) * (Math.PI / 180);
|
||||
const x1 = 130 + innerR * Math.cos(rad);
|
||||
const y1 = 130 + innerR * Math.sin(rad);
|
||||
const x2 = 130 + outerR * Math.cos(rad);
|
||||
const y2 = 130 + outerR * Math.sin(rad);
|
||||
|
||||
if (isMajor) return null; // Put text here instead
|
||||
<div className="kpi-card" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center' }}>
|
||||
<div style={{ fontSize: '1rem', color: 'var(--text-muted)', marginBottom: '1rem' }}>
|
||||
{dict.title} {data.time ? `(${formatTime(data.time)})` : ''}
|
||||
</div>
|
||||
|
||||
return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} stroke="rgba(255,255,255,0.15)" strokeWidth={isMedium ? 2 : 1} />;
|
||||
})}
|
||||
|
||||
<text x="130" y="25" fill="var(--text-muted)" fontSize="18" fontWeight="bold" textAnchor="middle" alignmentBaseline="middle">{language === 'cs' ? 'S' : 'N'}</text>
|
||||
<text x="235" y="130" fill="var(--text-muted)" fontSize="18" fontWeight="bold" textAnchor="middle" alignmentBaseline="middle">{language === 'cs' ? 'V' : 'E'}</text>
|
||||
<text x="130" y="235" fill="var(--text-muted)" fontSize="18" fontWeight="bold" textAnchor="middle" alignmentBaseline="middle">{language === 'cs' ? 'J' : 'S'}</text>
|
||||
<text x="25" y="130" fill="var(--text-muted)" fontSize="18" fontWeight="bold" textAnchor="middle" alignmentBaseline="middle">{language === 'cs' ? 'Z' : 'W'}</text>
|
||||
|
||||
{/* Direction Indicator */}
|
||||
{(() => {
|
||||
const dirRad = (data.windDir + 180 - 90) * (Math.PI / 180);
|
||||
const x = 130 + 94 * Math.cos(dirRad);
|
||||
const y = 130 + 94 * Math.sin(dirRad);
|
||||
return (
|
||||
<g transform={`translate(${x}, ${y}) rotate(${data.windDir})`}>
|
||||
<path d="M-8,-8 L0,8 L8,-8 L0,-4 Z" fill="var(--color-cyan)" />
|
||||
</g>
|
||||
);
|
||||
})()}
|
||||
</svg>
|
||||
<div style={{ position: 'relative', display: 'flex', justifyContent: 'center', alignItems: 'center', height: '160px', marginTop: '-1rem', width: '100%' }}>
|
||||
|
||||
{/* Center Data */}
|
||||
<FiWind size={26} color="var(--color-cyan)" style={{ position: 'absolute', top: '26px', left: '50%', transform: 'translateX(-50%)', zIndex: 10 }} />
|
||||
|
||||
<div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', marginTop: '-6px', zIndex: 10, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||||
<span style={{ fontSize: '2.8rem', fontWeight: 'bold', color: 'var(--text-main)', lineHeight: 1, textShadow: '0 2px 10px rgba(0,0,0,0.5)' }}>{data.windSpeed.toFixed(1)}</span>
|
||||
<span style={{ position: 'absolute', left: '100%', bottom: '0.3rem', marginLeft: '0.2rem', fontSize: '0.9rem', color: 'var(--text-main)', whiteSpace: 'nowrap' }}>{windUnit === 'kmh' ? 'km/h' : 'm/s'}</span>
|
||||
{/* Compass and Wind Info Wrapper */}
|
||||
<div style={{ position: 'absolute', width: '160px', height: '160px', top: '44%', left: '50%', transform: 'translate(-50%, -50%)' }}>
|
||||
{/* SVG Compass Ring */}
|
||||
<svg width="160" height="160" viewBox="0 0 260 260" style={{ position: 'absolute', top: 0, left: 0 }}>
|
||||
<circle cx="130" cy="130" r="100" fill="transparent" stroke="rgba(255,255,255,0.03)" strokeWidth="30" />
|
||||
|
||||
{/* Generate Ticks */}
|
||||
{Array.from({ length: 72 }).map((_, i) => {
|
||||
const angle = i * 5;
|
||||
const isMajor = angle % 90 === 0;
|
||||
const isMedium = angle % 45 === 0;
|
||||
const innerR = isMajor ? 90 : isMedium ? 100 : 105;
|
||||
const outerR = 115;
|
||||
const rad = (angle - 90) * (Math.PI / 180);
|
||||
const x1 = 130 + innerR * Math.cos(rad);
|
||||
const y1 = 130 + innerR * Math.sin(rad);
|
||||
const x2 = 130 + outerR * Math.cos(rad);
|
||||
const y2 = 130 + outerR * Math.sin(rad);
|
||||
|
||||
if (isMajor) return null; // Put text here instead
|
||||
|
||||
return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} stroke="rgba(255,255,255,0.15)" strokeWidth={isMedium ? 2 : 1} />;
|
||||
})}
|
||||
|
||||
<text x="130" y="25" fill="var(--text-muted)" fontSize="18" fontWeight="bold" textAnchor="middle" alignmentBaseline="middle">{language === 'cs' ? 'S' : 'N'}</text>
|
||||
<text x="235" y="130" fill="var(--text-muted)" fontSize="18" fontWeight="bold" textAnchor="middle" alignmentBaseline="middle">{language === 'cs' ? 'V' : 'E'}</text>
|
||||
<text x="130" y="235" fill="var(--text-muted)" fontSize="18" fontWeight="bold" textAnchor="middle" alignmentBaseline="middle">{language === 'cs' ? 'J' : 'S'}</text>
|
||||
<text x="25" y="130" fill="var(--text-muted)" fontSize="18" fontWeight="bold" textAnchor="middle" alignmentBaseline="middle">{language === 'cs' ? 'Z' : 'W'}</text>
|
||||
|
||||
{/* Direction Indicator */}
|
||||
{(() => {
|
||||
const dirRad = (data.windDir + 180 - 90) * (Math.PI / 180);
|
||||
const x = 130 + 94 * Math.cos(dirRad);
|
||||
const y = 130 + 94 * Math.sin(dirRad);
|
||||
return (
|
||||
<g transform={`translate(${x}, ${y}) rotate(${data.windDir})`}>
|
||||
<path d="M-5,-5 L0,5 L5,-5 L0,-3 Z" fill="var(--color-cyan)" />
|
||||
</g>
|
||||
);
|
||||
})()}
|
||||
</svg>
|
||||
|
||||
{/* Center Data */}
|
||||
<FiWind size={20} color="var(--color-cyan)" style={{ position: 'absolute', top: '28px', left: '50%', transform: 'translateX(-50%)', zIndex: 10 }} />
|
||||
|
||||
<div style={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', marginTop: '-6px', zIndex: 10, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||||
<span style={{ fontSize: '1.9rem', fontWeight: 'bold', color: 'var(--text-main)', lineHeight: 1, textShadow: '0 2px 10px rgba(0,0,0,0.5)' }}>{data.windSpeed.toFixed(1)}</span>
|
||||
<span style={{ position: 'absolute', left: '100%', bottom: '0.3rem', marginLeft: '0.2rem', fontSize: '0.75rem', color: 'var(--text-main)', whiteSpace: 'nowrap' }}>{windUnit === 'kmh' ? 'km/h' : 'm/s'}</span>
|
||||
</div>
|
||||
|
||||
<div style={{ position: 'absolute', bottom: '42px', left: '50%', transform: 'translateX(-50%)', zIndex: 10, fontSize: '0.6rem', color: 'var(--color-purple)', whiteSpace: 'nowrap' }}>
|
||||
{dict.gusts}: {data.windGusts.toFixed(1)} {windUnit === 'kmh' ? 'km/h' : 'm/s'}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ position: 'absolute', bottom: '50px', left: '50%', transform: 'translateX(-50%)', zIndex: 10, fontSize: '0.75rem', color: 'var(--color-purple)', whiteSpace: 'nowrap' }}>
|
||||
{dict.gusts}: {data.windGusts.toFixed(1)} {windUnit === 'kmh' ? 'km/h' : 'm/s'}
|
||||
</div>
|
||||
|
||||
{/* Corner Elements */}
|
||||
<div style={{ position: 'absolute', bottom: '0px', left: '0px', display: 'flex', alignItems: 'center', gap: '0.4rem', fontSize: '1rem' }} title={sensorTemp !== undefined ? (language === 'cs' ? 'Měřeno přímo senzorem na hrázi' : 'Measured by sensor at the dam') : 'OpenMeteo API'}>
|
||||
<FiThermometer color="var(--color-orange)" size={18} />
|
||||
<div style={{ position: 'absolute', bottom: '0px', left: '0px', display: 'flex', alignItems: 'center', gap: '0.3rem', fontSize: '0.9rem' }} title={sensorTemp !== undefined ? (language === 'cs' ? 'Měřeno přímo senzorem na hrázi' : 'Measured by sensor at the dam') : 'OpenMeteo API'}>
|
||||
<FiThermometer color="var(--color-orange)" size={15} />
|
||||
<span style={{ fontWeight: 'bold', color: 'var(--text-main)' }}>{sensorTemp !== undefined ? sensorTemp.toFixed(1) : data.temp.toFixed(1)} °C</span>
|
||||
</div>
|
||||
|
||||
<div style={{ position: 'absolute', bottom: '0px', right: '0px', display: 'flex', flexDirection: 'column', gap: '0.3rem', fontSize: '0.9rem' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', color: 'var(--text-main)' }}>
|
||||
<FiSunrise color="var(--color-orange)" size={16} />
|
||||
<div style={{ position: 'absolute', bottom: '0px', right: '0px', display: 'flex', flexDirection: 'column', gap: '0.2rem', fontSize: '0.8rem' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.3rem', color: 'var(--text-main)' }}>
|
||||
<FiSunrise color="var(--color-orange)" size={14} />
|
||||
<span style={{ fontWeight: 'bold' }}>{formatTime(data.sunrise)}</span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.4rem', color: 'var(--text-main)' }}>
|
||||
<FiSunset color="var(--color-orange)" size={16} />
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.3rem', color: 'var(--text-main)' }}>
|
||||
<FiSunset color="var(--color-orange)" size={14} />
|
||||
<span style={{ fontWeight: 'bold' }}>{formatTime(data.sunset)}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
background-color: var(--bg-card);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user