From b711350c0c269ab6d5cc3ee5058dca6c3f27b0bc Mon Sep 17 00:00:00 2001 From: Xin Wang Date: Wed, 10 Jun 2026 14:39:52 +0800 Subject: [PATCH] Refactor frontend routing and component structure for improved navigation - Update CLAUDE.md to reflect changes in the navigation model, emphasizing the use of App Router routes for sidebar sections. - Refactor layout.tsx to wrap children in AppShell, enhancing the overall layout structure. - Replace AppShell usage in page.tsx with HomePage component for better separation of concerns. - Introduce new pages for assistants, components, dashboard, history, profile, and test, each rendering their respective components. - Revise Sidebar component to utilize Next.js Link for navigation and improve active state handling based on the current pathname. - Update AssistantPage to support routing-driven modes (list, choose, edit) and streamline form handling for assistant creation and editing. --- frontend/CLAUDE.md | 19 +- frontend/src/app/assistants/[id]/page.tsx | 10 + frontend/src/app/assistants/new/page.tsx | 5 + frontend/src/app/assistants/page.tsx | 5 + .../src/app/components/knowledge/page.tsx | 5 + frontend/src/app/components/models/page.tsx | 5 + frontend/src/app/components/tools/page.tsx | 5 + frontend/src/app/dashboard/page.tsx | 5 + frontend/src/app/history/page.tsx | 5 + frontend/src/app/layout.tsx | 5 +- frontend/src/app/page.tsx | 6 +- frontend/src/app/profile/page.tsx | 5 + frontend/src/app/test/page.tsx | 5 + frontend/src/components/layout/AppShell.tsx | 46 +- frontend/src/components/layout/Sidebar.tsx | 111 ++-- .../src/components/pages/AssistantPage.tsx | 509 ++++++++++-------- frontend/src/components/pages/HomePage.tsx | 28 +- 17 files changed, 424 insertions(+), 355 deletions(-) create mode 100644 frontend/src/app/assistants/[id]/page.tsx create mode 100644 frontend/src/app/assistants/new/page.tsx create mode 100644 frontend/src/app/assistants/page.tsx create mode 100644 frontend/src/app/components/knowledge/page.tsx create mode 100644 frontend/src/app/components/models/page.tsx create mode 100644 frontend/src/app/components/tools/page.tsx create mode 100644 frontend/src/app/dashboard/page.tsx create mode 100644 frontend/src/app/history/page.tsx create mode 100644 frontend/src/app/profile/page.tsx create mode 100644 frontend/src/app/test/page.tsx diff --git a/frontend/CLAUDE.md b/frontend/CLAUDE.md index a771f79..a90361c 100644 --- a/frontend/CLAUDE.md +++ b/frontend/CLAUDE.md @@ -14,13 +14,24 @@ npm run lint # ESLint (no test suite exists yet) ## Architecture -This is a single-page admin console for managing AI video assistants. It is a Next.js 16 app using the App Router, React 19, Tailwind CSS v4, and shadcn components backed by Radix UI primitives. +This is an admin console for managing AI video assistants. It is a Next.js 16 app using the App Router, React 19, Tailwind CSS v4, and shadcn components backed by Radix UI primitives. -**Navigation model** — the app has no Next.js routes beyond `/`. All "pages" are React components in `src/components/pages/` that are conditionally rendered by `AppShell` based on a `NavKey` state value. `AppShell` owns the active page and sidebar-collapsed state and threads them down as props. +**Navigation model** — each sidebar section is a real App Router route, so refresh/deep-link lands on the same page. Route files in `src/app/` are thin server components that render the page components from `src/components/pages/`. The route map: + +| Route | Page | +| --- | --- | +| `/` | `HomePage` | +| `/assistants` | `AssistantPage mode="list"` (助手列表) | +| `/assistants/new` | `AssistantPage mode="choose"` (引导:取名+选构建方式,确认即 POST 建库并跳转编辑页) | +| `/assistants/[id]` | `AssistantPage mode="edit"` (按 id 拉取并按类型回填编辑器) | +| `/components/{models,knowledge,tools}` | 组件库三页 | +| `/history`, `/dashboard`, `/test`, `/profile` | 其余侧栏页 | + +`AssistantPage` is one client component driven by a discriminated-union `mode` prop; all in-page transitions (创建/编辑/返回) navigate via `router.push` instead of local view state. There is no separate create form: the 引导 page creates the assistant immediately (blank fields + chosen name/type) and the editor always works against an existing id. 保存 stays on the editor page — the save button is enabled only when the form differs from the last-saved snapshot (`savedSnapshot` JSON diff), and the header back button returns to the list. **Component layers:** -- `src/app/` — Next.js entry: `layout.tsx` (fonts, theme-flash script, metadata) and `page.tsx` (renders ``) -- `src/components/layout/` — `AppShell` (page-switching shell), `Sidebar` (collapsible nav, 252 → 76px), `Topbar` (theme toggle, notifications), `ThemeToggle` +- `src/app/` — Next.js entry: `layout.tsx` (fonts, theme-flash script, metadata, wraps everything in `AppShell`) plus one thin `page.tsx` per route +- `src/components/layout/` — `AppShell` (sidebar+topbar shell around route children, owns sidebar-collapsed state), `Sidebar` (collapsible nav, 252 → 76px; `Link`-based, active state from `usePathname`), `Topbar` (theme toggle, notifications), `ThemeToggle` - `src/components/pages/` — one component per nav section; `PlaceholderPage` is a shared editorial header for unimplemented pages - `src/components/ui/` — shadcn primitives (button, card, badge, dialog, etc.) - `src/hooks/` — `use-mobile.ts` diff --git a/frontend/src/app/assistants/[id]/page.tsx b/frontend/src/app/assistants/[id]/page.tsx new file mode 100644 index 0000000..c27312b --- /dev/null +++ b/frontend/src/app/assistants/[id]/page.tsx @@ -0,0 +1,10 @@ +import { AssistantPage } from "@/components/pages/AssistantPage"; + +export default async function Page({ + params, +}: { + params: Promise<{ id: string }>; +}) { + const { id } = await params; + return ; +} diff --git a/frontend/src/app/assistants/new/page.tsx b/frontend/src/app/assistants/new/page.tsx new file mode 100644 index 0000000..5c03fe3 --- /dev/null +++ b/frontend/src/app/assistants/new/page.tsx @@ -0,0 +1,5 @@ +import { AssistantPage } from "@/components/pages/AssistantPage"; + +export default function Page() { + return ; +} diff --git a/frontend/src/app/assistants/page.tsx b/frontend/src/app/assistants/page.tsx new file mode 100644 index 0000000..b84c1b5 --- /dev/null +++ b/frontend/src/app/assistants/page.tsx @@ -0,0 +1,5 @@ +import { AssistantPage } from "@/components/pages/AssistantPage"; + +export default function Page() { + return ; +} diff --git a/frontend/src/app/components/knowledge/page.tsx b/frontend/src/app/components/knowledge/page.tsx new file mode 100644 index 0000000..b277f08 --- /dev/null +++ b/frontend/src/app/components/knowledge/page.tsx @@ -0,0 +1,5 @@ +import { ComponentsKnowledgePage } from "@/components/pages/ComponentsKnowledgePage"; + +export default function Page() { + return ; +} diff --git a/frontend/src/app/components/models/page.tsx b/frontend/src/app/components/models/page.tsx new file mode 100644 index 0000000..4e15a50 --- /dev/null +++ b/frontend/src/app/components/models/page.tsx @@ -0,0 +1,5 @@ +import { ComponentsModelsPage } from "@/components/pages/ComponentsModelsPage"; + +export default function Page() { + return ; +} diff --git a/frontend/src/app/components/tools/page.tsx b/frontend/src/app/components/tools/page.tsx new file mode 100644 index 0000000..1af9be8 --- /dev/null +++ b/frontend/src/app/components/tools/page.tsx @@ -0,0 +1,5 @@ +import { ComponentsToolsPage } from "@/components/pages/ComponentsToolsPage"; + +export default function Page() { + return ; +} diff --git a/frontend/src/app/dashboard/page.tsx b/frontend/src/app/dashboard/page.tsx new file mode 100644 index 0000000..90421bc --- /dev/null +++ b/frontend/src/app/dashboard/page.tsx @@ -0,0 +1,5 @@ +import { DashboardPage } from "@/components/pages/DashboardPage"; + +export default function Page() { + return ; +} diff --git a/frontend/src/app/history/page.tsx b/frontend/src/app/history/page.tsx new file mode 100644 index 0000000..c797c18 --- /dev/null +++ b/frontend/src/app/history/page.tsx @@ -0,0 +1,5 @@ +import { HistoryPage } from "@/components/pages/HistoryPage"; + +export default function Page() { + return ; +} diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index 4211032..f61bfff 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata } from "next"; import { Geist_Mono, Inter, Cormorant_Garamond } from "next/font/google"; import "./globals.css"; import { cn } from "@/lib/utils"; +import { AppShell } from "@/components/layout/AppShell"; const inter = Inter({ subsets: ["latin"], variable: "--font-sans" }); @@ -48,7 +49,9 @@ export default function RootLayout({