Trae Assistant commited on
Commit
ad893f7
·
0 Parent(s):

chore: pull .gitattributes from huggingface

Browse files
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Logs
2
+ logs
3
+ *.log
4
+ npm-debug.log*
5
+ yarn-debug.log*
6
+ yarn-error.log*
7
+ pnpm-debug.log*
8
+ lerna-debug.log*
9
+
10
+ node_modules
11
+ dist
12
+ dist-ssr
13
+ *.local
14
+
15
+ # Editor directories and files
16
+ .vscode/*
17
+ !.vscode/extensions.json
18
+ .idea
19
+ .DS_Store
20
+ *.suo
21
+ *.ntvs*
22
+ *.njsproj
23
+ *.sln
24
+ *.sw?
25
+ .vite
README.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # React + TypeScript + Vite
2
+
3
+ This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
+
5
+ Currently, two official plugins are available:
6
+
7
+ - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
8
+ - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
+
10
+ ## Expanding the ESLint configuration
11
+
12
+ If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
13
+
14
+ ```js
15
+ export default tseslint.config({
16
+ extends: [
17
+ // Remove ...tseslint.configs.recommended and replace with this
18
+ ...tseslint.configs.recommendedTypeChecked,
19
+ // Alternatively, use this for stricter rules
20
+ ...tseslint.configs.strictTypeChecked,
21
+ // Optionally, add this for stylistic rules
22
+ ...tseslint.configs.stylisticTypeChecked,
23
+ ],
24
+ languageOptions: {
25
+ // other options...
26
+ parserOptions: {
27
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
28
+ tsconfigRootDir: import.meta.dirname,
29
+ },
30
+ },
31
+ })
32
+ ```
33
+
34
+ You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
35
+
36
+ ```js
37
+ // eslint.config.js
38
+ import reactX from 'eslint-plugin-react-x'
39
+ import reactDom from 'eslint-plugin-react-dom'
40
+
41
+ export default tseslint.config({
42
+ extends: [
43
+ // other configs...
44
+ // Enable lint rules for React
45
+ reactX.configs['recommended-typescript'],
46
+ // Enable lint rules for React DOM
47
+ reactDom.configs.recommended,
48
+ ],
49
+ languageOptions: {
50
+ // other options...
51
+ parserOptions: {
52
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
53
+ tsconfigRootDir: import.meta.dirname,
54
+ },
55
+ },
56
+ })
57
+ ```
api/app.ts ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * 这是一个 API 服务端程序
3
+ */
4
+
5
+ import express, {
6
+ type Request,
7
+ type Response,
8
+ type NextFunction,
9
+ } from 'express'
10
+ import cors from 'cors'
11
+ import path from 'path'
12
+ import dotenv from 'dotenv'
13
+ import { fileURLToPath } from 'url'
14
+ import authRoutes from './routes/auth.js'
15
+ import aiRoutes from './routes/ai.js'
16
+
17
+ // ESM 模式下的路径处理
18
+ const __filename = fileURLToPath(import.meta.url)
19
+ const __dirname = path.dirname(__filename)
20
+
21
+ // 加载环境变量
22
+ dotenv.config()
23
+
24
+ const app: express.Application = express()
25
+
26
+ app.use(cors())
27
+ app.use(express.json({ limit: '10mb' }))
28
+ app.use(express.urlencoded({ extended: true, limit: '10mb' }))
29
+
30
+ /**
31
+ * API 路由配置
32
+ */
33
+ app.use('/api/auth', authRoutes)
34
+ app.use('/api/ai', aiRoutes)
35
+
36
+ /**
37
+ * 健康检查接口
38
+ */
39
+ app.use(
40
+ '/api/health',
41
+ (req: Request, res: Response, next: NextFunction): void => {
42
+ res.status(200).json({
43
+ success: true,
44
+ message: '服务运行正常',
45
+ })
46
+ },
47
+ )
48
+
49
+ /**
50
+ * 错误处理中间件
51
+ */
52
+ app.use((error: Error, req: Request, res: Response, next: NextFunction) => {
53
+ console.error('Server Error:', error)
54
+ res.status(500).json({
55
+ success: false,
56
+ error: '服务器内部错误',
57
+ })
58
+ })
59
+
60
+ /**
61
+ * 404 未找到处理
62
+ */
63
+ app.use((req: Request, res: Response) => {
64
+ res.status(404).json({
65
+ success: false,
66
+ error: '接口不存在',
67
+ })
68
+ })
69
+
70
+ export default app
api/index.ts ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Vercel deploy entry handler, for serverless deployment, please don't modify this file
3
+ */
4
+ import type { VercelRequest, VercelResponse } from '@vercel/node';
5
+ import app from './app.js';
6
+
7
+ export default function handler(req: VercelRequest, res: VercelResponse) {
8
+ return app(req, res);
9
+ }
api/routes/ai.ts ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * AI 生成相关接口
3
+ */
4
+ import { Router, type Request, type Response } from 'express'
5
+ import axios from 'axios'
6
+
7
+ const router = Router()
8
+
9
+ /**
10
+ * 生成 UI 代码
11
+ * POST /api/ai/generate
12
+ */
13
+ router.post('/generate', async (req: Request, res: Response): Promise<void> => {
14
+ const { prompt } = req.body
15
+
16
+ if (!prompt) {
17
+ res.status(400).json({
18
+ success: false,
19
+ error: '请输入描述内容',
20
+ })
21
+ return
22
+ }
23
+
24
+ try {
25
+ const apiKey = process.env.SILICONFLOW_API_KEY
26
+ const model = process.env.SILICONFLOW_MODEL || 'deepseek-ai/DeepSeek-V3'
27
+
28
+ const response = await axios.post(
29
+ 'https://api.siliconflow.cn/v1/chat/completions',
30
+ {
31
+ model: model,
32
+ messages: [
33
+ {
34
+ role: 'system',
35
+ content: `你是一个专业的前端 UI 界面生成专家。
36
+ 你的任务是根据用户的描述,生成高质量、响应式、现代化的 React 代码。
37
+ 要求:
38
+ 1. 使用 React (Function Components) 和 Tailwind CSS。
39
+ 2. 代码必须是完整的、可运行的。
40
+ 3. 只返回代码块中的内容,不要有其他解释说明。
41
+ 4. 使用常见的库如 lucide-react 作为图标库。
42
+ 5. 界面风格应符合现代化设计,注重用户体验。`,
43
+ },
44
+ {
45
+ role: 'user',
46
+ content: prompt,
47
+ },
48
+ ],
49
+ stream: false,
50
+ },
51
+ {
52
+ headers: {
53
+ Authorization: `Bearer ${apiKey}`,
54
+ 'Content-Type': 'application/json',
55
+ },
56
+ }
57
+ )
58
+
59
+ const content = response.data.choices[0].message.content
60
+ // 提取代码块中的内容
61
+ const codeMatch = content.match(/```(?:tsx|jsx|javascript|typescript|react)?\s*([\s\S]*?)```/)
62
+ const code = codeMatch ? codeMatch[1].trim() : content.trim()
63
+
64
+ res.status(200).json({
65
+ success: true,
66
+ data: {
67
+ code: code,
68
+ },
69
+ })
70
+ } catch (error: any) {
71
+ console.error('AI Generation Error:', error.response?.data || error.message)
72
+ res.status(500).json({
73
+ success: false,
74
+ error: 'AI 生成失败,请稍后再试',
75
+ })
76
+ }
77
+ })
78
+
79
+ export default router
api/routes/auth.ts ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * This is a user authentication API route demo.
3
+ * Handle user registration, login, token management, etc.
4
+ */
5
+ import { Router, type Request, type Response } from 'express'
6
+
7
+ const router = Router()
8
+
9
+ /**
10
+ * User Login
11
+ * POST /api/auth/register
12
+ */
13
+ router.post('/register', async (req: Request, res: Response): Promise<void> => {
14
+ // TODO: Implement register logic
15
+ })
16
+
17
+ /**
18
+ * User Login
19
+ * POST /api/auth/login
20
+ */
21
+ router.post('/login', async (req: Request, res: Response): Promise<void> => {
22
+ // TODO: Implement login logic
23
+ })
24
+
25
+ /**
26
+ * User Logout
27
+ * POST /api/auth/logout
28
+ */
29
+ router.post('/logout', async (req: Request, res: Response): Promise<void> => {
30
+ // TODO: Implement logout logic
31
+ })
32
+
33
+ export default router
api/server.ts ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * local server entry file, for local development
3
+ */
4
+ import app from './app.js';
5
+
6
+ /**
7
+ * start server with port
8
+ */
9
+ const PORT = process.env.PORT || 3001;
10
+
11
+ const server = app.listen(PORT, () => {
12
+ console.log(`Server ready on port ${PORT}`);
13
+ });
14
+
15
+ /**
16
+ * close server
17
+ */
18
+ process.on('SIGTERM', () => {
19
+ console.log('SIGTERM signal received');
20
+ server.close(() => {
21
+ console.log('Server closed');
22
+ process.exit(0);
23
+ });
24
+ });
25
+
26
+ process.on('SIGINT', () => {
27
+ console.log('SIGINT signal received');
28
+ server.close(() => {
29
+ console.log('Server closed');
30
+ process.exit(0);
31
+ });
32
+ });
33
+
34
+ export default app;
eslint.config.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import js from '@eslint/js'
2
+ import globals from 'globals'
3
+ import reactHooks from 'eslint-plugin-react-hooks'
4
+ import reactRefresh from 'eslint-plugin-react-refresh'
5
+ import tseslint from 'typescript-eslint'
6
+
7
+ export default tseslint.config(
8
+ { ignores: ['dist'] },
9
+ {
10
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
11
+ files: ['**/*.{ts,tsx}'],
12
+ languageOptions: {
13
+ ecmaVersion: 2020,
14
+ globals: globals.browser,
15
+ },
16
+ plugins: {
17
+ 'react-hooks': reactHooks,
18
+ 'react-refresh': reactRefresh,
19
+ },
20
+ rules: {
21
+ ...reactHooks.configs.recommended.rules,
22
+ 'react-refresh/only-export-components': [
23
+ 'warn',
24
+ { allowConstantExport: true },
25
+ ],
26
+ },
27
+ },
28
+ )
index.html ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>My Trae Project</title>
8
+ <script type="module">
9
+ if (import.meta.hot?.on) {
10
+ import.meta.hot.on('vite:error', (error) => {
11
+ if (error.err) {
12
+ console.error(
13
+ [error.err.message, error.err.frame].filter(Boolean).join('\n'),
14
+ )
15
+ }
16
+ })
17
+ }
18
+ </script>
19
+ </head>
20
+ <body>
21
+ <div id="root"></div>
22
+ <script type="module" src="/src/main.tsx"></script>
23
+ </body>
24
+ </html>
nodemon.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "watch": ["api"],
3
+ "ext": "ts,mts,js,json",
4
+ "ignore": ["api/dist/*"],
5
+ "exec": "tsx api/server.ts",
6
+ "env": {
7
+ "NODE_ENV": "development"
8
+ },
9
+ "delay": 1000
10
+ }
package.json ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "generative-ui-agent",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "client:dev": "vite",
8
+ "build": "tsc -b && vite build",
9
+ "lint": "eslint .",
10
+ "preview": "vite preview",
11
+ "check": "tsc --noEmit",
12
+ "server:dev": "nodemon",
13
+ "dev": "concurrently \"npm run client:dev\" \"npm run server:dev\""
14
+ },
15
+ "dependencies": {
16
+ "@ant-design/icons": "^6.1.0",
17
+ "@supabase/supabase-js": "^2.48.1",
18
+ "antd": "^5.23.0",
19
+ "axios": "^1.7.9",
20
+ "clsx": "^2.1.1",
21
+ "cors": "^2.8.5",
22
+ "dotenv": "^17.2.1",
23
+ "express": "^4.21.2",
24
+ "jsonwebtoken": "^9.0.2",
25
+ "lucide-react": "^0.511.0",
26
+ "react": "^18.3.1",
27
+ "react-dom": "^18.3.1",
28
+ "react-router-dom": "^7.3.0",
29
+ "tailwind-merge": "^3.0.2",
30
+ "zustand": "^5.0.3"
31
+ },
32
+ "devDependencies": {
33
+ "@eslint/js": "^9.25.0",
34
+ "@types/cors": "^2.8.19",
35
+ "@types/express": "^4.17.21",
36
+ "@types/jsonwebtoken": "^9.0.8",
37
+ "@types/node": "^22.15.30",
38
+ "@types/react": "^18.3.12",
39
+ "@types/react-dom": "^18.3.1",
40
+ "@vercel/node": "^5.3.6",
41
+ "@vitejs/plugin-react": "^4.4.1",
42
+ "autoprefixer": "^10.4.21",
43
+ "babel-plugin-react-dev-locator": "^1.0.0",
44
+ "concurrently": "^9.2.0",
45
+ "eslint": "^9.25.0",
46
+ "eslint-plugin-react-hooks": "^5.2.0",
47
+ "eslint-plugin-react-refresh": "^0.4.19",
48
+ "globals": "^16.0.0",
49
+ "nodemon": "^3.1.10",
50
+ "postcss": "^8.5.3",
51
+ "tailwindcss": "^3.4.17",
52
+ "tsx": "^4.20.3",
53
+ "typescript": "~5.8.3",
54
+ "typescript-eslint": "^8.30.1",
55
+ "vite": "^6.3.5",
56
+ "vite-plugin-trae-solo-badge": "^1.0.0",
57
+ "vite-tsconfig-paths": "^5.1.4"
58
+ }
59
+ }
pnpm-lock.yaml ADDED
The diff for this file is too large to render. See raw diff
 
postcss.config.js ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ /** WARNING: DON'T EDIT THIS FILE */
2
+ /** WARNING: DON'T EDIT THIS FILE */
3
+ /** WARNING: DON'T EDIT THIS FILE */
4
+
5
+ export default {
6
+ plugins: {
7
+ tailwindcss: {},
8
+ autoprefixer: {},
9
+ },
10
+ };
public/favicon.svg ADDED
src/App.tsx ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
2
+ import Home from "@/pages/Home";
3
+
4
+ export default function App() {
5
+ return (
6
+ <Router>
7
+ <Routes>
8
+ <Route path="/" element={<Home />} />
9
+ <Route path="/other" element={<div className="text-center text-xl">Other Page - Coming Soon</div>} />
10
+ </Routes>
11
+ </Router>
12
+ );
13
+ }
src/assets/react.svg ADDED
src/components/Empty.tsx ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import { cn } from '@/lib/utils'
2
+
3
+ // Empty component
4
+ export default function Empty() {
5
+ return (
6
+ <div className={cn('flex h-full items-center justify-center')}>Empty</div>
7
+ )
8
+ }
src/hooks/useTheme.ts ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { useState, useEffect } from 'react';
2
+
3
+ type Theme = 'light' | 'dark';
4
+
5
+ export function useTheme() {
6
+ const [theme, setTheme] = useState<Theme>(() => {
7
+ const savedTheme = localStorage.getItem('theme') as Theme;
8
+ if (savedTheme) {
9
+ return savedTheme;
10
+ }
11
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
12
+ });
13
+
14
+ useEffect(() => {
15
+ document.documentElement.classList.remove('light', 'dark');
16
+ document.documentElement.classList.add(theme);
17
+ localStorage.setItem('theme', theme);
18
+ }, [theme]);
19
+
20
+ const toggleTheme = () => {
21
+ setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light');
22
+ };
23
+
24
+ return {
25
+ theme,
26
+ toggleTheme,
27
+ isDark: theme === 'dark'
28
+ };
29
+ }
src/index.css ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
7
+ line-height: 1.5;
8
+ font-weight: 400;
9
+
10
+ font-synthesis: none;
11
+ text-rendering: optimizeLegibility;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ }
src/lib/utils.ts ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
src/main.tsx ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import { StrictMode } from 'react'
2
+ import { createRoot } from 'react-dom/client'
3
+ import App from './App'
4
+ import './index.css'
5
+
6
+ createRoot(document.getElementById('root')!).render(
7
+ <StrictMode>
8
+ <App />
9
+ </StrictMode>,
10
+ )
src/pages/Home.tsx ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react';
2
+ import { Layout, Input, Button, Card, List, Typography, Space, Divider } from 'antd';
3
+ import { SendOutlined, HistoryOutlined, SettingOutlined, ProjectOutlined } from '@ant-design/icons';
4
+
5
+ const { Header, Content, Sider } = Layout;
6
+ const { TextArea } = Input;
7
+ const { Title, Text } = Typography;
8
+
9
+ export default function Home() {
10
+ const [input, setInput] = useState('');
11
+ const [history] = useState([
12
+ '生成一个蓝色风格的登录页面',
13
+ '创建一个电商首页轮播图',
14
+ '设计一个响应式的个人主页',
15
+ ]);
16
+
17
+ return (
18
+ <Layout style={{ minHeight: '100vh' }}>
19
+ <Header style={{ background: '#fff', padding: '0 24px', display: 'flex', alignItems: 'center', borderBottom: '1px solid #f0f0f0' }}>
20
+ <Title level={4} style={{ margin: 0, color: '#1890ff' }}>Generative UI Agent</Title>
21
+ <div style={{ marginLeft: 'auto' }}>
22
+ <Space size="large">
23
+ <Button type="text" icon={<ProjectOutlined />}>项目管理</Button>
24
+ <Button type="text" icon={<SettingOutlined />}>设置</Button>
25
+ </Space>
26
+ </div>
27
+ </Header>
28
+ <Layout>
29
+ <Sider width={250} style={{ background: '#fff', borderRight: '1px solid #f0f0f0' }}>
30
+ <div style={{ padding: '16px' }}>
31
+ <Title level={5}><HistoryOutlined /> 历史记录</Title>
32
+ <List
33
+ dataSource={history}
34
+ renderItem={(item) => (
35
+ <List.Item style={{ cursor: 'pointer', padding: '8px 0' }}>
36
+ <Text ellipsis>{item}</Text>
37
+ </List.Item>
38
+ )}
39
+ />
40
+ </div>
41
+ </Sider>
42
+ <Content style={{ padding: '24px', display: 'flex', gap: '24px' }}>
43
+ <div style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: '16px' }}>
44
+ <Card title="AI 对话输入" bordered={false} style={{ boxShadow: '0 2px 8px rgba(0,0,0,0.06)' }}>
45
+ <TextArea
46
+ rows={4}
47
+ value={input}
48
+ onChange={(e) => setInput(e.target.value)}
49
+ placeholder="描述你想要的 UI 界面..."
50
+ style={{ marginBottom: '16px' }}
51
+ />
52
+ <div style={{ textAlign: 'right' }}>
53
+ <Button type="primary" icon={<SendOutlined />} size="large">
54
+ 开始生成
55
+ </Button>
56
+ </div>
57
+ </Card>
58
+
59
+ <Card title="系统状态" bordered={false} style={{ boxShadow: '0 2px 8px rgba(0,0,0,0.06)' }}>
60
+ <Space direction="vertical" style={{ width: '100%' }}>
61
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
62
+ <Text>API 状态</Text>
63
+ <Text type="success">已连接</Text>
64
+ </div>
65
+ <div style={{ display: 'flex', justifyContent: 'space-between' }}>
66
+ <Text>模型版本</Text>
67
+ <Text>GPT-4o</Text>
68
+ </div>
69
+ </Space>
70
+ </Card>
71
+ </div>
72
+
73
+ <div style={{ flex: 2 }}>
74
+ <Card
75
+ title="实时预览"
76
+ extra={<Space><Button size="small">桌面端</Button><Button size="small">移动端</Button></Space>}
77
+ style={{ height: '100%', boxShadow: '0 2px 8px rgba(0,0,0,0.06)' }}
78
+ bodyStyle={{ height: 'calc(100% - 58px)', display: 'flex', alignItems: 'center', justifyCenter: 'center', background: '#f5f5f5' }}
79
+ >
80
+ <div style={{ width: '100%', height: '100%', background: '#fff', border: '1px dashed #d9d9d9', borderRadius: '4px', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
81
+ <Text type="secondary">生成的 UI 将在这里实时显示</Text>
82
+ </div>
83
+ </Card>
84
+ </div>
85
+ </Content>
86
+ </Layout>
87
+ </Layout>
88
+ );
89
+ }
src/vite-env.d.ts ADDED
@@ -0,0 +1 @@
 
 
1
+ /// <reference types="vite/client" />
tailwind.config.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('tailwindcss').Config} */
2
+
3
+ export default {
4
+ darkMode: "class",
5
+ content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
6
+ theme: {
7
+ container: {
8
+ center: true,
9
+ },
10
+ extend: {},
11
+ },
12
+ plugins: [],
13
+ };
tsconfig.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
4
+ "target": "ES2020",
5
+ "useDefineForClassFields": true,
6
+ "lib": [
7
+ "ES2020",
8
+ "DOM",
9
+ "DOM.Iterable"
10
+ ],
11
+ "module": "ESNext",
12
+ "skipLibCheck": true,
13
+ "moduleResolution": "bundler",
14
+ "allowImportingTsExtensions": true,
15
+ "verbatimModuleSyntax": false,
16
+ "moduleDetection": "force",
17
+ "noEmit": true,
18
+ "jsx": "react-jsx",
19
+ "strict": false,
20
+ "noUnusedLocals": false,
21
+ "noUnusedParameters": false,
22
+ "noFallthroughCasesInSwitch": false,
23
+ "noUncheckedSideEffectImports": false,
24
+ "forceConsistentCasingInFileNames": false,
25
+ "baseUrl": "./",
26
+ "paths": {
27
+ "@/*": [
28
+ "./src/*"
29
+ ]
30
+ },
31
+ "types": [
32
+ "node",
33
+ "express"
34
+ ]
35
+ },
36
+ "include": [
37
+ "src",
38
+ "api"
39
+ ]
40
+ }
vercel.json ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "rewrites": [
3
+ {
4
+ "source": "/api/(.*)",
5
+ "destination": "/api/index"
6
+ },
7
+ {
8
+ "source": "/(.*)",
9
+ "destination": "/index.html"
10
+ }
11
+ ]
12
+ }
vite.config.ts ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { defineConfig } from 'vite'
2
+ import react from '@vitejs/plugin-react'
3
+ import tsconfigPaths from "vite-tsconfig-paths";
4
+ import { traeBadgePlugin } from 'vite-plugin-trae-solo-badge';
5
+
6
+ // https://vite.dev/config/
7
+ export default defineConfig({
8
+ plugins: [
9
+ react({
10
+ babel: {
11
+ plugins: [
12
+ 'react-dev-locator',
13
+ ],
14
+ },
15
+ }),
16
+ traeBadgePlugin({
17
+ variant: 'dark',
18
+ position: 'bottom-right',
19
+ prodOnly: true,
20
+ clickable: true,
21
+ clickUrl: 'https://www.trae.ai/solo?showJoin=1',
22
+ autoTheme: true,
23
+ autoThemeTarget: '#root'
24
+ }),
25
+ tsconfigPaths(),
26
+ ],
27
+ server: {
28
+ proxy: {
29
+ '/api': {
30
+ target: 'http://localhost:3001',
31
+ changeOrigin: true,
32
+ secure: false,
33
+ configure: (proxy, _options) => {
34
+ proxy.on('error', (err, _req, _res) => {
35
+ console.log('proxy error', err);
36
+ });
37
+ proxy.on('proxyReq', (proxyReq, req, _res) => {
38
+ console.log('Sending Request to the Target:', req.method, req.url);
39
+ });
40
+ proxy.on('proxyRes', (proxyRes, req, _res) => {
41
+ console.log('Received Response from the Target:', proxyRes.statusCode, req.url);
42
+ });
43
+ },
44
+ }
45
+ }
46
+ }
47
+ })