72 lines
2.2 KiB
TypeScript
72 lines
2.2 KiB
TypeScript
import React, { useState, useEffect } from "react";
|
|
import { LineChart, Line, CartesianGrid, XAxis, YAxis } from "recharts";
|
|
import { format, addDays } from "date-fns";
|
|
import {
|
|
formatDate,
|
|
minDate,
|
|
ForecastDatePicker,
|
|
} from "@/components/ui/DatePicker";
|
|
|
|
const fetchWeekForecastData = async function (dateTime, cb) {
|
|
const formattedDate = formatDate(dateTime);
|
|
|
|
const forecastRequests = Array.from({ length: 7 }).map((_, index) => {
|
|
const date = addDays(dateTime, index);
|
|
const formattedDate = format(date, "yyyy-MM-d");
|
|
const url = `http://api.weatherapi.com/v1/future.json?key=bfca7632f8dc4253859120435242301&q=Vienna&dt=${formattedDate}`;
|
|
const dataPromise = fetch(url).then((x) => x.json());
|
|
|
|
return dataPromise;
|
|
});
|
|
|
|
const data = await Promise.all(forecastRequests);
|
|
|
|
const chartData = data.map((forecastData) => {
|
|
const dayData = forecastData.forecast.forecastday[0];
|
|
const date = dayData.date;
|
|
const { avgtemp_c, mintemp_c, maxtemp_c } = dayData.day;
|
|
|
|
return {
|
|
name: date,
|
|
avgtemp_c,
|
|
mintemp_c,
|
|
maxtemp_c,
|
|
};
|
|
});
|
|
|
|
cb(chartData);
|
|
};
|
|
|
|
const WeatherChart = function ({ data }) {
|
|
return (
|
|
<LineChart width={400} height={400} data={data}>
|
|
<Line type="monotone" dataKey="avgtemp_c" stroke="#8884d8" />
|
|
<Line type="monotone" dataKey="mintemp_c" stroke="#8884d8" />
|
|
<Line type="monotone" dataKey="maxtemp_c" stroke="#8884d8" />
|
|
<CartesianGrid stroke="#ccc" />
|
|
<XAxis dataKey="name" />
|
|
<YAxis />
|
|
</LineChart>
|
|
);
|
|
};
|
|
|
|
export const Dashboard = function ({ state, updateState }) {
|
|
const [dateTime, setDateTime] = useState(
|
|
minDate(state?.options?.startDate || new Date()),
|
|
);
|
|
|
|
useEffect(() => {
|
|
fetchWeekForecastData(dateTime, (data) => updateState({ dataCache: data }));
|
|
}, [dateTime]);
|
|
|
|
return (
|
|
<div className="flex p-5 bg-white border border-solid border-slate-300 rounded-lg space-y-5">
|
|
<div>
|
|
<h1 className="text-lg font-medium mb-2">Forecast</h1>
|
|
<ForecastDatePicker dateTime={dateTime} onChange={setDateTime} />
|
|
</div>
|
|
{state.dataCache ? <WeatherChart data={state.dataCache} /> : "Loading..."}
|
|
</div>
|
|
);
|
|
};
|