Files
STP/front-end/src/app/pages/LoginPage.tsx
T
vame 7f0f79420c feat(front-end): 初始化STP前端工程并提交页面框架
引入前端项目基础结构、页面骨架和UI组件,建立可运行的开发与构建配置,方便后续按模块迭代。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-22 14:25:22 +08:00

140 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from "react";
import { useNavigate, Link } from "react-router";
import { Hexagon, User, Lock, ShieldCheck, Sparkles, ArrowRight } from "lucide-react";
import { Button } from "../components/ui/button";
export function LoginPage() {
const navigate = useNavigate();
const [account, setAccount] = useState("zhangwei");
const [pwd, setPwd] = useState("123456");
return (
<div className="flex h-screen w-full overflow-hidden bg-slate-50">
{/* 左侧品牌区 */}
<div className="relative hidden w-1/2 flex-col justify-between overflow-hidden bg-gradient-to-br from-[#0f1e3d] via-[#13306b] to-[#2563eb] p-12 text-white lg:flex">
<div className="flex items-center gap-3">
<div className="flex size-11 items-center justify-center rounded-xl bg-white/15 backdrop-blur">
<Hexagon className="size-6" />
</div>
<div>
<div className="text-lg font-semibold"></div>
<div className="text-sm text-white/60">Binhua Smart Tendering Platform</div>
</div>
</div>
<div className="relative z-10">
<div className="mb-4 inline-flex items-center gap-2 rounded-full bg-white/10 px-3 py-1 text-sm backdrop-blur">
<Sparkles className="size-4" /> AI · 线
</div>
<h1 className="text-white" style={{ fontSize: 40, lineHeight: 1.2, fontWeight: 700 }}>
AI
</h1>
<p className="mt-4 max-w-md text-white/70">
</p>
<div className="mt-8 grid grid-cols-3 gap-4">
{[
{ k: "全流程", v: "9 大阶段闭环" },
{ k: "AI 预填", v: "委托效率 +60%" },
{ k: "链上存证", v: "投标哈希上链" },
].map((s) => (
<div key={s.k} className="rounded-xl bg-white/10 p-4 backdrop-blur">
<div className="text-lg font-semibold">{s.k}</div>
<div className="mt-1 text-xs text-white/60">{s.v}</div>
</div>
))}
</div>
</div>
<div className="text-xs text-white/40">© 2026 · </div>
{/* 装饰 */}
<div className="pointer-events-none absolute -right-20 top-1/4 size-72 rounded-full bg-blue-400/20 blur-3xl" />
<div className="pointer-events-none absolute -bottom-10 right-1/3 size-60 rounded-full bg-violet-400/20 blur-3xl" />
</div>
{/* 右侧表单区 */}
<div className="flex flex-1 items-center justify-center p-8">
<div className="w-full max-w-sm">
<div className="mb-8 lg:hidden">
<div className="flex items-center gap-2">
<Hexagon className="size-7 text-primary" />
<span className="font-semibold"></span>
</div>
</div>
<h2 className="text-foreground"></h2>
<p className="mt-1 text-sm text-muted-foreground"></p>
<form
className="mt-8 space-y-4"
onSubmit={(e) => {
e.preventDefault();
navigate("/app");
}}
>
<div>
<label className="mb-1.5 block text-sm"></label>
<div className="relative">
<User className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
<input
value={account}
onChange={(e) => setAccount(e.target.value)}
className="h-11 w-full rounded-lg border bg-input-background pl-10 pr-3 text-sm outline-none focus:border-primary"
placeholder="请输入账号"
/>
</div>
</div>
<div>
<label className="mb-1.5 block text-sm"></label>
<div className="relative">
<Lock className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
<input
type="password"
value={pwd}
onChange={(e) => setPwd(e.target.value)}
className="h-11 w-full rounded-lg border bg-input-background pl-10 pr-3 text-sm outline-none focus:border-primary"
placeholder="请输入密码"
/>
</div>
</div>
<div className="flex gap-3">
<div className="relative flex-1">
<ShieldCheck className="absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
<input
className="h-11 w-full rounded-lg border bg-input-background pl-10 pr-3 text-sm outline-none focus:border-primary"
placeholder="验证码"
/>
</div>
<div className="flex h-11 w-28 items-center justify-center rounded-lg bg-gradient-to-r from-blue-100 to-violet-100 font-mono tracking-widest text-primary select-none">
8 K 2 7
</div>
</div>
<div className="flex items-center justify-between text-sm">
<label className="flex items-center gap-2 text-muted-foreground">
<input type="checkbox" className="size-4 rounded border-border accent-[var(--primary)]" defaultChecked />
</label>
<button type="button" className="text-primary hover:underline">
</button>
</div>
<Button type="submit" className="h-11 w-full">
<ArrowRight className="size-4" />
</Button>
</form>
<div className="mt-6 text-center text-sm text-muted-foreground">
<Link to="/register" className="ml-1 font-medium text-primary hover:underline">
</Link>
</div>
</div>
</div>
</div>
);
}