feat: add using enter instead pushing the button

This commit is contained in:
Koosha Lahouti
2025-09-14 00:02:08 +03:30
parent 9ec1415f70
commit 19bbf55904
17 changed files with 675 additions and 559 deletions

View File

@@ -1,4 +1,4 @@
import { useState, useEffect } from 'react';
import { useState, useEffect, useMemo } from 'react';
import { useTranslation } from 'react-i18next';
import parsePhoneNumberFromString from 'libphonenumber-js';
import { PageWrapper } from '../PageWrapper';
@@ -40,20 +40,21 @@ export function PhoneNumber() {
const { loading: isSendingCode, execute: executeSendCode } =
useApi(sendVerificationCode);
const { loading: isVerifying, execute: executeConfirmCode } = useApi(
confirmPhoneNumberCode,
);
const { loading: isChangingPhone, execute: executeChangePhone } =
useApi(changePhoneNumber);
const isBusy = useMemo(
() => isVerifying || isSendingCode || isChangingPhone,
[isVerifying, isSendingCode, isChangingPhone],
);
useEffect(() => {
const loadProfile = async () => {
const profileData = await refetchProfile();
if (!profileData) return;
if (profileData?.success) {
setPhones([
{
@@ -69,36 +70,32 @@ export function PhoneNumber() {
});
}
};
loadProfile();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
void loadProfile();
}, [refetchProfile, toast]);
useEffect(() => {
if (!phoneNumberTouched) return;
if (!phoneNumber) {
setPhoneNumberError(t('settingForm.thisFieldIsRequired'));
return;
}
if (!isPhoneValid(countryCode, phoneNumber)) {
const parsed = parsePhoneNumberFromString(countryCode + phoneNumber);
const valid = Boolean(parsed?.isValid());
if (!valid) {
setPhoneNumberError(t('settingForm.phoneNumberIsInvalid'));
} else {
setPhoneNumberError(undefined);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [countryCode, phoneNumber, phoneNumberTouched]);
}, [countryCode, phoneNumber, phoneNumberTouched, t]);
useEffect(() => {
if (!verificationCodeTouched) return;
if (!verificationCode) {
setVerificationCodeError(t('settingForm.verificationCodeRequired'));
return;
}
setVerificationCodeError(undefined);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [verificationCode, verificationCodeTouched]);
const isPhoneValid = (code: string, phone: string) => {
const phoneNum = parsePhoneNumberFromString(code + phone);
return phoneNum?.isValid();
};
}, [verificationCode, verificationCodeTouched, t]);
const handleBlur = (key: string) => {
if (key === 'phoneNumber') {
@@ -126,14 +123,11 @@ export function PhoneNumber() {
const handleSendCode = async () => {
setPhoneNumberTouched(true);
if (phoneNumberError) return;
if (!phoneNumber || phoneNumberError) return;
const result = await executeSendCode({
phoneNumber: countryCode + phoneNumber.replace(/^0/, ''),
});
if (!result) return;
if (result?.success) {
setButtonState('counting');
setIsVerified(false);
@@ -151,18 +145,13 @@ export function PhoneNumber() {
const handleVerifyCode = async () => {
setVerificationCodeTouched(true);
if (verificationCodeError) return;
if (!verificationCode || verificationCodeError) return;
const fullPhoneNumber = countryCode + phoneNumber.replace(/^0/, '');
const confirmResult = await executeConfirmCode({
phoneNumber: fullPhoneNumber,
verifyCode: verificationCode,
});
if (!confirmResult) return;
if (!confirmResult.success || !confirmResult.confirm) {
toast({
message: confirmResult?.message || t('message.serverError'),
@@ -170,19 +159,15 @@ export function PhoneNumber() {
});
return;
}
setIsVerified(true);
toast({
message: t('settingForm.phoneVerified'),
severity: 'success',
});
const changeResult = await executeChangePhone({
phoneNumber: fullPhoneNumber,
});
if (!changeResult) return;
if (changeResult?.success) {
setPhones([
{
@@ -212,6 +197,8 @@ export function PhoneNumber() {
isEditing={isEditing}
toggleEdit={toggleEdit}
t={t}
formId="phoneForm"
isSubmitting={isBusy}
/>
}
>
@@ -228,27 +215,40 @@ export function PhoneNumber() {
<CircularProgress />
</Box>
) : isEditing ? (
<PhoneEditForm
phoneNumber={phoneNumber}
setPhoneNumber={setPhoneNumber}
countryCode={countryCode}
setCountryCode={setCountryCode}
verificationCode={verificationCode}
setVerificationCode={setVerificationCode}
isVerified={isVerified}
isVerifying={isVerifying || isSendingCode || isChangingPhone}
isSendingCode={isSendingCode}
buttonState={buttonState}
setButtonState={setButtonState}
handleSendCode={handleSendCode}
handleVerifyClick={handleVerifyCode}
phoneNumberError={phoneNumberTouched ? phoneNumberError : undefined}
verificationCodeError={
verificationCodeTouched ? verificationCodeError : undefined
}
handleBlur={handleBlur}
phones={phones}
/>
<Box
component="form"
id="phoneForm"
noValidate
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
if (!isBusy) void handleVerifyCode();
}}
>
<PhoneEditForm
phoneNumber={phoneNumber}
setPhoneNumber={setPhoneNumber}
countryCode={countryCode}
setCountryCode={setCountryCode}
verificationCode={verificationCode}
setVerificationCode={setVerificationCode}
isVerified={isVerified}
isVerifying={isBusy}
isSendingCode={isSendingCode}
buttonState={buttonState}
setButtonState={setButtonState}
handleSendCode={handleSendCode}
handleVerifyClick={handleVerifyCode}
phoneNumberError={
phoneNumberTouched ? phoneNumberError : undefined
}
verificationCodeError={
verificationCodeTouched ? verificationCodeError : undefined
}
handleBlur={handleBlur}
phones={phones}
/>
</Box>
) : (
<PhoneDisplay
phones={phones.map((p) => {