Skip to content

Commit

Permalink
Added options to the fancy graph:
Browse files Browse the repository at this point in the history
- add today's date or not
- use first of month or last of month
  • Loading branch information
Theophile-Madet committed Dec 10, 2024
1 parent c19bc43 commit 6ca741b
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 36 deletions.
25 changes: 3 additions & 22 deletions src/statistics/FancyGraphCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,27 +68,6 @@ const FancyGraphCard: React.FC = () => {
setDateFrom(getFirstOfMonth(dateFromOnPageLoad));
}, []);

useEffect(() => {
if (!dateFrom || !dateTo) return;

let currentDate = new Date(dateFrom);
const dates = [];
while (currentDate <= dateTo) {
dates.push(currentDate);
currentDate = new Date(currentDate);
currentDate.setDate(currentDate.getDate() + 32);
currentDate.setDate(1);
}
dates.push(currentDate);

const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
dates.push(tomorrow);

setDates(dates);
setGraphLabels(dates.map((date) => formatDate(date)));
}, [dateFrom, dateTo]);

useEffect(() => {
fillCachedData();
buildAndSetGraphData();
Expand Down Expand Up @@ -253,12 +232,14 @@ const FancyGraphCard: React.FC = () => {
<h5>
{gettext("Graph")} {fetching && <Spinner size={"sm"} />}
</h5>
<span className={"d-flex gap-2"}>
<span className={"d-flex gap-2 align-items-center"}>
<DateRangePicker
dateFrom={dateFrom}
setDateFrom={setDateFrom}
dateTo={dateTo}
setDateTo={setDateTo}
setDates={setDates}
setGraphLabels={setGraphLabels}
/>
<TapirButton
variant={"outline-secondary"}
Expand Down
101 changes: 87 additions & 14 deletions src/statistics/components/DateRangePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import React, { useEffect, useState } from "react";
import { FloatingLabel, Form } from "react-bootstrap";
import { getFirstOfMonth } from "../utils.tsx";
import { getFirstOfMonth, getLastOfMonth } from "../utils.tsx";
import { formatDate } from "../../utils/formatDate.ts";

declare let gettext: (english_text: string) => string;

Expand All @@ -9,27 +10,103 @@ interface DateRangePickerProps {
setDateFrom: (date: Date) => void;
dateTo: Date;
setDateTo: (date: Date) => void;
setDates: (dates: Date[]) => void;
setGraphLabels: (graphLabels: string[]) => void;
}

const DateRangePicker: React.FC<DateRangePickerProps> = ({
dateFrom,
setDateFrom,
dateTo,
setDateTo,
setDates,
setGraphLabels,
}) => {
const [includeToday, setIncludeToday] = useState(true);
const [startOfMonth, setStartOfMonth] = useState(true);

useEffect(() => {
if (!dateFrom || !dateTo) return;

let currentDate = new Date(dateFrom);
const dates = [];
while (currentDate <= dateTo) {
dates.push(currentDate);
currentDate = new Date(currentDate);
currentDate.setDate(currentDate.getDate() + (startOfMonth ? 32 : 1));
currentDate.setDate(1);
currentDate = adaptDate(currentDate);
}
dates.push(currentDate);

if (includeToday) {
const today = new Date();
let todayAlreadyInArray = false;
for (const date of dates) {
if (
date.getDate() === today.getDate() &&
date.getMonth() === today.getMonth() &&
date.getFullYear() === today.getFullYear()
) {
todayAlreadyInArray = true;
break;
}
}
if (!todayAlreadyInArray) {
dates.push(today);
}
}

dates.sort((date1, date2) => date1.getTime() - date2.getTime());

setDates(dates);
setGraphLabels(dates.map((date) => formatDate(date)));
}, [dateFrom, dateTo, includeToday, startOfMonth]);

function adaptDate(date: Date) {
let dateAdapter = getFirstOfMonth;
if (!startOfMonth) {
dateAdapter = getLastOfMonth;
}
return dateAdapter(date);
}

function getDateInputValue(date: Date) {
if (isNaN(date.getTime())) {
return undefined;
}
return date.toISOString().substring(0, 10);
}

return (
<>
<Form.Group>
<Form.Check
type={"switch"}
checked={includeToday}
onChange={(e) => {
setIncludeToday(e.target.checked);
}}
label={"Include today"}
/>
</Form.Group>
<Form.Group>
<Form.Select
onChange={(event) => {
setStartOfMonth(event.target.value === "startOfMonth");
}}
>
<option value={"startOfMonth"}>{gettext("First of month")}</option>
<option value={"lastOfMonth"}>{gettext("Last of month")}</option>
</Form.Select>
</Form.Group>
<Form.Group>
<FloatingLabel label={"Date from"}>
<Form.Control
type={"date"}
value={
!isNaN(dateFrom.getTime())
? dateFrom.toISOString().substring(0, 10)
: undefined
}
value={getDateInputValue(dateFrom)}
onChange={(event) => {
setDateFrom(getFirstOfMonth(new Date(event.target.value)));
setDateFrom(adaptDate(new Date(event.target.value)));
}}
/>
</FloatingLabel>
Expand All @@ -38,13 +115,9 @@ const DateRangePicker: React.FC<DateRangePickerProps> = ({
<FloatingLabel label={"Date to"}>
<Form.Control
type={"date"}
value={
!isNaN(dateTo.getTime())
? dateTo.toISOString().substring(0, 10)
: undefined
}
value={getDateInputValue(dateTo)}
onChange={(event) => {
setDateTo(getFirstOfMonth(new Date(event.target.value)));
setDateTo(adaptDate(new Date(event.target.value)));
}}
/>
</FloatingLabel>
Expand Down
4 changes: 4 additions & 0 deletions src/statistics/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ export function getFirstOfMonth(date: Date) {
date.setDate(1);
return date;
}

export function getLastOfMonth(date: Date) {
return new Date(date.getFullYear(), date.getMonth() + 1, 0);
}

0 comments on commit 6ca741b

Please sign in to comment.