Files
boursecu_user/src/views/login/composables/useLoginForm.ts
T

199 lines
5.7 KiB
TypeScript

import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue'
import type { FormInstance } from 'ant-design-vue'
import { message } from 'ant-design-vue'
import type SmsOtpField from '@/components/SmsOtpField.vue'
import type { Login } from '@/models/login'
import {
authenticateWithFingerprint,
getToken,
loading,
setToken,
} from '@/utils'
import useCountdownTimer from '@/utils/useCountdownTimer'
import { loginCustomer, verifyToken } from '@/api/login'
import { useUserStore } from '@/store/userStore'
import { useWalletStore } from '@/store/walletStore'
import { useSettingsStore } from '@/store/settingsStore'
import { setTruth } from '@/app/authBoot'
import { completeLoginNavigation } from '@/layouts/composables/useMobileScrollReset'
import { normalizeAuthFormFields, persianToEnglishDigits } from '@/utils/persianDigits'
import { beginSmsOtpCapture, clearPendingSmsOtp } from '@/utils/webOtp'
import { usePwaInstall } from '@/composables/usePwaInstall'
import {
canRequestBrowserNotification,
requestBrowserNotificationPermission,
} from '@/utils/browserNotification'
export function useLoginForm() {
const { time, onFinish, reset } = useCountdownTimer('00:02:00', 'mm:ss')
const enableSendAgainCode = ref(false)
const stepTwoVerify = ref(false)
const formRef = ref<FormInstance>()
const userStore = useUserStore()
const walletStore = useWalletStore()
const refOtpInput = ref<InstanceType<typeof SmsOtpField> | null>(null)
const isSMS = ref(true)
const isRegister = ref<boolean | undefined>()
const { tryInstallOrOpenGuide, completeGuide } = usePwaInstall()
const userFormState = reactive<Login>({
provider: 'customer',
})
onFinish(() => {
enableSendAgainCode.value = true
})
onBeforeUnmount(() => {
// SmsOtpField cleans its own listener
})
async function reSendCode() {
userFormState.token = undefined
clearPendingSmsOtp()
refOtpInput.value?.clearInput?.()
enableSendAgainCode.value = false
normalizeAuthFormFields(userFormState)
beginSmsOtpCapture()
await loginCustomer(userFormState)
refOtpInput.value?.startWebOtp?.()
refOtpInput.value?.focusInput?.()
reset()
}
function setIsSMS(val: boolean) {
isSMS.value = val
if (!val) stepTwoVerify.value = false
userFormState.token = ''
userFormState.password = ''
}
async function enterFingerPrint() {
const fingerPrint = await authenticateWithFingerprint()
if (fingerPrint) {
setTruth()
await completeLoginNavigation()
} else {
message.error('خطا در اعتبارسنجی')
}
}
function handleOnChange(value: string) {
userFormState.token = persianToEnglishDigits(String(value ?? ''))
normalizeAuthFormFields(userFormState)
}
async function handleOnComplete(value: string) {
userFormState.token = persianToEnglishDigits(String(value ?? ''))
normalizeAuthFormFields(userFormState)
phoneVerification()
}
async function login(accessToken: string | undefined) {
setToken(accessToken)
await userStore.getMyInfo()
if (!userStore.userInfo) {
message.error('ورود انجام شد ولی دریافت اطلاعات کاربر ممکن نشد. اتصال سرور را بررسی کنید.')
return
}
await walletStore.getMyWallet()
setTruth()
await completeLoginNavigation()
}
function phoneVerification() {
return formRef.value?.validateFields().then(async () => {
try {
loading.value = true
normalizeAuthFormFields(userFormState)
if (isSMS.value) {
if (!stepTwoVerify.value) {
userFormState.token = undefined
userFormState.password = undefined
userFormState.provider = 'customer'
beginSmsOtpCapture()
const { id } = await loginCustomer(userFormState)
userFormState.id = id
stepTwoVerify.value = true
reset()
} else {
// نوتیف را در gesture شروع کن؛ await نکن تا ورود بلاک نشود
if (canRequestBrowserNotification()) {
void requestBrowserNotificationPermission()
}
const { access_token } = await verifyToken(userFormState)
await login(access_token)
}
} else {
userFormState.token = undefined
if (canRequestBrowserNotification()) {
void requestBrowserNotificationPermission()
}
const { access_token } = await loginCustomer(userFormState)
await login(access_token)
}
} catch (e) {
console.log(e)
} finally {
loading.value = false
}
})
}
function editPhoneNumber() {
stepTwoVerify.value = false
}
async function isOpenRegister() {
const settingsStore = useSettingsStore()
await settingsStore.fetchSettings()
isRegister.value = settingsStore.settings.find(
(s) => s?.key === 'open_register' && s?.is_active === true,
)
}
function installWebApp() {
void tryInstallOrOpenGuide()
}
function proceedWithInstall() {
void completeGuide()
}
const submitLabel = computed(() => {
if (!isSMS.value) return 'ورود'
return stepTwoVerify.value ? 'ورود' : 'ارسال کد'
})
const showFingerprint = computed(
() => Boolean(getToken() && userStore.userInfo?.finger_print),
)
onMounted(async () => {
await isOpenRegister()
})
return {
time,
enableSendAgainCode,
stepTwoVerify,
formRef,
refOtpInput,
isSMS,
isRegister,
userFormState,
loading,
submitLabel,
showFingerprint,
setIsSMS,
reSendCode,
enterFingerPrint,
handleOnChange,
handleOnComplete,
phoneVerification,
editPhoneNumber,
installWebApp,
proceedWithInstall,
}
}