"use client"; import Link from "next/link"; import { useCallback, useMemo, useState } from "react"; import { GitFork } from "lucide-react"; import { BrapiEntityPage, type BrapiFormField } from "@/components/brapi/BrapiEntityPage"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { CROSS_TYPE_OPTIONS, PLANNED_CROSS_STATUS_OPTIONS, crossTypeLabel, plannedStatusLabel, } from "../constants"; import { createCrossRow, createPlannedCrossRow, normalizeCrossForm, normalizePlannedCrossForm, updateCrossRow, updatePlannedCrossRow, } from "../api"; import { useCrossPedigree } from "../CrossPedigreeContext"; import { NONE_SELECT_VALUE } from "../types"; export function CrossEntityTab() { const { snapshot, refresh } = useCrossPedigree(); const [subTab, setSubTab] = useState("planned"); const crossingProjectOptions = snapshot?.crossingProjectOptions ?? []; const plannedCrossOptions = snapshot?.plannedCrossOptions ?? []; const loadPlannedRows = useCallback(async () => { const data = await refresh(false); return data.plannedCrosses as unknown as Record[]; }, [refresh]); const loadActualRows = useCallback(async () => { const data = await refresh(false); return data.actualCrosses as unknown as Record[]; }, [refresh]); const fetchPlannedRecord = useCallback(async (id: string) => { const data = await refresh(false); const row = data.plannedCrosses.find((item) => item.id === id); if (!row) throw new Error("计划杂交不存在"); return normalizePlannedCrossForm(row); }, [refresh]); const fetchActualRecord = useCallback(async (id: string) => { const data = await refresh(false); const row = data.actualCrosses.find((item) => item.id === id); if (!row) throw new Error("实际杂交不存在"); return normalizeCrossForm(row); }, [refresh]); const plannedFields = useMemo(() => [ { key: "name", label: "计划杂交名称", type: "text", required: true, placeholder: "如 B73 x Mo17 / Cross-2026-001", }, { key: "crossing_project_id", label: "杂交项目", type: "select", required: true, options: [{ value: NONE_SELECT_VALUE, label: "请选择杂交项目" }, ...crossingProjectOptions], }, { key: "cross_type", label: "杂交类型", type: "select", options: [{ value: NONE_SELECT_VALUE, label: "不指定类型" }, ...CROSS_TYPE_OPTIONS], }, { key: "status", label: "状态", type: "select", options: PLANNED_CROSS_STATUS_OPTIONS, }, ], [crossingProjectOptions]); const actualFields = useMemo(() => [ { key: "name", label: "实际杂交名称", type: "text", required: true, placeholder: "如 B73 x Mo17 实际杂交", }, { key: "crossing_project_id", label: "杂交项目", type: "select", required: true, options: [{ value: NONE_SELECT_VALUE, label: "请选择杂交项目" }, ...crossingProjectOptions], }, { key: "cross_type", label: "杂交类型", type: "select", options: [{ value: NONE_SELECT_VALUE, label: "不指定类型" }, ...CROSS_TYPE_OPTIONS], }, { key: "planned_cross_id", label: "来源计划杂交", type: "select", options: [{ value: NONE_SELECT_VALUE, label: "不关联计划杂交" }, ...plannedCrossOptions], }, ], [crossingProjectOptions, plannedCrossOptions]); return ( 计划杂交 (planned=true) 实际杂交 (planned=false) {subTab === "planned" ? ( { const id = String(row.id ?? row.plannedCrossDbId ?? value ?? ""); if (!id) return "—"; return ( {id} ); }, }, { key: "name", label: "名称", render: (value, row) => { const id = String(row.id ?? row.plannedCrossDbId ?? ""); const name = String(value ?? "—"); if (!id) return name; return ( {name} ); }, }, { key: "crossing_project_name", label: "杂交项目" }, { key: "cross_type", label: "类型", render: crossTypeLabel }, { key: "status", label: "状态", render: plannedStatusLabel }, ]} fields={plannedFields} data={[]} stats={[ { label: "/brapi/v2/plannedcrosses", value: "BrAPI", className: "bg-emerald-50 text-emerald-700 dark:bg-emerald-400/10 dark:text-emerald-200", }, ]} loadData={loadPlannedRows} fetchRecord={fetchPlannedRecord} createRecord={(payload) => createPlannedCrossRow(payload) as unknown as Promise>} updateRecord={(id, payload) => updatePlannedCrossRow(id, payload) as unknown as Promise>} /> ) : null} {subTab === "actual" ? ( { const id = String(row.id ?? row.crossDbId ?? value ?? ""); if (!id) return "—"; return ( {id} ); }, }, { key: "name", label: "名称", render: (value, row) => { const id = String(row.id ?? row.crossDbId ?? ""); const name = String(value ?? "—"); if (!id) return name; return ( {name} ); }, }, { key: "crossing_project_name", label: "杂交项目" }, { key: "plannedCrossName", label: "来源计划杂交" }, { key: "cross_type", label: "类型", render: crossTypeLabel }, ]} fields={actualFields} data={[]} stats={[ { label: "/brapi/v2/crosses", value: "BrAPI", className: "bg-green-50 text-green-700 dark:bg-green-400/10 dark:text-green-200", }, ]} loadData={loadActualRows} fetchRecord={fetchActualRecord} createRecord={(payload) => createCrossRow(payload) as unknown as Promise>} updateRecord={(id, payload) => updateCrossRow(id, payload) as unknown as Promise>} /> ) : null} ); }