From 1b6798b578bc2d2600914d9d8bbdd5ae0af6832e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Connor=20B=C3=A4r?= Date: Sun, 11 Aug 2024 15:44:52 +0200 Subject: [PATCH] Group games into leagues --- db/seed.ts | 6 +----- src/actions/index.ts | 34 +++++++++++++++++++++++++++++----- src/constants.ts | 2 ++ src/db.ts | 10 ++++++++-- src/pages/index.astro | 4 ++-- src/utils/date.ts | 5 +++++ 6 files changed, 47 insertions(+), 14 deletions(-) diff --git a/db/seed.ts b/db/seed.ts index 510f93d..222e048 100644 --- a/db/seed.ts +++ b/db/seed.ts @@ -2,11 +2,7 @@ import { db, Game, Player, PlayerInGame, Scores } from 'astro:db'; import { createId } from '../src/utils/id'; -const games = [ - { id: 'KVMGQ' }, - // TODO: Add complete game data - { id: 'MFFRA', endedAt: new Date() }, -]; +const games = [{ id: 'KVMGQ' }]; const players = [ { id: createId(), name: 'Apple' }, diff --git a/src/actions/index.ts b/src/actions/index.ts index 5a1c2f7..8f38d56 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -1,8 +1,18 @@ import { defineAction, z } from 'astro:actions'; -import { db, eq, Game, Player, PlayerInGame, Scores, sql } from 'astro:db'; -import { getMaxRounds } from 'src/utils/game'; +import { + db, + eq, + Game, + League, + Player, + PlayerInGame, + Scores, + sql, +} from 'astro:db'; +import { inDaysFromNow } from 'src/utils/date'; -import { MAX_PLAYERS, MIN_PLAYERS } from '../constants'; +import { LEAGUE_COOKIE, MAX_PLAYERS, MIN_PLAYERS } from '../constants'; +import { getMaxRounds } from '../utils/game'; import { createHumanId } from '../utils/id'; export const server = { @@ -12,12 +22,26 @@ export const server = { playerIds: z.array(z.string()).min(MIN_PLAYERS).max(MAX_PLAYERS), playerNames: z.array(z.string()).min(MIN_PLAYERS).max(MAX_PLAYERS), }), - handler: async ({ playerIds, playerNames }) => { + handler: async ({ playerIds, playerNames }, context) => { + let leagueId: string; + if (context.cookies.has(LEAGUE_COOKIE)) { + leagueId = context.cookies.get(LEAGUE_COOKIE)!.value; + } else { + leagueId = createHumanId(); + await db.insert(League).values({ id: leagueId }); + } + + context.cookies.set(LEAGUE_COOKIE, leagueId, { + path: '/', + sameSite: 'strict', + expires: inDaysFromNow(90), + }); + const players = playerIds .map((id, index) => ({ id, name: playerNames[index] as string })) .filter((player) => Boolean(player.name)); - const game = { id: createHumanId() }; + const game = { id: createHumanId(), leagueId }; const playersInGame = players.map((player, index) => ({ id: `${game.id}-${player.id}`, gameId: game.id, diff --git a/src/constants.ts b/src/constants.ts index e3ad31a..59321e0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -9,3 +9,5 @@ export const MAX_PLAYERS = 6; // TODO: Make configurable per game? export const POINTS_CORRECT = 20; export const POINTS_PER_TRICK = 10; + +export const LEAGUE_COOKIE = 'wizard-league'; diff --git a/src/db.ts b/src/db.ts index 6042eee..486a56f 100644 --- a/src/db.ts +++ b/src/db.ts @@ -5,8 +5,14 @@ import { createArray, shiftArray } from './utils/array'; import { calculateScoreDelta } from './utils/game'; import type { GameId } from './types'; -export function getGames() { - return db.select().from(Game).orderBy(Game.endedAt); +export function getGames(leagueId: string | undefined) { + return leagueId + ? db + .select() + .from(Game) + .where(eq(Game.leagueId, leagueId)) + .orderBy(Game.endedAt) + : []; } export function getGame(gameId: GameId) { diff --git a/src/pages/index.astro b/src/pages/index.astro index 35ebaa5..330a32e 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -2,13 +2,13 @@ import Layout from '../layouts/Standard.astro'; import GameCard from '../components/GameCard.astro'; import { getGames } from '../db'; -import { MAX_PLAYERS, MIN_PLAYERS } from '../constants'; +import { LEAGUE_COOKIE, MAX_PLAYERS, MIN_PLAYERS } from '../constants'; const title = 'Wizard Scorekeeper'; const description = 'Keep track of the scores in the trick-taking card game Wizard for three to six players'; -const games = await getGames(); +const games = await getGames(Astro.cookies.get(LEAGUE_COOKIE)?.value); const hasActiveGame = games.some(game => !game.endedAt) --- diff --git a/src/utils/date.ts b/src/utils/date.ts index de2e437..7dffa46 100644 --- a/src/utils/date.ts +++ b/src/utils/date.ts @@ -7,3 +7,8 @@ const dateTimeFormat = new Intl.DateTimeFormat(LOCALE, { export function formatDate(date: Date): string { return dateTimeFormat.format(date); } + +export function inDaysFromNow(days: number) { + const today = new Date(); + return new Date(today.getTime() + days * 24 * 60 * 60 * 1000); +}