import { useState } from 'react'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useTranslation } from 'react-i18next'; import { contestsApi, ContestInfo, ContestGameData } from '../api/contests'; const GamepadIcon = () => ( ); const TrophyIcon = () => ( ); export default function Contests() { const { t } = useTranslation(); const queryClient = useQueryClient(); const [selectedContest, setSelectedContest] = useState(null); const [gameData, setGameData] = useState(null); const [result, setResult] = useState<{ is_winner: boolean; message: string } | null>(null); const { data: contests, isLoading, error, } = useQuery({ queryKey: ['contests'], queryFn: contestsApi.getContests, }); const getGameMutation = useMutation({ mutationFn: contestsApi.getContestGame, onSuccess: (data) => { setGameData(data); setResult(null); }, }); const submitAnswerMutation = useMutation({ mutationFn: ({ roundId, answer }: { roundId: number; answer: string }) => contestsApi.submitAnswer(roundId, answer), onSuccess: (data) => { setResult(data); queryClient.invalidateQueries({ queryKey: ['contests'] }); }, }); const handlePlayContest = async (contest: ContestInfo) => { setSelectedContest(contest); getGameMutation.mutate(contest.id); }; const handleSubmitAnswer = (answer: string) => { if (gameData) { submitAnswerMutation.mutate({ roundId: gameData.round_id, answer }); } }; const handleCloseGame = () => { setSelectedContest(null); setGameData(null); setResult(null); }; if (isLoading) { return ( ); } if (error) { return ( {t('contests.error')} ); } return ( {t('contests.title')} {/* Game Modal */} {selectedContest && ( e.stopPropagation()} > {selectedContest.name} {getGameMutation.isPending && ( )} {result && ( {result.message} )} {gameData && !result && ( {gameData.instructions} {/* Render game based on type */} {(gameData.game_type === 'quest' || gameData.game_type === 'locks') && ( {Array.from({ length: gameData.game_data.total || gameData.game_data.grid_size || 9, }).map((_, i) => ( handleSubmitAnswer(`${i}_${gameData.game_data.secret}`)} disabled={submitAnswerMutation.isPending} className="flex aspect-square items-center justify-center rounded-lg bg-dark-700 text-2xl transition-colors hover:bg-dark-600" > {gameData.game_type === 'locks' ? '🔒' : '🎛'} ))} )} {gameData.game_type === 'server' && ( {gameData.game_data.flags?.map((flag: string, i: number) => ( handleSubmitAnswer(flag)} disabled={submitAnswerMutation.isPending} className="rounded-lg bg-dark-700 p-3 text-2xl transition-colors hover:bg-dark-600" > {flag} ))} )} {gameData.game_type === 'blitz' && ( handleSubmitAnswer('blitz')} disabled={submitAnswerMutation.isPending} className="w-full rounded-lg bg-accent-500 py-4 text-lg font-bold transition-colors hover:bg-accent-600" > {gameData.game_data.button_text || t('contests.imHere')} )} {['cipher', 'emoji', 'anagram'].includes(gameData.game_type) && ( { e.preventDefault(); const input = e.currentTarget.elements.namedItem( 'answer', ) as HTMLInputElement; handleSubmitAnswer(input.value); }} className="space-y-3" > {gameData.game_data.question || gameData.game_data.letters} {t('contests.submit')} )} )} {result && ( {t('common.close')} )} )} {/* Contests List */} {contests && contests.length > 0 ? ( {contests.map((contest) => ( {contest.name} {contest.description && ( {contest.description} )} +{t('contests.days', { count: contest.prize_days })} {contest.already_played ? ( {t('contests.alreadyPlayed')} ) : ( handlePlayContest(contest)} className="btn-primary w-full"> {t('contests.play')} )} ))} ) : ( {t('contests.noContests')} )} ); }
{t('contests.error')}
{result.message}
{gameData.instructions}
{contest.description}
{t('contests.noContests')}