doctor-mail/apps/web/src/app/auth/register.tsx

207 lines
5.4 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 AvatarUploader from "@web/src/components/common/uploader/AvatarUploader";
import DepartmentSelect from "@web/src/components/models/department/department-select";
import { Form, Input, Button, Select } from "antd";
import { motion } from "framer-motion";
import { useState } from "react";
export interface RegisterFormData {
deptId: string;
domainId: string;
username: string;
showname: string;
officerId: string;
password: string;
repeatPass: string;
rank: string;
office: string;
email: string;
phoneNumber: string;
}
interface RegisterFormProps {
onSubmit: (data: RegisterFormData) => void;
isLoading: boolean;
}
export const RegisterForm = ({ onSubmit, isLoading }: RegisterFormProps) => {
const [form] = Form.useForm<RegisterFormData>();
const [domainId, setDomainId] = useState<string>();
return (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}>
<Form
form={form}
layout="vertical"
onFinish={onSubmit}
scrollToFirstError>
<div className="flex items-center gap-2 mb-2">
<div className="flex-1">
<Form.Item name="photoUrl" label="头像" noStyle>
<AvatarUploader
className="rounded-lg"
placeholder="点击上传头像"
style={{
width: `100%`,
height: 210,
}}
/>
</Form.Item>
</div>
<div className="flex-1 grid grid-cols-1 gap-3">
<Form.Item
name="username"
label="用户名"
noStyle
rules={[
{ required: true, message: "请输入用户名" },
{ min: 2, message: "用户名至少需要2个字符" },
]}>
<Input placeholder="用户名" />
</Form.Item>
<Form.Item
name="showname"
label="姓名"
noStyle
rules={[
{ required: true, message: "请输入姓名" },
{ min: 2, message: "姓名至少需要2个字符" },
]}>
<Input placeholder="姓名" />
</Form.Item>
<Form.Item
noStyle
name={"domainId"}
label="所属域"
rules={[{ required: true }]}>
<DepartmentSelect
placeholder="选择域"
onChange={(value) => {
setDomainId(value as string);
}}
domain={true}
/>
</Form.Item>
<Form.Item
name="deptId"
noStyle
label="部门"
rules={[{ required: true, message: "请选择部门" }]}>
<DepartmentSelect rootId={domainId} />
</Form.Item>
<Form.Item noStyle name={"rank"}>
<Input
placeholder="请输入职级(可选)"
autoComplete="off"
spellCheck={false}
allowClear
/>
</Form.Item>
</div>
</div>
<div className="flex items-center gap-2">
<div className="flex-1 grid grid-cols-1 gap-2">
<Form.Item
noStyle
rules={[
{
required: false,
pattern: /^\d{6,11}$/,
message: "请输入正确的手机号(数字)",
},
]}
name={"phoneNumber"}
label="手机号">
<Input
autoComplete="new-phone" // 使用非标准的自动完成值
spellCheck={false}
allowClear
placeholder="请输入手机号(可选)"
/>
</Form.Item>
<Form.Item noStyle name={"office"}>
<Input
placeholder="请输入办公室地点"
autoComplete="off"
spellCheck={false}
allowClear
/>
</Form.Item>
<Form.Item
name="password"
rules={[
{ required: true, message: "请输入密码" },
{ min: 8, message: "密码至少需要8个字符" },
{
pattern:
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/,
message:
"密码必须包含大小写字母、数字和特殊字符",
},
]}>
<Input.Password placeholder="密码" />
</Form.Item>
</div>
<div className="flex-1 grid grid-cols-1 gap-2">
<Form.Item
name="officerId"
label="证件号"
noStyle
rules={[
{ required: true, message: "请输入证件号" },
{
pattern: /^\d{5,12}$/,
message: "请输入有效的证件号5-12位数字",
},
]}>
<Input placeholder="证件号" />
</Form.Item>
<Form.Item noStyle name={"email"}>
<Input
placeholder="请输入邮箱(可选)"
autoComplete="off"
spellCheck={false}
allowClear
/>
</Form.Item>
<Form.Item
name="repeatPass"
dependencies={["password"]}
rules={[
{ required: true, message: "请确认密码" },
({ getFieldValue }) => ({
validator(_, value) {
if (
!value ||
getFieldValue("password") === value
) {
return Promise.resolve();
}
return Promise.reject(
new Error("两次输入的密码不一致")
);
},
}),
]}>
<Input.Password placeholder="确认密码" />
</Form.Item>
</div>
</div>
<div className="grid grid-cols-1 flex-1 my-2"></div>
<Form.Item>
<Button
type="primary"
htmlType="submit"
loading={isLoading}
className="w-full h-10 rounded-lg">
{isLoading ? "正在注册..." : "注册"}
</Button>
</Form.Item>
</Form>
</motion.div>
);
};