'use client' import React, { useState, useEffect } from 'react' import { useRouter } from 'next/navigation' import { Trophy, Clock, Users, Send, RefreshCw, Play, Code, Wallet, Shield, TestTube } from 'lucide-react' interface Participant { name: string score: number rank: number completed: boolean language?: string submission_time?: string wallet_address?: string wallet_short?: string blockchain_verified?: boolean } interface Problem { title: string description: string function_name: string languages: string[] examples: Array<{input: string, expected_output: string, description: string}> constraints: string[] starter_code: {[key: string]: string} } interface ExamSession { exam_code: string student_name: string wallet_address?: string blockchain_verified?: boolean exam_info: any } export default function EnhancedExamInterface() { const [examSession, setExamSession] = useState(null) const [problem, setProblem] = useState(null) const [selectedLanguage, setSelectedLanguage] = useState('python') const [code, setCode] = useState('') const [output, setOutput] = useState('') const [testResults, setTestResults] = useState([]) const [leaderboard, setLeaderboard] = useState([]) const [waitingParticipants, setWaitingParticipants] = useState([]) const [timeRemaining, setTimeRemaining] = useState(0) const [isRunning, setIsRunning] = useState(false) const [isSubmitting, setIsSubmitting] = useState(false) const [hasSubmitted, setHasSubmitted] = useState(false) const [examStats, setExamStats] = useState({}) const [timerInitialized, setTimerInitialized] = useState(false) const router = useRouter() const languageIcons: {[key: string]: string} = { python: 'šŸ', java: 'ā˜•', c: '⚔', bash: 'šŸ’»' } useEffect(() => { const sessionData = localStorage.getItem('exam_session') if (!sessionData) { router.push('/coding/join') return } const session = JSON.parse(sessionData) setExamSession(session) // Fetch problem details fetchProblem(session.exam_code) // More frequent polling for real-time updates const interval = setInterval(() => { fetchLeaderboard(session.exam_code) }, 2000) return () => clearInterval(interval) }, [router]) // Timer countdown useEffect(() => { if (!timerInitialized || timeRemaining <= 0) return const timer = setInterval(() => { setTimeRemaining(prev => { const newTime = Math.max(0, prev - 1) if (newTime === 0) { alert('ā° Time is up! Exam has ended.') } return newTime }) }, 1000) return () => clearInterval(timer) }, [timerInitialized, timeRemaining]) const fetchProblem = async (examCode: string) => { try { const response = await fetch(`http://127.0.0.1:5000/api/exam/get-problem/${examCode}`) const data = await response.json() if (data.success) { setProblem(data.problem) const defaultLang = data.problem.languages[0] || 'python' setSelectedLanguage(defaultLang) setCode(data.problem.starter_code[defaultLang] || '') } } catch (error) { console.error('Failed to fetch problem:', error) } } // āœ… ENHANCED: More aggressive leaderboard fetching with better debugging const fetchLeaderboard = async (examCode: string) => { try { console.log('šŸ† Fetching leaderboard for:', examCode) // Add cache busting to prevent stale data const response = await fetch(`http://127.0.0.1:5000/api/exam/leaderboard/${examCode}?t=${Date.now()}`) const data = await response.json() console.log('šŸ“¦ Leaderboard data received:', { success: data.success, completed_count: data.leaderboard?.length || 0, waiting_count: data.waiting_participants?.length || 0, ultimate_fix_applied: data.ultimate_fix_applied }) if (data.success) { setLeaderboard(data.leaderboard || []) setWaitingParticipants(data.waiting_participants || []) setExamStats(data.stats || {}) // Timer calculation if (data.exam_info && data.exam_info.status === 'active') { if (data.exam_info.end_time) { const now = Date.now() const endTime = new Date(data.exam_info.end_time).getTime() const remaining = Math.max(0, Math.floor((endTime - now) / 1000)) setTimeRemaining(remaining) if (!timerInitialized) { setTimerInitialized(true) } } } // āœ… ENHANCED: Better user status checking const currentUser = examSession?.student_name if (currentUser) { const userInCompleted = data.leaderboard.find((p: Participant) => p.name === currentUser) const userInWaiting = data.waiting_participants.find((p: Participant) => p.name === currentUser) console.log(`šŸ‘¤ User status check:`, { username: currentUser, in_completed: !!userInCompleted, in_waiting: !!userInWaiting, current_hasSubmitted: hasSubmitted, user_score: userInCompleted?.score }) if (userInCompleted && !hasSubmitted) { console.log('āœ… User found in completed leaderboard, updating hasSubmitted state') setHasSubmitted(true) } } // Debug logging for leaderboard content if (data.leaderboard.length > 0) { console.log('šŸ† Completed participants:', data.leaderboard.map((p: any) => `${p.name}: ${p.score}%`)) } if (data.waiting_participants.length > 0) { console.log('ā³ Waiting participants:', data.waiting_participants.map((p: any) => p.name)) } } else { console.error('āŒ Leaderboard fetch failed:', data.error) } } catch (error) { console.error('āŒ Failed to fetch leaderboard:', error) } } const handleLanguageChange = (language: string) => { setSelectedLanguage(language) if (problem?.starter_code[language]) { setCode(problem.starter_code[language]) } setOutput('') setTestResults([]) } const runCode = async () => { if (!code.trim()) { alert('Please write some code first!') return } setIsRunning(true) setOutput('') setTestResults([]) try { const response = await fetch('http://127.0.0.1:5000/api/compiler/execute', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code, language: selectedLanguage }) }) const result = await response.json() if (result.success) { setOutput(`āœ… Output:\n${result.output}`) if (result.execution_time) { setOutput(prev => prev + `\nā±ļø Execution time: ${result.execution_time}s`) } } else { setOutput(`āŒ Error:\n${result.error}`) } } catch (error) { setOutput(`Execution failed: ${(error as Error).message}`) } finally { setIsRunning(false) } } // āœ… COMPLETELY FIXED SUBMIT SOLUTION with aggressive leaderboard refresh const submitSolution = async () => { if (!code.trim()) { alert('Please write some code before submitting!') return } if (!confirm('Submit your solution? This cannot be undone.')) return setIsSubmitting(true) try { console.log('šŸ“¤ Submitting solution...') console.log('šŸ‘¤ Participant:', examSession?.student_name) console.log('šŸ”¢ Exam Code:', examSession?.exam_code) const response = await fetch('http://127.0.0.1:5000/api/exam/submit-solution', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ exam_code: examSession?.exam_code, language: selectedLanguage, code: code, participant_name: examSession?.student_name || 'Anonymous' }) }) const data = await response.json() console.log('šŸ“¦ Submit result:', data) if (data.success) { setHasSubmitted(true) setTestResults(data.test_results || []) // āœ… ENHANCED: Detailed alert with proper test results formatting let alertMessage = `šŸŽ‰ Solution submitted successfully!\n\n` alertMessage += `šŸ“Š Overall Score: ${data.score}%\n` alertMessage += `āœ… Tests Passed: ${data.passed_tests}/${data.total_tests}\n` if (data.execution_time) { alertMessage += `ā±ļø Execution Time: ${data.execution_time}s\n` } // Enhanced test results display in alert if (data.test_results && data.test_results.length > 0) { alertMessage += `\nšŸ“‹ Detailed Test Results:\n` alertMessage += `${'='.repeat(30)}\n` data.test_results.forEach((test: any, i: number) => { const status = test.passed ? 'āœ… PASSED' : 'āŒ FAILED' const points = test.points_earned || 0 alertMessage += `Test ${i+1}: ${status} (+${points} points)\n` if (test.description && test.description !== `Test case ${i+1}`) { alertMessage += ` Description: ${test.description}\n` } if (test.input) { alertMessage += ` Input: "${test.input}"\n` } if (test.expected_output) { alertMessage += ` Expected: "${test.expected_output}"\n` } if (test.actual_output) { alertMessage += ` Your Output: "${test.actual_output}"\n` } if (!test.passed && test.error) { alertMessage += ` Error: ${test.error}\n` } alertMessage += `\n` }) // Add summary const totalPoints = data.test_results.reduce((sum: number, test: any) => sum + (test.points_earned || 0), 0) const maxPoints = data.scoring_details?.total_points || 100 alertMessage += `šŸ“ˆ Points Earned: ${totalPoints}/${maxPoints}\n` } alertMessage += `\nšŸ† Your score will appear in the leaderboard shortly!` alert(alertMessage) // āœ… CRITICAL FIX: Aggressive leaderboard refresh sequence console.log('šŸ”„ Starting aggressive leaderboard refresh sequence...') // Immediate refresh setTimeout(() => { console.log('šŸ”„ Refresh 1/6 - Immediate') fetchLeaderboard(examSession!.exam_code) }, 200) // Quick follow-up setTimeout(() => { console.log('šŸ”„ Refresh 2/6 - Quick follow-up') fetchLeaderboard(examSession!.exam_code) }, 800) // Medium delay setTimeout(() => { console.log('šŸ”„ Refresh 3/6 - Medium delay') fetchLeaderboard(examSession!.exam_code) }, 2000) // Longer delay setTimeout(() => { console.log('šŸ”„ Refresh 4/6 - Longer delay') fetchLeaderboard(examSession!.exam_code) }, 4000) // Extended delay setTimeout(() => { console.log('šŸ”„ Refresh 5/6 - Extended delay') fetchLeaderboard(examSession!.exam_code) }, 7000) // Final refresh setTimeout(() => { console.log('šŸ”„ Refresh 6/6 - Final check') fetchLeaderboard(examSession!.exam_code) }, 10000) } else { alert(`āŒ Submission failed: ${data.error}`) } } catch (error) { console.error('āŒ Submit network error:', error) alert('āŒ Network error: Could not submit solution. Please try again.') } finally { setIsSubmitting(false) } } // āœ… Enhanced Test Results Display Component const TestResultsDisplay = ({ results }: { results: any[] }) => { if (!results || results.length === 0) return null return (

Test Results

{results.map((result, index) => (
Test {index + 1}: {result.passed ? 'āœ… PASSED' : 'āŒ FAILED'} +{result.points_earned || 0} points
{result.description && result.description !== `Test case ${index+1}` && (

{result.description}

)}
{result.input && (
Input: "{result.input}"
)} {result.expected_output && (
Expected: "{result.expected_output}"
)} {result.actual_output && (
Your Output: "{result.actual_output}"
)}
{!result.passed && result.error && (
Error: {result.error}
)}
))}
{/* Summary */}
Passed: {results.filter(r => r.passed).length}/{results.length} tests Points: {results.reduce((sum, r) => sum + (r.points_earned || 0), 0)} total
) } // Debug function for troubleshooting const debugLeaderboard = async () => { try { const response = await fetch(`http://127.0.0.1:5000/api/exam/leaderboard/${examSession?.exam_code}`) const data = await response.json() console.log('šŸ› DEBUG LEADERBOARD:', { success: data.success, completed_count: data.leaderboard?.length || 0, waiting_count: data.waiting_participants?.length || 0, my_name: examSession?.student_name, in_completed: data.leaderboard?.find((p: any) => p.name === examSession?.student_name), in_waiting: data.waiting_participants?.find((p: any) => p.name === examSession?.student_name), ultimate_fix_applied: data.ultimate_fix_applied, full_leaderboard: data.leaderboard, full_waiting: data.waiting_participants }) alert(`Debug Info:\nCompleted: ${data.leaderboard?.length || 0}\nWaiting: ${data.waiting_participants?.length || 0}\nCheck console for details`) } catch (error) { console.error('Debug error:', error) } } const formatTime = (seconds: number) => { if (seconds < 0) return "00:00" const mins = Math.floor(seconds / 60) const secs = seconds % 60 return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}` } const getRankColor = (rank: number) => { switch (rank) { case 1: return 'bg-gradient-to-r from-yellow-400 to-yellow-600 text-white' case 2: return 'bg-gradient-to-r from-gray-300 to-gray-500 text-white' case 3: return 'bg-gradient-to-r from-orange-400 to-orange-600 text-white' default: return 'bg-gray-100 text-gray-700' } } if (!examSession || !problem) { return (

Loading exam interface...

) } return (
{/* Header with Timer */}

{problem.title}

Code: {examSession.exam_code} | Participant: {examSession.student_name}

{/* Timer */} {timeRemaining > 0 && (
{formatTime(timeRemaining)}
)} {/* Participant Count */}
{examStats.total_participants || 0} participants
{/* Submission Status Indicator */} {hasSubmitted && (
āœ… Submitted
)}
{/* Problem & Code Editor */}
{/* Problem Description */}

{problem.title}

{hasSubmitted && (
Solution Submitted
)}

{problem.description}

Examples:

{problem.examples.map((example, index) => (
Input: "{example.input}"
Output: "{example.expected_output}"
{example.description && (
{example.description}
)}
))}

Constraints:

    {problem.constraints.map((constraint, index) => (
  • {constraint}
  • ))}
{/* Code Editor */}

Your Solution

{/* Language Selector */}