From c61fcf52142f3d4ad1efe6bd2b65082e7e65fde0 Mon Sep 17 00:00:00 2001 From: Koosha Lahouti Date: Mon, 18 Aug 2025 16:27:43 +0330 Subject: [PATCH] fix: api issue and merge styles problem --- .../AuthenticationSteps/EnterPasswordForm.tsx | 7 ++-- src/features/profile/api/settingsApi.ts | 24 ++++++++++++-- .../components/security/PasswordDialog.tsx | 33 ++++++++++++++----- .../components/security/PasswordSecurity.tsx | 9 +++-- .../userInformation/PersonalInformation.tsx | 22 +++++++++++-- src/features/profile/routes/SettingPage.tsx | 4 +-- src/features/profile/types/settingsType.ts | 4 +++ 7 files changed, 79 insertions(+), 24 deletions(-) diff --git a/src/features/authorization/components/AuthenticationSteps/EnterPasswordForm.tsx b/src/features/authorization/components/AuthenticationSteps/EnterPasswordForm.tsx index 6e412f6..602ca73 100644 --- a/src/features/authorization/components/AuthenticationSteps/EnterPasswordForm.tsx +++ b/src/features/authorization/components/AuthenticationSteps/EnterPasswordForm.tsx @@ -55,11 +55,8 @@ export const EnterPasswordForm = ({ useApi(sendSmsOtp); const { loading: emailResendLoading, execute: emailResendCall } = useApi(sendEmailOtp); - const { - data: loginWithPassResult, - loading: loginWithPassLoading, - execute: loginWithPassCall, - } = useApi(loginWithPassword); + const { loading: loginWithPassLoading, execute: loginWithPassCall } = + useApi(loginWithPassword); const auth = useAuth(); const handleBlur = () => { diff --git a/src/features/profile/api/settingsApi.ts b/src/features/profile/api/settingsApi.ts index bec087f..f840d7f 100644 --- a/src/features/profile/api/settingsApi.ts +++ b/src/features/profile/api/settingsApi.ts @@ -20,11 +20,29 @@ export async function fetchProfile() { export async function saveProfile(payload: { data: InfoRowData; - imageUrl: string | null; + imageUrl: File | null; }) { + const { data, imageUrl } = payload; + + const formData = new FormData(); + formData.append('FirstName', data.firstName || ''); + formData.append('LastName', data.lastName || ''); + formData.append('NationalCode', data.nationalCode || ''); + formData.append('Gender', String(data.gender)); + formData.append('CountryCode', data.country || ''); + + if (imageUrl) { + formData.append('Image', imageUrl); + } + return apiClient.post( '/Profile/SaveProfilePersonalInforamtion', - payload, + formData, + { + headers: { + 'Content-Type': 'multipart/form-data', + }, + }, ); } @@ -70,7 +88,7 @@ export async function deleteSessions(payload: { keys: string[] }) { ); } -export async function addPassword(payload: { password: string }) { +export async function addPassword(payload: { newPassword: string }) { return apiClient.post('/Profile/AddPassword', payload); } diff --git a/src/features/profile/components/security/PasswordDialog.tsx b/src/features/profile/components/security/PasswordDialog.tsx index 2c2c729..a0bdf2d 100644 --- a/src/features/profile/components/security/PasswordDialog.tsx +++ b/src/features/profile/components/security/PasswordDialog.tsx @@ -14,6 +14,7 @@ import { import { CloseCircle } from 'iconsax-react'; import { Icon } from '@rkheftan/harmony-ui'; import { type PasswordDialogProps } from '../../types/settingsType'; +import { PasswordValidationItem } from './PasswordValidation'; export function PasswordDialog({ open, @@ -33,6 +34,10 @@ export function PasswordDialog({ changePassword, apiError, t, + hasMinLength, + hasNumber, + hasUpperAndLower, + hasSpecialChar, }: PasswordDialogProps) { return ( setPassword(e.target.value)} - sx={{ '& .MuiOutlinedInput-root': { borderRadius: 2 } }} + sx={{ '& .MuiOutlinedInput-root': { borderRadius: 2 }, mt: 2 }} /> {showValidation && ( - - {validPassword - ? t('securityForm.passwordIsValid') - : t('securityForm.passwordIsInvalid')} - + + + + + + )} { if (addError || changeError) { showToast({ - message: getErrorMessage(addError || changeError) || t('error.general'), + message: + getErrorMessage(addError || changeError) || t('securityForm.general'), severity: 'error', }); } @@ -116,7 +117,7 @@ export function PasswordSecurity() { newPassword: password, }); } else { - await executeAddPassword({ password }); + await executeAddPassword({ newPassword: password }); } }; @@ -206,6 +207,10 @@ export function PasswordSecurity() { changePassword={changePasswordUI} apiError={getErrorMessage(apiError)} t={t} + hasMinLength={hasMinLength} + hasNumber={hasNumber} + hasUpperAndLower={hasUpperAndLower} + hasSpecialChar={hasSpecialChar} /> )} diff --git a/src/features/profile/components/userInformation/PersonalInformation.tsx b/src/features/profile/components/userInformation/PersonalInformation.tsx index 226040b..a6b2ce4 100644 --- a/src/features/profile/components/userInformation/PersonalInformation.tsx +++ b/src/features/profile/components/userInformation/PersonalInformation.tsx @@ -15,6 +15,7 @@ export function PersonalInformation() { const { t } = useTranslation('setting'); const [isEditing, setIsEditing] = useState(false); const [uploadedImageUrl, setUploadedImageUrl] = useState(null); + const [uploadedImageFile, setUploadedImageFile] = useState(null); const [data, setData] = useState({ firstName: '', lastName: '', @@ -51,7 +52,15 @@ export function PersonalInformation() { }; setData(fetchedData); setOriginalData(fetchedData); - setUploadedImageUrl(profileData.profileImageUrl || null); + + if (profileData.profileImageUrl) { + const imageBaseUrl = 'https://accounts.business-harmony.com/uploads/'; + setUploadedImageUrl(`${imageBaseUrl}${profileData.profileImageUrl}`); + } else { + setUploadedImageUrl(null); + } + + setUploadedImageFile(null); } }, [profileData]); @@ -63,6 +72,7 @@ export function PersonalInformation() { }); setIsEditing(false); setOriginalData(data); + setUploadedImageFile(null); } }, [saveData, data, showToast, t]); @@ -78,11 +88,12 @@ export function PersonalInformation() { if (originalData) { setData(originalData); } + setUploadedImageFile(null); }; const handleSaveClick = async () => { if (!data) return; - executeSaveProfile({ data, imageUrl: uploadedImageUrl }); + executeSaveProfile({ data, imageUrl: uploadedImageFile }); }; const getErrorMessage = (error: unknown): string | null => { @@ -90,6 +101,7 @@ export function PersonalInformation() { if (error instanceof Error) return error.message; return String(error); }; + useEffect(() => { if (saveProfileError) { showToast({ @@ -212,12 +224,16 @@ export function PersonalInformation() { initials={initials} uploadedImageUrl={uploadedImageUrl} onImageChange={(file) => { + setUploadedImageFile(file); const reader = new FileReader(); reader.onload = () => setUploadedImageUrl(reader.result as string); reader.readAsDataURL(file); }} - onRemoveImage={() => setUploadedImageUrl(null)} + onRemoveImage={() => { + setUploadedImageFile(null); + setUploadedImageUrl(null); + }} /> )} {data && diff --git a/src/features/profile/routes/SettingPage.tsx b/src/features/profile/routes/SettingPage.tsx index d598bc0..b1da343 100644 --- a/src/features/profile/routes/SettingPage.tsx +++ b/src/features/profile/routes/SettingPage.tsx @@ -260,7 +260,7 @@ export function SettingPage() { })) } renderInput={(p) => } - size="small" + size="medium" fullWidth disableClearable /> @@ -288,7 +288,7 @@ export function SettingPage() { v && setDraftSettings((prev) => ({ ...prev, calendar: v })) } renderInput={(params) => } - size="small" + size="medium" fullWidth disableClearable /> diff --git a/src/features/profile/types/settingsType.ts b/src/features/profile/types/settingsType.ts index fac5e45..09dd51b 100644 --- a/src/features/profile/types/settingsType.ts +++ b/src/features/profile/types/settingsType.ts @@ -38,6 +38,10 @@ export interface PasswordDialogProps { changePassword: boolean; apiError: string | null; t: (key: string) => string; + hasMinLength: boolean; + hasNumber: boolean; + hasUpperAndLower: boolean; + hasSpecialChar: boolean; } export interface ValidationItemProps {