203 lines
6.7 KiB
TypeScript
203 lines
6.7 KiB
TypeScript
|
|
'use client'
|
|||
|
|
|
|||
|
|
import { useState } from 'react'
|
|||
|
|
import { useRouter } from 'next/navigation'
|
|||
|
|
import { useForm } from 'react-hook-form'
|
|||
|
|
import { useAuth } from '@/components/providers/auth-provider'
|
|||
|
|
import { Button } from '@nice/ui/components/button'
|
|||
|
|
import { Input } from '@nice/ui/components/input'
|
|||
|
|
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@nice/ui/components/form'
|
|||
|
|
import { Alert, AlertDescription } from '@nice/ui/components/alert'
|
|||
|
|
import { DeptSelect } from '@/components/selector/dept-select'
|
|||
|
|
import Link from 'next/link'
|
|||
|
|
|
|||
|
|
interface RegisterForm {
|
|||
|
|
username: string
|
|||
|
|
password: string
|
|||
|
|
confirmPassword: string
|
|||
|
|
email?: string
|
|||
|
|
organizationId?: string
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default function RegisterPage() {
|
|||
|
|
const router = useRouter()
|
|||
|
|
const { register: registerUser, isLoading } = useAuth()
|
|||
|
|
|
|||
|
|
const [error, setError] = useState<string | null>(null)
|
|||
|
|
|
|||
|
|
const form = useForm<RegisterForm>({
|
|||
|
|
defaultValues: {
|
|||
|
|
username: '',
|
|||
|
|
password: '',
|
|||
|
|
confirmPassword: '',
|
|||
|
|
email: '',
|
|||
|
|
organizationId: ''
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
const handleSubmit = async (data: RegisterForm) => {
|
|||
|
|
// 验证密码确认
|
|||
|
|
if (data.password !== data.confirmPassword) {
|
|||
|
|
form.setError('confirmPassword', { message: '两次输入的密码不一致' })
|
|||
|
|
return
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
setError(null)
|
|||
|
|
try {
|
|||
|
|
await registerUser({
|
|||
|
|
data: {
|
|||
|
|
username: data.username,
|
|||
|
|
password: data.password,
|
|||
|
|
organizationId: data.organizationId,
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
// 注册成功,跳转到登录页
|
|||
|
|
router.push('/auth/login?message=register_success')
|
|||
|
|
} catch (err) {
|
|||
|
|
setError(err instanceof Error ? err.message : '注册失败,请重试')
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div className="w-full">
|
|||
|
|
{/* 欢迎标题 */}
|
|||
|
|
<div className="text-center mb-12">
|
|||
|
|
<h1 className="text-3xl font-bold text-gray-900 mb-3">注册风火账号</h1>
|
|||
|
|
|
|||
|
|
{/* 错误消息 */}
|
|||
|
|
{error && (
|
|||
|
|
<Alert className="mb-4 border-red-200 bg-red-50">
|
|||
|
|
<AlertDescription className="text-red-800">
|
|||
|
|
{error}
|
|||
|
|
</AlertDescription>
|
|||
|
|
</Alert>
|
|||
|
|
)}
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
{/* 注册表单 */}
|
|||
|
|
<Form {...form}>
|
|||
|
|
<form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-6">
|
|||
|
|
{/* 用户名输入 */}
|
|||
|
|
<FormField
|
|||
|
|
control={form.control}
|
|||
|
|
name="username"
|
|||
|
|
rules={{
|
|||
|
|
required: '请输入用户名',
|
|||
|
|
minLength: { value: 2, message: '用户名至少2个字符' },
|
|||
|
|
pattern: {
|
|||
|
|
value: /^[\u4e00-\u9fa5a-zA-Z0-9_@.-]+$/,
|
|||
|
|
message: '用户名只能包含中文、字母、数字、下划线、@、点和横线'
|
|||
|
|
}
|
|||
|
|
}}
|
|||
|
|
render={({ field }) => (
|
|||
|
|
<FormItem>
|
|||
|
|
<FormLabel className="text-base text-gray-700 font-medium">用户名</FormLabel>
|
|||
|
|
<FormControl>
|
|||
|
|
<Input
|
|||
|
|
type="text"
|
|||
|
|
placeholder="请输入用户名"
|
|||
|
|
className="h-12 text-base focus-visible:ring-1 focus-visible:ring-blue-500 focus-visible:border-blue-500"
|
|||
|
|
autoComplete="username"
|
|||
|
|
disabled={isLoading}
|
|||
|
|
{...field}
|
|||
|
|
/>
|
|||
|
|
</FormControl>
|
|||
|
|
<FormMessage />
|
|||
|
|
</FormItem>
|
|||
|
|
)}
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
{/* 所属部门选择 */}
|
|||
|
|
<FormField
|
|||
|
|
control={form.control}
|
|||
|
|
name="organizationId"
|
|||
|
|
render={({ field }) => (
|
|||
|
|
<FormItem>
|
|||
|
|
<FormLabel className="text-base text-gray-700 font-medium">所属部门 (可选)</FormLabel>
|
|||
|
|
<FormControl>
|
|||
|
|
<DeptSelect
|
|||
|
|
value={field.value}
|
|||
|
|
onValueChange={field.onChange}
|
|||
|
|
placeholder="选择所属部门"
|
|||
|
|
className="w-full h-12"
|
|||
|
|
disabled={isLoading}
|
|||
|
|
allowClear={true}
|
|||
|
|
/>
|
|||
|
|
</FormControl>
|
|||
|
|
<FormMessage />
|
|||
|
|
</FormItem>
|
|||
|
|
)}
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
{/* 密码输入 */}
|
|||
|
|
<FormField
|
|||
|
|
control={form.control}
|
|||
|
|
name="password"
|
|||
|
|
rules={{
|
|||
|
|
required: '请输入密码',
|
|||
|
|
minLength: { value: 6, message: '密码至少6个字符' }
|
|||
|
|
}}
|
|||
|
|
render={({ field }) => (
|
|||
|
|
<FormItem>
|
|||
|
|
<FormLabel className="text-base text-gray-700 font-medium">密码</FormLabel>
|
|||
|
|
<FormControl>
|
|||
|
|
<Input
|
|||
|
|
type="password"
|
|||
|
|
placeholder="请输入密码(至少6个字符)"
|
|||
|
|
className="h-12 text-base focus-visible:ring-1 focus-visible:ring-blue-500 focus-visible:border-blue-500"
|
|||
|
|
autoComplete="new-password"
|
|||
|
|
disabled={isLoading}
|
|||
|
|
{...field}
|
|||
|
|
/>
|
|||
|
|
</FormControl>
|
|||
|
|
<FormMessage />
|
|||
|
|
</FormItem>
|
|||
|
|
)}
|
|||
|
|
/>
|
|||
|
|
|
|||
|
|
{/* 确认密码输入 */}
|
|||
|
|
<FormField
|
|||
|
|
control={form.control}
|
|||
|
|
name="confirmPassword"
|
|||
|
|
rules={{
|
|||
|
|
required: '请确认密码',
|
|||
|
|
minLength: { value: 6, message: '密码至少6个字符' }
|
|||
|
|
}}
|
|||
|
|
render={({ field }) => (
|
|||
|
|
<FormItem>
|
|||
|
|
<FormLabel className="text-base text-gray-700 font-medium">确认密码</FormLabel>
|
|||
|
|
<FormControl>
|
|||
|
|
<Input
|
|||
|
|
type="password"
|
|||
|
|
placeholder="请再次输入密码"
|
|||
|
|
className="h-12 text-base focus-visible:ring-1 focus-visible:ring-blue-500 focus-visible:border-blue-500"
|
|||
|
|
autoComplete="new-password"
|
|||
|
|
disabled={isLoading}
|
|||
|
|
{...field}
|
|||
|
|
/>
|
|||
|
|
</FormControl>
|
|||
|
|
<FormMessage />
|
|||
|
|
</FormItem>
|
|||
|
|
)}
|
|||
|
|
/>
|
|||
|
|
{/* 注册按钮 */}
|
|||
|
|
<Button
|
|||
|
|
type="submit"
|
|||
|
|
className="w-full h-12 bg-blue-600 hover:bg-blue-700 text-white rounded-lg font-medium text-base transition-colors mt-8"
|
|||
|
|
disabled={isLoading}
|
|||
|
|
>
|
|||
|
|
{isLoading ? '注册中...' : '注册账号'}
|
|||
|
|
</Button>
|
|||
|
|
</form>
|
|||
|
|
</Form>
|
|||
|
|
|
|||
|
|
{/* 登录链接 */}
|
|||
|
|
<div className="text-center mt-8">
|
|||
|
|
<span className="text-base text-gray-600">已有账号?</span>
|
|||
|
|
<Link href="/auth/login" className="text-base text-blue-600 hover:underline ml-2">
|
|||
|
|
立即登录
|
|||
|
|
</Link>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|