feat: implement multilingual SEO support and enhance map UI with data synchronization updates

This commit is contained in:
David Fencl
2026-06-06 17:24:30 +02:00
parent 66021e001e
commit 6395df1992
30 changed files with 3036 additions and 280 deletions
+7 -6
View File
@@ -6,6 +6,7 @@ interface WeatherProps {
lng: number;
language: 'cs' | 'en';
sensorTemp?: number;
windUnit?: 'kmh' | 'ms';
}
interface WeatherData {
@@ -31,7 +32,7 @@ const formatTime = (isoString: string) => {
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
};
export const WeatherWidget = ({ lat, lng, language, sensorTemp }: WeatherProps) => {
export const WeatherWidget = ({ lat, lng, language, sensorTemp, windUnit = 'kmh' }: WeatherProps) => {
const [data, setData] = useState<WeatherData | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
@@ -46,7 +47,7 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp }: WeatherProps)
const fetchWeather = async () => {
try {
setLoading(true);
const res = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}&current=temperature_2m,wind_speed_10m,wind_direction_10m,wind_gusts_10m&daily=sunrise,sunset&timezone=auto&wind_speed_unit=ms`);
const res = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}&current=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();
@@ -98,7 +99,7 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp }: WeatherProps)
<div className="kpi-card" style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center' }}>
<h3 style={{ fontSize: '1rem', color: 'var(--text-muted)', margin: '0 0 1rem 0' }}>{dict.title}</h3>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1.5rem' }}>
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '0.5rem', alignItems: 'center' }}>
{/* Left Column: Wind */}
<div style={{ display: 'flex', alignItems: 'flex-start', gap: '1rem' }}>
@@ -113,16 +114,16 @@ export const WeatherWidget = ({ lat, lng, language, sensorTemp }: WeatherProps)
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div style={{ fontSize: '1.5rem', fontWeight: 'bold', lineHeight: 1.1, color: 'var(--text-main)' }}>
{data.windSpeed.toFixed(1)} <span style={{ fontSize: '0.8rem', color: 'var(--text-muted)', fontWeight: 'normal' }}>m/s</span>
{data.windSpeed.toFixed(1)} <span style={{ fontSize: '0.8rem', color: 'var(--text-muted)', fontWeight: 'normal' }}>{windUnit === 'kmh' ? 'km/h' : 'm/s'}</span>
</div>
<div style={{ fontSize: '0.8rem', color: 'var(--text-muted)', marginTop: '4px' }}>
{getCompassDirection(data.windDir, language)} {dict.gusts}: <span style={{ color: data.windGusts > 10 ? 'var(--color-red)' : 'var(--text-main)' }}>{data.windGusts.toFixed(1)} m/s</span>
{getCompassDirection(data.windDir, language)} {dict.gusts}: <span style={{ color: data.windGusts > (windUnit === 'kmh' ? 50 : 13.8) ? 'var(--color-red)' : 'var(--text-main)' }}>{data.windGusts.toFixed(1)} {windUnit === 'kmh' ? 'km/h' : 'm/s'}</span>
</div>
</div>
</div>
{/* Right Column: Other Info */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem', borderLeft: '1px solid var(--border-color)', paddingLeft: '1.5rem' }}>
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem', borderLeft: '1px solid var(--border-color)', paddingLeft: '1rem' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.5rem', 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)" />
<span style={{ fontWeight: 'bold' }}>{sensorTemp !== undefined ? sensorTemp.toFixed(1) : data.temp.toFixed(1)} °C</span>