Refine wide layout and disable canvas entry
This commit is contained in:
@@ -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` |
|
||||
|
||||
@@ -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`.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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. |
|
||||
|
||||
@@ -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. |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { InfiniteCanvasWorkspace } from '@/components/canvas/infinite-canvas-workspace';
|
||||
import { notFound } from 'next/navigation';
|
||||
|
||||
export default function CanvasPage() {
|
||||
return <InfiniteCanvasWorkspace />;
|
||||
notFound();
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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开启你的创作之旅
|
||||
|
||||
@@ -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>}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user