From e993e13db7b425e14949463988c209a5d37439f2 Mon Sep 17 00:00:00 2001 From: johnmeshulam <55348702+johnmeshulam@users.noreply.github.com> Date: Sat, 14 Feb 2026 18:06:50 +0200 Subject: [PATCH 1/2] Review stage queries awards from the backend --- .../final/components/review/review-stage.tsx | 76 +++++++++++++------ .../deliberation/final/graphql/query.ts | 36 ++++++++- .../deliberation/final/graphql/types.ts | 19 +++++ 3 files changed, 105 insertions(+), 26 deletions(-) diff --git a/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/components/review/review-stage.tsx b/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/components/review/review-stage.tsx index 717a7d9db..2a88adde6 100644 --- a/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/components/review/review-stage.tsx +++ b/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/components/review/review-stage.tsx @@ -3,37 +3,57 @@ import { useCallback, useMemo, useState } from 'react'; import { useRouter } from 'next/navigation'; import { useTranslations } from 'next-intl'; -import { Box, Paper, Typography, Grid, Button } from '@mui/material'; +import { Box, Paper, Typography, Grid, Button, CircularProgress } from '@mui/material'; +import { useQuery } from '@apollo/client/react'; import { useFinalDeliberation } from '../../final-deliberation-context'; import { EnrichedTeam } from '../../types'; +import { GET_DIVISION_AWARDS } from '../../graphql'; import { AwardSection } from './award-section'; import { ApprovalModal } from './approval-modal'; export const ReviewStage: React.FC = () => { const router = useRouter(); const t = useTranslations('pages.deliberations.final.review'); - const { awards, deliberation, division, teams } = useFinalDeliberation(); + const { deliberation, division, teams } = useFinalDeliberation(); const [openConfirmDialog, setOpenConfirmDialog] = useState(false); - // Filter out personal awards and group by name + // Query for live award assignments + const { data: awardsData, loading: awardsLoading } = useQuery(GET_DIVISION_AWARDS, { + variables: { divisionId: division.id } + }); + + // Transform awarded data into mappedWinners structure const mappedWinners = useMemo(() => { const mapped: Record = {}; - for (const [awardName, value] of Object.entries(awards)) { - let teamIds: string[] = []; - if (awardName === 'champions') { - teamIds = Object.values(deliberation.champions); - } else { - teamIds = value as string[]; + + if (!awardsData?.division?.judging?.awards) { + return mapped; + } + + // Group awards by name, filtering for TEAM awards with winners only + for (const award of awardsData.division.judging.awards) { + if (award.type !== 'TEAM' || !award.winner) { + continue; } - const winners = []; - for (const teamId of teamIds) { - const team = teams.find(t => t.id === teamId); - winners.push(team!); + + if (!mapped[award.name]) { + mapped[award.name] = []; + } + + // Extract team from the winner (only TeamWinner has team property) + if ('team' in award.winner) { + const teamWinner = award.winner; + if (teamWinner.team) { + const team = teams.find(t => t.id === teamWinner.team.id); + if (team) { + mapped[award.name].push(team); + } + } } - mapped[awardName] = winners; } + return mapped; - }, [awards, deliberation.champions, teams]); + }, [awardsData, teams]); const handleOpenConfirm = useCallback(() => { setOpenConfirmDialog(true); @@ -57,15 +77,21 @@ export const ReviewStage: React.FC = () => { - - - {Object.entries(mappedWinners).map(([awardName, winners]) => ( - - - - ))} - - + {awardsLoading ? ( + + + + ) : ( + + + {Object.entries(mappedWinners).map(([awardName, winners]) => ( + + + + ))} + + + )} diff --git a/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/graphql/query.ts b/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/graphql/query.ts index f6e098409..da450575d 100644 --- a/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/graphql/query.ts +++ b/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/graphql/query.ts @@ -1,6 +1,11 @@ import { gql, TypedDocumentNode } from '@apollo/client'; import { merge } from '@lems/shared/utils'; -import type { FinalDeliberationData, FinalDeliberationVars } from './types'; +import type { + FinalDeliberationData, + FinalDeliberationVars, + DivisionAwardsData, + DivisionAwardsVars +} from './types'; export const GET_FINAL_DELIBERATION: TypedDocumentNode< FinalDeliberationData, @@ -142,6 +147,35 @@ export const GET_FINAL_DELIBERATION: TypedDocumentNode< } `; +export const GET_DIVISION_AWARDS: TypedDocumentNode = gql` + query GetDivisionAwards($divisionId: String!) { + division(id: $divisionId) { + id + judging { + awards { + id + name + type + place + winner { + ... on TeamWinner { + team { + id + number + name + slug + } + } + ... on PersonalWinner { + name + } + } + } + } + } + } +`; + export function parseFinalDeliberationData(data: FinalDeliberationData) { const updates: Record = {}; diff --git a/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/graphql/types.ts b/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/graphql/types.ts index 2ac741bca..35042fc3f 100644 --- a/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/graphql/types.ts +++ b/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/graphql/types.ts @@ -66,3 +66,22 @@ export interface FinalDeliberationData { export interface FinalDeliberationVars { divisionId: string; } + +export interface DivisionAwardsData { + division: { + id: string; + judging: { + awards: Array<{ + id: string; + name: string; + type: 'PERSONAL' | 'TEAM'; + place: number; + winner?: TeamWinner | PersonalWinner; + }>; + }; + }; +} + +export interface DivisionAwardsVars { + divisionId: string; +} From d3ee630e59e49e68385dcb9dd8d6e4bb8c5ff50d Mon Sep 17 00:00:00 2001 From: johnmeshulam <55348702+johnmeshulam@users.noreply.github.com> Date: Sat, 14 Feb 2026 18:07:19 +0200 Subject: [PATCH 2/2] remove ai slop --- .../deliberation/final/components/review/review-stage.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/components/review/review-stage.tsx b/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/components/review/review-stage.tsx index 2a88adde6..831a832c4 100644 --- a/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/components/review/review-stage.tsx +++ b/apps/frontend/src/app/[locale]/lems/(volunteer)/deliberation/final/components/review/review-stage.tsx @@ -17,12 +17,10 @@ export const ReviewStage: React.FC = () => { const { deliberation, division, teams } = useFinalDeliberation(); const [openConfirmDialog, setOpenConfirmDialog] = useState(false); - // Query for live award assignments const { data: awardsData, loading: awardsLoading } = useQuery(GET_DIVISION_AWARDS, { variables: { divisionId: division.id } }); - // Transform awarded data into mappedWinners structure const mappedWinners = useMemo(() => { const mapped: Record = {}; @@ -40,7 +38,6 @@ export const ReviewStage: React.FC = () => { mapped[award.name] = []; } - // Extract team from the winner (only TeamWinner has team property) if ('team' in award.winner) { const teamWinner = award.winner; if (teamWinner.team) {