diff --git a/README-DUAL-WRITE-SYNC.md b/README-DUAL-WRITE-SYNC.md index ef4b5ce..d3b4a4d 100644 --- a/README-DUAL-WRITE-SYNC.md +++ b/README-DUAL-WRITE-SYNC.md @@ -231,3 +231,7 @@ import { DatabaseMonitor } from '@/components/admin/database-monitor'; + + + + diff --git a/components/admin/competition-management.tsx b/components/admin/competition-management.tsx index 789cb96..285e7fb 100644 --- a/components/admin/competition-management.tsx +++ b/components/admin/competition-management.tsx @@ -1997,12 +1997,13 @@ export function CompetitionManagement() { if (!competition) return { completed: 0, total: 0, percentage: 0 } const participantCount = getParticipantCount(competition) - const totalExpected = competition.judges.length * participantCount + const judgesCount = competition.judges?.length || 0 + const totalExpected = judgesCount * participantCount const completed = judgeScores.filter((score) => { const individualParticipants = competition.participatingApps || [] const teamParticipants = competition.participatingTeams || [] const allParticipants = [...individualParticipants, ...teamParticipants] - return allParticipants.includes(score.appId) && competition.judges.includes(score.judgeId) + return allParticipants.includes(score.appId) && (competition.judges || []).includes(score.judgeId) }).length return { diff --git a/contexts/competition-context.tsx b/contexts/competition-context.tsx index 5ec2129..a2b3d5d 100644 --- a/contexts/competition-context.tsx +++ b/contexts/competition-context.tsx @@ -122,21 +122,29 @@ export function CompetitionProvider({ children }: { children: ReactNode }) { const [teams, setTeams] = useState(mockTeams) const [proposals, setProposals] = useState(mockProposals) - // 載入當前競賽 + // 載入所有競賽和當前競賽 useEffect(() => { - const loadCurrentCompetition = async () => { + const loadCompetitions = async () => { try { - const response = await fetch('/api/competitions/current') - const data = await response.json() - if (data.success && data.data) { - setCurrentCompetition(data.data) + // 載入所有競賽 + const competitionsResponse = await fetch('/api/competitions') + const competitionsData = await competitionsResponse.json() + if (competitionsData.success && competitionsData.data) { + setCompetitions(competitionsData.data) + } + + // 載入當前競賽 + const currentResponse = await fetch('/api/competitions/current') + const currentData = await currentResponse.json() + if (currentData.success && currentData.data) { + setCurrentCompetition(currentData.data) } } catch (error) { - console.error('載入當前競賽失敗:', error) + console.error('載入競賽數據失敗:', error) } } - loadCurrentCompetition() + loadCompetitions() }, []) // Load judge scores from localStorage diff --git a/lib/services/database-service.ts b/lib/services/database-service.ts index d828c28..061ca15 100644 --- a/lib/services/database-service.ts +++ b/lib/services/database-service.ts @@ -1275,7 +1275,26 @@ export class CompetitionService { // 獲取所有競賽 static async getAllCompetitions(): Promise { const sql = 'SELECT * FROM competitions WHERE is_active = TRUE ORDER BY year DESC, month DESC'; - return await db.query(sql); + const competitions = await db.query(sql); + + // 轉換字段名稱以匹配前端期望的格式 + return competitions.map(competition => ({ + ...competition, + startDate: competition.start_date, + endDate: competition.end_date, + evaluationFocus: competition.evaluation_focus, + maxTeamSize: competition.max_team_size, + isActive: competition.is_active, + createdAt: competition.created_at, + updatedAt: competition.updated_at, + // 添加默認的空數組,因為這些字段在競賽列表中不需要詳細數據 + judges: [], + participatingApps: [], + participatingTeams: [], + participatingProposals: [], + rules: [], + awardTypes: [] + })); } // 獲取競賽統計