From fa68ec0b3438044a83320d1b7597be2352836e8f Mon Sep 17 00:00:00 2001 From: SpecialX <47072643+wangxiner55@users.noreply.github.com> Date: Mon, 6 Jul 2026 20:49:54 +0800 Subject: [PATCH] =?UTF-8?q?refactor(lesson-preparation,ai,dashboard):=20?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E5=8C=96=E9=87=8D=E6=9E=84=E7=AC=AC=203=20?= =?UTF-8?q?=E6=89=B9=20-=20=E9=AB=98=E9=A3=8E=E9=99=A9=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - lesson-preparation: 拆分 lesson-plan-editor (594→273),新增 toolbar/dialogs/publish-button 子组件 + 持久化 Hook - ai: 拆分 ai-chat-panel (417→218),新增 messages/input 子组件,保持流式响应状态稳定 - dashboard: 新增 DashboardShell 布局壳,4 个角色 dashboard 统一使用 - 删除 6 个重复组件(filters/skeletons/error-boundaries) - tsc 零错误 --- .../(dashboard)/admin/dashboard/loading.tsx | 4 +- src/app/(dashboard)/dashboard/loading.tsx | 4 +- .../(dashboard)/student/dashboard/loading.tsx | 4 +- .../(dashboard)/teacher/dashboard/loading.tsx | 4 +- src/modules/ai/components/ai-chat-input.tsx | 128 +++++ .../ai/components/ai-chat-messages.tsx | 199 ++++++++ src/modules/ai/components/ai-chat-panel.tsx | 297 ++--------- .../ai/components/ai-child-summary.tsx | 10 +- .../ai/components/ai-error-book-analysis.tsx | 12 +- .../ai/components/ai-error-boundary.tsx | 31 -- .../ai/components/ai-grading-assist.tsx | 10 +- .../ai-lesson-content-generator.tsx | 10 +- .../ai-question-variant-generator.tsx | 10 +- src/modules/ai/components/ai-skeleton.tsx | 47 -- src/modules/ai/components/ai-study-path.tsx | 10 +- .../ai/components/ai-usage-dashboard.tsx | 6 +- .../admin-dashboard/admin-dashboard.tsx | 110 ++-- .../admin-dashboard/admin-sections.tsx | 21 - .../components/dashboard-greeting-header.tsx | 35 -- .../components/dashboard-loading-skeleton.tsx | 44 -- .../dashboard/components/dashboard-shell.tsx | 36 ++ .../parent-dashboard/parent-dashboard.tsx | 17 +- .../student-dashboard-header.tsx | 11 - .../student-dashboard-view.tsx | 106 +++- .../teacher-dashboard-header.tsx | 15 - .../teacher-dashboard-view.tsx | 100 +++- .../teacher-dashboard/teacher-stats.tsx | 61 --- .../components/blocks/blackboard-block.tsx | 6 +- .../components/blocks/exercise-block.tsx | 14 +- .../components/blocks/new-teaching-block.tsx | 6 +- .../blocks/rich-text-block-inner.tsx | 10 +- .../components/blocks/rich-text-block.tsx | 10 +- .../components/inline-question-editor.tsx | 6 +- .../components/knowledge-point-picker.tsx | 4 +- .../components/lesson-plan-dialogs.tsx | 124 +++++ .../components/lesson-plan-editor.tsx | 469 +++--------------- .../components/lesson-plan-error-boundary.tsx | 81 --- .../components/lesson-plan-filters.tsx | 89 ---- .../components/lesson-plan-list.tsx | 80 ++- .../components/lesson-plan-publish-button.tsx | 82 +++ .../components/lesson-plan-skeleton.tsx | 79 --- .../components/lesson-plan-toolbar.tsx | 212 ++++++++ .../components/question-bank-picker.tsx | 4 +- .../components/version-history-drawer.tsx | 4 +- .../hooks/use-lesson-plan-persistence.ts | 155 ++++++ src/shared/components/ui/stats-grid.tsx | 2 +- .../i18n/messages/en/lesson-preparation.json | 2 + .../messages/zh-CN/lesson-preparation.json | 2 + 48 files changed, 1457 insertions(+), 1326 deletions(-) create mode 100644 src/modules/ai/components/ai-chat-input.tsx create mode 100644 src/modules/ai/components/ai-chat-messages.tsx delete mode 100644 src/modules/ai/components/ai-error-boundary.tsx delete mode 100644 src/modules/ai/components/ai-skeleton.tsx delete mode 100644 src/modules/dashboard/components/dashboard-greeting-header.tsx delete mode 100644 src/modules/dashboard/components/dashboard-loading-skeleton.tsx create mode 100644 src/modules/dashboard/components/dashboard-shell.tsx delete mode 100644 src/modules/dashboard/components/student-dashboard/student-dashboard-header.tsx delete mode 100644 src/modules/dashboard/components/teacher-dashboard/teacher-dashboard-header.tsx delete mode 100644 src/modules/dashboard/components/teacher-dashboard/teacher-stats.tsx create mode 100644 src/modules/lesson-preparation/components/lesson-plan-dialogs.tsx delete mode 100644 src/modules/lesson-preparation/components/lesson-plan-error-boundary.tsx delete mode 100644 src/modules/lesson-preparation/components/lesson-plan-filters.tsx create mode 100644 src/modules/lesson-preparation/components/lesson-plan-publish-button.tsx delete mode 100644 src/modules/lesson-preparation/components/lesson-plan-skeleton.tsx create mode 100644 src/modules/lesson-preparation/components/lesson-plan-toolbar.tsx create mode 100644 src/modules/lesson-preparation/hooks/use-lesson-plan-persistence.ts diff --git a/src/app/(dashboard)/admin/dashboard/loading.tsx b/src/app/(dashboard)/admin/dashboard/loading.tsx index ba4d093..731b99b 100644 --- a/src/app/(dashboard)/admin/dashboard/loading.tsx +++ b/src/app/(dashboard)/admin/dashboard/loading.tsx @@ -1,5 +1,5 @@ -import { DashboardLoadingSkeleton } from "@/modules/dashboard/components/dashboard-loading-skeleton" +import { SkeletonCard } from "@/shared/components/ui/skeleton" export default function AdminDashboardLoading() { - return + return } diff --git a/src/app/(dashboard)/dashboard/loading.tsx b/src/app/(dashboard)/dashboard/loading.tsx index dc464d6..be129f2 100644 --- a/src/app/(dashboard)/dashboard/loading.tsx +++ b/src/app/(dashboard)/dashboard/loading.tsx @@ -1,5 +1,5 @@ -import { DashboardLoadingSkeleton } from "@/modules/dashboard/components/dashboard-loading-skeleton" +import { SkeletonCard } from "@/shared/components/ui/skeleton" export default function DashboardLoading() { - return + return } diff --git a/src/app/(dashboard)/student/dashboard/loading.tsx b/src/app/(dashboard)/student/dashboard/loading.tsx index d9e7c4a..44b23f4 100644 --- a/src/app/(dashboard)/student/dashboard/loading.tsx +++ b/src/app/(dashboard)/student/dashboard/loading.tsx @@ -1,5 +1,5 @@ -import { DashboardLoadingSkeleton } from "@/modules/dashboard/components/dashboard-loading-skeleton" +import { SkeletonCard } from "@/shared/components/ui/skeleton" export default function StudentDashboardLoading() { - return + return } diff --git a/src/app/(dashboard)/teacher/dashboard/loading.tsx b/src/app/(dashboard)/teacher/dashboard/loading.tsx index 0ac89b1..10ea8d1 100644 --- a/src/app/(dashboard)/teacher/dashboard/loading.tsx +++ b/src/app/(dashboard)/teacher/dashboard/loading.tsx @@ -1,5 +1,5 @@ -import { DashboardLoadingSkeleton } from "@/modules/dashboard/components/dashboard-loading-skeleton" +import { SkeletonCard } from "@/shared/components/ui/skeleton" export default function TeacherDashboardLoading() { - return + return } diff --git a/src/modules/ai/components/ai-chat-input.tsx b/src/modules/ai/components/ai-chat-input.tsx new file mode 100644 index 0000000..89a7c89 --- /dev/null +++ b/src/modules/ai/components/ai-chat-input.tsx @@ -0,0 +1,128 @@ +"use client" + +import { useTranslations } from "next-intl" +import { Send, Square } from "lucide-react" + +import { Button } from "@/shared/components/ui/button" +import { Textarea } from "@/shared/components/ui/textarea" + +type AiChatInputProps = { + value: string + onChange: (value: string) => void + onKeyDown: (e: React.KeyboardEvent) => void + streaming: boolean + onSend: () => void + onStop: () => void + maxReached: boolean + variant: "card" | "widget" + placeholder?: string +} + +/** + * AI 聊天输入框 + * + * 渲染文本输入区域与发送/停止按钮,支持 card / widget 两种视觉变体。 + * 纯展示组件,所有状态由容器通过 props 注入。 + */ +export function AiChatInput({ + value, + onChange, + onKeyDown, + streaming, + onSend, + onStop, + maxReached, + variant, + placeholder, +}: AiChatInputProps): React.ReactNode { + const t = useTranslations("ai") + const isWidget = variant === "widget" + + if (isWidget) { + return ( +
+
+