"use client" import { useTranslations } from "next-intl" import Link from "next/link" import { X, ExternalLink, Plus, Trash2 } from "lucide-react" import { Button } from "@/shared/components/ui/button" import { Badge } from "@/shared/components/ui/badge" import { ScrollArea } from "@/shared/components/ui/scroll-area" import { Separator } from "@/shared/components/ui/separator" import type { KpWithRelations, MasteryInfo } from "../types" interface GraphNodeDetailPanelProps { kp: KpWithRelations mastery: MasteryInfo | null prerequisites: { id: string; name: string; description: string | null }[] successors: { id: string; name: string; description: string | null }[] canEdit: boolean onClose: () => void onJumpToKp: (kpId: string) => void onAddPrerequisite: () => void onRemovePrerequisite: (prereqId: string) => void } export function GraphNodeDetailPanel({ kp, mastery, prerequisites, successors, canEdit, onClose, onJumpToKp, onAddPrerequisite, onRemovePrerequisite, }: GraphNodeDetailPanelProps) { const t = useTranslations("textbooks") const correctRate = mastery && mastery.totalQuestions > 0 ? Math.round((mastery.correctQuestions / mastery.totalQuestions) * 100) : null return (

{t("graph.detail.title")}

{/* 知识点名称 */}

{kp.name}

{kp.chapterTitle && (

{kp.chapterTitle}

)}
{/* 描述 */}
{t("graph.detail.title")}

{kp.description || t("graph.detail.noDescription")}

{/* 掌握度 */} {mastery && ( <>
{t("graph.node.mastery")}
{t("graph.detail.correctRate")} {correctRate !== null ? `${correctRate}%` : t("graph.detail.masteryNotAssessed")}
{t("graph.detail.totalQuestions")} {mastery.totalQuestions}
)} {/* 关联题目 */}
{t("graph.node.questions")} ({kp.questionCount})
{kp.questionCount > 0 && ( )}
{/* 前置知识点 */}
{t("graph.node.prerequisite")} ({prerequisites.length})
{canEdit && ( )}
{prerequisites.length === 0 ? (

{t("graph.detail.noPrerequisites")}

) : (
{prerequisites.map((p) => (
{canEdit && ( )}
))}
)}
{/* 后置知识点 */}
{t("graph.node.successor")} ({successors.length})
{successors.length === 0 ? (

{t("graph.detail.noSuccessors")}

) : (
{successors.map((s) => ( onJumpToKp(s.id)} > {s.name} ))}
)}
) }