"use client" import { useState, useEffect } from "react" import { useSearchParams } from "next/navigation" import { Sidebar } from "@/components/sidebar" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Progress } from "@/components/ui/progress" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell, RadarChart, PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar, } from "recharts" import { Download, Share2, TrendingUp, AlertCircle, CheckCircle, Star } from "lucide-react" import { useToast } from "@/hooks/use-toast" import { ShareModal } from "@/components/share-modal" // 模擬評分結果數據 - 使用您提到的例子:8, 7, 6, 8, 4,平均 = 6.6 const mockCriteria = [ { name: "內容品質", score: 8, maxScore: 10, weight: 25, weightedScore: 20, feedback: "內容結構清晰,資訊豐富且準確。建議增加更多實際案例來支撐論點。", strengths: ["邏輯清晰", "資料準確", "結構完整"], improvements: ["增加案例", "深化分析"], }, { name: "視覺設計", score: 7, maxScore: 10, weight: 20, weightedScore: 14, feedback: "整體設計風格統一,色彩搭配合理。部分頁面文字密度過高,影響閱讀體驗。", strengths: ["風格統一", "色彩協調", "版面整潔"], improvements: ["減少文字密度", "增加視覺元素"], }, { name: "邏輯結構", score: 6, maxScore: 10, weight: 20, weightedScore: 12, feedback: "邏輯架構清晰,各章節銜接自然,論述層次分明。", strengths: ["邏輯清晰", "結構完整", "銜接自然"], improvements: ["可增加總結回顧"], }, { name: "創新性", score: 8, maxScore: 10, weight: 15, weightedScore: 12, feedback: "內容具有一定創新性,但可以更大膽地提出獨特觀點和解決方案。", strengths: ["思路新穎", "角度獨特"], improvements: ["增加創新元素", "提出獨特見解"], }, { name: "實用性", score: 4, maxScore: 10, weight: 20, weightedScore: 8, feedback: "內容實用性有待提升,提供的解決方案需要更具可操作性。", strengths: ["實用性強", "可操作性好", "價值明確"], improvements: ["增加實施步驟"], }, ]; // 計算 mock 數據的 overview - 基於平均分作為閾值 const calculateMockOverview = (criteria: any[]) => { if (!criteria || criteria.length === 0) { return { excellentItems: 0, improvementItems: 0, overallPerformance: 0 }; } // 計算所有項目的平均分數(不考慮權重) const totalScore = criteria.reduce((sum, item) => sum + item.score, 0); const averageScore = totalScore / criteria.length; // 以平均分作為閾值 // ≥ 平均分 = 優秀項目,< 平均分 = 待改進項目 const excellentItems = criteria.filter(item => item.score >= averageScore).length; const improvementItems = criteria.filter(item => item.score < averageScore).length; // 整體表現:基於權重的加權平均分數 const overallPerformance = Math.round(criteria.reduce((sum, item) => sum + (item.score / item.maxScore) * item.weight, 0)); return { excellentItems, improvementItems, overallPerformance }; }; const mockResults = { projectTitle: "產品介紹簡報", overallScore: 82, totalPossible: 100, grade: "B+", analysisDate: "2024-01-15", criteria: mockCriteria, overview: calculateMockOverview(mockCriteria), } // 圖表數據將在組件內部動態生成 const COLORS = ["#0891b2", "#6366f1", "#f59e0b", "#dc2626", "#10b981"] export default function ResultsContent() { const [activeTab, setActiveTab] = useState("overview") const [evaluationData, setEvaluationData] = useState(null) const [isLoading, setIsLoading] = useState(true) const [error, setError] = useState(null) const [isShareModalOpen, setIsShareModalOpen] = useState(false) const { toast } = useToast() const searchParams = useSearchParams() useEffect(() => { const loadEvaluationData = async () => { try { setIsLoading(true) setError(null) // 檢查是否有 URL 參數中的評審 ID const evaluationId = searchParams.get('id') if (evaluationId) { // 從 API 獲取評審數據 console.log(`📊 從 API 獲取評審數據: ID=${evaluationId}`) const response = await fetch(`/api/evaluation/${evaluationId}`) const result = await response.json() if (result.success) { setEvaluationData(result.data) console.log('✅ 成功載入評審數據:', result.data.projectTitle) } else { throw new Error(result.error || '獲取評審數據失敗') } } else { // 回退到從 localStorage 獲取評審結果 console.log('📊 從 localStorage 獲取評審結果') const storedData = localStorage.getItem('evaluationResult') if (storedData) { const data = JSON.parse(storedData) setEvaluationData(data) console.log('✅ 成功載入 localStorage 數據') } else { throw new Error('沒有找到評審結果') } } } catch (error) { console.error('載入評審結果失敗:', error) setError((error as Error).message) toast({ title: "載入失敗", description: (error as Error).message || "無法載入評審結果,請重新進行評審", variant: "destructive", }) } finally { setIsLoading(false) } } loadEvaluationData() }, [searchParams, toast]) // 如果正在載入,顯示載入狀態 if (isLoading) { return (

載入評審結果中...

) } // 如果沒有數據或發生錯誤,顯示錯誤狀態 if (!evaluationData || error) { return (

{error ? `載入失敗: ${error}` : '沒有找到評審結果'}

) } // 使用真實數據或回退到模擬數據 const results = (evaluationData as any)?.evaluation?.fullData || evaluationData || mockResults // 計算統計數據 - 基於 criteria_items 的平均分作為閾值 const calculateOverview = (criteria: any[]): any => { if (!criteria || criteria.length === 0) { return { excellentItems: 0, improvementItems: 0, overallPerformance: 0 }; } // 計算所有項目的平均分數(不考慮權重) const totalScore = criteria.reduce((sum, item) => sum + item.score, 0); const averageScore = totalScore / criteria.length; // 以平均分作為閾值 // ≥ 平均分 = 優秀項目,< 平均分 = 待改進項目 const excellentItems = criteria.filter(item => item.score >= averageScore).length; const improvementItems = criteria.filter(item => item.score < averageScore).length; // 整體表現:基於權重的加權平均分數 const overallPerformance = Math.round(criteria.reduce((sum, item) => sum + (item.score / item.maxScore) * item.weight, 0)); return { excellentItems, improvementItems, overallPerformance }; }; // 確保所有必要的數據結構存在 const safeResults = { ...results, overview: results.overview || calculateOverview(results.criteria || []), chartData: results.chartData || { barChart: [], pieChart: [], radarChart: [] }, improvementSuggestions: results.improvementSuggestions || { overallSuggestions: '暫無改進建議', maintainStrengths: [], keyImprovements: [], actionPlan: [] } } const downloadReport = async () => { try { // 顯示載入提示 toast({ title: "報告下載中", description: "評審報告 PDF 正在生成,請稍候...", }); // 獲取評審 ID const evaluationId = searchParams.get('id'); if (!evaluationId) { throw new Error('無法獲取評審 ID'); } // 調用下載 API const response = await fetch(`/api/evaluation/${evaluationId}/download`); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || '下載失敗'); } // 獲取 PDF Blob const pdfBlob = await response.blob(); // 創建下載連結 const url = window.URL.createObjectURL(pdfBlob); const link = document.createElement('a'); link.href = url; // 從 Content-Disposition 標頭獲取檔案名稱,或使用預設名稱 const contentDisposition = response.headers.get('Content-Disposition'); let fileName = `評審報告_${safeResults.projectTitle}_${safeResults.analysisDate}.pdf`; if (contentDisposition) { const fileNameMatch = contentDisposition.match(/filename="(.+)"/); if (fileNameMatch) { fileName = decodeURIComponent(fileNameMatch[1]); } } link.download = fileName; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(url); // 顯示成功提示 toast({ title: "下載完成", description: "評審報告已成功下載", }); } catch (error) { console.error('下載失敗:', error); toast({ title: "下載失敗", description: error instanceof Error ? error.message : '下載過程中發生錯誤', variant: "destructive", }); } } const shareResults = () => { setIsShareModalOpen(true) } const getScoreColor = (score: number, maxScore: number) => { const percentage = (score / maxScore) * 100 if (percentage >= 90) return "text-green-600" if (percentage >= 80) return "text-blue-600" if (percentage >= 70) return "text-yellow-600" if (percentage >= 60) return "text-orange-600" return "text-red-600" } const getGradeColor = (grade: string) => { if (grade.startsWith("A")) return "bg-green-100 text-green-800" if (grade.startsWith("B")) return "bg-blue-100 text-blue-800" if (grade.startsWith("C")) return "bg-yellow-100 text-yellow-800" return "bg-red-100 text-red-800" } return (
{/* Header */}

評審結果

{safeResults.projectTitle} - 分析完成於 {safeResults.analysisDate}

{/* Overall Score */}
{safeResults.overallScore}
總分 / {safeResults.totalPossible}
{safeResults.grade}
等級評定
{safeResults.performanceStatus}
{Array.from({ length: safeResults.recommendedStars || 0 }, (_, i) => ( ))}
推薦等級
{/* Detailed Results */} 總覽 詳細分析 圖表分析 改進建議 {/* Score Breakdown */} 評分明細 各項評分標準的得分情況
{safeResults.criteria.map((item: any, index: number) => (

{item.name}

{item.weight}% 權重
{item.score}
/ {item.maxScore}
))}
{/* Quick Stats */}
{safeResults.overview.excellentItems}
優秀項目
{safeResults.overview.improvementItems}
待改進項目
{safeResults.overview.overallPerformance}%
整體表現
{safeResults.criteria.map((item: any, index: number) => (
{item.name} {item.weight}% 權重
{item.score}/{item.maxScore}

AI 評語

{item.feedback}

優點

    {item.strengths.map((strength: any, i: number) => (
  • {strength}
  • ))}

改進建議

    {item.improvements.map((improvement: any, i: number) => (
  • {improvement}
  • ))}
))}
{/* Bar Chart */} 各項目得分 {/* Pie Chart */} 權重分布 `${name} (${weight}%)`} outerRadius={80} fill="#8884d8" dataKey="value" > {safeResults.chartData.pieChart.map((entry: any, index: number) => ( ))}
{/* Radar Chart */} 能力雷達圖 各項能力的綜合表現分析
整體改進建議 {safeResults.improvementSuggestions.overallSuggestions}

繼續保持的優勢

{safeResults.improvementSuggestions.maintainStrengths.map((strength: any, index: number) => (
{strength.title}

{strength.description}

))}

重點改進方向

{safeResults.improvementSuggestions.keyImprovements.map((improvement: any, index: number) => (
{improvement.title}

{improvement.description}

    {improvement.suggestions.map((suggestion: any, sIndex: number) => (
  • • {suggestion}
  • ))}
))}

下一步行動計劃

{safeResults.improvementSuggestions.actionPlan.map((action: any, index: number) => (
{index + 1}
{action.phase}

{action.description}

))}
{/* Share Modal */} setIsShareModalOpen(false)} evaluationId={searchParams.get('id') || undefined} projectTitle={safeResults.projectTitle} />
) }