Weather Station / ECOWITT / DNT
0

Configure Feed

Select the types of activity you want to include in your feed.

optimization 2

+17 -9
+6 -4
src/app/api/forecast/analysis/route.ts
··· 12 12 try { 13 13 const { searchParams } = new URL(req.url); 14 14 const stationId = searchParams.get("stationId"); 15 - const daysParam = Number(searchParams.get("days") || "30"); 16 - const days = Number.isFinite(daysParam) && daysParam > 0 ? Math.min(Math.floor(daysParam), 3650) : 30; 15 + const daysRaw = searchParams.get("days") || "30"; 16 + const allDays = daysRaw === "all"; 17 + const daysParam = Number(daysRaw); 18 + const days = allDays ? null : Number.isFinite(daysParam) && daysParam > 0 ? Math.min(Math.floor(daysParam), 3650) : 30; 17 19 18 20 if (!stationId) { 19 21 return NextResponse.json({ error: "stationId parameter is required" }, { status: 400 }); ··· 55 57 forecast_wind_speed 56 58 FROM forecast_analysis 57 59 WHERE station_id = ${sqlLiteral(stationId)} 58 - AND analysis_date >= CURRENT_DATE - INTERVAL '${days}' DAYS 60 + ${days === null ? "" : `AND analysis_date >= CURRENT_DATE - INTERVAL '${days}' DAYS`} 59 61 ORDER BY analysis_date DESC, forecast_date DESC, source 60 62 `; 61 63 ··· 124 126 125 127 const payload = { 126 128 stationId, 127 - days, 129 + days: days === null ? "all" : days, 128 130 dailyAnalysis: Object.values(byDate), 129 131 accuracyStats, 130 132 generated: new Date().toISOString(),
+6 -4
src/components/ForecastAnalysis.tsx
··· 6 6 7 7 interface ForecastAccuracyData { 8 8 stationId: string; 9 - days: number; 9 + days: number | "all"; 10 10 data: { 11 11 dailyComparisons: DailyComparison[]; 12 12 accuracyStats: AccuracyStats; ··· 50 50 const { t, i18n } = useTranslation(); 51 51 const locale = i18n.language === "en" ? "en-GB" : "de-DE"; 52 52 const [stationId, setStationId] = useState(""); 53 - const [days, setDays] = useState(30); 53 + const [days, setDays] = useState<number | "all">(30); 54 54 const [data, setData] = useState<ForecastAccuracyData | null>(null); 55 55 const [loading, setLoading] = useState(true); // Start with loading true 56 56 const [error, setError] = useState<string | null>(null); ··· 193 193 <div> 194 194 <label className="block text-sm font-medium mb-1">{t("analysis.daysLabel")}</label> 195 195 <select 196 - value={days} 197 - onChange={(e) => setDays(parseInt(e.target.value))} 196 + value={String(days)} 197 + onChange={(e) => setDays(e.target.value === "all" ? "all" : parseInt(e.target.value))} 198 198 className="border rounded px-3 py-2" 199 199 > 200 200 <option value={7}>{t("analysis.days7")}</option> 201 201 <option value={14}>{t("analysis.days14")}</option> 202 202 <option value={30}>{t("analysis.days30")}</option> 203 203 <option value={60}>{t("analysis.days60")}</option> 204 + <option value={90}>{t("analysis.days90")}</option> 205 + <option value="all">{t("analysis.daysAll")}</option> 204 206 </select> 205 207 </div> 206 208
+2
src/locales/de/common.json
··· 194 194 "days14": "14 Tage", 195 195 "days30": "30 Tage", 196 196 "days60": "60 Tage", 197 + "days90": "90 Tage", 198 + "daysAll": "Alles", 197 199 "sourceGeosphere": "Geosphere 🇦🇹", 198 200 "sourceOpenweather": "OpenWeatherMap 🌍", 199 201 "sourceMeteoblue": "Meteoblue 🇨🇭",
+3 -1
src/locales/en/common.json
··· 193 193 "days7": "7 days", 194 194 "days14": "14 days", 195 195 "days30": "30 days", 196 - "days60": "60 days" 196 + "days60": "60 days", 197 + "days90": "90 days", 198 + "daysAll": "All" 197 199 }, 198 200 "weather": { 199 201 "clear": "Clear",