import md5 from 'md5' import QRCode from 'qrcode' import { Fragment } from 'react' import {loginWithEmail, loginWithPhone} from '@/api/auth' import SvgIcon from '@/components/SvgIcon' import { state } from '@/store' import { setCookies } from '@/utils/cookie' enum Method { QRCODE = 'qrcode', EMAIL = 'email', PHONE = 'phone', } // Shared components and methods const EmailInput = ({ email, setEmail, }: { email: string setEmail: (email: string) => void }) => { return (
Email
setEmail(e.target.value)} className='w-full rounded-md border border-gray-300 px-2 py-2 dark:border-gray-600 dark:bg-gray-700 dark:text-white' type='email' />
) } const PhoneInput = ({ countryCode, setCountryCode, phone, setPhone, }: { countryCode: string setCountryCode: (code: string) => void phone: string setPhone: (phone: string) => void }) => { return (
Phone
= 5 && 'w-20' )} type='text' placeholder='+86' value={countryCode} onChange={e => setCountryCode(e.target.value)} /> setPhone(e.target.value)} />
) } const PasswordInput = ({ password, setPassword, }: { password: string setPassword: (password: string) => void }) => { const [showPassword, setShowPassword] = useState(false) return (
Password
setPassword(e.target.value)} className='w-full rounded-md rounded-r-none border border-r-0 border-gray-300 px-2 py-2 dark:border-gray-600 dark:bg-gray-700 dark:text-white' type={showPassword ? 'text' : 'password'} />
) } const LoginButton = ({ onClick, disabled, }: { onClick: () => void disabled: boolean }) => { // TODO: Add loading indicator return ( ) } const OtherLoginMethods = ({ method, setMethod, }: { method: Method setMethod: (method: Method) => void }) => { const otherLoginMethods: { id: Method name: string }[] = [ { id: Method.QRCODE, name: 'QR Code', }, { id: Method.EMAIL, name: 'Email', }, { id: Method.PHONE, name: 'Phone', }, ] return (
or
{otherLoginMethods.map( ({ id, name }) => method !== id && ( ) )}
) } const saveCookie = (cookies: string) => { setCookies(cookies) } // Login with Email const LoginWithEmail = () => { const [password, setPassword] = useState('') const [email, setEmail] = useState('') const navigate = useNavigate() const doLogin = useMutation( () => { return loginWithEmail({ email: email.trim(), md5_password: md5(password.trim()) }) }, { onSuccess: result => { if (result?.code !== 200) { toast(`Login failed: ${result.code}`) return } saveCookie(result.cookie) navigate(-1) }, onError: error => { toast(`Login failed: ${error}`) }, } ) const handleLogin = () => { if (!email) { toast.error('Please enter email') return } if (!password) { toast.error('Please enter password') return } if (email.match(/^[^\s@]+@(126|163|yeah|188|vip\.163|vip\.126)\.(com|net)$/) == null){ toast.error('Please use netease email') return } doLogin.mutate() } return ( ) } // Login with Phone const LoginWithPhone = () => { const [password, setPassword] = useState('') const [phone, setPhone] = useState('') const countryCode = useSnapshot(state).uiStates.loginPhoneCountryCode const setCountryCode = (countryCode: string) => { state.uiStates.loginPhoneCountryCode = countryCode } const navigate = useNavigate() const doLogin = useMutation( () => { return loginWithPhone({ countrycode: Number(countryCode.replace('+', '').trim()) || 86, phone: phone.trim(), md5_password: md5(password.trim()), }) }, { onSuccess: result => { if (result?.code !== 200) { toast(`Login failed: ${result.code}`) return } saveCookie(result.cookie) navigate(-1) }, onError: error => { toast(`Login failed: ${error}`) }, } ) const handleLogin = () => { if (!countryCode || !Number(countryCode.replace('+', '').trim())) { toast.error('Please enter country code') return } if (!phone) { toast.error('Please enter phone number') return } if (!password) { toast.error('Please enter password') return } doLogin.mutate() } return ( ) } // Login with QRCode const LoginWithQRCode = () => { const [qrCodeUrl, setQrCodeUrl] = useState('dasdasfa') const [qrCodeImage, setQrCodeImage] = useState('') useMemo(async () => { try { const image = await QRCode.toDataURL(qrCodeUrl, { width: 1024, margin: 0, color: { dark: '#335eea', // TODO: change brand color light: '#ffffff00', }, }) setQrCodeImage(image) } catch (err) { console.error(err) } }, [qrCodeUrl]) const qrCodeMessage = 'test' return (
QR Code
{qrCodeMessage}
) } export default function Login() { const [method, setMethod] = useState(Method.PHONE) return (
{method === Method.EMAIL && } {method === Method.PHONE && } {method === Method.QRCODE && }
) }