"use client"; /** * lesson-plan-editor(teacher / main) * * 备课画布:左侧备课列表 + 右侧编辑区。 * 通过 useWidgetQuery 查询 apollo-router → core-edu 子图的 lessonPlans 数据, * 通过 useWidgetMutation 调用 saveLessonPlan 保存。 * classId 从 URL Search Params 读取(class-selector 切换时自动响应)。 * * 关联:portal-shell spec §5.2.1 URL 驱动、§5.6 统一 Hook */ import { useSearchParams } from "next/navigation"; import { useState } from "react"; import { useLessonPlans, useSaveLessonPlan, type LessonPlan, type SaveLessonPlanInput, } from "@/lib/api"; import { PluginSkeleton } from "@/shell/PluginLoader"; import type { PluginProps } from "@/lib/types"; function createEmptyDraft(): LessonPlan { return { id: "", title: "", objectives: "", content: "", resources: [] }; } export default function LessonPlanEditor( _props: PluginProps, ): React.ReactElement { const searchParams = useSearchParams(); const classId = searchParams.get("classId") ?? ""; const { data, loading, refetch } = useLessonPlans(classId); const { run: saveLessonPlan, loading: saving } = useSaveLessonPlan(); const [draft, setDraft] = useState(createEmptyDraft()); if (loading && !data) { return ; } if (!classId) { return (

备课画布

请先选择班级

); } const plans = data ?? []; const handleSelect = (plan: LessonPlan): void => { setDraft({ ...plan, resources: [...plan.resources] }); }; const handleNew = (): void => { setDraft(createEmptyDraft()); }; const handleResourceAdd = (): void => { setDraft((d) => ({ ...d, resources: [...d.resources, ""] })); }; const handleResourceChange = (index: number, value: string): void => { setDraft((d) => { const next = [...d.resources]; next[index] = value; return { ...d, resources: next }; }); }; const handleResourceRemove = (index: number): void => { setDraft((d) => ({ ...d, resources: d.resources.filter((_, i) => i !== index), })); }; const handleSave = async (): Promise => { if (!draft.title.trim()) { return; } const input: SaveLessonPlanInput = { classId, id: draft.id || undefined, title: draft.title, objectives: draft.objectives, content: draft.content, resources: draft.resources.filter((r) => r.trim().length > 0), }; try { const saved = await saveLessonPlan(input); setDraft((d) => ({ ...d, id: saved.id })); await refetch(); } catch { /* toast: 保存失败 */ } }; return (

备课画布

    {plans.length === 0 ? (
  • 暂无备课记录
  • ) : ( plans.map((p) => (
  • )) )}