- 移除 useGameBoardVm 数据层实施说明文档 - 移除核心玩法与前端规则摘要文档 - 移除游戏模块数据与界面分层第一阶段实施稿文档 - 清理与数据层重构相关的技术方案说明 - 删除关于 PC 和 Mobile 界面分离的设计规划 - 移除 view-model hooks 架构设计相关内容
51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
import { useMutation } from '@tanstack/react-query'
|
|
import { useEffect, useState } from 'react'
|
|
import { sendSmsCode } from '@/api'
|
|
import { SMS_CODE_COOLDOWN_FALLBACK_SECONDS } from '@/constants'
|
|
import i18n from '@/i18n'
|
|
import { notify } from '@/lib/notify'
|
|
import { toAuthSubmitErrorKey } from './auth-error-key'
|
|
|
|
export function useSendSmsCode() {
|
|
const [remainingSeconds, setRemainingSeconds] = useState(0)
|
|
const mutation = useMutation({
|
|
mutationFn: (mobile: string) => sendSmsCode({ mobile: mobile.trim() }),
|
|
onError: (error) => {
|
|
const errorKey = toAuthSubmitErrorKey(error, 'register')
|
|
|
|
notify.error(
|
|
errorKey
|
|
? i18n.t(errorKey)
|
|
: i18n.t('auth.register.sms.errors.submitFailed'),
|
|
)
|
|
},
|
|
onSuccess: (result) => {
|
|
setRemainingSeconds(
|
|
result.expiresIn > 0
|
|
? result.expiresIn
|
|
: SMS_CODE_COOLDOWN_FALLBACK_SECONDS,
|
|
)
|
|
notify.success(i18n.t('auth.register.sms.success'))
|
|
},
|
|
})
|
|
|
|
useEffect(() => {
|
|
if (remainingSeconds <= 0) {
|
|
return
|
|
}
|
|
|
|
const timer = window.setTimeout(() => {
|
|
setRemainingSeconds((value) => Math.max(0, value - 1))
|
|
}, 1000)
|
|
|
|
return () => window.clearTimeout(timer)
|
|
}, [remainingSeconds])
|
|
|
|
return {
|
|
canSend: !mutation.isPending && remainingSeconds <= 0,
|
|
isSending: mutation.isPending,
|
|
remainingSeconds,
|
|
send: mutation.mutateAsync,
|
|
}
|
|
}
|