-
+
+
+
+
+
+
Todo List
+ 轻松管理您的任务
+
+
+ {error && (
+ setError(null)}
+ style={{ marginBottom: 24 }}
+ />
+ )}
+
+
+ }
+ placeholder="账户"
+ size="large"
+ />
+
+
+
+ }
+ placeholder="密码"
+ size="large"
+ />
+
+
+
+
+ 自动登录
+
+ 忘记密码
+ 注册新账号
+
+
+
+
+
+
+
+
+
+
);
-};
+}
export default Login;
\ No newline at end of file
diff --git a/client/src/pages/Register.tsx b/client/src/pages/Register.tsx
index f75a28f..749e846 100644
--- a/client/src/pages/Register.tsx
+++ b/client/src/pages/Register.tsx
@@ -1,58 +1,131 @@
import React, { useState } from 'react';
-import { register } from '../api/auth';
-import { useNavigate, Link } from 'react-router-dom';
+import { useNavigate } from 'react-router-dom';
+import { Form, Input, Button, Card, Space, Typography, Alert } from 'antd';
+import { UserOutlined, LockOutlined, CheckSquareOutlined } from '@ant-design/icons';
+import { api } from '../api/axios';
-const Register: React.FC = () => {
- const [username, setUsername] = useState('');
- const [password, setPassword] = useState('');
- const [error, setError] = useState('');
- const [success, setSuccess] = useState('');
+const { Title, Text, Link } = Typography;
+
+function Register() {
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState
(null);
const navigate = useNavigate();
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault();
- setError('');
- setSuccess('');
+ const onFinish = async (values: any) => {
+ setLoading(true);
+ setError(null);
try {
- await register(username, password);
- setSuccess('注册成功,请登录');
- setTimeout(() => navigate('/login'), 1000);
+ await api.post('/auth/register', {
+ username: values.username,
+ password: values.password,
+ });
+ navigate('/login');
} catch (err: any) {
- setError(err.response?.data?.message || '注册失败');
+ const errorMessage = err.response?.data?.message || '注册失败,用户名可能已被占用或服务器错误。';
+ setError(errorMessage);
+ } finally {
+ setLoading(false);
}
};
return (
-
-
+
+
+
+
+
+
Todo List
+ 轻松管理您的任务
+
+
+ {error && (
+ setError(null)}
+ style={{ marginBottom: 24 }}
+ />
+ )}
+
+
+ }
+ placeholder="用户名"
+ size="large"
+ />
+
+
+
+ }
+ placeholder="密码"
+ size="large"
+ />
+
+
+ ({
+ validator(_, value) {
+ if (!value || getFieldValue('password') === value) {
+ return Promise.resolve();
+ }
+ return Promise.reject(new Error('两次输入的密码不一致!'));
+ },
+ }),
+ ]}
+ >
+ }
+ placeholder="确认密码"
+ size="large"
+ />
+
+
+
+
+
+
+ 已有账号?去登录
+
+
+
+
);
-};
+}
export default Register;
\ No newline at end of file
diff --git a/client/src/react-app-env.d.ts b/client/src/react-app-env.d.ts
deleted file mode 100644
index 6431bc5..0000000
--- a/client/src/react-app-env.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-///
diff --git a/client/src/types/todo.ts b/client/src/types/todo.ts
index 081360a..56f949e 100644
--- a/client/src/types/todo.ts
+++ b/client/src/types/todo.ts
@@ -3,18 +3,16 @@ export type Priority = 'low' | 'medium' | 'high';
export interface Todo {
_id: string;
title: string;
+ description: string;
completed: boolean;
priority: Priority;
- userId: string;
- createdAt: string;
- updatedAt: string;
}
-export const priorityColors = {
- low: 'bg-blue-100 text-blue-800',
- medium: 'bg-yellow-100 text-yellow-800',
- high: 'bg-red-100 text-red-800'
-} as const;
+export const priorityColors: Record
= {
+ low: 'green',
+ medium: 'orange',
+ high: 'red',
+};
export const priorityLabels = {
low: '低',
diff --git a/client-temp/src/utils/priorityUtils.ts b/client/src/utils/priorityUtils.ts
similarity index 100%
rename from client-temp/src/utils/priorityUtils.ts
rename to client/src/utils/priorityUtils.ts
diff --git a/client-temp/src/vite-env.d.ts b/client/src/vite-env.d.ts
similarity index 100%
rename from client-temp/src/vite-env.d.ts
rename to client/src/vite-env.d.ts
diff --git a/client/tailwind.config.js b/client/tailwind.config.js
index 115da8e..d37737f 100644
--- a/client/tailwind.config.js
+++ b/client/tailwind.config.js
@@ -1,9 +1,12 @@
-module.exports = {
+/** @type {import('tailwindcss').Config} */
+export default {
content: [
- "./src/**/*.{js,jsx,ts,tsx}",
+ "./index.html",
+ "./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
+
diff --git a/client-temp/tsconfig.app.json b/client/tsconfig.app.json
similarity index 100%
rename from client-temp/tsconfig.app.json
rename to client/tsconfig.app.json
diff --git a/client/tsconfig.json b/client/tsconfig.json
index a273b0c..1ffef60 100644
--- a/client/tsconfig.json
+++ b/client/tsconfig.json
@@ -1,26 +1,7 @@
{
- "compilerOptions": {
- "target": "es5",
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
- "allowJs": true,
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "noFallthroughCasesInSwitch": true,
- "module": "esnext",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react-jsx"
- },
- "include": [
- "src"
+ "files": [],
+ "references": [
+ { "path": "./tsconfig.app.json" },
+ { "path": "./tsconfig.node.json" }
]
}
diff --git a/client-temp/tsconfig.node.json b/client/tsconfig.node.json
similarity index 100%
rename from client-temp/tsconfig.node.json
rename to client/tsconfig.node.json
diff --git a/client-temp/vite.config.ts b/client/vite.config.ts
similarity index 100%
rename from client-temp/vite.config.ts
rename to client/vite.config.ts