UNPKG

bananas-commerce-admin

Version:

What's this, an admin for apes?

153 lines 6.33 kB
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