Skip to content

Commit

Permalink
feat(web-office): add change password modal
Browse files Browse the repository at this point in the history
ref:MANAGER-16126

Signed-off-by: stif59100 <[email protected]>
  • Loading branch information
stif59100 committed Jan 17, 2025
1 parent 40c109e commit 863381b
Show file tree
Hide file tree
Showing 11 changed files with 439 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"dashboard_users_change-password_title": "Modifier le mot de passe",
"dashboard_users_change-password_description": "Vous êtes sur le point de modifier le mot de passe de votre compte",
"dashboard_users_change-password_subdescription": "Voulez-vous continuez ?",
"dashboard_users_change-password_confirm": "Êtes-vous sûr de vouloir supprimer l'utilisateur <strong>{{t0}}</strong> ?",
"dashboard_users_change-password_label1": "Mot de passe :",
"dashboard_users_change-password_label2": "Confirmation :",
"dashboard_users_change-password_label3": "Email :",
"dashboard_users_change-password_cta_cancel": "Annuler",
"dashboard_users_change-password_cta_confirm": "Confirmer",
"dashboard_users_change-password_helper1": "Attention, le mot de passe doit respecter les conditions suivantes :",
"dashboard_users_change-password_helper2": "Minimum 8 caractères",
"dashboard_users_change-password_helper3": "Maximum 16 caractères",
"dashboard_users_change-password_helper4": "Au moins 1 lettre minuscule, 1 lettre majuscule, 1 chiffre ou 1 caractère spécial",
"dashboard_users_change-password_email-edit-title": "Si vous ne renseignez pas de mot de passe, celui-ci sera généré aléatoirement et envoyé par email à l'adresse précisée",
"dashboard_users_change-password_email-edit": "Éditer l'email",
"dashboard_users_change-password_email-placeholder": "l'adresse email du contact admin",
"dashboard_users_change-password_message_error": "Une erreur s'est produite lors de la récupération des informations.",
"dashboard_users_change-password_message_success": "Votre changement de mot de passe a bien été pris en compte."
}
6 changes: 6 additions & 0 deletions packages/manager/apps/web-office/src/api/api.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,9 @@ export type UserParamsType = {
firstName: string;
lastName: string;
};

export type UserChangePasswordType = {
password?: string;
shouldSendMail: boolean;
notifyEmail?: string;
};
19 changes: 18 additions & 1 deletion packages/manager/apps/web-office/src/api/users/api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { fetchIcebergV6, v6 } from '@ovh-ux/manager-core-api';
import { getApiPath } from '../utils/apiPath';
import { UserChangePasswordType, UserParamsType } from '../api.type';
import { UserNativeType } from './type';
import { UserParamsType } from '../api.type';
import { useOfficeServiceType } from '@/hooks';

// GET

Expand All @@ -26,7 +27,23 @@ export const getOfficeUserDetail = async (
};

// POST
export const postUsersPassword = async (
serviceName: string,
activationEmail: string,
params: UserChangePasswordType,
) => {
const serviceType = useOfficeServiceType(serviceName);
const apiPath = getApiPath(serviceName);

const endpoint =
serviceType === 'payAsYouGo'
? `${apiPath}user/${activationEmail}/changePassword`
: `${apiPath}changePassword`;

const { data } = await v6.post(endpoint, params);

return data;
};
// PUT

export const putOfficeUserDetail = async (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const Modal: React.FC<ModalProps> = ({
data-testid="modal"
color={color}
isDismissible={isDismissible}
className="text-left"
className="text-left max-height-modal"
onOdsClose={onClose}
isOpen={isOpen}
class="max-height-modal"
Expand Down
1 change: 1 addition & 0 deletions packages/manager/apps/web-office/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from './useGenerateUrl';
export * from './useOfficeServiceType';
export * from './useOfficeUsers';
export * from './useOfficeUserDetail';
export * from './useForm';
82 changes: 82 additions & 0 deletions packages/manager/apps/web-office/src/hooks/useForm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { useState } from 'react';

export type FieldType = {
value: string;
touched?: boolean;
defaultValue?: string;
hasError?: boolean;
required?: boolean;
validate?: ((value: string) => boolean) | RegExp;
};

export interface FormTypeInterface {
[key: string]: FieldType;
}

export const validateField = (
name: string,
value: string,
form: FormTypeInterface,
) => {
const field = form[name];

if (!field) {
throw new Error(`validateField field is not defined for name "${name}"`);
}

if (!field.required && !value) {
return true;
}

if (typeof field.validate === 'function') {
return field.validate(value);
}

if (field.validate instanceof RegExp) {
return field.validate.test(String(value));
}

return !field.required || !!value;
};

export const validateForm = (form: FormTypeInterface) => {
const touched = Object.values(form).find((field) => field.touched);
const error = Object.values(form).find(
(field) => field.hasError || (field.required && field.value === ''),
);
return touched && !error;
};

type FormTypeOptions = {
onValueChange?: (
state: FormTypeInterface,
value: string,
name?: string,
) => FormTypeInterface;
};

export const useForm = (
initialForm: FormTypeInterface = {},
options: FormTypeOptions = {},
) => {
const [isFormValid, setIsFormValid] = useState(false);
const [form, setForm] = useState<FormTypeInterface>(initialForm);

const setValue = (name: string, value: string, isBlur = false) => {
let newForm = form;
if (value !== form[name].value || isBlur) {
newForm[name] = {
...form[name],
value,
touched: true,
hasError: !validateField(name, value, form),
};
if (typeof options?.onValueChange === 'function') {
newForm = options.onValueChange(newForm, name, value);
}
setForm((oldForm) => ({ ...oldForm, ...newForm }));
setIsFormValid(validateForm(form));
}
};
return { isFormValid, form, setValue, setForm };
};
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,19 @@ const ActionButtonUsers: React.FC<ActionButtonUsersProps> = ({
}),
});

const hrefChangePasswordUsers = useGenerateUrl(
'./users/change-password',
'path',
{
activationEmail: usersItem.activationEmail,
...(!licenceDetail.serviceType && {
licencePrepaidName: licenceDetail.serviceName,
}),
},
);

const handlePasswordChangeClick = () => {
// @todo: for next user story
console.log('handlePasswordChangeClick');
return navigate(hrefChangePasswordUsers);
};

const handleDeleteUserClick = () => navigate(hrefDeleteUsers);
Expand Down
Loading

0 comments on commit 863381b

Please sign in to comment.