Move dashboardi into own route

This commit is contained in:
Florian Schroedl
2024-01-23 14:58:25 +01:00
parent e27a78d612
commit 15033f6131
3 changed files with 110 additions and 23 deletions

View File

@@ -1,6 +1,7 @@
import React, { useState, useEffect } from "react";
import { LineChart, Line, CartesianGrid, XAxis, YAxis } from "recharts";
import { format, addDays } from "date-fns";
import { Dashboard } from "@/components/main/routes/Dashboard";
const formatDate = function (dateTime) {
return format(dateTime, "yyyy-MM-dd");
@@ -50,35 +51,19 @@ const WeatherChart = function ({ data }) {
</LineChart>
);
};
const App: React.FC = () => {
const [data, setData] = useState(null);
const minDate = addDays(new Date(), 14);
const maxDate = addDays(new Date(), 300);
const [dateTime, setDateTime] = useState(minDate);
useEffect(() => {
fetchWeekForecastData(dateTime, setData);
}, [dateTime]);
const [options, setOptions] = useState({
lineWidth: undefined,
defaultDate: undefined,
});
return (
<div className="fixed top-0 right-0 bottom-0 left-0 flex">
<main className="flex grow flex-col">
<nav className="flex p-3 border-b border-solid border-slate-300">
<label>
Forecast date (min. of 14 days in advance)
<input
type="date"
value={formatDate(dateTime)}
min={formatDate(minDate)}
max={formatDate(maxDate)}
onChange={(e) => setDateTime(e.target.valueAsDate)}
/>
</label>
</nav>
<nav className="flex p-3 border-b border-solid border-slate-300"></nav>
<div className="flex grow items-center justify-center h-full w-full">
{data ? <WeatherChart data={data} /> : "Loading..."}
<Dashboard startDate={options.defaultDate} />
</div>
</main>
</div>

View File

@@ -0,0 +1,69 @@
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);
console.log(data);
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 ({ startDate = new Date() }) {
const [dateTime, setDateTime] = useState(minDate(startDate));
const [data, setData] = useState(null);
useEffect(() => {
fetchWeekForecastData(dateTime, setData);
}, [dateTime]);
return (
<div>
<ForecastDatePicker dateTime={dateTime} onChange={setDateTime} />
{data ? <WeatherChart data={data} /> : "Loading..."}
</div>
);
};

View File

@@ -0,0 +1,33 @@
import React, { useState, useEffect } from "react";
import { format, addDays } from "date-fns";
export const formatDate = function (dateTime) {
return format(dateTime, "yyyy-MM-dd");
};
export const minDate = function (dateTime) {
return addDays(dateTime, 14);
};
export const maxDate = function (dateTime) {
return addDays(dateTime, 300);
};
export const ForecastDatePicker = function ({
dateTime = new Date(),
onChange,
}) {
console.log(dateTime);
return (
<label>
Forecast date (min. of 14 days in advance)
<input
type="date"
value={formatDate(dateTime)}
min={formatDate(minDate(dateTime))}
max={formatDate(maxDate(dateTime))}
onChange={(e) => onChange(e.target.valueAsDate)}
/>
</label>
);
};