Make pages full width and center count options
This commit is contained in:
@@ -29,6 +29,7 @@ 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. |
|
||||
| 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. |
|
||||
|
||||
|
||||
@@ -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, and toaster. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
| 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. |
|
||||
|
||||
@@ -26,7 +26,7 @@ function CreateContent() {
|
||||
|
||||
return (
|
||||
<Tabs value={activeTab} onValueChange={setActiveTab} className="space-y-6">
|
||||
<TabsList className="grid w-full grid-cols-5 max-w-4xl">
|
||||
<TabsList className="grid w-full 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="mx-auto max-w-7xl px-4 sm:px-6 py-8">
|
||||
<div className="w-full px-4 sm:px-6 py-8">
|
||||
<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="mx-auto max-w-7xl px-4 sm:px-6 py-8">
|
||||
<div className="w-full px-4 sm:px-6 py-8">
|
||||
{/* 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="mx-auto max-w-7xl px-4 sm:px-6 pt-20 pb-24 text-center">
|
||||
<div className="w-full px-4 sm:px-6 pt-20 pb-24 text-center">
|
||||
<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="mx-auto max-w-7xl px-4 sm:px-6">
|
||||
<div className="w-full px-4 sm:px-6">
|
||||
<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="mx-auto max-w-7xl px-4 sm:px-6">
|
||||
<div className="w-full px-4 sm:px-6">
|
||||
<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="mx-auto max-w-7xl px-4 sm:px-6">
|
||||
<div className="w-full px-4 sm:px-6">
|
||||
<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="mx-auto max-w-4xl px-4 sm:px-6 text-center">
|
||||
<div className="w-full px-4 sm:px-6 text-center">
|
||||
<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="mx-auto max-w-7xl px-4 sm:px-6 py-8">
|
||||
<div className="w-full px-4 sm:px-6 py-8">
|
||||
<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="mx-auto max-w-7xl px-4 sm:px-6 py-8">
|
||||
<div className="w-full px-4 sm:px-6 py-8">
|
||||
{/* 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'} max-w-3xl`}>
|
||||
<TabsList className={`grid w-full 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>}
|
||||
|
||||
@@ -18,7 +18,7 @@ export function AppShell({ children }: { children: ReactNode }) {
|
||||
<AccountThemeSync />
|
||||
{!isConsole && <VisitTracker />}
|
||||
{!isConsole && <Navbar />}
|
||||
<main>{children}</main>
|
||||
<main className="min-w-0 w-full">{children}</main>
|
||||
<Toaster />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -87,7 +87,7 @@ export function ImageCountCombobox({ value, onChange, className }: ImageCountCom
|
||||
role="option"
|
||||
aria-selected={value === option.value}
|
||||
className={cn(
|
||||
'focus:bg-accent focus:text-accent-foreground flex min-h-8 w-full items-center rounded-sm px-2 text-sm outline-none',
|
||||
'focus:bg-accent focus:text-accent-foreground flex min-h-8 w-full items-center justify-center rounded-sm px-2 text-center text-sm outline-none',
|
||||
value === option.value && 'bg-accent text-accent-foreground',
|
||||
)}
|
||||
onMouseDown={event => event.preventDefault()}
|
||||
|
||||
@@ -94,7 +94,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="mx-auto flex h-16 max-w-7xl items-center justify-between px-4 sm:px-6">
|
||||
<div className="flex h-16 w-full items-center justify-between px-4 sm:px-6">
|
||||
{/* 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="mx-auto max-w-7xl px-4 sm:px-6">
|
||||
<div className="w-full px-4 sm:px-6">
|
||||
<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="mx-auto flex min-h-screen w-full max-w-3xl flex-col px-4 py-10 sm:px-6">
|
||||
<div className="flex min-h-screen w-full flex-col px-4 py-10 sm:px-6">
|
||||
<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