管理后台初始化,登录,团队管理,报价单管理 完成

This commit is contained in:
‘Liammcl’
2024-12-15 17:39:58 +08:00
commit 5882bf9548
91 changed files with 16260 additions and 0 deletions

102
src/pages/auth/Login.jsx Normal file
View File

@@ -0,0 +1,102 @@
import React from 'react';
import { Form, Input, Button, Divider, message } from 'antd';
import { GoogleOutlined } from '@ant-design/icons';
import { Link, useNavigate } from 'react-router-dom';
import { useAuth } from '@/contexts/AuthContext';
const Login = () => {
const navigate = useNavigate();
const { login, signInWithGoogle } = useAuth();
const [form] = Form.useForm();
const handleLogin = async (values) => {
try {
await login(values.email, values.password);
message.success('登录成功!');
navigate('/');
} catch (error) {
console.error('Login error:', error);
}
};
const handleGoogleLogin = async () => {
try {
await signInWithGoogle();
navigate('/');
} catch (error) {
console.error('Google login error:', error);
}
};
return (
<div className="min-h-screen flex bg-gradient-to-br from-[#f5f7fa] to-[#c3cfe2]">
<div className="w-full max-w-[1200px] mx-auto flex p-8 gap-16">
<div className="flex-1 bg-white p-12 rounded-[20px] shadow-[0_10px_30px_rgba(0,0,0,0.1)]">
<div className="mb-8 text-center">
<h1 className="text-3xl font-bold mb-2 bg-gradient-to-r from-primary-500 to-[#36cff0] bg-clip-text text-transparent">
Uppeta
</h1>
<p className="text-gray-500">欢迎回来请登录您的账户</p>
</div>
<Form
form={form}
name="login"
onFinish={handleLogin}
layout="vertical"
size="large"
>
<Form.Item
name="email"
rules={[
{ required: true, message: '请输入邮箱!' },
{ type: 'email', message: '请输入有效的邮箱地址!' }
]}
>
<Input placeholder="邮箱" />
</Form.Item>
<Form.Item
name="password"
rules={[
{ required: true, message: '请输入密码!' }
]}
>
<Input.Password placeholder="密码" />
</Form.Item>
<div className="flex justify-between items-center mb-6">
<Form.Item name="remember" valuePropName="checked" noStyle>
<Link to="/forgot-password" className="text-primary-500 hover:text-primary-600">
忘记密码
</Link>
</Form.Item>
</div>
<Form.Item>
<Button type="primary" htmlType="submit" block>
登录
</Button>
</Form.Item>
<Divider></Divider>
<Button
icon={<GoogleOutlined />}
block
onClick={handleGoogleLogin}
className="mb-6"
>
使用 Google 账号登录
</Button>
</Form>
</div>
<div className="flex-1 hidden md:block rounded-[20px] bg-[url('https://uppeta.com/img/svg/main.svg')] bg-center bg-contain bg-no-repeat" />
</div>
</div>
);
};
export default Login;

120
src/pages/auth/Register.jsx Normal file
View File

@@ -0,0 +1,120 @@
import React from 'react';
import { Form, Input, Button, Divider, message } from 'antd';
import { GoogleOutlined } from '@ant-design/icons';
import { Link, useNavigate } from 'react-router-dom';
import { useAuth } from '@/contexts/AuthContext';
const Register = () => {
const navigate = useNavigate();
const { register, signInWithGoogle } = useAuth();
const [form] = Form.useForm();
const handleRegister = async (values) => {
try {
await register(values.email, values.password);
message.success('注册成功!请查看您的邮箱进行验证。');
navigate('/login');
} catch (error) {
console.error('Registration error:', error);
}
};
const handleGoogleSignUp = async () => {
try {
await signInWithGoogle();
navigate('/');
} catch (error) {
console.error('Google sign up error:', error);
}
};
return (
<div className="min-h-screen flex bg-gradient-to-br from-[#f5f7fa] to-[#c3cfe2]">
<div className="w-full max-w-[1200px] mx-auto flex p-8 gap-16">
{/* Register Form */}
<div className="flex-1 bg-white p-12 rounded-[20px] shadow-[0_10px_30px_rgba(0,0,0,0.1)]">
<div className="mb-8 text-center">
<h1 className="text-3xl font-bold mb-2 bg-gradient-to-r from-primary-500 to-[#36cff0] bg-clip-text text-transparent">
创建账户
</h1>
<p className="text-gray-500">加入 Uppeta开启您的管理之旅</p>
</div>
<Form
form={form}
name="register"
onFinish={handleRegister}
layout="vertical"
size="large"
>
<Form.Item
name="email"
rules={[
{ required: true, message: '请输入邮箱!' },
{ type: 'email', message: '请输入有效的邮箱地址!' }
]}
>
<Input placeholder="邮箱" />
</Form.Item>
<Form.Item
name="password"
rules={[
{ required: true, message: '请输入密码!' },
{ min: 6, message: '密码长度至少为 6 位!' }
]}
>
<Input.Password placeholder="密码" />
</Form.Item>
<Form.Item
name="confirmPassword"
dependencies={['password']}
rules={[
{ required: true, message: '请确认密码!' },
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('两次输入的密码不一致!'));
},
}),
]}
>
<Input.Password placeholder="确认密码" />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" block>
注册
</Button>
</Form.Item>
<Divider></Divider>
<Button
icon={<GoogleOutlined />}
block
onClick={handleGoogleSignUp}
className="mb-6"
>
使用 Google 账号注册
</Button>
<div className="text-center">
<Link to="/login" className="text-primary-500 hover:text-primary-600">
已有账户立即登录
</Link>
</div>
</Form>
</div>
{/* Register Image */}
<div className="flex-1 hidden md:block rounded-[20px] bg-[url('/auth-bg.png')] bg-center bg-cover" />
</div>
</div>
);
};
export default Register;