Refine wide layout and disable canvas entry

This commit is contained in:
FengLee
2026-05-12 20:38:29 +08:00
parent c674f79f07
commit 901a9ce898
13 changed files with 33 additions and 33 deletions

View File

@@ -50,7 +50,7 @@ Use this table before searching.
| Model/provider visibility | `src/lib/model-config.ts`, `src/lib/model-config-types.ts`, `src/lib/server-api-config.ts` | `src/app/api/model-config/route.ts`, `src/app/api/admin/system-apis/route.ts`, `src/app/api/admin/providers/route.ts`, `src/app/api/user-api-keys/route.ts` |
| User auth/login/register/profile | `src/lib/session-auth.ts`, `src/lib/auth-store.ts` | `src/app/api/auth/*`, `src/app/api/profile/*` |
| Admin console | `src/app/console/page.tsx`, `src/app/console/dashboard/page.tsx`, `src/modules/console/pages/*` | `src/components/admin/*`, `src/app/api/admin/*` |
| Canvas | `src/app/canvas/page.tsx`, `src/components/canvas/infinite-canvas-workspace.tsx`, `src/components/canvas/react-flow-canvas.tsx` | `src/lib/canvas-store.ts`, `src/lib/canvas-types.ts`, `src/app/api/canvas/projects/*` |
| Canvas (legacy, disabled in UI) | `src/app/canvas/page.tsx`, `src/components/canvas/infinite-canvas-workspace.tsx`, `src/components/canvas/react-flow-canvas.tsx` | `/canvas` intentionally returns 404 and navbar must not show `画布`; legacy source/API files remain only for future cleanup or explicit re-enable work. |
| Gallery and creation history | `src/app/gallery/page.tsx`, `src/app/profile/page.tsx`, `src/components/profile/creation-history-tab.tsx` | `src/lib/creation-history-store.ts`, `src/app/api/gallery/*`, `src/app/api/creation-history/route.ts` |
| Local files/downloads | `src/lib/local-storage.ts`, `src/app/api/local-storage/[...path]/route.ts` | `src/app/api/download/route.ts` |
| Email and policy pages | `src/lib/email-service.ts`, `src/components/site-policy-page.tsx` | `src/app/api/email/*`, `src/app/about/page.tsx`, `src/app/terms/page.tsx`, `src/app/privacy/page.tsx`, `src/app/help/page.tsx` |

View File

@@ -99,6 +99,8 @@ Important generation helpers:
## Canvas Routes
The public `/canvas` page is currently disabled and returns 404. These authenticated API routes remain in source as legacy canvas persistence endpoints; do not surface them in UI unless the canvas feature is explicitly re-enabled.
| Method | Path | Auth | Source | Request | Response |
| --- | --- | --- | --- | --- | --- |
| GET | `/api/canvas/projects` | User | `src/app/api/canvas/projects/route.ts` | None | `{ projects }`. |
@@ -149,4 +151,3 @@ Primary SQL tables touched directly in API routes include:
- `platform_logs`
`src/storage/database/shared/schema.ts` contains a Drizzle snapshot of core tables, while several runtime APIs add compatibility columns/tables with `CREATE TABLE IF NOT EXISTS` or `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`.

View File

@@ -52,7 +52,7 @@ Production is controlled by `ecosystem.config.cjs` and the scripts under `script
| `src/components/ui` | Radix/shadcn-style primitives. Keep generic. |
| `src/components/create` | Create center panels and shared generation UI. |
| `src/components/admin` | Admin console tab components. |
| `src/components/canvas` | Infinite canvas UI and rendering. |
| `src/components/canvas` | Legacy infinite canvas UI and rendering. The public `/canvas` route is currently disabled and should not appear in navbar unless explicitly re-enabled. |
| `src/components/profile` | Profile page tabs and API key manager. |
| `src/lib` | Business logic, stores, model config, auth, storage, email, generation jobs, provider resolution. |
| `src/modules` | Thin module export and console page wrappers. |
@@ -71,7 +71,7 @@ The app is route-driven through `src/app`:
- Create center: `src/app/create/page.tsx` plus `src/components/create/*`.
- Gallery: `src/app/gallery/page.tsx`.
- Profile: `src/app/profile/page.tsx` plus `src/components/profile/*`.
- Canvas: `src/app/canvas/page.tsx` plus `src/components/canvas/*`.
- Canvas: legacy `src/app/canvas/page.tsx` plus `src/components/canvas/*`; `/canvas` currently returns 404 and is not part of public navigation.
- Admin console: `src/app/console/*`, `src/modules/console/pages/*`, `src/components/admin/*`.
Client stores in `src/lib/*-store.ts` mediate API calls and local UI state. When fixing a UI persistence bug, inspect both the component and the matching store/API route.
@@ -90,7 +90,7 @@ Major groups:
- `generation-jobs/*`: queued generation job creation/status.
- `creation-history`: user works/history.
- `gallery/*`: public gallery and publishing.
- `canvas/projects/*`: canvas persistence.
- `canvas/projects/*`: legacy canvas persistence routes. They remain in source, but the public `/canvas` UI is disabled.
- `admin/*`: console dashboard, users, providers, system APIs, orders, payment, upgrade, data import/export, email settings.
- `site-config`, `site-stats`, `announcements`: public site content and counters.
- `local-storage/*`, `download`: file serving and download proxy.
@@ -182,7 +182,7 @@ Core data areas:
- API credentials: `user_api_keys`, `system_api_configs`, `api_providers`.
- Site content: `site_config`, `announcements`, `site_stats`.
- Jobs/logs: `generation_jobs`, `platform_logs`.
- Canvas: handled through `src/lib/canvas-store.ts` and canvas project routes.
- Canvas: legacy state handled through `src/lib/canvas-store.ts` and canvas project routes; the user-facing route is disabled.
Because several routes self-migrate compatibility columns, DB bugs often require checking both SQL scripts and route-level `ensure...Schema` functions.

View File

@@ -29,7 +29,8 @@ Use this guide when the user reports behavior. Start from the symptom row, inspe
| Footer content missing or not Markdown-rendered | `src/components/site-footer.tsx`, `src/components/site-policy-page.tsx`, `src/lib/site-config.ts`, `src/app/api/site-config/route.ts` | Config response fields, Markdown renderer, fallback defaults, PUT persistence. |
| Policy pages start mid-page after navigation | `src/components/site-policy-page.tsx`, `src/app/about/page.tsx`, `src/app/terms/page.tsx`, `src/app/privacy/page.tsx`, `src/app/help/page.tsx` | Scroll reset behavior and shared policy page wrapper. |
| Site name/logo/favicon not updating | `src/components/site-config-sync.tsx`, `src/components/site-brand.tsx`, `src/app/api/site-config/route.ts`, `src/lib/local-storage.ts` | `site_config` row, base64 image save, generated `/api/local-storage/*` URL. |
| Page content leaves large unused horizontal margins or does not fill browser width | `src/components/app-shell.tsx`, `src/components/navbar.tsx`, `src/components/site-footer.tsx`, page-level wrappers under `src/app/*/page.tsx`, `src/components/site-policy-page.tsx` | Page-level wrappers should use `w-full` with responsive padding rather than `mx-auto max-w-*`; keep only local cards/dialogs/readability blocks constrained. |
| Page content leaves large unused horizontal margins, or wide screens look like the UI was simply enlarged | `src/components/app-shell.tsx`, `src/components/navbar.tsx`, `src/components/site-footer.tsx`, page-level wrappers under `src/app/*/page.tsx`, `src/components/site-policy-page.tsx` | The viewport/background should be `w-full`, but content should use wide adaptive containers such as `max-w-[1680px]` plus responsive padding. Do not fix this by removing all max widths; keep text, tabs, policy articles, and compact controls constrained for readability. |
| Disabled canvas/`画布` appears again in public UI | `src/components/navbar.tsx`, `src/app/canvas/page.tsx`, `docs/codex-miaojing/feature-code-index.md` | Navbar should not include `/canvas`, and `/canvas` should continue to call `notFound()` unless the product explicitly re-enables the legacy canvas feature. |
| Announcement not popping up | `src/components/announcement-popup.tsx`, `src/app/api/announcements/route.ts`, `src/components/app-shell.tsx` | App shell includes popup, active date range, local/session dismissal behavior, GET payload shape. |
| Announcement admin edit fails | `src/components/admin/announcement-tab.tsx`, `src/app/api/announcements/route.ts` | Admin token, required fields, `starts_at`/`expires_at` compatibility. |
@@ -73,7 +74,7 @@ Use this guide when the user reports behavior. Start from the symptom row, inspe
| Symptom | Check Files | What To Verify |
| --- | --- | --- |
| Canvas projects not listed | `src/app/canvas/page.tsx`, `src/components/canvas/infinite-canvas-workspace.tsx`, `src/app/api/canvas/projects/route.ts`, `src/lib/canvas-store.ts` | Auth token, `listCanvasProjects(userId)`, DB/local persistence assumptions. |
| Canvas projects not listed | `src/app/canvas/page.tsx`, `src/components/canvas/infinite-canvas-workspace.tsx`, `src/app/api/canvas/projects/route.ts`, `src/lib/canvas-store.ts` | Legacy-only while `/canvas` is disabled. First confirm the product intentionally re-enabled canvas; otherwise keep the route hidden/404. |
| Canvas save drops nodes/groups/connections | `src/lib/canvas-store.ts`, `src/lib/canvas-types.ts`, `src/components/canvas/infinite-canvas-workspace.tsx` | `normalizeCanvasState` preserves all state fields and types. |
| Connection lines missing/duplicated/ugly | `src/components/canvas/react-flow-canvas.tsx`, `src/lib/canvas-types.ts` | Single render source, no duplicate React Flow edges plus overlay lines unless intentional. |
| Canvas image proportions wrong | `src/lib/canvas-types.ts`, `src/components/canvas/react-flow-canvas.tsx`, `src/components/canvas/infinite-canvas-workspace.tsx` | Stored image dimensions and render sizing. |

View File

@@ -8,10 +8,10 @@ Use this document to jump directly to code before broad searching.
| Feature | Primary Files | Notes |
| --- | --- | --- |
| Root layout and providers | `src/app/layout.tsx`, `src/components/app-shell.tsx` | App shell wires navbar, site config sync, visit tracking, theme/account sync, toaster, and full-width page mounting. |
| Root layout and providers | `src/app/layout.tsx`, `src/components/app-shell.tsx` | App shell wires navbar, site config sync, visit tracking, theme/account sync, toaster, and full-width page mounting. Use wide adaptive containers inside pages instead of stretching all content to viewport edges. |
| Home page | `src/app/page.tsx` | Landing/dashboard-like public entry. Check site config dependencies when changing brand text. |
| Navbar | `src/components/navbar.tsx`, `src/components/site-brand.tsx` | Navigation, brand display, auth-aware links. |
| Footer | `src/components/site-footer.tsx` | Uses site config for policy/help/about links and filing text; page-level footer content should span browser width. |
| Navbar | `src/components/navbar.tsx`, `src/components/site-brand.tsx` | Navigation, brand display, auth-aware links. User-facing nav intentionally excludes the disabled legacy canvas route. |
| Footer | `src/components/site-footer.tsx` | Uses site config for policy/help/about links and filing text; footer background spans browser width while inner content uses the shared wide adaptive width. |
| Announcement popup | `src/components/announcement-popup.tsx`, `src/app/api/announcements/route.ts` | Frontend popup behavior plus backend announcement CRUD. |
| Site config sync | `src/components/site-config-sync.tsx`, `src/lib/site-config.ts`, `src/app/api/site-config/route.ts` | Site name, tab title, logo, favicon, policy Markdown, filing, membership switch. |
| Visit tracking | `src/components/visit-tracker.tsx`, `src/app/api/site-stats/route.ts` | Public visit counter. |
@@ -24,7 +24,7 @@ Use this document to jump directly to code before broad searching.
| `/create` | `src/app/create/page.tsx` | `src/components/create/*` |
| `/gallery` | `src/app/gallery/page.tsx` | `src/lib/creation-history-store.ts`, `src/app/api/gallery/route.ts` |
| `/profile` | `src/app/profile/page.tsx` | `src/components/profile/*`, `src/app/api/profile/route.ts` |
| `/canvas` | `src/app/canvas/page.tsx` | `src/components/canvas/*`, `src/lib/canvas-store.ts` |
| `/canvas` | `src/app/canvas/page.tsx` | Disabled legacy route; currently calls `notFound()` and must not be linked from navbar. |
| `/about` | `src/app/about/page.tsx` | `src/components/site-policy-page.tsx`, `src/lib/site-policy-defaults.ts` |
| `/terms` | `src/app/terms/page.tsx` | `src/components/site-policy-page.tsx` |
| `/privacy` | `src/app/privacy/page.tsx` | `src/components/site-policy-page.tsx` |
@@ -110,9 +110,9 @@ Use this document to jump directly to code before broad searching.
| Feature | Files | Notes |
| --- | --- | --- |
| Canvas page | `src/app/canvas/page.tsx` | Page entry. |
| Workspace | `src/components/canvas/infinite-canvas-workspace.tsx` | High-level canvas UI, project interaction. |
| React Flow canvas | `src/components/canvas/react-flow-canvas.tsx` | Node/edge/rendering interactions. |
| Canvas page | `src/app/canvas/page.tsx` | Disabled legacy route; keep it returning 404 unless the product explicitly re-enables canvas. |
| Workspace | `src/components/canvas/infinite-canvas-workspace.tsx` | Legacy high-level canvas UI, project interaction. Not user-facing while `/canvas` is disabled. |
| React Flow canvas | `src/components/canvas/react-flow-canvas.tsx` | Legacy node/edge/rendering interactions. |
| Canvas state types | `src/lib/canvas-types.ts` | Canonical node, layer, viewport, connection types. |
| Canvas persistence | `src/lib/canvas-store.ts` | Normalize/list/create/get/update/delete projects. |
| Canvas APIs | `src/app/api/canvas/projects/route.ts`, `src/app/api/canvas/projects/[id]/route.ts` | Authenticated project CRUD. |

View File

@@ -1,5 +1,5 @@
import { InfiniteCanvasWorkspace } from '@/components/canvas/infinite-canvas-workspace';
import { notFound } from 'next/navigation';
export default function CanvasPage() {
return <InfiniteCanvasWorkspace />;
notFound();
}

View File

@@ -26,7 +26,7 @@ function CreateContent() {
return (
<Tabs value={activeTab} onValueChange={setActiveTab} className="space-y-6">
<TabsList className="grid w-full grid-cols-5">
<TabsList className="mx-auto grid w-full max-w-5xl grid-cols-5">
<TabsTrigger value="text2img" className="gap-2">
<Brush className="h-4 w-4" />
<span className="hidden sm:inline"></span>
@@ -74,7 +74,7 @@ function CreateContent() {
export default function CreatePage() {
return (
<div className="min-h-screen bg-background">
<div className="w-full px-4 sm:px-6 py-8">
<div className="mx-auto w-full max-w-[1680px] px-4 py-8 sm:px-6 lg:px-8 2xl:px-10">
<div className="mb-8">
<h1 className="font-serif text-3xl font-bold"></h1>
<p className="mt-2 text-muted-foreground">

View File

@@ -424,7 +424,7 @@ export default function GalleryPage() {
return (
<div className="min-h-screen bg-background">
<div className="w-full px-4 sm:px-6 py-8">
<div className="mx-auto w-full max-w-[1800px] px-4 py-8 sm:px-6 lg:px-8 2xl:px-10">
{/* Header */}
<div className="mb-8">
<div className="flex items-center gap-3">

View File

@@ -107,7 +107,7 @@ export default function HomePage() {
<div className="absolute bottom-0 right-0 w-[400px] h-[400px] bg-primary/3 rounded-full blur-[100px]" />
</div>
<div className="w-full px-4 sm:px-6 pt-20 pb-24 text-center">
<div className="mx-auto w-full max-w-[1440px] px-4 pb-24 pt-20 text-center sm:px-6 lg:px-8">
<Badge variant="secondary" className="mb-6 px-4 py-1.5 text-sm font-medium gap-2">
<SiteLogo className="h-5 w-5 rounded" />
AI多模态创作平台
@@ -157,7 +157,7 @@ export default function HomePage() {
{/* Core Features */}
<section className="py-24 bg-muted/20">
<div className="w-full px-4 sm:px-6">
<div className="mx-auto w-full max-w-[1680px] px-4 sm:px-6 lg:px-8 2xl:px-10">
<div className="text-center mb-16">
<h2 className="font-serif text-3xl sm:text-4xl font-bold"></h2>
<p className="mt-4 text-muted-foreground text-lg">AI创作体验</p>
@@ -193,7 +193,7 @@ export default function HomePage() {
{/* Highlights */}
<section className="py-24">
<div className="w-full px-4 sm:px-6">
<div className="mx-auto w-full max-w-[1440px] px-4 sm:px-6 lg:px-8">
<div className="text-center mb-16">
<h2 className="font-serif text-3xl sm:text-4xl font-bold"></h2>
<p className="mt-4 text-muted-foreground text-lg"></p>
@@ -219,7 +219,7 @@ export default function HomePage() {
{/* Pricing */}
<BillingPlanGuard>
<section className="py-24 bg-muted/20">
<div className="w-full px-4 sm:px-6">
<div className="mx-auto w-full max-w-[1680px] px-4 sm:px-6 lg:px-8 2xl:px-10">
<div className="text-center mb-16">
<h2 className="font-serif text-3xl sm:text-4xl font-bold"></h2>
<p className="mt-4 text-muted-foreground text-lg"></p>
@@ -271,7 +271,7 @@ export default function HomePage() {
{/* CTA */}
<section className="py-24">
<div className="w-full px-4 sm:px-6 text-center">
<div className="mx-auto w-full max-w-[1120px] px-4 text-center sm:px-6 lg:px-8">
<h2 className="font-serif text-3xl sm:text-4xl font-bold"></h2>
<p className="mt-4 text-lg text-muted-foreground">
AI开启你的创作之旅

View File

@@ -411,7 +411,7 @@ export default function ProfilePage() {
if (!mounted) {
return (
<div className="min-h-screen bg-background">
<div className="w-full px-4 sm:px-6 py-8">
<div className="mx-auto w-full max-w-[1680px] px-4 py-8 sm:px-6 lg:px-8 2xl:px-10">
<div className="mb-8">
<div className="flex items-center gap-4">
<div className="h-16 w-16 rounded-full bg-muted animate-pulse" />
@@ -428,7 +428,7 @@ export default function ProfilePage() {
return (
<div className="min-h-screen bg-background">
<div className="w-full px-4 sm:px-6 py-8">
<div className="mx-auto w-full max-w-[1680px] px-4 py-8 sm:px-6 lg:px-8 2xl:px-10">
{/* Profile Header */}
<div className="mb-8">
<div className="flex items-center justify-between">
@@ -518,7 +518,7 @@ export default function ProfilePage() {
{/* Tabs */}
<Tabs value={activeTab} onValueChange={setActiveTab}>
<TabsList className={`grid w-full grid-cols-3 ${membershipEnabled ? 'sm:grid-cols-6' : 'sm:grid-cols-3'}`}>
<TabsList className={`grid w-full max-w-5xl grid-cols-3 ${membershipEnabled ? 'sm:grid-cols-6' : 'sm:grid-cols-3'}`}>
<TabsTrigger value="account" className="gap-1.5"><User className="h-4 w-4" /><span className="hidden sm:inline"></span></TabsTrigger>
{membershipEnabled && <TabsTrigger value="membership" className="gap-1.5"><Crown className="h-4 w-4" /><span className="hidden sm:inline"></span></TabsTrigger>}
{membershipEnabled && <TabsTrigger value="credits" className="gap-1.5"><Coins className="h-4 w-4" /><span className="hidden sm:inline"></span></TabsTrigger>}

View File

@@ -17,7 +17,6 @@ import {
Sparkles,
LogOut,
Shield,
PanelsTopLeft,
Moon,
Sun,
} from 'lucide-react';
@@ -27,7 +26,6 @@ const navItems = [
{ href: '/', label: '首页', icon: Sparkles },
{ href: '/create', label: '创作', icon: Brush },
{ href: '/gallery', label: '画廊', icon: LayoutGrid },
{ href: '/canvas', label: '画布', icon: PanelsTopLeft },
{ href: '/profile', label: '我的', icon: User },
];
@@ -94,7 +92,7 @@ export function Navbar() {
return (
<header className="sticky top-0 z-50 w-full border-b border-border/50 bg-background/80 backdrop-blur-xl">
<div className="flex h-16 w-full items-center justify-between px-4 sm:px-6">
<div className="mx-auto flex h-16 w-full max-w-[1680px] items-center justify-between px-4 sm:px-6 lg:px-8 2xl:px-10">
{/* Logo */}
<Link href="/" className="flex items-center gap-2.5 group">
<img

View File

@@ -18,7 +18,7 @@ export function SiteFooter() {
return (
<footer className="border-t border-border/50 py-12">
<div className="w-full px-4 sm:px-6">
<div className="mx-auto w-full max-w-[1680px] px-4 sm:px-6 lg:px-8 2xl:px-10">
<div className="flex flex-col gap-5 sm:flex-row sm:items-start sm:justify-between">
<div className="flex flex-col gap-2 text-center sm:text-left">
<div className="flex items-center justify-center gap-2 sm:justify-start">

View File

@@ -21,7 +21,7 @@ export function SitePolicyPage({ kind }: { kind: PolicyPageKind }) {
return (
<main className="min-h-screen bg-background">
<div className="flex min-h-screen w-full flex-col px-4 py-10 sm:px-6">
<div className="mx-auto flex min-h-screen w-full max-w-[1120px] flex-col px-4 py-10 sm:px-6 lg:px-8">
<header className="mb-10 flex items-center justify-between gap-4">
<Link href="/" className="inline-flex items-center gap-2">
<SiteLogo className="h-8 w-8 rounded" />