Skip to content
Clone
163952e
39 lines 1.5 KB
import { useState } from 'preact/hooks'
import type { LoginComplete } from '@/entities/session'
import { markCode, useCodeTimer } from '@/entities/verification-code'
import { t } from '@/shared/i18n'
import { emailError, normalizeEmail, useCountdown, useTask } from '@/shared/lib'
import { loginWithCode, sendLoginCode } from '../api/login-code'
export function useLoginByCode(onComplete: LoginComplete) {
const [email, setEmail] = useState('')
const [sentEmail, setSentEmail] = useState('')
const [code, setCode] = useState('')
const task = useTask()
const timer = useCodeTimer(`login:${sentEmail}`)
const retry = useCountdown(task.retryUntil)
function send() {
const address = normalizeEmail(sentEmail || email)
const error = emailError(address)
if (error) return task.fail({ email: error })
void task.run(async (signal) => {
const response = await sendLoginCode(address, signal)
markCode(`login:${address}`, response.expires_in_secs)
setSentEmail(address)
setCode('')
task.setNotice({ kind: 'success', text: t('loginCode.notice') })
})
}
function changeEmail() {
setSentEmail('')
setCode('')
task.setNotice(undefined)
}
function submit() {
if (!/^\d{6}$/.test(code)) return task.fail({ code: t('loginCode.codeError') })
void task.run(async (signal) => onComplete(await loginWithCode(sentEmail, code, signal)))
}
return { email, setEmail, sentEmail, code, setCode, task, timer, retry, send, changeEmail, submit }
}
export type LoginByCodeModel = ReturnType<typeof useLoginByCode>