15 lines
3.6 KiB
TypeScript
15 lines
3.6 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { ArrowLeft, ArrowRight, UserPlus } from "lucide-react";
|
|
import { FormEvent, useState } from "react";
|
|
import { apiFetch } from "@/lib/api";
|
|
|
|
export default function RegisterPage() {
|
|
const [form, setForm] = useState({ username: "", password: "", phone: "", real_name: "" });
|
|
const [message, setMessage] = useState(""); const [loading, setLoading] = useState(false); const [done, setDone] = useState(false);
|
|
async function handleSubmit(event: FormEvent) { event.preventDefault(); setMessage(""); setLoading(true); try { await apiFetch("/auth/register", { method: "POST", body: JSON.stringify(form) }); setDone(true); } catch (error) { setMessage(error instanceof Error ? error.message : "注册失败,请稍后重试"); } finally { setLoading(false); } }
|
|
const update = (key: keyof typeof form, value: string) => setForm((current) => ({ ...current, [key]: value }));
|
|
return <main className="flex min-h-screen items-center justify-center bg-slate-50 p-8"><div className="w-full max-w-xl rounded-2xl border border-slate-200 bg-white p-8 shadow-xl sm:p-12"><Link href="/" className="inline-flex items-center gap-2 text-sm text-slate-500 hover:text-[var(--brand-primary)]"><ArrowLeft className="h-4 w-4" />返回首页</Link><div className="mt-10 flex h-10 w-10 items-center justify-center rounded-xl bg-indigo-50 text-[var(--brand-primary)]"><UserPlus className="h-5 w-5" /></div><h1 className="mt-6 text-2xl font-semibold text-[var(--brand-navy)]">创建华夏基金账户</h1><p className="mt-2 text-sm text-slate-500">注册后即可查看个人账户和基金持仓。</p>{done ? <div className="mt-8 rounded-xl bg-emerald-50 p-5 text-sm text-emerald-700">注册成功,请前往登录。<Link href="/login" className="ml-2 font-semibold underline">登录账户</Link></div> : <form onSubmit={handleSubmit} className="mt-8 grid gap-5 sm:grid-cols-2"><label className="text-sm font-medium text-slate-700">用户名<input required value={form.username} onChange={(event) => update("username", event.target.value)} className="mt-2 w-full rounded-lg border border-slate-200 px-3 py-3 outline-none focus:border-[var(--brand-primary)]" /></label><label className="text-sm font-medium text-slate-700">真实姓名<input value={form.real_name} onChange={(event) => update("real_name", event.target.value)} className="mt-2 w-full rounded-lg border border-slate-200 px-3 py-3 outline-none focus:border-[var(--brand-primary)]" /></label><label className="text-sm font-medium text-slate-700">手机号<input required pattern="1\d{10}" value={form.phone} onChange={(event) => update("phone", event.target.value)} className="mt-2 w-full rounded-lg border border-slate-200 px-3 py-3 outline-none focus:border-[var(--brand-primary)]" /></label><label className="text-sm font-medium text-slate-700">密码<input required minLength={8} type="password" value={form.password} onChange={(event) => update("password", event.target.value)} className="mt-2 w-full rounded-lg border border-slate-200 px-3 py-3 outline-none focus:border-[var(--brand-primary)]" /></label>{message && <p className="rounded-lg bg-rose-50 px-3 py-2 text-sm text-rose-600 sm:col-span-2">{message}</p>}<button disabled={loading} className="flex items-center justify-center gap-2 rounded-lg bg-[var(--brand-primary)] px-4 py-3.5 text-sm font-semibold text-white hover:bg-[var(--brand-primary-dark)] disabled:opacity-50 sm:col-span-2">{loading ? "注册中..." : "创建账户"}<ArrowRight className="h-4 w-4" /></button></form>}<p className="mt-7 text-center text-sm text-slate-500">已有账号? <Link href="/login" className="font-semibold text-[var(--brand-primary)]">立即登录</Link></p></div></main>;
|
|
}
|