'use client'; import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { KeyRound, Phone, Mail } from "lucide-react" import { useCallback, useState } from "react" import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp" import { InputOTP, InputOTPGroup, InputOTPSlot } from "./ui/input-otp"; import LoginBG from './login-bg.jpg'; import { toast } from "sonner"; import Image from "next/image"; export type SubmitMode = 'password' | 'phone' | 'email'; export type LoginFormData = { type: SubmitMode; account?: string; password?: string; phone?: string; email?: string; code?: string; } export type SendCodeMode = 'phone' | 'email'; export type SendCodeFormData = { type: SendCodeMode; phone?: string; email?: string; } export function useLoginForm(onSubmit: (data: LoginFormData) => Promise, onSendCode: (data: SendCodeFormData) => Promise) { const [loginMode, setLoginMode] = useState('password'); const handleForgetPassword = useCallback(() => { toast.warning('开发中,敬请期待!暂时可通过发送邮件至网站管理员进行密码重置。'); }, []); const handleSubmit = useCallback(async (formData: LoginFormData) => { try { await onSubmit({ ...formData, type: loginMode }); } catch (error) { if (error instanceof Error) { toast.error('登录失败,请重试'); } } }, [loginMode, onSubmit]); const handleSendCode = useCallback(async (formData: SendCodeFormData) => { try { await onSendCode(formData); } catch (error) { if (error instanceof Error) { toast.error('发送验证码失败,请重试'); } } }, [onSendCode]); return { loginMode, setLoginMode, handleForgetPassword, handleSendCode, handleSubmit }; } function LoginHeader() { return ( <>

欢迎回来

登陆到您的账户

) } function PasswordLoginMode({ forgetPassword }: { forgetPassword: () => void }) { return ( <>
) } function PhoneLoginMode({ onSendCode }: { onSendCode: (data: SendCodeFormData) => Promise }) { const [phone, setPhone] = useState(""); const handleSendCode = useCallback(() => { if (phone.trim().length !== 11) { toast.error('请输入正确的手机号'); return; } onSendCode({ type: 'phone', phone, }) }, [phone, onSendCode]); return ( <>
setPhone(e.target.value)} required />
) } function EmailLoginMode({ onSendCode }: { onSendCode: (data: SendCodeFormData) => Promise }) { const [email, setEmail] = useState(""); const handleSendCode = useCallback(() => { if (!email.trim().match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) { toast.error('请输入正确的邮箱地址'); return; } onSendCode({ type: 'email', email, }) }, [email, onSendCode]); return ( <>
setEmail(e.target.value)} required />
) } export function LoginForm({ onSubmit, onSendCode, className, }: { onSubmit: (data: LoginFormData) => Promise; onSendCode: (data: SendCodeFormData) => Promise; className?: string; }) { const { loginMode, setLoginMode, handleForgetPassword, handleSendCode, handleSubmit, } = useLoginForm(onSubmit, onSendCode); return (
{ e.preventDefault(); const formData = new FormData(e.currentTarget); handleSubmit({ type: loginMode, account: formData.get('account')?.toString(), password: formData.get('password')?.toString(), phone: formData.get('phone')?.toString(), email: formData.get('email')?.toString(), code: formData.get('code')?.toString(), }) }}>
{loginMode === 'password' ? : null} {loginMode === 'phone' ? : null} {loginMode === 'email' ? : null}
或者使用
还没有账号?{" "} setLoginMode('phone')}> 注册
Image
登录即表示您同意我们的{" "} 服务条款 {" "} 和{" "} 隐私政策
) }