From 2dfc943ab4606a86b0f27d447fb5443fe0bf31b7 Mon Sep 17 00:00:00 2001 From: Sebastian Sebald Date: Mon, 30 Oct 2023 22:08:57 +0100 Subject: [PATCH] date range filter --- __test__/lib/utils/url.utils.test.ts | 8 +-- .../[[...range]]/compositions.tsx | 2 +- .../compositions/[[...range]]/page.tsx | 20 ++++--- lib/utils/url.utils.ts | 5 +- ui/filter/date-range-filter.tsx | 56 +++++++++++++++++++ .../small-samples-filter.tsx | 0 ui/{params => filter}/useParams.tsx | 0 7 files changed, 77 insertions(+), 14 deletions(-) create mode 100644 ui/filter/date-range-filter.tsx rename ui/{params => filter}/small-samples-filter.tsx (100%) rename ui/{params => filter}/useParams.tsx (100%) diff --git a/__test__/lib/utils/url.utils.test.ts b/__test__/lib/utils/url.utils.test.ts index 3a846708..8423089e 100644 --- a/__test__/lib/utils/url.utils.test.ts +++ b/__test__/lib/utils/url.utils.test.ts @@ -1,16 +1,16 @@ -import { toRange } from '@/lib/utils/url.utils'; +import { fromDateRange } from '@/lib/utils/url.utils'; test('extract date range', () => { - expect(toRange('')).toMatchInlineSnapshot(`null`); + expect(fromDateRange('')).toMatchInlineSnapshot(`null`); - expect(toRange('2022-01-01')).toMatchInlineSnapshot(` + expect(fromDateRange('2022-01-01')).toMatchInlineSnapshot(` { "from": "2022-01-01", "to": undefined, } `); - expect(toRange('2022-01-01.2022-01-05')).toMatchInlineSnapshot(` + expect(fromDateRange('2022-01-01.2022-01-05')).toMatchInlineSnapshot(` { "from": "2022-01-01", "to": "2022-01-05", diff --git a/app/(stats)/compositions/[[...range]]/compositions.tsx b/app/(stats)/compositions/[[...range]]/compositions.tsx index f1e6dbea..b22a8fd3 100644 --- a/app/(stats)/compositions/[[...range]]/compositions.tsx +++ b/app/(stats)/compositions/[[...range]]/compositions.tsx @@ -1,7 +1,7 @@ 'use client'; import { Card } from '@/ui'; -import { useSmallSamplesFilter } from '@/ui/params/small-samples-filter'; +import { useSmallSamplesFilter } from '@/ui/filter/small-samples-filter'; import { CompositionTable } from '@/ui/stats/composition-stats'; import type { CompositionData } from '@/lib/stats/module/composition'; diff --git a/app/(stats)/compositions/[[...range]]/page.tsx b/app/(stats)/compositions/[[...range]]/page.tsx index 5c2fd54f..35b873a2 100644 --- a/app/(stats)/compositions/[[...range]]/page.tsx +++ b/app/(stats)/compositions/[[...range]]/page.tsx @@ -5,23 +5,22 @@ import { createMetadata } from '@/lib/metadata'; import { getFactionCount, getSquads } from '@/lib/db/squads'; import { getTournamentsCount } from '@/lib/db/tournaments'; import { formatDate, fromDate, toDate, today } from '@/lib/utils/date.utils'; -import { toRange } from '@/lib/utils/url.utils'; +import { fromDateRange } from '@/lib/utils/url.utils'; -import { Caption, Card, Inline, Title } from '@/ui'; +import { Caption, Inline, Title } from '@/ui'; import { Calendar, Rocket, Trophy } from '@/ui/icons'; import { CompositionFilter, CompositionFilterProvider, - CompositionTable, } from '@/ui/stats/composition-stats'; import { StatsFilter } from '@/ui/stats/stats-filter'; import { StatsHint } from '@/ui/stats/stats-hint'; import { setup } from '@/lib/stats'; import { CompositionData, composition } from '@/lib/stats/module'; -import { SmallSamplesFilter } from '@/ui/params/small-samples-filter'; -import { Suspense } from 'react'; +import { SmallSamplesFilter } from '@/ui/filter/small-samples-filter'; import { Compositions } from './compositions'; +import { DateRangeFilter } from '@/ui/filter/date-range-filter'; // Config // --------------- @@ -79,9 +78,10 @@ const CompositionsPage = async ({ params }: PageProps) => { notFound(); } - const range = toRange(params.range?.[0]); + const range = fromDateRange(params.range?.[0]); + const from = fromDate(range ? range.from : pointsUpdateDate); - const to = range ? fromDate(range.to) : undefined; + const to = range && range.to ? fromDate(range.to) : undefined; const { stats, meta } = await getStats(from, to); @@ -104,8 +104,12 @@ const CompositionsPage = async ({ params }: PageProps) => { - + + diff --git a/lib/utils/url.utils.ts b/lib/utils/url.utils.ts index ca72e16c..f1c50cf8 100644 --- a/lib/utils/url.utils.ts +++ b/lib/utils/url.utils.ts @@ -2,7 +2,10 @@ const DATE_RANGE_REGEX = /(?\d{4}-(\d{2})-(\d{2}))(?:\.(?\d{4}-(\d{2})-(\d{2})))?/; -export const toRange = (val: string = '') => { +export const fromDateRange = (val: string = '') => { const result = val.match(DATE_RANGE_REGEX); return result ? result.groups! : null; }; + +export const toDateRange = (from: string, to?: string) => + to ? `${from}.${to}` : from; diff --git a/ui/filter/date-range-filter.tsx b/ui/filter/date-range-filter.tsx new file mode 100644 index 00000000..9722f174 --- /dev/null +++ b/ui/filter/date-range-filter.tsx @@ -0,0 +1,56 @@ +'use client'; + +import type { ChangeEvent } from 'react'; +import { useRouter } from 'next/navigation'; + +import { pointsUpdateDate } from '@/lib/config'; +import { + toDate, + lastWeekend, + monthsAgo, + fromDate, +} from '@/lib/utils/date.utils'; +import { toDateRange } from '@/lib/utils/url.utils'; + +import { Select } from '../select'; +import type { SelectProps } from '../select'; + +export interface DateRangeFilterProps extends Omit { + /** + * Pathname of the base URL (range will be appended) + */ + pathname: string; +} + +export const DateRangeFilter = ({ + pathname, + ...props +}: DateRangeFilterProps) => { + const router = useRouter(); + + let options = { + 'Last Points Update': '', + 'Last Weekend': toDate.apply(null, lastWeekend()), + 'Last Month': toDate(monthsAgo(1)), + // Add the option if the last points update is older + ...(fromDate(pointsUpdateDate) < monthsAgo(3) + ? { 'Last 3 Months': toDate(monthsAgo(3)) } + : {}), + }; + type Options = keyof typeof options; + + const updateDateRange = (e: ChangeEvent) => { + const [from, to] = e.target.value.split('/'); + router.push(`${pathname}/${toDateRange(from, to)}`); + }; + + return ( + + ); +}; diff --git a/ui/params/small-samples-filter.tsx b/ui/filter/small-samples-filter.tsx similarity index 100% rename from ui/params/small-samples-filter.tsx rename to ui/filter/small-samples-filter.tsx diff --git a/ui/params/useParams.tsx b/ui/filter/useParams.tsx similarity index 100% rename from ui/params/useParams.tsx rename to ui/filter/useParams.tsx