diff --git a/.env b/.env
index 28a64fc..c7fa122 100644
--- a/.env
+++ b/.env
@@ -1,8 +1,8 @@
VITE_GOOGLE_CLIENT_ID=https://272098283932-bft2gvlgjn8edopg0lnqjq1i9ekdmipt.apps.googleusercontent.com
VITE_DEFUALT_AUTH_RETURN_URL=/setting/profile
VITE_APP_URL=https://accounts.business-harmony.com
-VITE_API_URL=https://accounts.business-harmony.com/apiapp/api
-VITE_IDENTITY_URL=https://accounts.business-harmony.com/apiapp/connect/token
+VITE_API_URL=https://accounts.business-harmony.com/api
+VITE_IDENTITY_URL=https://accounts.business-harmony.com/connect/token
VITE_IDENTITY_CLIENT_ID=harmony_identity
VITE_IDENTITY_SCOPE=openid profile offline_access
IMAGE_BASE_URL=https://accounts.business-harmony.com/uploads/
diff --git a/src/features/authentication/components/AuthenticationSteps/CompleteSignUp.tsx b/src/features/authentication/components/AuthenticationSteps/CompleteSignUp.tsx
index 6b63783..6ec07f3 100644
--- a/src/features/authentication/components/AuthenticationSteps/CompleteSignUp.tsx
+++ b/src/features/authentication/components/AuthenticationSteps/CompleteSignUp.tsx
@@ -1,4 +1,4 @@
-import { Button, TextField, Typography } from '@mui/material';
+import { Box, Button, TextField, Typography } from '@mui/material';
import parsePhoneNumberFromString from 'libphonenumber-js';
import { useRef, useState, type Dispatch } from 'react';
import { useTranslation } from 'react-i18next';
@@ -69,47 +69,56 @@ export const CompleteSignUp = ({
return (
-
- {t('completeSignUp.completeSignUp')}
-
-
-
- {t(
- 'completeSignUp.emailHasBeenSuccessfullyVerifiedPleaseEnterYourContactNumberToContinue',
- { email },
- )}
-
-
- setValue(e.target.value)}
- onBlur={handleBlur}
- error={inputError}
- helperText={inputError ? error : ''}
- autoFocus
- slotProps={{
- htmlInput: { dir: 'auto', sx: { lineHeight: 1.5, paddingX: 0 } },
- input: {
- endAdornment: (
-
- ),
- },
+ {
+ e.preventDefault();
+ e.stopPropagation();
+ if (!sendSmsLoading) void handleCompleteSignUp();
}}
- sx={{ my: 4 }}
- />
+ >
+
+ {t('completeSignUp.completeSignUp')}
+
-
+
+ {t(
+ 'completeSignUp.emailHasBeenSuccessfullyVerifiedPleaseEnterYourContactNumberToContinue',
+ { email },
+ )}
+
+
+ setValue(e.target.value)}
+ onBlur={handleBlur}
+ error={inputError}
+ helperText={inputError ? error : ''}
+ autoFocus
+ slotProps={{
+ htmlInput: { dir: 'auto', sx: { lineHeight: 1.5, paddingX: 0 } },
+ input: {
+ endAdornment: (
+
+ ),
+ },
+ }}
+ sx={{ my: 4 }}
+ />
+
+
+
);
};
diff --git a/src/features/authentication/components/AuthenticationSteps/EnterPasswordForm.tsx b/src/features/authentication/components/AuthenticationSteps/EnterPasswordForm.tsx
index 8cc4a59..6dc9f56 100644
--- a/src/features/authentication/components/AuthenticationSteps/EnterPasswordForm.tsx
+++ b/src/features/authentication/components/AuthenticationSteps/EnterPasswordForm.tsx
@@ -21,7 +21,6 @@ import {
import type { LoginResult, PasswordLoginRequest } from '../../types/userTypes';
import { Icon, useToast } from '@rkheftan/harmony-ui';
import { useApi } from '@/hooks/useApi';
-import { useAuth } from '@/hooks/useAuth';
import {
generateTokenWithPassword,
type GenerateTokenResponse,
diff --git a/src/features/authentication/components/AuthenticationSteps/GoogleAuthentication.tsx b/src/features/authentication/components/AuthenticationSteps/GoogleAuthentication.tsx
index 7fedd8d..275a430 100644
--- a/src/features/authentication/components/AuthenticationSteps/GoogleAuthentication.tsx
+++ b/src/features/authentication/components/AuthenticationSteps/GoogleAuthentication.tsx
@@ -14,7 +14,6 @@ import {
generateTokenWithGoogle,
type GenerateTokenResponse,
} from '../../api/identityAPI';
-import { useAuth } from '@/hooks/useAuth';
import type { AuthFactory } from '../../types/authTypes';
export interface GoogleAuthenticationProps {
diff --git a/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx b/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx
index dceb8b5..74be9d9 100644
--- a/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx
+++ b/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx
@@ -1,4 +1,4 @@
-import { Button, Stack, TextField, Typography } from '@mui/material';
+import { Button, Stack, TextField, Typography, Box } from '@mui/material';
import { useRef, useState, type Dispatch } from 'react';
import { useTranslation } from 'react-i18next';
import { isNumeric } from '@/utils/regexes/isNumeric';
@@ -120,51 +120,62 @@ export function LoginRegisterForm({
return (
-
- {t('loginForm.title')}
-
- {t('loginForm.description')}
-
-
-
-
- ),
- },
+ {
+ e.preventDefault();
+ e.stopPropagation();
+ if (!userStatusLoading) {
+ void handleSubmit();
+ }
}}
- sx={{ my: 4 }}
- />
+ >
+
+ {t('loginForm.title')}
+
+ {t('loginForm.description')}
+
+
-
-
-
-
+ ),
+ },
+ }}
+ sx={{ my: 4 }}
/>
-
+
+
+
+
+
+
+
);
}
diff --git a/src/features/authentication/components/AuthenticationSteps/OtpVerifyForm.tsx b/src/features/authentication/components/AuthenticationSteps/OtpVerifyForm.tsx
index 319e90f..db87c48 100644
--- a/src/features/authentication/components/AuthenticationSteps/OtpVerifyForm.tsx
+++ b/src/features/authentication/components/AuthenticationSteps/OtpVerifyForm.tsx
@@ -18,7 +18,6 @@ import {
generateTokenWithOtp,
type GenerateTokenResponse,
} from '../../api/identityAPI';
-import { useAuth } from '@/hooks/useAuth';
interface OtpVerifyFormProps {
value: string;
@@ -166,43 +165,54 @@ export function OtpVerifyForm({
{
+ e.preventDefault();
+ e.stopPropagation();
+ if (!loginSignUpLoading) {
+ void handleVerifyOTP();
+ }
}}
>
- {t('verify.verify')}
-
- }
- onClick={onEditValue}
+
- {authType === 'phone' ? countryCode + value : value}
+ {t('verify.verify')}
+
+ }
+ onClick={onEditValue}
+ >
+ {authType === 'phone' ? countryCode + value : value}
+
+
+
+
+ {otpMessage}
+
+
+ setOtpCode(value)}
+ />
+
+
-
-
- {otpMessage}
-
-
- setOtpCode(value)}
- />
-
-
{
+ e.preventDefault();
+ e.stopPropagation();
+ if (!confirmSmsOtpLoading) {
+ void handleVerifyOTP();
+ }
}}
>
- {t('verify.verify')}
-
- }
- onClick={onEditValue}
+
- {countryCode + value}
+ {t('verify.verify')}
+
+ }
+ onClick={onEditValue}
+ >
+ {countryCode + value}
+
+
+
+
+ {t(
+ 'verify.a4DigitVerificationCodeHasBeenSentToYourBobileNumberPleaseEnterIt',
+ )}
+
+
+ setOtpCode(value)}
+ />
+
+
-
-
- {t(
- 'verify.a4DigitVerificationCodeHasBeenSentToYourBobileNumberPleaseEnterIt',
- )}
-
-
- setOtpCode(value)}
- />
-
-
{
+ e.preventDefault();
+ e.stopPropagation();
+ if (!confirmForgetPassCodeLoading) {
+ void handleVerifyOTP();
+ }
}}
>
-
- {t('forgetPassword.forgetPassword')}
+
+
+ {t('forgetPassword.forgetPassword')}
+
+
+ }
+ onClick={onEditInfo}
+ >
+ {infoType === 'phone'
+ ? countryCode + forgettedPasswordInfo
+ : forgettedPasswordInfo}
+
+
+
+
+ {infoType === 'email'
+ ? t(
+ 'forgetPassword.anEmailContainingARecoveryCodeHasBeenSentToThisEmailAddress',
+ )
+ : t(
+ 'forgetPassword.anCodeContainingARecoveryCodeHasBeenSentToThisPhoneNumber',
+ )}
- }
- onClick={onEditInfo}
- >
- {infoType === 'phone'
- ? countryCode + forgettedPasswordInfo
- : forgettedPasswordInfo}
+ setOtpCode(value)}
+ />
+
+
-
-
- {infoType === 'email'
- ? t(
- 'forgetPassword.anEmailContainingARecoveryCodeHasBeenSentToThisEmailAddress',
- )
- : t(
- 'forgetPassword.anCodeContainingARecoveryCodeHasBeenSentToThisPhoneNumber',
- )}
-
-
- setOtpCode(value)}
- />
-
-
{
+ e.preventDefault();
+ e.stopPropagation();
+ void handleSubmit();
}}
>
-
-
- {t('completion.title')}
-
-
- {t('completion.description')}
-
+
+
+
+ {t('completion.title')}
+
+
+ {t('completion.description')}
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
diff --git a/src/features/authentication/types/settingForm.ts b/src/features/authentication/types/settingForm.ts
index 68d7030..bcc4387 100644
--- a/src/features/authentication/types/settingForm.ts
+++ b/src/features/authentication/types/settingForm.ts
@@ -72,6 +72,5 @@ export interface PersonalInfoFieldsProps extends ValidationProps {
}
export interface SubmitProps {
- onSubmit: () => void;
loading: boolean;
}
diff --git a/src/features/profile/components/security/PasswordDialog.tsx b/src/features/profile/components/security/PasswordDialog.tsx
index 5920786..f83ca8c 100644
--- a/src/features/profile/components/security/PasswordDialog.tsx
+++ b/src/features/profile/components/security/PasswordDialog.tsx
@@ -46,6 +46,12 @@ export function PasswordDialog({
const [showConfirm, setShowConfirm] = useState(false);
const navigate = useNavigate();
+ const onFormSubmit: React.FormEventHandler = (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ if (!loading) handleSubmit();
+ };
+
return (
);
}
diff --git a/src/features/profile/components/userInformation/PersonalInformation.tsx b/src/features/profile/components/userInformation/PersonalInformation.tsx
index d5de493..c89212c 100644
--- a/src/features/profile/components/userInformation/PersonalInformation.tsx
+++ b/src/features/profile/components/userInformation/PersonalInformation.tsx
@@ -14,7 +14,6 @@ import { useProfile } from '../../hooks/useProfile';
export function PersonalInformation() {
const imageBaseUrl = import.meta.env.IMAGE_BASE_URL;
-
const { t } = useTranslation('setting');
const [isEditing, setIsEditing] = useState(false);
const [uploadedImageUrl, setUploadedImageUrl] = useState(null);
@@ -29,18 +28,14 @@ export function PersonalInformation() {
const [originalData, setOriginalData] = useState(null);
const showToast = useToast();
const infoRowEditRef = useRef<{ validateFields: () => boolean }>(null);
-
const { isLoadingProfile, refetchProfile } = useProfile();
-
const { loading: isSavingProfile, execute: executeSaveProfile } =
useApi(saveProfile);
useEffect(() => {
const loadProfile = async () => {
const profileData = await refetchProfile();
-
if (!profileData) return;
-
if (profileData.success) {
const fetchedData = {
firstName: profileData.firstName ?? '',
@@ -66,7 +61,6 @@ export function PersonalInformation() {
});
}
};
-
loadProfile();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
@@ -85,14 +79,11 @@ export function PersonalInformation() {
if (!data) return;
const isValid = infoRowEditRef.current?.validateFields?.();
if (!isValid) return;
-
const saveData = await executeSaveProfile({
data,
imageUrl: uploadedImageFile,
});
-
if (!saveData) return;
-
if (saveData?.success) {
showToast({
message: t('settingForm.successSaveProfile'),
@@ -101,7 +92,6 @@ export function PersonalInformation() {
setIsEditing(false);
setOriginalData(data);
setUploadedImageFile(null);
- // Force a refetch to update the cache with the new data
refetchProfile({ force: true });
} else {
showToast({
@@ -122,6 +112,7 @@ export function PersonalInformation() {
{isEditing ? (
<>