前后端基本架构和完全excel表的解析及统计图表的生成以及excel表的到出
This commit is contained in:
184
frontend/src/pages/Login.tsx
Normal file
184
frontend/src/pages/Login.tsx
Normal file
@@ -0,0 +1,184 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useAuth } from '@/context/AuthContext';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
||||
import { FileText, Lock, User, CheckCircle2, AlertCircle } from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
const Login: React.FC = () => {
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { signIn, signUp } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const handleLogin = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (!username || !password) return toast.error('请输入用户名和密码');
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const email = `${username}@miaoda.com`;
|
||||
const { error } = await signIn(email, password);
|
||||
if (error) throw error;
|
||||
toast.success('登录成功');
|
||||
navigate('/');
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || '登录失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSignUp = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (!username || !password) return toast.error('请输入用户名和密码');
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const email = `${username}@miaoda.com`;
|
||||
const { error } = await signUp(email, password);
|
||||
if (error) throw error;
|
||||
toast.success('注册成功,请登录');
|
||||
} catch (err: any) {
|
||||
toast.error(err.message || '注册失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-[radial-gradient(ellipse_at_top_left,_var(--tw-gradient-stops))] from-primary/10 via-background to-background p-4 relative overflow-hidden">
|
||||
{/* Decorative elements */}
|
||||
<div className="absolute top-0 left-0 w-96 h-96 bg-primary/5 rounded-full blur-3xl -translate-x-1/2 -translate-y-1/2" />
|
||||
<div className="absolute bottom-0 right-0 w-64 h-64 bg-primary/5 rounded-full blur-3xl translate-x-1/3 translate-y-1/3" />
|
||||
|
||||
<div className="w-full max-w-md space-y-8 relative animate-fade-in">
|
||||
<div className="text-center space-y-2">
|
||||
<div className="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-primary text-primary-foreground shadow-2xl shadow-primary/30 mb-4 animate-slide-in">
|
||||
<FileText size={32} />
|
||||
</div>
|
||||
<h1 className="text-4xl font-extrabold tracking-tight gradient-text">智联文档</h1>
|
||||
<p className="text-muted-foreground">多源数据融合与智能文档处理系统</p>
|
||||
</div>
|
||||
|
||||
<Card className="border-border/50 shadow-2xl backdrop-blur-sm bg-card/95">
|
||||
<Tabs defaultValue="login" className="w-full">
|
||||
<TabsList className="grid w-full grid-cols-2 rounded-t-xl h-12 bg-muted/50 p-1">
|
||||
<TabsTrigger value="login" className="rounded-lg data-[state=active]:bg-background data-[state=active]:shadow-sm">登录</TabsTrigger>
|
||||
<TabsTrigger value="signup" className="rounded-lg data-[state=active]:bg-background data-[state=active]:shadow-sm">注册</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="login">
|
||||
<form onSubmit={handleLogin}>
|
||||
<CardHeader>
|
||||
<CardTitle>欢迎回来</CardTitle>
|
||||
<CardDescription>使用您的账号登录智联文档系统</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="username">用户名</Label>
|
||||
<div className="relative">
|
||||
<User className="absolute left-3 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="username"
|
||||
placeholder="请输入用户名"
|
||||
className="pl-9 bg-muted/30 border-none focus-visible:ring-primary"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="password">密码</Label>
|
||||
<div className="relative">
|
||||
<Lock className="absolute left-3 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="password"
|
||||
type="password"
|
||||
placeholder="请输入密码"
|
||||
className="pl-9 bg-muted/30 border-none focus-visible:ring-primary"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button className="w-full h-11 text-lg font-semibold rounded-xl" type="submit" disabled={loading}>
|
||||
{loading ? '登录中...' : '立即登录'}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</form>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="signup">
|
||||
<form onSubmit={handleSignUp}>
|
||||
<CardHeader>
|
||||
<CardTitle>创建账号</CardTitle>
|
||||
<CardDescription>开启智能文档处理的新体验</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="signup-username">用户名</Label>
|
||||
<div className="relative">
|
||||
<User className="absolute left-3 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="signup-username"
|
||||
placeholder="仅字母、数字和下划线"
|
||||
className="pl-9 bg-muted/30 border-none focus-visible:ring-primary"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="signup-password">密码</Label>
|
||||
<div className="relative">
|
||||
<Lock className="absolute left-3 top-2.5 h-4 w-4 text-muted-foreground" />
|
||||
<Input
|
||||
id="signup-password"
|
||||
type="password"
|
||||
placeholder="不少于 6 位"
|
||||
className="pl-9 bg-muted/30 border-none focus-visible:ring-primary"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<Button className="w-full h-11 text-lg font-semibold rounded-xl" type="submit" disabled={loading}>
|
||||
{loading ? '注册中...' : '注册账号'}
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</form>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</Card>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4 text-center text-xs text-muted-foreground">
|
||||
<div className="flex flex-col items-center gap-1">
|
||||
<CheckCircle2 size={16} className="text-primary" />
|
||||
<span>智能解析</span>
|
||||
</div>
|
||||
<div className="flex flex-col items-center gap-1">
|
||||
<CheckCircle2 size={16} className="text-primary" />
|
||||
<span>极速填表</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="text-center text-sm text-muted-foreground">
|
||||
© 2026 智联文档 | 多源数据融合系统
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Login;
|
||||
Reference in New Issue
Block a user