import { useEffect, useState } from 'react' import { useParams } from 'react-router-dom' import { fetchAdminCompetitionWinnerPreview, publishAdminCompetitionWinner } from '../../api/session' import type { CompetitionWinnerAdminPreviewResponse, CompetitionWinnerPreviewStudentRow } from '../../api/types' import { ApiScopeNote, CompetitionPageShell, competitionLabel } from './competitionWinnersShared' /** CI `admin/competition_winners/preview.php` */ export function CompetitionWinnerPreviewPage() { const { id } = useParams() const competitionId = Number(id) const [data, setData] = useState(null) const [message, setMessage] = useState(null) const [error, setError] = useState(null) const [publishing, setPublishing] = useState(false) async function load() { try { const response = await fetchAdminCompetitionWinnerPreview(competitionId) setData(response) setError(response.ok ? null : response.message ?? 'Competition not found.') } catch (e) { setError(e instanceof Error ? e.message : 'Unable to load winners preview.') } } useEffect(() => { if (!Number.isFinite(competitionId) || competitionId <= 0) return void load() }, [competitionId]) async function handlePublish() { try { setPublishing(true) setMessage(null) const result = await publishAdminCompetitionWinner(competitionId) if (!result.ok) { setError(result.message ?? 'Unable to publish competition winners.') return } setMessage(result.message ?? 'Competition winners published.') await load() } catch (e) { setError(e instanceof Error ? e.message : 'Unable to publish competition winners.') } finally { setPublishing(false) } } return ( Preview is generated from the admin scoring data, so it works before a competition is publicly published. {error ?
{error}
: null} {message ?
{message}
: null} {data?.competition ? ( <>
Competition: {competitionLabel(data.competition)}
School Year: {data.competition.school_year ?? '—'}
Published: {data.competition.is_published ? 'Yes' : 'No'}
{Object.keys(data.topByClass ?? {}).length === 0 ? (
No ranked winners found for this competition yet.
) : ( Object.entries(data.topByClass ?? {}).map(([classId, rows]) => (
Top Winners - {data.classMap?.[classId] ?? `Class ${classId}`}
{(rows as CompetitionWinnerPreviewStudentRow[]).map((row, index) => ( ))}
Rank Student Score Question Count Prize
{row.rank ?? index + 1} {row.name ?? `Student #${row.student_id ?? ''}`} {row.score ?? '—'} {data.questionCounts?.[classId] ?? '—'} {row.prize_amount ?? '—'}
)) )} ) : null}
) }