Skip to content
Clone
main
69 lines 2.4 KB
import { useState } from 'react'
import { registrationDraft, useRegistrationDraft } from '@/entities/registration'
import { markCode, useCodeTimer } from '@/entities/verification-code'
import { t } from '@/shared/i18n'
import type { Errors } from '@/shared/lib'
import {
birthError,
emailError,
normalizeEmail,
passwordDigest,
passwordError,
useCountdown,
usernameError,
useTask,
} from '@/shared/lib'
import type { BirthValue } from '@/shared/ui'
import { emptyBirth } from '@/shared/ui'
import { sendRegisterCode } from '../api/register'
export function useRegisterAccount(onSent: () => void) {
const draft = useRegistrationDraft()
const [email, setEmail] = useState(draft?.email || '')
const [username, setUsername] = useState(draft?.username || '')
const [password, setPassword] = useState('')
const [birth, setBirth] = useState<BirthValue>(draft?.birth || emptyBirth)
const [agreed, setAgreed] = useState(draft?.agreed || false)
const task = useTask()
const retry = useCountdown(task.retryUntil)
const timer = useCodeTimer(`register:${normalizeEmail(email)}`)
function submit() {
const address = normalizeEmail(email)
const name = username.trim()
const errors: Errors = {}
if (emailError(address)) errors.email = emailError(address)
if (usernameError(name)) errors.username = usernameError(name)
if (password ? passwordError(password) : !draft?.passwordHash) errors.password = passwordError(password)
if (birthError(birth.year, birth.month, birth.day)) errors.birth = birthError(birth.year, birth.month, birth.day)
if (!agreed) errors.agreement = t('register.agreementError')
if (Object.keys(errors).length) return task.fail(errors)
void task.run(async (signal) => {
const passwordHash = password ? await passwordDigest(password) : (draft?.passwordHash ?? '')
if (address !== draft?.email || !timer.expiry) {
const response = await sendRegisterCode(address, signal)
markCode(`register:${address}`, response.expires_in_secs)
}
registrationDraft.set({ email: address, username: name, passwordHash, birth, agreed })
onSent()
})
}
return {
draft,
email,
setEmail,
username,
setUsername,
password,
setPassword,
birth,
setBirth,
agreed,
setAgreed,
task,
retry,
timer,
submit,
}
}
export type RegisterAccountModel = ReturnType<typeof useRegisterAccount>