181 lines
6.2 KiB
TypeScript
181 lines
6.2 KiB
TypeScript
'use client'
|
||
|
||
import { useEffect, useState } from 'react'
|
||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||
import { Button } from '@/components/ui/button'
|
||
|
||
export default function DebugScoringPage() {
|
||
const [competitions, setCompetitions] = useState<any[]>([])
|
||
const [selectedCompetition, setSelectedCompetition] = useState<any>(null)
|
||
const [competitionJudges, setCompetitionJudges] = useState<any[]>([])
|
||
const [competitionParticipants, setCompetitionParticipants] = useState<any[]>([])
|
||
const [loading, setLoading] = useState(false)
|
||
const [logs, setLogs] = useState<string[]>([])
|
||
|
||
const addLog = (message: string) => {
|
||
setLogs(prev => [...prev, `${new Date().toLocaleTimeString()}: ${message}`])
|
||
}
|
||
|
||
// 載入競賽列表
|
||
const loadCompetitions = async () => {
|
||
try {
|
||
addLog('🔄 開始載入競賽列表...')
|
||
const response = await fetch('/api/competitions')
|
||
const data = await response.json()
|
||
addLog(`📋 競賽API回應: ${JSON.stringify(data)}`)
|
||
|
||
if (data.success && data.data) {
|
||
setCompetitions(data.data)
|
||
addLog(`✅ 載入 ${data.data.length} 個競賽`)
|
||
} else {
|
||
addLog(`❌ 競賽載入失敗: ${data.message}`)
|
||
}
|
||
} catch (error) {
|
||
addLog(`❌ 競賽載入錯誤: ${error.message}`)
|
||
}
|
||
}
|
||
|
||
// 載入競賽數據
|
||
const loadCompetitionData = async (competitionId: string) => {
|
||
if (!competitionId) return
|
||
|
||
setLoading(true)
|
||
addLog(`🔍 開始載入競賽數據,ID: ${competitionId}`)
|
||
|
||
try {
|
||
// 載入評審
|
||
addLog('📋 載入評審...')
|
||
const judgesResponse = await fetch(`/api/competitions/${competitionId}/judges`)
|
||
const judgesData = await judgesResponse.json()
|
||
addLog(`評審API回應: ${JSON.stringify(judgesData)}`)
|
||
|
||
if (judgesData.success && judgesData.data && judgesData.data.judges) {
|
||
setCompetitionJudges(judgesData.data.judges)
|
||
addLog(`✅ 載入 ${judgesData.data.judges.length} 個評審`)
|
||
} else {
|
||
addLog(`❌ 評審載入失敗: ${judgesData.message}`)
|
||
setCompetitionJudges([])
|
||
}
|
||
|
||
// 載入參賽者
|
||
addLog('📱 載入參賽者...')
|
||
const [appsResponse, teamsResponse] = await Promise.all([
|
||
fetch(`/api/competitions/${competitionId}/apps`),
|
||
fetch(`/api/competitions/${competitionId}/teams`)
|
||
])
|
||
|
||
const appsData = await appsResponse.json()
|
||
const teamsData = await teamsResponse.json()
|
||
|
||
addLog(`應用API回應: ${JSON.stringify(appsData)}`)
|
||
addLog(`團隊API回應: ${JSON.stringify(teamsData)}`)
|
||
|
||
const participants = []
|
||
|
||
if (appsData.success && appsData.data && appsData.data.apps) {
|
||
participants.push(...appsData.data.apps.map((app: any) => ({
|
||
id: app.id,
|
||
name: app.name,
|
||
type: 'individual',
|
||
creator: app.creator
|
||
})))
|
||
addLog(`✅ 載入 ${appsData.data.apps.length} 個應用`)
|
||
} else {
|
||
addLog(`❌ 應用載入失敗: ${appsData.message}`)
|
||
}
|
||
|
||
if (teamsData.success && teamsData.data && teamsData.data.teams) {
|
||
participants.push(...teamsData.data.teams.map((team: any) => ({
|
||
id: team.id,
|
||
name: team.name,
|
||
type: 'team',
|
||
creator: team.members && team.members.find((m: any) => m.role === '隊長')?.name || '未知隊長'
|
||
})))
|
||
addLog(`✅ 載入 ${teamsData.data.teams.length} 個團隊`)
|
||
} else {
|
||
addLog(`❌ 團隊載入失敗: ${teamsData.message}`)
|
||
}
|
||
|
||
setCompetitionParticipants(participants)
|
||
addLog(`✅ 參賽者載入完成: ${participants.length} 個`)
|
||
|
||
} catch (error) {
|
||
addLog(`❌ 載入失敗: ${error.message}`)
|
||
} finally {
|
||
setLoading(false)
|
||
}
|
||
}
|
||
|
||
useEffect(() => {
|
||
loadCompetitions()
|
||
}, [])
|
||
|
||
return (
|
||
<div className="container mx-auto p-6 space-y-6">
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle>評分表單調試頁面</CardTitle>
|
||
</CardHeader>
|
||
<CardContent className="space-y-4">
|
||
<div>
|
||
<label className="block text-sm font-medium mb-2">選擇競賽:</label>
|
||
<select
|
||
value={selectedCompetition?.id || ""}
|
||
onChange={(e) => {
|
||
const competition = competitions.find(c => c.id === e.target.value)
|
||
setSelectedCompetition(competition)
|
||
if (competition) {
|
||
loadCompetitionData(competition.id)
|
||
}
|
||
}}
|
||
className="w-full p-2 border rounded"
|
||
>
|
||
<option value="">選擇競賽</option>
|
||
{competitions.map(comp => (
|
||
<option key={comp.id} value={comp.id}>
|
||
{comp.name} ({comp.type})
|
||
</option>
|
||
))}
|
||
</select>
|
||
</div>
|
||
|
||
{selectedCompetition && (
|
||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
<div>
|
||
<h3 className="font-semibold mb-2">評審 ({competitionJudges.length})</h3>
|
||
<div className="space-y-2">
|
||
{competitionJudges.map(judge => (
|
||
<div key={judge.id} className="p-2 bg-gray-100 rounded">
|
||
{judge.name} - {judge.title} - {judge.department}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div>
|
||
<h3 className="font-semibold mb-2">參賽者 ({competitionParticipants.length})</h3>
|
||
<div className="space-y-2">
|
||
{competitionParticipants.map(participant => (
|
||
<div key={participant.id} className="p-2 bg-gray-100 rounded">
|
||
{participant.name} ({participant.type}) - {participant.creator}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
<div>
|
||
<h3 className="font-semibold mb-2">調試日誌</h3>
|
||
<div className="bg-gray-100 p-4 rounded max-h-96 overflow-y-auto">
|
||
{logs.map((log, index) => (
|
||
<div key={index} className="text-sm font-mono">{log}</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
)
|
||
}
|