feat: route structure, providers, layouts, and placeholder pages

This commit is contained in:
zetaloop
2026-02-20 12:43:34 +08:00
parent 1f87f4676e
commit 3093da1665
35 changed files with 324 additions and 70 deletions
+16
View File
@@ -0,0 +1,16 @@
export default function AccountLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex min-h-screen">
<aside className="w-64 border-r bg-muted/30 p-4">
<h2 className="mb-4 text-lg font-semibold"></h2>
<nav className="space-y-2 text-sm text-muted-foreground">
<div></div>
<div></div>
<div></div>
<div></div>
</nav>
</aside>
<main className="flex-1 p-6">{children}</main>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function NotificationsPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function SettingsPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function VerifyPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function WalletPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+9
View File
@@ -0,0 +1,9 @@
export default function AuthLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex min-h-screen items-center justify-center bg-muted/30">
<div className="w-full max-w-md rounded-lg border bg-background p-6 shadow-sm">
{children}
</div>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function LoginPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-sm text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function RegisterPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-sm text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function DashboardPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
@@ -0,0 +1,8 @@
export default function NewServicePage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
@@ -0,0 +1,8 @@
export default function ServicesPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
@@ -0,0 +1,8 @@
export default function EmployeesPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function ShopManagementPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
@@ -0,0 +1,8 @@
export default function ShopTemplatesPage() {
return (
<div>
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+15
View File
@@ -0,0 +1,15 @@
export default function DashboardLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex min-h-screen">
<aside className="w-64 border-r bg-muted/30 p-4">
<h2 className="mb-4 text-lg font-semibold"></h2>
<nav className="space-y-2 text-sm text-muted-foreground">
<div></div>
<div></div>
<div></div>
</nav>
</aside>
<main className="flex-1 p-6">{children}</main>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function CommunityPage() {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+20
View File
@@ -0,0 +1,20 @@
export default function MainLayout({ children }: { children: React.ReactNode }) {
return (
<div className="flex min-h-screen flex-col">
<header className="border-b">
<nav className="container mx-auto flex h-16 items-center justify-between px-4">
<span className="text-xl font-bold"></span>
<div className="flex items-center gap-4">
<span className="text-sm text-muted-foreground"></span>
</div>
</nav>
</header>
<main className="flex-1">{children}</main>
<footer className="border-t py-6">
<div className="container mx-auto px-4 text-center text-sm text-muted-foreground">
© -
</div>
</footer>
</div>
)
}
+22
View File
@@ -0,0 +1,22 @@
export default function HomePage() {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-3xl font-bold"></h1>
<p className="mt-2 text-lg text-muted-foreground"></p>
<div className="mt-8 grid gap-6 md:grid-cols-2 lg:grid-cols-3">
<div className="rounded-lg border p-6">
<h2 className="font-semibold"></h2>
<p className="mt-1 text-sm text-muted-foreground"></p>
</div>
<div className="rounded-lg border p-6">
<h2 className="font-semibold"></h2>
<p className="mt-1 text-sm text-muted-foreground"></p>
</div>
<div className="rounded-lg border p-6">
<h2 className="font-semibold"></h2>
<p className="mt-1 text-sm text-muted-foreground"></p>
</div>
</div>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function PlayerDetailPage({ params: _params }: { params: Promise<{ id: string }> }) {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function PostDetailPage({ params: _params }: { params: Promise<{ id: string }> }) {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function NewPostPage() {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function SearchPage() {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function ShopDetailPage({ params: _params }: { params: Promise<{ id: string }> }) {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function ChatDetailPage({ params: _params }: { params: Promise<{ id: string }> }) {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function ChatListPage() {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function DisputePage({ params: _params }: { params: Promise<{ id: string }> }) {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+3
View File
@@ -0,0 +1,3 @@
export default function OrderLayout({ children }: { children: React.ReactNode }) {
return <div className="min-h-screen bg-muted/30">{children}</div>
}
+8
View File
@@ -0,0 +1,8 @@
export default function OrderDetailPage({ params: _params }: { params: Promise<{ id: string }> }) {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function OrderListPage() {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+8
View File
@@ -0,0 +1,8 @@
export default function ReviewPage({ params: _params }: { params: Promise<{ id: string }> }) {
return (
<div className="container mx-auto py-8 px-4">
<h1 className="text-2xl font-bold"></h1>
<p className="mt-2 text-muted-foreground"></p>
</div>
)
}
+7 -4
View File
@@ -1,5 +1,6 @@
import type { Metadata } from "next"
import { Geist, Geist_Mono } from "next/font/google"
import { Providers } from "./providers"
import "./globals.css"
const geistSans = Geist({
@@ -13,8 +14,8 @@ const geistMono = Geist_Mono({
})
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
title: "聚玩",
description: "游戏陪玩服务平台",
}
export default function RootLayout({
@@ -23,8 +24,10 @@ export default function RootLayout({
children: React.ReactNode
}>) {
return (
<html lang="en">
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>{children}</body>
<html lang="zh-CN">
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
<Providers>{children}</Providers>
</body>
</html>
)
}
-65
View File
@@ -1,65 +0,0 @@
import Image from "next/image"
export default function Home() {
return (
<div className="flex min-h-screen items-center justify-center bg-zinc-50 font-sans dark:bg-black">
<main className="flex min-h-screen w-full max-w-3xl flex-col items-center justify-between py-32 px-16 bg-white dark:bg-black sm:items-start">
<Image
className="dark:invert"
src="/next.svg"
alt="Next.js logo"
width={100}
height={20}
priority
/>
<div className="flex flex-col items-center gap-6 text-center sm:items-start sm:text-left">
<h1 className="max-w-xs text-3xl font-semibold leading-10 tracking-tight text-black dark:text-zinc-50">
To get started, edit the page.tsx file.
</h1>
<p className="max-w-md text-lg leading-8 text-zinc-600 dark:text-zinc-400">
Looking for a starting point or more instructions? Head over to{" "}
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="font-medium text-zinc-950 dark:text-zinc-50"
>
Templates
</a>{" "}
or the{" "}
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="font-medium text-zinc-950 dark:text-zinc-50"
>
Learning
</a>{" "}
center.
</p>
</div>
<div className="flex flex-col gap-4 text-base font-medium sm:flex-row">
<a
className="flex h-12 w-full items-center justify-center gap-2 rounded-full bg-foreground px-5 text-background transition-colors hover:bg-[#383838] dark:hover:bg-[#ccc] md:w-[158px]"
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
<Image
className="dark:invert"
src="/vercel.svg"
alt="Vercel logomark"
width={16}
height={16}
/>
Deploy Now
</a>
<a
className="flex h-12 w-full items-center justify-center rounded-full border border-solid border-black/[.08] px-5 transition-colors hover:border-transparent hover:bg-black/[.04] dark:border-white/[.145] dark:hover:bg-[#1a1a1a] md:w-[158px]"
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Documentation
</a>
</div>
</main>
</div>
)
}
+20
View File
@@ -0,0 +1,20 @@
"use client"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import { useState } from "react"
export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000,
refetchOnWindowFocus: false,
},
},
}),
)
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
}
+1 -1
View File
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts"
import "./.next/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
+19
View File
@@ -0,0 +1,19 @@
import { create } from "zustand"
export type UserRole = "consumer" | "player" | "owner"
interface AuthState {
isAuthenticated: boolean
currentRole: UserRole
switchRole: (role: UserRole) => void
login: () => void
logout: () => void
}
export const useAuthStore = create<AuthState>((set) => ({
isAuthenticated: false,
currentRole: "consumer",
switchRole: (role) => set({ currentRole: role }),
login: () => set({ isAuthenticated: true }),
logout: () => set({ isAuthenticated: false, currentRole: "consumer" }),
}))