From 0df94ddeb4262e1004363377e2cc5ac546327b4d Mon Sep 17 00:00:00 2001 From: Erik Vroon <11857441+evroon@users.noreply.github.com> Date: Sat, 27 Dec 2025 15:19:16 +0100 Subject: [PATCH] Add stages and clubs typing (#1489) --- frontend/src/components/brackets/courts.tsx | 4 ++-- frontend/src/components/builder/builder.tsx | 9 ++++----- .../components/modals/activate_next_stage_modal.tsx | 2 +- frontend/src/components/modals/tournament_modal.tsx | 4 ++-- frontend/src/components/tables/clubs.tsx | 8 ++++++-- frontend/src/components/utils/stage.tsx | 9 ++++++--- .../[id]/stages/swiss/[stage_item_id].tsx | 2 +- frontend/src/services/lookups.tsx | 12 +++++++++--- 8 files changed, 31 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/brackets/courts.tsx b/frontend/src/components/brackets/courts.tsx index e6fd10ae..d407de79 100644 --- a/frontend/src/components/brackets/courts.tsx +++ b/frontend/src/components/brackets/courts.tsx @@ -2,12 +2,12 @@ import { Grid, Title } from '@mantine/core'; import { SWRResponse } from 'swr'; import { TournamentMinimal } from '@components/utils/tournament'; -import { RoundWithMatches } from '@openapi'; +import { RoundWithMatches, StagesWithStageItemsResponse } from '@openapi'; import { getStages } from '@services/adapter'; import Match from './match'; function getRoundsGridCols( - swrStagesResponse: SWRResponse, + swrStagesResponse: SWRResponse, activeRound: RoundWithMatches, tournamentData: TournamentMinimal ) { diff --git a/frontend/src/components/builder/builder.tsx b/frontend/src/components/builder/builder.tsx index 7a4ea959..d97c0c54 100644 --- a/frontend/src/components/builder/builder.tsx +++ b/frontend/src/components/builder/builder.tsx @@ -35,7 +35,6 @@ import { StageItemInputOption, formatStageItemInputTentative, } from '@components/utils/stage_item_input'; -import { responseIsValid } from '@components/utils/util'; import { Ranking, StageItemInputOptionsResponse, @@ -162,7 +161,7 @@ function StageItemInputComboBox({ } export function getAvailableInputs( - swrAvailableInputsResponse: SWRResponse, + swrAvailableInputsResponse: SWRResponse, teamsMap: any, stageItemMap: any ) { @@ -193,9 +192,9 @@ export function getAvailableInputs( already_taken: option.already_taken, }; }; - return responseIsValid(swrAvailableInputsResponse) - ? Object.keys(swrAvailableInputsResponse.data.data).reduce((result: any, stage_id: string) => { - const option = swrAvailableInputsResponse.data.data[stage_id]; + return swrAvailableInputsResponse.data != undefined + ? Object.keys(swrAvailableInputsResponse.data?.data).reduce((result: any, stage_id: string) => { + const option = assert_not_none(swrAvailableInputsResponse.data?.data[stage_id]); result[stage_id] = option .map((opt: StageItemInputOption) => getComboBoxOptionForStageItemInput(opt)) .filter((o: StageItemInputOption | null) => o != null); diff --git a/frontend/src/components/modals/activate_next_stage_modal.tsx b/frontend/src/components/modals/activate_next_stage_modal.tsx index e1cd0f34..74d12afe 100644 --- a/frontend/src/components/modals/activate_next_stage_modal.tsx +++ b/frontend/src/components/modals/activate_next_stage_modal.tsx @@ -74,7 +74,7 @@ export default function ActivateNextStageModal({ }: { tournamentId: number; swrStagesResponse: SWRResponse; - swrRankingsPerStageItemResponse: SWRResponse; + swrRankingsPerStageItemResponse: SWRResponse; }) { const { t } = useTranslation(); const [opened, setOpened] = useState(false); diff --git a/frontend/src/components/modals/tournament_modal.tsx b/frontend/src/components/modals/tournament_modal.tsx index f20bfd15..ec60a357 100644 --- a/frontend/src/components/modals/tournament_modal.tsx +++ b/frontend/src/components/modals/tournament_modal.tsx @@ -180,8 +180,8 @@ export default function TournamentModal({ const { t } = useTranslation(); const [opened, setOpened] = useState(false); const operation_text = t('create_tournament_button'); - const swrClubsResponse: SWRResponse = getClubs(); - const clubs: Club[] = swrClubsResponse.data != null ? swrClubsResponse.data.data : []; + const swrClubsResponse = getClubs(); + const clubs = swrClubsResponse.data?.data || []; return ( <> diff --git a/frontend/src/components/tables/clubs.tsx b/frontend/src/components/tables/clubs.tsx index 28885ecf..95c182dd 100644 --- a/frontend/src/components/tables/clubs.tsx +++ b/frontend/src/components/tables/clubs.tsx @@ -7,11 +7,15 @@ import ClubModal from '@components/modals/club_modal'; import { EmptyTableInfo } from '@components/no_content/empty_table_info'; import RequestErrorAlert from '@components/utils/error_alert'; import { TableSkeletonSingleColumn } from '@components/utils/skeletons'; -import { Club } from '@openapi'; +import { Club, ClubsResponse } from '@openapi'; import { deleteClub } from '@services/club'; import TableLayout, { ThNotSortable, ThSortable, getTableState, sortTableEntries } from './table'; -export default function ClubsTable({ swrClubsResponse }: { swrClubsResponse: SWRResponse }) { +export default function ClubsTable({ + swrClubsResponse, +}: { + swrClubsResponse: SWRResponse; +}) { const clubs: Club[] = swrClubsResponse.data != null ? swrClubsResponse.data.data : []; const tableState = getTableState('name'); const { t } = useTranslation(); diff --git a/frontend/src/components/utils/stage.tsx b/frontend/src/components/utils/stage.tsx index 12fc1b3b..fac09e30 100644 --- a/frontend/src/components/utils/stage.tsx +++ b/frontend/src/components/utils/stage.tsx @@ -1,7 +1,10 @@ import { SWRResponse } from 'swr'; -import { StageWithStageItems } from '@openapi'; +import { StagesWithStageItemsResponse } from '@openapi'; -export function getStageById(swrStagesResponse: SWRResponse, stageId: number) { - return swrStagesResponse.data.data.filter((stage: StageWithStageItems) => stage.id === stageId); +export function getStageById( + swrStagesResponse: SWRResponse, + stageId: number +) { + return (swrStagesResponse.data?.data || []).filter((stage) => stage.id === stageId); } diff --git a/frontend/src/pages/tournaments/[id]/stages/swiss/[stage_item_id].tsx b/frontend/src/pages/tournaments/[id]/stages/swiss/[stage_item_id].tsx index 744cadf8..6b43f693 100644 --- a/frontend/src/pages/tournaments/[id]/stages/swiss/[stage_item_id].tsx +++ b/frontend/src/pages/tournaments/[id]/stages/swiss/[stage_item_id].tsx @@ -209,7 +209,7 @@ export default function SwissTournamentPage() { displaySettings={displaySettings} swrUpcomingMatchesResponse={swrUpcomingMatchesResponse} /> - {showScheduler ? ( + {showScheduler && activeStage ? ( , matchesByCourtId: any ): { court: Court; matches: MatchWithDetails[] }[] { - return swrCourtsResponse.data.data.map((court: Court) => ({ + return (swrCourtsResponse.data?.data || []).map((court: Court) => ({ matches: (matchesByCourtId[court.id] || []) .filter((match: MatchWithDetails) => match.start_time != null) .sort((m1: MatchWithDetails, m2: MatchWithDetails) => {