feat(ui): unify content shell layout

This commit is contained in:
zetaloop
2026-04-26 01:53:15 +08:00
parent 30c336345e
commit 58dc001146
16 changed files with 42 additions and 39 deletions
+3 -3
View File
@@ -4,13 +4,13 @@ import { Header } from "@/components/header"
export default function AccountLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex min-h-screen flex-col">
<div className="flex min-h-screen flex-col bg-muted/20">
<Header />
<div className="container mx-auto flex flex-1 px-4">
<div className="mx-auto flex w-full max-w-5xl flex-1 px-4">
<div className="hidden md:block">
<AccountSidebar />
</div>
<main className="flex-1 p-6">
<main className="flex-1 py-8 md:px-6">
<AuthGuard>{children}</AuthGuard>
</main>
</div>
+1 -1
View File
@@ -223,7 +223,7 @@ export default function NotificationsPage() {
)
return (
<div className="container mx-auto max-w-2xl px-4 py-8 space-y-6">
<div className="mx-auto max-w-2xl space-y-6">
<div className="flex items-center justify-between pb-2 border-b border-border/40">
<div className="flex items-center gap-3">
<h1 className="text-2xl font-bold tracking-tight"></h1>
+1 -1
View File
@@ -94,7 +94,7 @@ export default function SettingsPage() {
}
return (
<div className="container mx-auto max-w-2xl px-4 py-8 space-y-6">
<div className="mx-auto max-w-2xl space-y-6">
<h1 className="text-2xl font-bold"></h1>
<Card>
+1 -1
View File
@@ -156,7 +156,7 @@ export default function VerifyPage() {
}
return (
<div className="container mx-auto max-w-2xl px-4 py-8 space-y-8">
<div className="mx-auto max-w-2xl space-y-8">
<h1 className="text-2xl font-bold"></h1>
<section className="space-y-4">
+1 -1
View File
@@ -202,7 +202,7 @@ export default function WalletPage() {
}
return (
<div className="container mx-auto max-w-2xl px-4 py-8 space-y-6">
<div className="mx-auto max-w-2xl space-y-6">
<h1 className="text-2xl font-bold"></h1>
<Card className="border-border/60 shadow-sm">
+2 -2
View File
@@ -7,9 +7,9 @@ import { RoleGuard } from "@/components/role-guard"
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex min-h-screen flex-col">
<div className="flex min-h-screen flex-col bg-muted/20">
<Header />
<div className="container mx-auto flex flex-1 px-4">
<div className="mx-auto flex w-full max-w-7xl flex-1 px-4">
<div className="hidden md:block">
<DashboardSidebar />
</div>
+1 -1
View File
@@ -3,7 +3,7 @@ import { Header } from "@/components/header"
export default function MainLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex min-h-screen flex-col">
<div className="flex min-h-screen flex-col bg-muted/20">
<Header />
<main className="flex-1">{children}</main>
<Footer />
+1 -1
View File
@@ -103,7 +103,7 @@ export default function ChatDetailPage({ params }: { params: Promise<{ id: strin
const other = session.participants.find((p) => p.id !== userId) ?? session.participants[0]
return (
<div className="container mx-auto max-w-3xl px-4 py-8 h-[calc(100vh-3.5rem)] flex flex-col">
<div className="container mx-auto max-w-2xl px-4 py-8 h-[calc(100vh-3.5rem)] flex flex-col">
<Card className="flex-1 flex flex-col overflow-hidden border-border/80 shadow-sm">
<div className="border-b border-border/60 px-4 py-3 flex items-center gap-3 bg-background">
<Link href="/chat" className="text-muted-foreground hover:text-foreground">
+5 -5
View File
@@ -197,7 +197,7 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
if (loading) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState title="争议加载中" icon={Clock} />
</div>
)
@@ -205,7 +205,7 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
if (!order) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState title="订单不存在" description="无法找到对应订单。" icon={FileText} />
</div>
)
@@ -216,7 +216,7 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
)
if (!isParticipant) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState
title="无法访问争议页面"
description="仅该订单参与方可访问争议页面。"
@@ -474,7 +474,7 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
if (showSubmitted) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState
title="争议已提交,请等待平台处理"
description={`平台将在约 ${Math.floor(DISPUTE_TO_RESOLVED_MS / 1000)} 秒内给出模拟处理结果。`}
@@ -490,7 +490,7 @@ export default function DisputePage({ params }: { params: Promise<{ id: string }
}
return (
<div className="container mx-auto max-w-lg px-4 py-8 space-y-4">
<div className="container mx-auto max-w-2xl px-4 py-8 space-y-4">
<Link
href={`/order/${id}`}
className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
+2 -4
View File
@@ -12,11 +12,9 @@ export default function OrderLayout({ children }: { children: React.ReactNode })
)
return (
<div className="flex min-h-screen flex-col">
<div className="flex min-h-screen flex-col bg-muted/20">
<Header />
<main className="flex-1 bg-muted/30">
{shouldGuard ? <AuthGuard>{children}</AuthGuard> : children}
</main>
<main className="flex-1">{shouldGuard ? <AuthGuard>{children}</AuthGuard> : children}</main>
</div>
)
}
+1 -1
View File
@@ -167,7 +167,7 @@ export default function OrderDetailPage({ params }: { params: Promise<{ id: stri
})()
return (
<div className="container mx-auto py-8 px-4 max-w-3xl">
<div className="container mx-auto py-8 px-4 max-w-2xl">
<Link
href="/orders"
className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground mb-4"
+3 -3
View File
@@ -95,7 +95,7 @@ export default function NewOrderPage() {
if (loading) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState title="加载中" description="正在读取服务信息..." icon={CreditCard} />
</div>
)
@@ -103,7 +103,7 @@ export default function NewOrderPage() {
if (!service || !player) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState title="服务不存在" description="该服务可能已下架或暂不可访问。" />
</div>
)
@@ -113,7 +113,7 @@ export default function NewOrderPage() {
if (submitted) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState
title="下单成功"
description="订单已创建,等待打手接单。你可以在订单列表中查看进度。"
+4 -4
View File
@@ -75,7 +75,7 @@ export default function OrderListPage() {
if (currentRole === "owner" && shopLoading) {
return (
<div className="container mx-auto max-w-3xl px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState title="加载中" description="正在读取店铺订单视角..." icon={RefreshCw} />
</div>
)
@@ -83,7 +83,7 @@ export default function OrderListPage() {
if (currentRole === "owner" && shopError) {
return (
<div className="container mx-auto max-w-3xl px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState title="无法读取订单" description={shopError} icon={ClipboardList} />
</div>
)
@@ -175,7 +175,7 @@ function OrderListContent({
})
return (
<div className="container mx-auto max-w-3xl px-4 py-8 space-y-6">
<div className="container mx-auto max-w-2xl px-4 py-8 space-y-6">
<div className="flex items-center justify-between">
<h1 className="text-2xl font-bold"></h1>
<Badge variant="outline" className="text-xs">
@@ -216,7 +216,7 @@ function OrderListContent({
filtered.map((order) => (
<Card key={order.id} className="border-border/80 shadow-sm">
<CardHeader className="pb-3">
<div className="flex items-center justify-between">
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<CardTitle className="text-base">{order.service.title}</CardTitle>
<StatusBadge
status={statusVariants[order.status]}
+6 -6
View File
@@ -55,7 +55,7 @@ export default function ReviewPage({ params }: { params: Promise<{ id: string }>
if (loading) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState title="加载中" description="正在读取评价信息..." icon={Star} />
</div>
)
@@ -63,7 +63,7 @@ export default function ReviewPage({ params }: { params: Promise<{ id: string }>
if (!order) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState title="订单不存在" description="该订单可能已被删除或暂不可访问。" />
</div>
)
@@ -74,7 +74,7 @@ export default function ReviewPage({ params }: { params: Promise<{ id: string }>
if (order.status !== "pending_review") {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState
title="当前阶段不可评价"
description="仅待评价状态的订单可以提交评价。"
@@ -91,7 +91,7 @@ export default function ReviewPage({ params }: { params: Promise<{ id: string }>
if (hasSubmitted && !isRevealed) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState
title="评价已提交"
description="等待对方提交评价,双方都提交后将同时揭晓。"
@@ -108,7 +108,7 @@ export default function ReviewPage({ params }: { params: Promise<{ id: string }>
if (hasSubmitted && isRevealed) {
return (
<div className="container mx-auto max-w-lg px-4 py-8">
<div className="container mx-auto max-w-2xl px-4 py-8">
<EmptyState
title="评价已揭晓"
description="双方评价已同步公开,可在订单详情查看。"
@@ -124,7 +124,7 @@ export default function ReviewPage({ params }: { params: Promise<{ id: string }>
}
return (
<div className="container mx-auto max-w-lg px-4 py-8 space-y-4">
<div className="container mx-auto max-w-2xl px-4 py-8 space-y-4">
<Link
href={`/order/${id}`}
className="inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground"
+1 -1
View File
@@ -17,7 +17,7 @@ export function AccountSidebar() {
const pathname = usePathname()
return (
<aside className="w-56 shrink-0 border-r border-border/60">
<aside className="w-56 shrink-0 border-r border-border/60 bg-background/80">
<div className="flex h-14 items-center border-b border-border/60 px-6 font-semibold">
</div>
+9 -4
View File
@@ -40,8 +40,8 @@ export function DashboardSidebar() {
const links = currentRole === "owner" ? ownerLinks : playerLinks
return (
<aside className="w-56 shrink-0 border-r bg-muted/30">
<div className="flex h-14 items-center gap-2 border-b px-4 font-semibold">
<aside className="w-56 shrink-0 border-r border-border/60 bg-background/80">
<div className="flex h-14 items-center gap-2 border-b border-border/60 px-4 font-semibold">
<Gamepad2 className="h-4 w-4" />
</div>
@@ -52,8 +52,13 @@ export function DashboardSidebar() {
return (
<Button
key={link.href}
variant={isActive ? "secondary" : "ghost"}
className={cn("w-full justify-start", !isActive && "text-muted-foreground")}
variant="ghost"
className={cn(
"h-10 w-full justify-start rounded-md border-l-2 transition-colors",
isActive
? "border-primary bg-primary/5 text-foreground font-medium"
: "border-transparent text-muted-foreground hover:bg-accent/50 hover:text-foreground",
)}
asChild
>
<Link href={link.href}>