feat: update water level metrics and optimize sidebar UI layout
This commit is contained in:
@@ -6,7 +6,7 @@ import { Helmet } from 'react-helmet-async';
|
||||
import { CircularProgress } from './CircularProgress';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { slugify } from '../utils/slugify';
|
||||
import { AreaChart, Area, ResponsiveContainer } from 'recharts';
|
||||
import { AreaChart, Area, ResponsiveContainer, YAxis } from 'recharts';
|
||||
import { FiTrendingUp, FiTrendingDown } from 'react-icons/fi';
|
||||
|
||||
interface Lake {
|
||||
@@ -80,7 +80,21 @@ const FavoritesOverview = ({ language }: Props) => {
|
||||
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(320px, 1fr))', gap: '1.5rem' }}>
|
||||
{favoriteLakes.map(lake => {
|
||||
const chartData = lake.sparkline.map((val, i) => ({ name: i, value: val }));
|
||||
const isFav = isFavorite(lake.id);
|
||||
|
||||
const minVal = Math.min(...lake.sparkline);
|
||||
const maxVal = Math.max(...lake.sparkline);
|
||||
const diff = maxVal - minVal;
|
||||
const padding = diff === 0 ? 0.1 : diff * 0.1;
|
||||
const yDomain = [minVal - padding, maxVal + padding];
|
||||
|
||||
const firstVal = lake.sparkline[0] || 0;
|
||||
const lastVal = lake.sparkline[lake.sparkline.length - 1] || 0;
|
||||
const trendDiff = lastVal - firstVal;
|
||||
|
||||
let trendColor = 'var(--color-cyan)';
|
||||
if (trendDiff > 0.01) trendColor = 'var(--color-green)';
|
||||
else if (trendDiff < -0.01) trendColor = 'var(--color-red)';
|
||||
|
||||
return (
|
||||
<div
|
||||
key={lake.id}
|
||||
@@ -127,14 +141,31 @@ const FavoritesOverview = ({ language }: Props) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', gap: '1rem', fontSize: '0.85rem' }}>
|
||||
<div style={{ display: 'flex', gap: '0.5rem' }}>
|
||||
<FiTrendingUp color="var(--color-green)" />
|
||||
<span style={{ color: 'var(--text-muted)' }}>{t[language].kpi.inflow} <span style={{ color: 'var(--color-green)' }}>{lake.inflow} m³/s</span></span>
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||
<div style={{ flex: 1, height: '40px', marginRight: '2rem' }}>
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<AreaChart data={chartData}>
|
||||
<defs>
|
||||
<linearGradient id={`colorSparkFav-${lake.id}`} x1="0" y1="0" x2="0" y2="1">
|
||||
<stop offset="5%" stopColor={trendColor} stopOpacity={0.8} />
|
||||
<stop offset="95%" stopColor={trendColor} stopOpacity={0} />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<YAxis domain={yDomain} hide />
|
||||
<Area type="monotone" dataKey="value" stroke={trendColor} fillOpacity={1} fill={`url(#colorSparkFav-${lake.id})`} baseValue={yDomain[0]} />
|
||||
</AreaChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: '0.5rem' }}>
|
||||
<FiTrendingDown color="var(--color-red)" />
|
||||
<span style={{ color: 'var(--text-muted)' }}>{t[language].kpi.outflow} <span style={{ color: 'var(--color-red)' }}>{lake.outflow} m³/s</span></span>
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', fontSize: '0.85rem' }}>
|
||||
<div style={{ display: 'flex', gap: '0.5rem' }}>
|
||||
<FiTrendingUp color="var(--color-green)" />
|
||||
<span style={{ color: 'var(--text-muted)' }}>{t[language].kpi.inflow} <span style={{ color: 'var(--color-green)' }}>{lake.inflow} m³/s</span></span>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: '0.5rem' }}>
|
||||
<FiTrendingDown color="var(--color-red)" />
|
||||
<span style={{ color: 'var(--text-muted)' }}>{t[language].kpi.outflow} <span style={{ color: 'var(--color-red)' }}>{lake.outflow} m³/s</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user