"use client"
import Link from "next/link"
import { useTranslations } from "next-intl"
import { Award, AlertTriangle, Lightbulb, FileText, History, ArrowRight } from "lucide-react"
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/shared/components/ui/card"
import { Badge } from "@/shared/components/ui/badge"
import { Button } from "@/shared/components/ui/button"
import { Tooltip, TooltipContent, TooltipTrigger } from "@/shared/components/ui/tooltip"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { formatDate } from "@/shared/lib/utils"
import { MasteryRadarChart } from "./mastery-radar-chart"
import {
getConfidenceLevel,
confidenceBadgeVariant,
type ConfidenceLevel,
} from "./confidence-utils"
import type { DiagnosticReportWithDetails, MasteryRadarPoint, StudentMasterySummary } from "../types"
interface StudentDiagnosticViewProps {
summary: StudentMasterySummary | null
reports: DiagnosticReportWithDetails[]
classAverageMastery?: MasteryRadarPoint[]
/**
* v3-P2-6: "练习"按钮的跳转基础路径。
* - 学生视角:默认 `/student/learning/assignments`
* - 教师视角:传入 `/teacher/questions`(题目库支持 kp 查询参数筛选)
* - 家长视角:传入 `null` 隐藏练习按钮(家长无练习入口)
* 最终链接会附加 `?kp={knowledgePointId}` 实现个性化练习推荐。
*/
practiceHrefBase?: string | null
}
export function StudentDiagnosticView({
summary,
reports,
classAverageMastery,
practiceHrefBase = "/student/learning/assignments",
}: StudentDiagnosticViewProps) {
const t = useTranslations("diagnostic")
if (!summary) {
return (
)
}
const radarData: MasteryRadarPoint[] = summary.allMastery.map((m) => {
const classAvg = classAverageMastery?.find((c) => c.knowledgePoint === m.knowledgePointName)
return {
knowledgePoint: m.knowledgePointName,
student: Math.round(m.masteryLevel * 100) / 100,
classAverage: classAvg?.classAverage,
}
})
const publishedReports = reports.filter((r) => r.status === "published")
// v4-P1-3: 移除草稿回退逻辑,仅展示已发布报告
// 调用方(学生/家长页面)已传 status: "published" 过滤,此处双重保障
const latestReport = publishedReports[0] ?? null
const statusLabel = (status: string): string => {
if (status === "draft") return t("status.draft")
if (status === "published") return t("status.published")
if (status === "archived") return t("status.archived")
return status
}
const typeLabel = (reportType: string): string => {
if (reportType === "individual") return t("type.individual")
if (reportType === "class") return t("type.class")
if (reportType === "grade") return t("type.grade")
return reportType
}
// v4-P3-7: 置信度标签与提示
const confidenceLabel = (level: ConfidenceLevel): string => {
if (level === "high") return t("reportList.confidenceHigh")
if (level === "medium") return t("reportList.confidenceMedium")
if (level === "low") return t("reportList.confidenceLow")
return t("reportList.confidenceInsufficient")
}
const confidenceHint = (level: ConfidenceLevel): string => {
if (level === "high") return t("reportList.confidenceHighHint")
if (level === "medium") return t("reportList.confidenceMediumHint")
if (level === "low") return t("reportList.confidenceLowHint")
return t("reportList.confidenceInsufficient")
}
return (
{/* 概览卡片 */}
{t("summary.student")}
{summary.studentName}
{t("summary.overallMastery")}
{summary.averageMastery.toFixed(1)}%
{t("summary.strengths")}
{summary.strengths.length}
{t("summary.weaknesses")}
{summary.weaknesses.length}
{/* 雷达图 */}
{/* 强项 / 弱项 */}
{t("strengths.title")}
{t("studentDiagnostic.strengthsDescription")}
{summary.strengths.length === 0 ? (
{t("studentDiagnostic.noStrengths")}
) : (
{summary.strengths.map((m) => (
-
{m.knowledgePointName}
{m.masteryLevel.toFixed(1)}%
))}
)}
{t("weaknesses.title")}
{t("studentDiagnostic.weaknessesDescription")}
{summary.weaknesses.length === 0 ? (
{t("studentDiagnostic.noWeaknesses")}
) : (
)}
{/* 最新报告 / 建议 */}
{latestReport ? (
{t("studentDiagnostic.diagnosticReportTitle")}
{statusLabel(latestReport.status)}
{(() => {
const level = getConfidenceLevel(latestReport)
return (
{confidenceLabel(level)}
{confidenceHint(level)}
)
})()}
{t("studentDiagnostic.reportMeta", {
period: latestReport.period ?? "-",
score: latestReport.overallScore?.toFixed(1) ?? "-",
})}
{latestReport.summary ? (
{latestReport.summary}
) : null}
{latestReport.recommendations && latestReport.recommendations.length > 0 ? (
{t("report.recommendations")}
{latestReport.recommendations.map((rec, i) => (
- • {rec}
))}
) : null}
) : null}
{/* 历史报告列表 */}
{publishedReports.length > 1 ? (
{t("report.history")}
{t("studentDiagnostic.historyDescription")}
{publishedReports.map((r) => (
{r.period ?? t("studentDiagnostic.untitledPeriod")}
{typeLabel(r.reportType)}
{r.overallScore !== null
? t("studentDiagnostic.historyReportMeta", {
date: formatDate(r.createdAt),
score: r.overallScore.toFixed(1),
})
: formatDate(r.createdAt)}
))}
) : null}
)
}