diff --git a/pb_migrations/1757263183_updated_matches.js b/pb_migrations/1757263183_updated_matches.js new file mode 100644 index 0000000..b3768ba --- /dev/null +++ b/pb_migrations/1757263183_updated_matches.js @@ -0,0 +1,27 @@ +/// +migrate((app) => { + const collection = app.findCollectionByNameOrId("pbc_2541054544") + + // add field + collection.fields.addAt(20, new Field({ + "hidden": false, + "id": "number3320769076", + "max": null, + "min": null, + "name": "round", + "onlyInt": false, + "presentable": false, + "required": false, + "system": false, + "type": "number" + })) + + return app.save(collection) +}, (app) => { + const collection = app.findCollectionByNameOrId("pbc_2541054544") + + // remove field + collection.fields.removeById("number3320769076") + + return app.save(collection) +}) diff --git a/src/app/routes/_authed/admin/tournaments/run.$id.tsx b/src/app/routes/_authed/admin/tournaments/run.$id.tsx index d348674..450e254 100644 --- a/src/app/routes/_authed/admin/tournaments/run.$id.tsx +++ b/src/app/routes/_authed/admin/tournaments/run.$id.tsx @@ -4,6 +4,10 @@ import { ensureServerQueryData } from '@/lib/tanstack-query/utils/ensure' import SeedTournament from '@/features/tournaments/components/seed-tournament' import { Container, Alert, Text } from '@mantine/core' import { Info } from '@phosphor-icons/react' +import { useMemo } from 'react' +import { BracketData } from '@/features/bracket/types' +import { Match } from '@/features/matches/types' +import BracketView from '@/features/bracket/components/bracket-view' export const Route = createFileRoute('/_authed/admin/tournaments/run/$id')({ beforeLoad: async ({ context, params }) => { @@ -31,6 +35,50 @@ function RouteComponent() { const { tournament } = Route.useRouteContext() const router = useRouter() + const bracket: BracketData = useMemo(() => { + if (!tournament.matches || tournament.matches.length === 0) { + return { winners: [], losers: [] } + } + + console.log('Tournament Matches:', tournament.matches) + + const winnersMap = new Map() + const losersMap = new Map() + + tournament.matches.sort((a, b) => a.lid - b.lid).forEach((match) => { + console.log('Processing Match:', match) + if (!match.is_losers_bracket) { + if (!winnersMap.has(match.round)) { + winnersMap.set(match.round, []) + } + winnersMap.get(match.round)!.push(match) + console.log('Added to Winners Bracket:', match) + } else { + if (!losersMap.has(match.round)) { + losersMap.set(match.round, []) + } + losersMap.get(match.round)!.push(match) + console.log('Added to Losers Bracket:', match) + } + }) + + // Convert to dense arrays sorted by round (0, 1, 2, 3...) + const winners = Array.from(winnersMap.entries()) + .sort(([a], [b]) => a - b) + .map(([, matches]) => matches) + + const losers = Array.from(losersMap.entries()) + .sort(([a], [b]) => a - b) + .map(([, matches]) => matches) + + console.log('Winners Bracket (fixed):', winners) + console.log('Losers Bracket (fixed):', losers) + return { winners, losers } + }, [tournament.matches]) + + + console.log('Bracket Data:', bracket) + const handleSuccess = () => { router.navigate({ to: '/admin/tournaments/$id', @@ -44,7 +92,7 @@ function RouteComponent() { { tournament.matches?.length ? -

Matches

+ : ( = ({ [match] ); - const showAnnounce = useMemo( - () => onAnnounce && match.home && match.away, - [onAnnounce, match.home, match.away] + const showToolbar = useMemo( + () => match.home && match.away, + [match.home, match.away] ); const handleAnnounce = useCallback( () => onAnnounce?.(match.home, match.away), - [match.home, match.away] + [onAnnounce, match.home, match.away] ); + const handleEdit = useCallback(() => { + // TODO: implement edit functionality + console.log('Edit match:', match); + }, [match]); + return ( {match.order} - - - - + + + + + - - - + + + - {match.reset && ( - + * If necessary + + )} + + + {showToolbar && ( + - * If necessary - + + + + )} - - {showAnnounce && ( - - - - )} - + ); }; diff --git a/src/features/bracket/components/match-slot.tsx b/src/features/bracket/components/match-slot.tsx index efa3e37..a3ac722 100644 --- a/src/features/bracket/components/match-slot.tsx +++ b/src/features/bracket/components/match-slot.tsx @@ -17,7 +17,7 @@ export const MatchSlot: React.FC = ({ seed, }) => ( - {seed && } + {(seed && seed > 0) ? : undefined} {team ? ( {team.name} diff --git a/src/lib/pocketbase/services/tournaments.ts b/src/lib/pocketbase/services/tournaments.ts index db6585d..6b58074 100644 --- a/src/lib/pocketbase/services/tournaments.ts +++ b/src/lib/pocketbase/services/tournaments.ts @@ -14,7 +14,7 @@ export function createTournamentsService(pb: PocketBase) { return { async getTournament(id: string): Promise { const result = await pb.collection("tournaments").getOne(id, { - expand: "teams, teams.players, matches, matches.tournament", + expand: "teams, teams.players, matches, matches.tournament, matches.home, matches.away", }); return transformTournament(result); }, diff --git a/src/lib/pocketbase/util/transform-types.ts b/src/lib/pocketbase/util/transform-types.ts index f71d1f0..9883a36 100644 --- a/src/lib/pocketbase/util/transform-types.ts +++ b/src/lib/pocketbase/util/transform-types.ts @@ -28,7 +28,7 @@ export function transformTeamInfo(record: any): TeamInfo { export const transformMatch = (record: any): Match => { return { id: record.id, - order: record.name, + order: record.order, lid: record.lid, reset: record.reset, round: record.round,