chore: Add Next.js project config and app entry for admin-web
The previous deploy.sh commit included Dockerfile and docker-compose
but was missing the actual Next.js project files needed for `npm ci`
and `npm run build` to succeed. This adds the complete project skeleton.
## Project configuration files
### package.json
- Next.js 15.1.11, React 18, TypeScript 5.9
- Dependencies: @reduxjs/toolkit, @tanstack/react-query,
@tanstack/react-table, axios, recharts, zustand, dayjs, clsx
- Scripts: dev, build, start, lint, format, type-check
### next.config.ts
- output: 'standalone' — required for Docker multi-stage build
- / redirects to /dashboard
- Remote image patterns enabled
### tsconfig.json
- Strict mode, bundler module resolution
- Path alias: @/* → ./src/*
- Incremental compilation enabled
### .gitignore / .dockerignore
- Standard Next.js ignores (node_modules, .next, out, coverage)
- Docker build excludes dev files, docs, git, IDE configs
## App Router entry files
### src/app/layout.tsx — Root layout
- HTML lang="zh-CN", imports globals.css + design-tokens.css
- Wraps children with Providers (placeholder for Redux/RQ/Auth)
### src/app/providers.tsx — Client-side providers wrapper
- Placeholder for Redux Provider, React Query, Theme, Auth
### src/app/page.tsx — Root page
- Redirects to /dashboard via next.config.ts
### src/app/globals.css — Global styles
- Imports design-tokens.css, box-sizing reset
- Custom scrollbar styling with design tokens
- Selection color using primary-container
### src/app/api/health/route.ts — Health check endpoint
- GET /api/health returns { status, service, timestamp }
- Used by Docker healthcheck and load balancers
### public/favicon.ico — Placeholder favicon
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
8042160f83
commit
6b90d61199
|
|
@ -0,0 +1,54 @@
|
||||||
|
# 依赖目录
|
||||||
|
node_modules
|
||||||
|
.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# 构建产物
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
build
|
||||||
|
dist
|
||||||
|
|
||||||
|
# 测试
|
||||||
|
coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# 开发环境
|
||||||
|
.env.local
|
||||||
|
.env.development
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
|
||||||
|
# 编辑器和IDE
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# 系统文件
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
Dockerfile
|
||||||
|
docker-compose*.yml
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# 日志
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# 文档
|
||||||
|
README.md
|
||||||
|
CHANGELOG.md
|
||||||
|
docs
|
||||||
|
|
||||||
|
# 其他
|
||||||
|
.claude
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
.yarn/install-state.gz
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# Claude Code
|
||||||
|
.claude/
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# OS
|
||||||
|
Thumbs.db
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import type { NextConfig } from 'next';
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
output: 'standalone',
|
||||||
|
reactStrictMode: true,
|
||||||
|
images: {
|
||||||
|
remotePatterns: [
|
||||||
|
{
|
||||||
|
protocol: 'https',
|
||||||
|
hostname: '**',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
async redirects() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: '/',
|
||||||
|
destination: '/dashboard',
|
||||||
|
permanent: false,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"name": "genex-admin-web",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"description": "Genex 券金融平台管理后台 - Admin Web",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "next lint",
|
||||||
|
"lint:fix": "next lint --fix",
|
||||||
|
"format": "prettier --write \"src/**/*.{ts,tsx,css,json}\"",
|
||||||
|
"format:check": "prettier --check \"src/**/*.{ts,tsx,css,json}\"",
|
||||||
|
"type-check": "tsc --noEmit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@reduxjs/toolkit": "^2.3.0",
|
||||||
|
"@tanstack/react-query": "^5.62.16",
|
||||||
|
"@tanstack/react-table": "^8.20.0",
|
||||||
|
"axios": "^1.7.9",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
|
"dayjs": "^1.11.13",
|
||||||
|
"next": "15.1.11",
|
||||||
|
"react": "^18.3.1",
|
||||||
|
"react-dom": "^18.3.1",
|
||||||
|
"react-redux": "^9.2.0",
|
||||||
|
"recharts": "^2.15.0",
|
||||||
|
"zustand": "^5.0.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^22.10.7",
|
||||||
|
"@types/react": "^18.3.18",
|
||||||
|
"@types/react-dom": "^18.3.5",
|
||||||
|
"eslint": "^9.18.0",
|
||||||
|
"eslint-config-next": "^15.1.6",
|
||||||
|
"prettier": "^3.4.2",
|
||||||
|
"typescript": "5.9.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { NextResponse } from 'next/server';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 健康检查 API
|
||||||
|
*
|
||||||
|
* Docker healthcheck 和负载均衡器使用
|
||||||
|
* GET /api/health
|
||||||
|
*/
|
||||||
|
export async function GET() {
|
||||||
|
return NextResponse.json({
|
||||||
|
status: 'ok',
|
||||||
|
service: 'genex-admin-web',
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
@import '../styles/design-tokens.css';
|
||||||
|
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-family: var(--font-family);
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: var(--color-bg);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--color-text-link);
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background: var(--color-primary-container);
|
||||||
|
color: var(--color-primary-dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scrollbar */
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--color-gray-300);
|
||||||
|
border-radius: var(--radius-full);
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--color-gray-400);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
import type { Metadata } from 'next';
|
||||||
|
import { Providers } from './providers';
|
||||||
|
import './globals.css';
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Genex Admin - 券金融平台管理后台',
|
||||||
|
description: 'Genex 券金融平台运营管理系统',
|
||||||
|
icons: {
|
||||||
|
icon: '/favicon.ico',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function RootLayout({
|
||||||
|
children,
|
||||||
|
}: Readonly<{
|
||||||
|
children: React.ReactNode;
|
||||||
|
}>) {
|
||||||
|
return (
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<body>
|
||||||
|
<Providers>{children}</Providers>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
/**
|
||||||
|
* 根页面 - 自动重定向到 /dashboard
|
||||||
|
* 重定向逻辑在 next.config.ts 中配置
|
||||||
|
*/
|
||||||
|
export default function Home() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局 Providers 包装
|
||||||
|
*
|
||||||
|
* 后续在此添加:
|
||||||
|
* - Redux Provider (RTK)
|
||||||
|
* - React Query Provider
|
||||||
|
* - Theme Provider
|
||||||
|
* - Auth Provider
|
||||||
|
*/
|
||||||
|
export function Providers({ children }: { children: React.ReactNode }) {
|
||||||
|
return <>{children}</>;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [{ "name": "next" }],
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
},
|
||||||
|
"baseUrl": ".",
|
||||||
|
"target": "ES2017"
|
||||||
|
},
|
||||||
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
|
"exclude": ["node_modules"]
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue