fix: api issue and merge styles problem
This commit is contained in:
@@ -55,11 +55,8 @@ export const EnterPasswordForm = ({
|
|||||||
useApi(sendSmsOtp);
|
useApi(sendSmsOtp);
|
||||||
const { loading: emailResendLoading, execute: emailResendCall } =
|
const { loading: emailResendLoading, execute: emailResendCall } =
|
||||||
useApi(sendEmailOtp);
|
useApi(sendEmailOtp);
|
||||||
const {
|
const { loading: loginWithPassLoading, execute: loginWithPassCall } =
|
||||||
data: loginWithPassResult,
|
useApi(loginWithPassword);
|
||||||
loading: loginWithPassLoading,
|
|
||||||
execute: loginWithPassCall,
|
|
||||||
} = useApi(loginWithPassword);
|
|
||||||
const auth = useAuth();
|
const auth = useAuth();
|
||||||
|
|
||||||
const handleBlur = () => {
|
const handleBlur = () => {
|
||||||
|
|||||||
@@ -20,11 +20,29 @@ export async function fetchProfile() {
|
|||||||
|
|
||||||
export async function saveProfile(payload: {
|
export async function saveProfile(payload: {
|
||||||
data: InfoRowData;
|
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<SaveProfileApiResponse>(
|
return apiClient.post<SaveProfileApiResponse>(
|
||||||
'/Profile/SaveProfilePersonalInforamtion',
|
'/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<PasswordApiResponse>('/Profile/AddPassword', payload);
|
return apiClient.post<PasswordApiResponse>('/Profile/AddPassword', payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
import { CloseCircle } from 'iconsax-react';
|
import { CloseCircle } from 'iconsax-react';
|
||||||
import { Icon } from '@rkheftan/harmony-ui';
|
import { Icon } from '@rkheftan/harmony-ui';
|
||||||
import { type PasswordDialogProps } from '../../types/settingsType';
|
import { type PasswordDialogProps } from '../../types/settingsType';
|
||||||
|
import { PasswordValidationItem } from './PasswordValidation';
|
||||||
|
|
||||||
export function PasswordDialog({
|
export function PasswordDialog({
|
||||||
open,
|
open,
|
||||||
@@ -33,6 +34,10 @@ export function PasswordDialog({
|
|||||||
changePassword,
|
changePassword,
|
||||||
apiError,
|
apiError,
|
||||||
t,
|
t,
|
||||||
|
hasMinLength,
|
||||||
|
hasNumber,
|
||||||
|
hasUpperAndLower,
|
||||||
|
hasSpecialChar,
|
||||||
}: PasswordDialogProps) {
|
}: PasswordDialogProps) {
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog
|
||||||
@@ -93,18 +98,28 @@ export function PasswordDialog({
|
|||||||
fullWidth
|
fullWidth
|
||||||
value={password}
|
value={password}
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
sx={{ '& .MuiOutlinedInput-root': { borderRadius: 2 } }}
|
sx={{ '& .MuiOutlinedInput-root': { borderRadius: 2 }, mt: 2 }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{showValidation && (
|
{showValidation && (
|
||||||
<Typography
|
<Box sx={{ mt: 1 }}>
|
||||||
variant="body2"
|
<PasswordValidationItem
|
||||||
color={validPassword ? 'success.main' : 'error.main'}
|
isValid={hasNumber}
|
||||||
>
|
label={t('securityForm.hasNumber')}
|
||||||
{validPassword
|
/>
|
||||||
? t('securityForm.passwordIsValid')
|
<PasswordValidationItem
|
||||||
: t('securityForm.passwordIsInvalid')}
|
isValid={hasMinLength}
|
||||||
</Typography>
|
label={t('securityForm.hasMinLength')}
|
||||||
|
/>
|
||||||
|
<PasswordValidationItem
|
||||||
|
isValid={hasUpperAndLower}
|
||||||
|
label={t('securityForm.hasUpperAndLower')}
|
||||||
|
/>
|
||||||
|
<PasswordValidationItem
|
||||||
|
isValid={hasSpecialChar}
|
||||||
|
label={t('securityForm.hasSpecialChar')}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
|
|||||||
@@ -100,7 +100,8 @@ export function PasswordSecurity() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (addError || changeError) {
|
if (addError || changeError) {
|
||||||
showToast({
|
showToast({
|
||||||
message: getErrorMessage(addError || changeError) || t('error.general'),
|
message:
|
||||||
|
getErrorMessage(addError || changeError) || t('securityForm.general'),
|
||||||
severity: 'error',
|
severity: 'error',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -116,7 +117,7 @@ export function PasswordSecurity() {
|
|||||||
newPassword: password,
|
newPassword: password,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await executeAddPassword({ password });
|
await executeAddPassword({ newPassword: password });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -206,6 +207,10 @@ export function PasswordSecurity() {
|
|||||||
changePassword={changePasswordUI}
|
changePassword={changePasswordUI}
|
||||||
apiError={getErrorMessage(apiError)}
|
apiError={getErrorMessage(apiError)}
|
||||||
t={t}
|
t={t}
|
||||||
|
hasMinLength={hasMinLength}
|
||||||
|
hasNumber={hasNumber}
|
||||||
|
hasUpperAndLower={hasUpperAndLower}
|
||||||
|
hasSpecialChar={hasSpecialChar}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export function PersonalInformation() {
|
|||||||
const { t } = useTranslation('setting');
|
const { t } = useTranslation('setting');
|
||||||
const [isEditing, setIsEditing] = useState(false);
|
const [isEditing, setIsEditing] = useState(false);
|
||||||
const [uploadedImageUrl, setUploadedImageUrl] = useState<string | null>(null);
|
const [uploadedImageUrl, setUploadedImageUrl] = useState<string | null>(null);
|
||||||
|
const [uploadedImageFile, setUploadedImageFile] = useState<File | null>(null);
|
||||||
const [data, setData] = useState<InfoRowData>({
|
const [data, setData] = useState<InfoRowData>({
|
||||||
firstName: '',
|
firstName: '',
|
||||||
lastName: '',
|
lastName: '',
|
||||||
@@ -51,7 +52,15 @@ export function PersonalInformation() {
|
|||||||
};
|
};
|
||||||
setData(fetchedData);
|
setData(fetchedData);
|
||||||
setOriginalData(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]);
|
}, [profileData]);
|
||||||
|
|
||||||
@@ -63,6 +72,7 @@ export function PersonalInformation() {
|
|||||||
});
|
});
|
||||||
setIsEditing(false);
|
setIsEditing(false);
|
||||||
setOriginalData(data);
|
setOriginalData(data);
|
||||||
|
setUploadedImageFile(null);
|
||||||
}
|
}
|
||||||
}, [saveData, data, showToast, t]);
|
}, [saveData, data, showToast, t]);
|
||||||
|
|
||||||
@@ -78,11 +88,12 @@ export function PersonalInformation() {
|
|||||||
if (originalData) {
|
if (originalData) {
|
||||||
setData(originalData);
|
setData(originalData);
|
||||||
}
|
}
|
||||||
|
setUploadedImageFile(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSaveClick = async () => {
|
const handleSaveClick = async () => {
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
executeSaveProfile({ data, imageUrl: uploadedImageUrl });
|
executeSaveProfile({ data, imageUrl: uploadedImageFile });
|
||||||
};
|
};
|
||||||
|
|
||||||
const getErrorMessage = (error: unknown): string | null => {
|
const getErrorMessage = (error: unknown): string | null => {
|
||||||
@@ -90,6 +101,7 @@ export function PersonalInformation() {
|
|||||||
if (error instanceof Error) return error.message;
|
if (error instanceof Error) return error.message;
|
||||||
return String(error);
|
return String(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (saveProfileError) {
|
if (saveProfileError) {
|
||||||
showToast({
|
showToast({
|
||||||
@@ -212,12 +224,16 @@ export function PersonalInformation() {
|
|||||||
initials={initials}
|
initials={initials}
|
||||||
uploadedImageUrl={uploadedImageUrl}
|
uploadedImageUrl={uploadedImageUrl}
|
||||||
onImageChange={(file) => {
|
onImageChange={(file) => {
|
||||||
|
setUploadedImageFile(file);
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = () =>
|
reader.onload = () =>
|
||||||
setUploadedImageUrl(reader.result as string);
|
setUploadedImageUrl(reader.result as string);
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
}}
|
}}
|
||||||
onRemoveImage={() => setUploadedImageUrl(null)}
|
onRemoveImage={() => {
|
||||||
|
setUploadedImageFile(null);
|
||||||
|
setUploadedImageUrl(null);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{data &&
|
{data &&
|
||||||
|
|||||||
@@ -260,7 +260,7 @@ export function SettingPage() {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
renderInput={(p) => <TextField {...p} />}
|
renderInput={(p) => <TextField {...p} />}
|
||||||
size="small"
|
size="medium"
|
||||||
fullWidth
|
fullWidth
|
||||||
disableClearable
|
disableClearable
|
||||||
/>
|
/>
|
||||||
@@ -288,7 +288,7 @@ export function SettingPage() {
|
|||||||
v && setDraftSettings((prev) => ({ ...prev, calendar: v }))
|
v && setDraftSettings((prev) => ({ ...prev, calendar: v }))
|
||||||
}
|
}
|
||||||
renderInput={(params) => <TextField {...params} />}
|
renderInput={(params) => <TextField {...params} />}
|
||||||
size="small"
|
size="medium"
|
||||||
fullWidth
|
fullWidth
|
||||||
disableClearable
|
disableClearable
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ export interface PasswordDialogProps {
|
|||||||
changePassword: boolean;
|
changePassword: boolean;
|
||||||
apiError: string | null;
|
apiError: string | null;
|
||||||
t: (key: string) => string;
|
t: (key: string) => string;
|
||||||
|
hasMinLength: boolean;
|
||||||
|
hasNumber: boolean;
|
||||||
|
hasUpperAndLower: boolean;
|
||||||
|
hasSpecialChar: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ValidationItemProps {
|
export interface ValidationItemProps {
|
||||||
|
|||||||
Reference in New Issue
Block a user