From da729abafb95edf87d6cf911ce68a77d2e74281d Mon Sep 17 00:00:00 2001 From: diced Date: Thu, 11 Jul 2024 15:29:20 -0700 Subject: [PATCH] feat: change how metrics is displayed --- src/components/pages/metrics/index.tsx | 63 +++++++++++++++++------ src/components/pages/metrics/useStats.tsx | 2 + src/server/routes/api/stats.ts | 18 ++++--- 3 files changed, 59 insertions(+), 24 deletions(-) diff --git a/src/components/pages/metrics/index.tsx b/src/components/pages/metrics/index.tsx index 2f3990474..8e8d60cdd 100755 --- a/src/components/pages/metrics/index.tsx +++ b/src/components/pages/metrics/index.tsx @@ -1,6 +1,6 @@ -import { Box, Button, Group, Loader, Modal, Paper, SimpleGrid, Text, Title } from '@mantine/core'; +import { Box, Button, Group, Loader, Modal, Paper, SimpleGrid, Text, Title, Tooltip } from '@mantine/core'; import { DatePicker } from '@mantine/dates'; -import { IconCalendarTime } from '@tabler/icons-react'; +import { IconCalendarSearch, IconCalendarTime } from '@tabler/icons-react'; import { useState } from 'react'; import FilesUrlsCountGraph from './parts/FilesUrlsCountGraph'; import StatsCards from './parts/StatsCards'; @@ -11,14 +11,16 @@ import { useApiStats } from './useStats'; export default function DashboardMetrics() { const [dateRange, setDateRange] = useState<[Date | null, Date | null]>([ - new Date(Date.now() - 86400000), + new Date(Date.now() - 86400000 * 7), new Date(), ]); const [open, setOpen] = useState(false); + const [allTime, setAllTime] = useState(false); const { data, isLoading } = useApiStats({ from: dateRange[0]?.toISOString() ?? undefined, to: dateRange[1]?.toISOString() ?? undefined, + all: allTime, }); return ( @@ -28,9 +30,12 @@ export default function DashboardMetrics() { { + setDateRange(value); + setAllTime(false); + }} allowSingleDateInRange={false} - maxDate={new Date(Date.now() + 86400000)} + maxDate={new Date(Date.now() + 0)} /> @@ -43,26 +48,50 @@ export default function DashboardMetrics() { Metrics - - - - {dateRange[0]?.toLocaleDateString()}{' '} - {dateRange[1] ? `to ${dateRange[1]?.toLocaleDateString()}` : ''} - + {!allTime ? ( + + {data?.length ? ( + <> + {new Date(data?.[data.length - 1]?.createdAt).toLocaleDateString()} + {' to '} + {new Date(data?.[0]?.createdAt).toLocaleDateString()}{' '} + + ) : ( + <> + {dateRange[0]?.toLocaleDateString()}{' '} + {dateRange[1] ? `to ${dateRange[1]?.toLocaleDateString()}` : ''} + + )} + + ) : ( + + All Time + + )} + + + {isLoading ? ( - ) : data ? ( + ) : data?.length ? (
@@ -73,14 +102,14 @@ export default function DashboardMetrics() { - {/* :skull: this stops it from overflowing somehow */} - +
- +
) : ( - Failed to load statistics for this time range. + Failed to load statistics for this time range. There may be no data available within the time + range specified. :( )}
diff --git a/src/components/pages/metrics/useStats.tsx b/src/components/pages/metrics/useStats.tsx index 4355b1bc8..a92b96964 100755 --- a/src/components/pages/metrics/useStats.tsx +++ b/src/components/pages/metrics/useStats.tsx @@ -4,12 +4,14 @@ import useSWR from 'swr'; type ApiStatsOptions = { from?: string; to?: string; + all?: boolean; }; const fetcher = async ({ options }: { options: ApiStatsOptions } = { options: {} }) => { const searchParams = new URLSearchParams(); if (options.from) searchParams.append('from', options.from); if (options.to) searchParams.append('to', options.to); + if (options.all) searchParams.append('all', 'true'); const res = await fetch(`/api/stats${searchParams.toString() ? `?${searchParams.toString()}` : ''}`); diff --git a/src/server/routes/api/stats.ts b/src/server/routes/api/stats.ts index 21f83cfc9..6d79483b2 100755 --- a/src/server/routes/api/stats.ts +++ b/src/server/routes/api/stats.ts @@ -9,6 +9,7 @@ export type ApiStatsResponse = Metric[]; type Query = { from?: string; to?: string; + all?: string; }; export const PATH = '/api/stats'; @@ -17,19 +18,22 @@ export default fastifyPlugin( server.get<{ Querystring: Query }>(PATH, { preHandler: [userMiddleware] }, async (req, res) => { if (!config.features.metrics) return res.forbidden('metrics are disabled'); - const { from, to } = req.query; + const { from, to, all } = req.query; - const fromDate = from ? new Date(from) : new Date(Date.now() - 86400000); + const fromDate = from ? new Date(from) : new Date(Date.now() - 86400000 * 7); // defaults to a week ago const toDate = to ? new Date(to) : new Date(); - if (isNaN(fromDate.getTime()) || isNaN(toDate.getTime())) return res.badRequest('invalid date(s)'); + if (!all && (isNaN(fromDate.getTime()) || isNaN(toDate.getTime()))) + return res.badRequest('invalid date(s)'); const stats = await prisma.metric.findMany({ where: { - createdAt: { - gte: fromDate, - lte: toDate, - }, + ...(!all && { + createdAt: { + gte: fromDate, + lte: toDate, + }, + }), }, orderBy: { createdAt: 'desc',