bananas-commerce-admin
Version:
What's this, an admin for apes?
153 lines • 6.33 kB
JavaScript
import React, { useCallback, useState } from "react";
import { useSearchParams } from "react-router-dom";
import { DateTime } from "luxon";
import { isGranularity } from "../types/dashboard";
import { useRouter } from "./RouterContext";
/**
* The default filter for the dashboard,used when the filter is not present in the URL.
* Might as well be a function to avoid stale dates.
*/
export function defaultFilter() {
return dashboardFilterFromPreset("last_7_days");
}
export function dashboardFilterFromPreset(preset) {
switch (preset) {
case "last_7_days":
return {
preset: "last_7_days",
granularity: "day",
startDate: DateTime.now().minus({ days: 6 }).startOf("day"),
endDate: DateTime.now().endOf("day"),
};
case "last_30_days":
return {
preset: "last_30_days",
granularity: "day",
startDate: DateTime.now().minus({ days: 29 }).startOf("day"),
endDate: DateTime.now().endOf("day"),
};
case "today":
return {
preset: "today",
granularity: "day",
startDate: DateTime.now().startOf("day"),
endDate: DateTime.now().endOf("day"),
};
case "yesterday":
return {
preset: "yesterday",
granularity: "day",
startDate: DateTime.now().minus({ days: 1 }).startOf("day"),
endDate: DateTime.now().minus({ days: 1 }).endOf("day"),
};
case "this_week":
return {
preset: "this_week",
granularity: "day",
startDate: DateTime.now().startOf("week"),
endDate: DateTime.now().endOf("day"),
};
case "last_week":
return {
preset: "last_week",
granularity: "day",
startDate: DateTime.now().minus({ weeks: 1 }).startOf("week"),
endDate: DateTime.now().minus({ weeks: 1 }).endOf("week"),
};
case "this_month":
return {
preset: "this_month",
granularity: "day",
startDate: DateTime.now().startOf("month"),
endDate: DateTime.now().endOf("day"),
};
case "last_month":
return {
preset: "last_month",
granularity: "day",
startDate: DateTime.now().minus({ months: 1 }).startOf("month"),
endDate: DateTime.now().minus({ months: 1 }).endOf("month"),
};
case "this_year":
return {
preset: "this_year",
granularity: "month",
startDate: DateTime.now().startOf("year"),
endDate: DateTime.now().endOf("day"),
};
case "last_year":
return {
preset: "last_year",
granularity: "month",
startDate: DateTime.now().minus({ years: 1 }).startOf("year"),
endDate: DateTime.now().minus({ years: 1 }).endOf("year"),
};
}
throw new TypeError(`Unknown filter preset: ${preset}`);
}
export const filterDateRangeLabel = (filter) => {
const { startDate, endDate } = filter;
const isSameDay = startDate.valueOf() == endDate.startOf("day").valueOf();
const startFormat = startDate.year === endDate.year ? "dd LLL" : "dd LLL, yyyy";
return isSameDay
? startDate.toFormat("dd LLL, yyyy")
: `${startDate.toFormat(startFormat)} - ${endDate.toFormat("dd LLL, yyyy")}`;
};
export const presetDateRangeLabel = (preset) => {
return filterDateRangeLabel(dashboardFilterFromPreset(preset));
};
/**
* Load the initial filter from session storage.
* If the filter is not present or invalid, return `defaultFilter`.
*/
export function dashboardFilterFromSearchParams(searchParams) {
// The URL always has to store the inclusive date since the backend expects it.
const searchEndDate = searchParams.get("end_date");
const searchStartDate = searchParams.get("start_date");
const granularity = searchParams.get("granularity");
if (searchStartDate == null || searchEndDate == null)
return defaultFilter();
if (!isGranularity(granularity))
return defaultFilter();
const startDate = DateTime.fromISO(searchStartDate);
const endDate = DateTime.fromISO(searchEndDate).minus({ days: 1 }).endOf("day");
return {
startDate,
endDate,
granularity,
preset: "custom", // TODO: Detect current preset, e.g. preset query param
};
}
export const DashboardFilterContext = React.createContext(undefined);
export const useDashboardFilter = () => React.useContext(DashboardFilterContext);
/**
* Convert `DashboardFilter` to a query string that can be used in the URL.
* Uses the inclusive `end_date` to make sure the backend always get the correct date.
*/
export function dashboardFilterToSearchParams({ startDate, endDate, granularity, }) {
const start_date = startDate.toISO({ suppressSeconds: true, suppressMilliseconds: true });
const end_date = endDate
.plus({ days: 1 })
.startOf("day")
.toISO({ suppressSeconds: true, suppressMilliseconds: true });
if (start_date == null || end_date == null)
return null;
return { start_date, end_date, granularity };
}
const DashboardFilterContextProvider = ({ children, }) => {
const { navigate } = useRouter();
const [searchParams] = useSearchParams();
const [filter, setFilterState] = useState(dashboardFilterFromSearchParams(searchParams));
const setFilter = useCallback((newFilter) => {
setFilterState(newFilter);
const query = dashboardFilterToSearchParams(newFilter);
if (query == null) {
console.error("[DASHBOARD_FILTER_CONTEXT] filter", newFilter);
return;
}
navigate(undefined, { query, replace: true });
}, []);
return (React.createElement(DashboardFilterContext.Provider, { value: { filter, setFilter } }, children));
};
export default DashboardFilterContextProvider;
//# sourceMappingURL=DashboardFilterContext.js.map