修正獎勵專區評審團資料異常 bug
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
import { useState, useEffect } from "react"
|
||||
import { useCompetition } from "@/contexts/competition-context"
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||
@@ -58,11 +58,38 @@ export function AwardDetailDialog({ open, onOpenChange, award }: AwardDetailDial
|
||||
const [activeTab, setActiveTab] = useState("overview")
|
||||
const [showPhotoGallery, setShowPhotoGallery] = useState(false)
|
||||
const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0)
|
||||
const [competitionJudges, setCompetitionJudges] = useState<any[]>([])
|
||||
|
||||
const competition = competitions.find((c) => c.id === award.competitionId)
|
||||
const judgeScores = getJudgeScores(award.id)
|
||||
const appData = getAppData(award.id)
|
||||
|
||||
// 載入競賽評審團資訊
|
||||
useEffect(() => {
|
||||
if (open && award.competitionId) {
|
||||
const loadCompetitionJudges = async () => {
|
||||
try {
|
||||
console.log('🔍 載入競賽評審團:', award.competitionId);
|
||||
const response = await fetch(`/api/competitions/${award.competitionId}/judges`);
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success && data.data && data.data.judges) {
|
||||
console.log('✅ 獲取到評審團:', data.data.judges.length, '位');
|
||||
setCompetitionJudges(data.data.judges);
|
||||
} else {
|
||||
console.error('❌ 獲取評審團失敗:', data.message);
|
||||
setCompetitionJudges([]);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ 載入評審團失敗:', error);
|
||||
setCompetitionJudges([]);
|
||||
}
|
||||
};
|
||||
|
||||
loadCompetitionJudges();
|
||||
}
|
||||
}, [open, award.competitionId]);
|
||||
|
||||
// Competition photos - empty for production
|
||||
const getCompetitionPhotos = () => {
|
||||
return []
|
||||
@@ -224,10 +251,20 @@ export function AwardDetailDialog({ open, onOpenChange, award }: AwardDetailDial
|
||||
<strong>競賽描述:</strong>
|
||||
{competition.description}
|
||||
</p>
|
||||
<p>
|
||||
<p className="mb-2">
|
||||
<strong>競賽期間:</strong>
|
||||
{competition.startDate} ~ {competition.endDate}
|
||||
</p>
|
||||
<p>
|
||||
<strong>評審團:</strong>
|
||||
{competitionJudges && competitionJudges.length > 0 ? (
|
||||
<span className="text-green-700">
|
||||
{competitionJudges.length} 位評審
|
||||
</span>
|
||||
) : (
|
||||
<span className="text-gray-500">暫無評審信息</span>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -251,7 +288,7 @@ export function AwardDetailDialog({ open, onOpenChange, award }: AwardDetailDial
|
||||
<ExternalLink className="w-5 h-5 text-green-600" />
|
||||
<div>
|
||||
<p className="font-medium text-green-800">正式應用</p>
|
||||
<p className="text-xs text-green-600">生產環境</p>
|
||||
<p className="text-xs text-green-600">APP 連結</p>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
@@ -407,7 +444,25 @@ export function AwardDetailDialog({ open, onOpenChange, award }: AwardDetailDial
|
||||
)
|
||||
|
||||
const renderJudgePanel = () => {
|
||||
if (!competition) return null
|
||||
if (!competitionJudges || competitionJudges.length === 0) {
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle className="flex items-center space-x-2">
|
||||
<Crown className="w-5 h-5 text-purple-500" />
|
||||
<span>評審團</span>
|
||||
</CardTitle>
|
||||
<CardDescription>本次競賽的專業評審團隊</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="text-center py-8 text-gray-500">
|
||||
<Crown className="w-12 h-12 mx-auto mb-4 text-gray-300" />
|
||||
<p>暫無評審信息</p>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Card>
|
||||
@@ -420,30 +475,25 @@ export function AwardDetailDialog({ open, onOpenChange, award }: AwardDetailDial
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{competition.judges.map((judgeId) => {
|
||||
const judge = judges.find((j) => j.id === judgeId)
|
||||
if (!judge) return null
|
||||
|
||||
return (
|
||||
<div key={judge.id} className="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg">
|
||||
<Avatar>
|
||||
<AvatarImage src={judge.avatar} />
|
||||
<AvatarFallback className="bg-purple-100 text-purple-700">{judge.name[0]}</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="flex-1">
|
||||
<h4 className="font-medium">{judge.name}</h4>
|
||||
<p className="text-sm text-gray-600">{judge.title}</p>
|
||||
<div className="flex flex-wrap gap-1 mt-1">
|
||||
{judge.expertise.slice(0, 2).map((skill) => (
|
||||
<Badge key={skill} variant="secondary" className="text-xs">
|
||||
{skill}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
{competitionJudges.map((judge) => (
|
||||
<div key={judge.id} className="flex items-center space-x-3 p-3 bg-gray-50 rounded-lg">
|
||||
<Avatar>
|
||||
<AvatarImage src={judge.avatar} />
|
||||
<AvatarFallback className="bg-purple-100 text-purple-700">{judge.name[0]}</AvatarFallback>
|
||||
</Avatar>
|
||||
<div className="flex-1">
|
||||
<h4 className="font-medium">{judge.name}</h4>
|
||||
<p className="text-sm text-gray-600">{judge.title}</p>
|
||||
<div className="flex flex-wrap gap-1 mt-1">
|
||||
{judge.expertise && judge.expertise.slice(0, 2).map((skill) => (
|
||||
<Badge key={skill} variant="secondary" className="text-xs">
|
||||
{skill}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
Reference in New Issue
Block a user