Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

mail-and-code-auth.tsx 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import { useState } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import { useRouter, useSearchParams } from 'next/navigation'
  4. import { useContext } from 'use-context-selector'
  5. import Input from '@/app/components/base/input'
  6. import Button from '@/app/components/base/button'
  7. import { emailRegex } from '@/config'
  8. import Toast from '@/app/components/base/toast'
  9. import { sendEMailLoginCode } from '@/service/common'
  10. import { COUNT_DOWN_KEY, COUNT_DOWN_TIME_MS } from '@/app/components/signin/countdown'
  11. import I18NContext from '@/context/i18n'
  12. import { noop } from 'lodash-es'
  13. type MailAndCodeAuthProps = {
  14. isInvite: boolean
  15. }
  16. export default function MailAndCodeAuth({ isInvite }: MailAndCodeAuthProps) {
  17. const { t } = useTranslation()
  18. const router = useRouter()
  19. const searchParams = useSearchParams()
  20. const emailFromLink = decodeURIComponent(searchParams.get('email') || '')
  21. const [email, setEmail] = useState(emailFromLink)
  22. const [loading, setIsLoading] = useState(false)
  23. const { locale } = useContext(I18NContext)
  24. const handleGetEMailVerificationCode = async () => {
  25. try {
  26. if (!email) {
  27. Toast.notify({ type: 'error', message: t('login.error.emailEmpty') })
  28. return
  29. }
  30. if (!emailRegex.test(email)) {
  31. Toast.notify({
  32. type: 'error',
  33. message: t('login.error.emailInValid'),
  34. })
  35. return
  36. }
  37. setIsLoading(true)
  38. const ret = await sendEMailLoginCode(email, locale)
  39. if (ret.result === 'success') {
  40. localStorage.setItem(COUNT_DOWN_KEY, `${COUNT_DOWN_TIME_MS}`)
  41. const params = new URLSearchParams(searchParams)
  42. params.set('email', encodeURIComponent(email))
  43. params.set('token', encodeURIComponent(ret.data))
  44. router.push(`/signin/check-code?${params.toString()}`)
  45. }
  46. }
  47. catch (error) {
  48. console.error(error)
  49. }
  50. finally {
  51. setIsLoading(false)
  52. }
  53. }
  54. return (<form onSubmit={noop}>
  55. <input type='text' className='hidden' />
  56. <div className='mb-2'>
  57. <label htmlFor="email" className='system-md-semibold my-2 text-text-secondary'>{t('login.email')}</label>
  58. <div className='mt-1'>
  59. <Input id='email' type="email" disabled={isInvite} value={email} placeholder={t('login.emailPlaceholder') as string} onChange={e => setEmail(e.target.value)} />
  60. </div>
  61. <div className='mt-3'>
  62. <Button loading={loading} disabled={loading || !email} variant='primary' className='w-full' onClick={handleGetEMailVerificationCode}>{t('login.continueWithCode')}</Button>
  63. </div>
  64. </div>
  65. </form>
  66. )
  67. }