Files
hlae-site/web/src/app/register/index.tsx
purp1e 6adadce2d6 feat: 新增门户功能并重构资源展示组件
- 新增门户(Portal)数据模型与后端 API 端点
- 新增个人资料页面,支持用户更新昵称
- 重构前端资源卡片组件,支持显示 GitHub 版本信息与加速下载链接
- 在登录/注册页面添加 GitHub OAuth 支持
- 更新环境变量示例文件,添加前后端配置项
- 优化导航栏响应式设计,添加移动端菜单
- 添加页脚组件,包含备案信息
- 更新 Prisma 数据模型,适配 Better Auth 并添加种子数据
- 统一前后端 API URL 配置,支持环境变量覆盖
2026-03-11 16:50:28 +08:00

146 lines
4.8 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 as RouterLink } from 'react-router-dom'
import {
Card,
Input,
Button,
Form,
toast,
TextField,
Label,
FieldError,
} from '@heroui/react'
import { buttonVariants } from '@heroui/styles'
import { signUp } from '../../lib/auth-client'
export default function RegisterPage() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [loading, setLoading] = useState(false)
const navigate = useNavigate()
const handleRegister = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
setLoading(true)
try {
await signUp.email(
{
email,
password,
name: email.split('@')[0], // Default name
},
{
onSuccess: () => {
navigate('/')
},
onError: (ctx) => {
toast.danger(ctx.error.message)
},
},
)
} catch (err) {
console.error(err)
} finally {
setLoading(false)
}
}
return (
<div className="flex min-h-[calc(100vh-64px)] flex-col items-center justify-center p-4">
<Card className="w-full max-w-md">
<Card.Header>
<Card.Title className="w-full text-center text-2xl font-bold">
HLAE
</Card.Title>
</Card.Header>
<Form validationBehavior="native" onSubmit={handleRegister}>
<Card.Content className="flex flex-col gap-6">
<TextField
isRequired
name="email"
type="email"
value={email}
onChange={setEmail}
>
<Label></Label>
<Input placeholder="请输入您的邮箱" variant="secondary" />
<FieldError />
</TextField>
<TextField
isRequired
name="password"
type="password"
value={password}
onChange={setPassword}
>
<Label></Label>
<Input placeholder="请输入您的密码" variant="secondary" />
<FieldError />
</TextField>
</Card.Content>
<Card.Footer className="mt-2 flex flex-col gap-3">
<Button
type="submit"
isPending={loading}
fullWidth
className="font-bold"
>
</Button>
<div className="flex w-full items-center gap-2">
<div className="bg-default-200 h-px flex-1" />
<span className="text-default-500 text-xs"></span>
<div className="bg-default-200 h-px flex-1" />
</div>
<Button
type="button"
variant="outline"
fullWidth
onPress={async () => {
await signUp.social({
provider: 'github',
callbackURL: window.location.origin,
})
}}
>
<svg
viewBox="0 0 24 24"
className="mr-2 h-5 w-5"
fill="currentColor"
>
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
</svg>
GitHub
</Button>
<RouterLink
to="/login"
className={buttonVariants({
variant: 'tertiary',
fullWidth: true,
className: 'font-bold',
})}
>
</RouterLink>
<div className="mt-2 flex justify-center">
<RouterLink
to="/"
className="text-default-500 hover:text-foreground text-sm"
>
</RouterLink>
</div>
</Card.Footer>
</Form>
</Card>
<p className="mt-4 text-sm text-gray-500">
{' '}
<RouterLink to="/login" className="text-primary hover:underline">
</RouterLink>
</p>
</div>
)
}