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:
hailin 2026-02-11 01:35:19 -08:00
parent 8042160f83
commit 6b90d61199
11 changed files with 302 additions and 0 deletions

View File

@ -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

47
frontend/admin-web/.gitignore vendored Normal file
View File

@ -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

View File

@ -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;

View File

@ -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"
}
}

View File

View File

@ -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(),
});
}

View File

@ -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);
}

View File

@ -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>
);
}

View File

@ -0,0 +1,7 @@
/**
* - /dashboard
* next.config.ts
*/
export default function Home() {
return null;
}

View File

@ -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}</>;
}

View File

@ -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"]
}