diff --git a/src/app/(home)/games-per-hour/_components/games-per-hour-chart.tsx b/src/app/(home)/games-per-hour/_components/games-per-hour-chart.tsx index f077de0..85a1629 100644 --- a/src/app/(home)/games-per-hour/_components/games-per-hour-chart.tsx +++ b/src/app/(home)/games-per-hour/_components/games-per-hour-chart.tsx @@ -1,5 +1,7 @@ 'use client' +import { Button } from '@/components/ui/button' +import { Calendar } from '@/components/ui/calendar' import { Card, CardContent, @@ -13,6 +15,11 @@ import { ChartTooltip, ChartTooltipContent, } from '@/components/ui/chart' +import { + Popover, + PopoverContent, + PopoverTrigger, +} from '@/components/ui/popover' import { Select, SelectContent, @@ -20,9 +27,12 @@ import { SelectTrigger, SelectValue, } from '@/components/ui/select' +import { cn } from '@/lib/utils' import { api } from '@/trpc/react' +import { format } from 'date-fns' +import { CalendarIcon } from 'lucide-react' import { useState } from 'react' -import { BarChart, CartesianGrid, XAxis, YAxis, Bar } from 'recharts' +import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from 'recharts' const chartConfig = { count: { @@ -35,10 +45,22 @@ type GroupByOption = 'hour' | 'day' | 'week' | 'month' export function GamesPerHourChart() { const [groupBy, setGroupBy] = useState('hour') + const [dateRange, setDateRange] = useState< + | { + from?: Date | undefined + to?: Date | undefined + } + | undefined + >({ + from: undefined, + to: undefined, + }) - // Fetch games data with the selected grouping + // Fetch games data with the selected grouping and date range const [gamesData] = api.history.games_per_hour.useSuspenseQuery({ groupBy, + startDate: dateRange?.from?.toISOString(), + endDate: dateRange?.to?.toISOString(), }) // Format the title and description based on the grouping @@ -76,26 +98,71 @@ export function GamesPerHourChart() { } return ( - - + +
{getTitleText()} Number of games played over time
- +
+ + + + + + + + + + +
- - + + - + `${value} games`} - /> + `${value} games`} /> } /> - + diff --git a/src/server/api/routers/history.ts b/src/server/api/routers/history.ts index 5ff44ba..58d4255 100644 --- a/src/server/api/routers/history.ts +++ b/src/server/api/routers/history.ts @@ -1,43 +1,40 @@ import { createTRPCRouter, publicProcedure } from '@/server/api/trpc' import { db } from '@/server/db' import { metadata, player_games, raw_history } from '@/server/db/schema' -import { desc, eq } from 'drizzle-orm' +import { and, desc, eq, gt, lt, sql } from 'drizzle-orm' import ky from 'ky' import { chunk } from 'remeda' import { z } from 'zod' export const history_router = createTRPCRouter({ - user_games: publicProcedure - .input( - z.object({ - user_id: z.string(), - }) - ) - .query(async ({ ctx, input }) => { - return await ctx.db - .select() - .from(player_games) - .where(eq(player_games.playerId, input.user_id)) - .orderBy(desc(player_games.gameNum)) - }), games_per_hour: publicProcedure .input( z .object({ groupBy: z.enum(['hour', 'day', 'week', 'month']).default('hour'), + startDate: z.string().optional(), + endDate: z.string().optional(), }) .optional() ) .query(async ({ ctx, input }) => { const groupBy = input?.groupBy || 'hour' - - // Fetch all games with their gameNum to identify unique games + const startDate = input?.startDate ? new Date(input.startDate) : undefined + const endDate = input?.endDate ? new Date(input.endDate) : undefined + const nextDay = endDate ? new Date(endDate) : undefined + if (nextDay) nextDay.setDate(nextDay.getDate() + 1) const games = await ctx.db .select({ gameTime: player_games.gameTime, gameNum: player_games.gameNum, }) .from(player_games) + .where( + and( + startDate ? gt(player_games.gameTime, startDate) : undefined, + nextDay ? lt(player_games.gameTime, nextDay) : undefined + ) + ) .orderBy(player_games.gameTime) // Track unique game numbers to avoid counting the same game twice @@ -97,6 +94,19 @@ export const history_router = createTRPCRouter({ sync: publicProcedure.mutation(async () => { return syncHistory() }), + user_games: publicProcedure + .input( + z.object({ + user_id: z.string(), + }) + ) + .query(async ({ ctx, input }) => { + return await ctx.db + .select() + .from(player_games) + .where(eq(player_games.playerId, input.user_id)) + .orderBy(desc(player_games.gameNum)) + }), }) export async function syncHistory() {