Merge branch 'dev' into staging
This commit is contained in:
commit
d7b67007c1
@ -1,10 +1,11 @@
|
||||
import React from "react";
|
||||
import classes from "./classes.module.scss";
|
||||
import Image from "next/image";
|
||||
import InfoIcon from "@Assets/Icons/info.svg";
|
||||
import NotificationIcon from "@Assets/Icons/notification.svg";
|
||||
import Toasts, { IToast } from "@Front/Stores/Toasts";
|
||||
import Image from "next/image";
|
||||
import React from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import NotificationModal from "./NotificationModal";
|
||||
import InfoIcon from "@Assets/Icons/info.svg";
|
||||
|
||||
type IProps = {
|
||||
isModalOpen: boolean;
|
||||
|
@ -20,7 +20,14 @@ export default class ProfileModal extends React.Component<IProps, IState> {
|
||||
<div className={classes["background"]} onClick={this.props.closeModal} />
|
||||
<div className={classes["root"]}>
|
||||
<NavigationLink path={Module.getInstance().get().modules.pages.MyAccount.props.path} text="Mon compte" />
|
||||
<NavigationLink path={Module.getInstance().get().modules.pages.Roles.props.path} text="Gestion des rôles" />
|
||||
<NavigationLink
|
||||
path={Module.getInstance().get().modules.pages.Roles.props.path}
|
||||
text="Gestion des rôles"
|
||||
routesActive={[
|
||||
Module.getInstance().get().modules.pages.Roles.props.path,
|
||||
Module.getInstance().get().modules.pages.Roles.pages.RolesInformations.props.path,
|
||||
]}
|
||||
/>
|
||||
<NavigationLink
|
||||
path={Module.getInstance().get().modules.pages.DeedTypes.props.path}
|
||||
text="Paramétrage des listes de pièces"
|
||||
@ -29,6 +36,10 @@ export default class ProfileModal extends React.Component<IProps, IState> {
|
||||
Module.getInstance().get().modules.pages.DeedTypes.pages.Create.props.path,
|
||||
Module.getInstance().get().modules.pages.DeedTypes.pages.DeedTypesInformations.props.path,
|
||||
Module.getInstance().get().modules.pages.DeedTypes.pages.Edit.props.path,
|
||||
Module.getInstance().get().modules.pages.DocumentTypes.pages.Edit.props.path,
|
||||
Module.getInstance().get().modules.pages.DocumentTypes.pages.Create.props.path,
|
||||
Module.getInstance().get().modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path,
|
||||
Module.getInstance().get().modules.pages.DocumentTypes.props.path,
|
||||
]}
|
||||
/>
|
||||
<NavigationLink
|
||||
|
37
src/front/Components/DesignSystem/Switch/classes.module.scss
Normal file
37
src/front/Components/DesignSystem/Switch/classes.module.scss
Normal file
@ -0,0 +1,37 @@
|
||||
.root {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
cursor: pointer;
|
||||
width: fit-content;
|
||||
.switch-container {
|
||||
position: relative;
|
||||
width: 46px;
|
||||
height: 24px;
|
||||
background-color: var(--grey-medium);
|
||||
border-radius: 64px;
|
||||
|
||||
transition: all 200ms ease-in-out;
|
||||
&[data-checked="true"] {
|
||||
background-color: var(--turquoise-flash);
|
||||
|
||||
.round {
|
||||
left: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.round {
|
||||
transition: all 200ms ease-in-out;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 100px;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 2px;
|
||||
background: white;
|
||||
}
|
||||
}
|
||||
}
|
33
src/front/Components/DesignSystem/Switch/index.tsx
Normal file
33
src/front/Components/DesignSystem/Switch/index.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import Typography, { ITypo, ITypoColor } from "../Typography";
|
||||
|
||||
type IProps = {
|
||||
onChange?: (checked: boolean) => void;
|
||||
checked?: boolean;
|
||||
label: string;
|
||||
};
|
||||
export default function Switch({ onChange, checked, label }: IProps) {
|
||||
const [isChecked, setIsChecked] = useState<boolean>(checked ? checked : false);
|
||||
|
||||
useEffect(() => {
|
||||
setIsChecked(checked ? checked : false);
|
||||
}, [checked]);
|
||||
|
||||
const handleChange = useCallback(() => {
|
||||
setIsChecked(!isChecked);
|
||||
onChange?.(!isChecked);
|
||||
}, [isChecked, onChange]);
|
||||
|
||||
return (
|
||||
<div className={classes["root"]} onClick={handleChange}>
|
||||
<div className={classes["switch-container"]} data-checked={isChecked.toString()}>
|
||||
<div className={classes["round"]} />
|
||||
</div>
|
||||
<Typography typo={ITypo.P_ERR_16} color={ITypoColor.BLACK}>
|
||||
{label}
|
||||
</Typography>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -3,9 +3,9 @@ import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
|
||||
import Roles from "@Front/Api/LeCoffreApi/Admin/Roles/Roles";
|
||||
import Users from "@Front/Api/LeCoffreApi/Admin/Users/Users";
|
||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
||||
import SelectField, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||
import Switch from "@Front/Components/DesignSystem/Switch";
|
||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import DefaultCollaboratorDashboard from "@Front/Components/LayoutTemplates/DefaultCollaboratorDashboard";
|
||||
import Module from "@Front/Config/Module";
|
||||
@ -26,9 +26,16 @@ export default function CollaboratorInformations(props: IProps) {
|
||||
|
||||
const [roleModalOpened, setRoleModalOpened] = useState<boolean>(false);
|
||||
const [adminModalOpened, setAdminModalOpened] = useState<boolean>(false);
|
||||
|
||||
const [adminRoleType, setAdminRoleType] = useState<"add" | "remove">("add");
|
||||
const [selectedOption, setSelectedOption] = useState<IOption | null>(null);
|
||||
|
||||
const [isAdminChecked, setIsAdminChecked] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!userSelected) return;
|
||||
setIsAdminChecked(userSelected.role?.name === "admin" && !userSelected.office_role);
|
||||
}, [userSelected]);
|
||||
|
||||
const handleRoleChange = useCallback((option: IOption) => {
|
||||
setSelectedOption(option);
|
||||
setRoleModalOpened(true);
|
||||
@ -56,31 +63,43 @@ export default function CollaboratorInformations(props: IProps) {
|
||||
}, [selectedOption, userSelected]);
|
||||
|
||||
const changeAdmin = useCallback(async () => {
|
||||
const adminRole = await Roles.getInstance().getOne({
|
||||
where: {
|
||||
name: "admin",
|
||||
},
|
||||
});
|
||||
try {
|
||||
if (adminRoleType === "add") {
|
||||
const adminRole = await Roles.getInstance().getOne({
|
||||
where: {
|
||||
name: "admin",
|
||||
},
|
||||
});
|
||||
|
||||
if (!adminRole) return;
|
||||
await Users.getInstance().put(
|
||||
userSelected?.uid as string,
|
||||
User.hydrate<User>({
|
||||
uid: userSelected?.uid as string,
|
||||
office_role: undefined,
|
||||
role: adminRole,
|
||||
}),
|
||||
);
|
||||
setRoleModalOpened(false);
|
||||
}, [userSelected]);
|
||||
if (!adminRole) return;
|
||||
await Users.getInstance().put(
|
||||
userSelected?.uid as string,
|
||||
User.hydrate<User>({
|
||||
uid: userSelected?.uid as string,
|
||||
office_role: undefined,
|
||||
role: adminRole,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
// retirer rôle admin
|
||||
}
|
||||
setAdminModalOpened(false);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}, [adminRoleType, userSelected]);
|
||||
|
||||
const openAdminModal = useCallback(() => {
|
||||
const openAdminModal = useCallback((checked: boolean) => {
|
||||
setIsAdminChecked(checked);
|
||||
if (checked) setAdminRoleType("add");
|
||||
else setAdminRoleType("remove");
|
||||
setAdminModalOpened(true);
|
||||
}, []);
|
||||
|
||||
const closeAdminModal = useCallback(() => {
|
||||
setIsAdminChecked(userSelected?.role?.name === "admin" && !userSelected.office_role);
|
||||
setAdminModalOpened(false);
|
||||
}, []);
|
||||
}, [userSelected]);
|
||||
|
||||
useEffect(() => {
|
||||
async function getUser() {
|
||||
@ -167,15 +186,7 @@ export default function CollaboratorInformations(props: IProps) {
|
||||
</div>
|
||||
{userSelected?.role?.name !== "super-admin" && (
|
||||
<div className={classes["third-line"]}>
|
||||
<CheckBox
|
||||
onChange={openAdminModal}
|
||||
option={{
|
||||
value: "1",
|
||||
label: "Nommer administrateur de l'office",
|
||||
}}
|
||||
toolTip="blabla"
|
||||
checked={userSelected?.role?.name === "admin" && !userSelected.office_role}
|
||||
/>
|
||||
<Switch checked={isAdminChecked} label="Administrateur de l'office" onChange={openAdminModal} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -189,7 +200,7 @@ export default function CollaboratorInformations(props: IProps) {
|
||||
cancelText={"Annuler"}>
|
||||
<div className={classes["modal-content"]}>
|
||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
||||
Attributer le rôle de <span className={classes["role-name"]}>{selectedOption?.label}</span> à{" "}
|
||||
Attribuer le rôle de <span className={classes["role-name"]}>{selectedOption?.label}</span> à{" "}
|
||||
{userSelected?.contact?.first_name} {userSelected?.contact?.last_name} ?
|
||||
</Typography>
|
||||
</div>
|
||||
@ -204,7 +215,8 @@ export default function CollaboratorInformations(props: IProps) {
|
||||
cancelText={"Annuler"}>
|
||||
<div className={classes["modal-content"]}>
|
||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
||||
Attributer le rôle d'administrateur à {userSelected?.contact?.first_name} {userSelected?.contact?.last_name} ?
|
||||
{adminRoleType === "add" ? "Attribuer" : "Retirer"} le rôle d'administrateur à{" "}
|
||||
{userSelected?.contact?.first_name} {userSelected?.contact?.last_name} ?
|
||||
</Typography>
|
||||
</div>
|
||||
</Confirm>
|
||||
|
@ -1,8 +1,8 @@
|
||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import DefaultCollaboratorDashboard from "@Front/Components/LayoutTemplates/DefaultCollaboratorDashboard";
|
||||
|
||||
import BasePage from "../Base";
|
||||
import classes from "./classes.module.scss";
|
||||
import DefaultCollaboratorDashboard from "@Front/Components/LayoutTemplates/DefaultCollaboratorDashboard";
|
||||
|
||||
type IProps = {};
|
||||
type IState = {};
|
||||
@ -12,7 +12,7 @@ export default class Collaborators extends BasePage<IProps, IState> {
|
||||
<DefaultCollaboratorDashboard title={"Dossier"} mobileBackText={"Liste des collaborateurs"}>
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["no-folder-selected"]}>
|
||||
<Typography typo={ITypo.H1Bis}>Informations du collaboraeur</Typography>
|
||||
<Typography typo={ITypo.H1Bis}>Informations du collaborateur</Typography>
|
||||
<div className={classes["choose-a-folder"]}>
|
||||
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
|
||||
Sélectionnez un collaborateur
|
||||
|
@ -1,15 +1,16 @@
|
||||
import WarningIcon from "@Assets/images/warning.png";
|
||||
import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
|
||||
import Users from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
|
||||
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
||||
import SelectField, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||
import Switch from "@Front/Components/DesignSystem/Switch";
|
||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import DefaultUserDashboard from "@Front/Components/LayoutTemplates/DefaultUserDashboard";
|
||||
import Toasts from "@Front/Stores/Toasts";
|
||||
import User from "le-coffre-resources/dist/Notary";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
|
||||
@ -21,42 +22,82 @@ export default function UserInformations(props: IProps) {
|
||||
const [userSelected, setUserSelected] = useState<User | null>(null);
|
||||
const [availableRoles, setAvailableRoles] = useState<IOption[]>([]);
|
||||
|
||||
const [addSuperAdminModalOpened, setAddSuperAdminModalOpened] = useState<boolean>(false);
|
||||
const [removeSuperAdminModalOpened, setRemoveSuperAdminModalOpened] = useState<boolean>(false);
|
||||
const [isSuperAdminModalOpened, setIsSuperAdminModalOpened] = useState<boolean>(false);
|
||||
const [superAdminModalType, setSuperAdminModalType] = useState<"add" | "remove">("add");
|
||||
const [adminModalType, setAdminModalType] = useState<"add" | "remove">("add");
|
||||
|
||||
const openAddSuperAdminModal = () => {
|
||||
setAddSuperAdminModalOpened(true);
|
||||
const [isSuperAdminChecked, setIsSuperAdminChecked] = useState<boolean>(false);
|
||||
const [isAdminChecked, setIsAdminChecked] = useState<boolean>(false);
|
||||
const [isAdminModalOpened, setIsAdminModalOpened] = useState<boolean>(false);
|
||||
|
||||
/** Functions for the admin modal */
|
||||
const openAdminModal = () => {
|
||||
setIsAdminModalOpened(true);
|
||||
};
|
||||
|
||||
const closeAddSuperAdminModal = () => {
|
||||
setAddSuperAdminModalOpened(false);
|
||||
const closeAdminModal = useCallback(() => {
|
||||
setIsAdminModalOpened(false);
|
||||
setIsAdminChecked(userSelected?.role?.name === "admin" && !userSelected.office_role);
|
||||
}, [userSelected]);
|
||||
|
||||
const handleAdminChanged = (checked: boolean) => {
|
||||
setIsAdminChecked(checked);
|
||||
setAdminModalType(checked ? "add" : "remove");
|
||||
openAdminModal();
|
||||
};
|
||||
|
||||
const openRemoveSuperAdminModal = () => {
|
||||
setRemoveSuperAdminModalOpened(true);
|
||||
};
|
||||
|
||||
const closeRemoveSuperAdminModal = () => {
|
||||
setRemoveSuperAdminModalOpened(false);
|
||||
};
|
||||
|
||||
const handleCheckboxAdminChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const checked = e.target.checked;
|
||||
if (checked) {
|
||||
openAddSuperAdminModal();
|
||||
const handleAdminModalAccepted = useCallback(async () => {
|
||||
if (!userSelected) return;
|
||||
if (adminModalType === "add") {
|
||||
// add super admin
|
||||
} else {
|
||||
openRemoveSuperAdminModal();
|
||||
// remove super admin
|
||||
}
|
||||
setIsAdminModalOpened(false);
|
||||
}, [userSelected, adminModalType]);
|
||||
|
||||
/** Functions for the super admin modal */
|
||||
const openSuperAdminModal = () => {
|
||||
setIsSuperAdminModalOpened(true);
|
||||
};
|
||||
|
||||
const addSuperAdmin = async () => {
|
||||
closeAddSuperAdminModal();
|
||||
const closeSuperAdminModal = useCallback(() => {
|
||||
setIsSuperAdminModalOpened(false);
|
||||
setIsSuperAdminChecked(userSelected?.role?.name === "super-admin" && !userSelected.office_role);
|
||||
}, [userSelected]);
|
||||
|
||||
const handleSuperAdminChanged = (checked: boolean) => {
|
||||
setIsSuperAdminChecked(checked);
|
||||
setSuperAdminModalType(checked ? "add" : "remove");
|
||||
openSuperAdminModal();
|
||||
};
|
||||
|
||||
const removeSuperAdmin = async () => {
|
||||
closeRemoveSuperAdminModal();
|
||||
};
|
||||
const handleSuperAdminModalAccepted = useCallback(async () => {
|
||||
if (!userSelected) return;
|
||||
if (superAdminModalType === "add") {
|
||||
Toasts.getInstance().open({
|
||||
title: "Vote attribué",
|
||||
text: "Vous avez voté pour attribuer le titre de Super Admin à " + userSelected.contact?.first_name,
|
||||
});
|
||||
// add super admin
|
||||
} else {
|
||||
Toasts.getInstance().open({
|
||||
title: "Vote attribué",
|
||||
text: "Vous avez voté pour supprimer le titre de Super Admin à " + userSelected.contact?.first_name,
|
||||
});
|
||||
// remove super admin
|
||||
}
|
||||
setIsSuperAdminModalOpened(false);
|
||||
}, [userSelected, superAdminModalType]);
|
||||
|
||||
/** Reset switch state when userSelect change */
|
||||
useEffect(() => {
|
||||
if (!userSelected) return;
|
||||
setIsSuperAdminChecked(userSelected.role?.name === "super-admin");
|
||||
setIsAdminChecked(userSelected.role?.name === "admin" && !userSelected.office_role);
|
||||
}, [userSelected]);
|
||||
|
||||
/** When page change, get the user of the page */
|
||||
useEffect(() => {
|
||||
async function getUser() {
|
||||
if (!userUid) return;
|
||||
@ -137,23 +178,8 @@ export default function UserInformations(props: IProps) {
|
||||
<Typography typo={ITypo.P_SB_18}>Attribuer un titre</Typography>
|
||||
</div>
|
||||
<div className={classes["second-line"]}>
|
||||
<CheckBox
|
||||
option={{
|
||||
label: "Nommer admin de son office",
|
||||
value: "title",
|
||||
}}
|
||||
name="admin"
|
||||
toolTip="tooltip"
|
||||
/>
|
||||
<CheckBox
|
||||
onChange={handleCheckboxAdminChanged}
|
||||
option={{
|
||||
label: "Nommer super admin LEcoffre.io",
|
||||
value: "title",
|
||||
}}
|
||||
name="superadmin"
|
||||
toolTip="tooltip"
|
||||
/>
|
||||
<Switch label="Admin de son office" checked={isAdminChecked} onChange={handleAdminChanged} />
|
||||
<Switch label="Super-admin LeCoffre.io" checked={isSuperAdminChecked} onChange={handleSuperAdminChanged} />
|
||||
<div className={classes["votes-block"]}>
|
||||
<div className={classes["left"]}>
|
||||
<Image src={WarningIcon} alt="warning" width={28} height={28} />
|
||||
@ -174,38 +200,33 @@ export default function UserInformations(props: IProps) {
|
||||
</div>
|
||||
</div>
|
||||
<Confirm
|
||||
isOpen={addSuperAdminModalOpened}
|
||||
onClose={closeAddSuperAdminModal}
|
||||
onAccept={addSuperAdmin}
|
||||
isOpen={isSuperAdminModalOpened}
|
||||
onClose={closeSuperAdminModal}
|
||||
onAccept={handleSuperAdminModalAccepted}
|
||||
closeBtn
|
||||
header={`Souhaitez-vous attribuer un vote à ${
|
||||
userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name
|
||||
} pour devenir Super Administrateur ?`}
|
||||
} pour ${superAdminModalType === "add" ? "devenir" : "retirer son rôle de"} Super Administrateur ?`}
|
||||
confirmText={"Attribuer un vote"}
|
||||
cancelText={"Annuler"}>
|
||||
<div className={classes["modal-content"]}>
|
||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
||||
Nommer une personne Super Administrateur nécessite 3 votes de super administrateurs existants. Souhaitez-vous
|
||||
attribuer un vote ?
|
||||
{superAdminModalType === "add" ? "Nommer" : "Retirer"} une personne Super Administrateur nécessite 3 votes de
|
||||
super administrateurs existants. Souhaitez-vous attribuer un vote ?
|
||||
</Typography>
|
||||
</div>
|
||||
</Confirm>
|
||||
<Confirm
|
||||
isOpen={removeSuperAdminModalOpened}
|
||||
onClose={closeRemoveSuperAdminModal}
|
||||
onAccept={removeSuperAdmin}
|
||||
isOpen={isAdminModalOpened}
|
||||
onClose={closeAdminModal}
|
||||
onAccept={handleAdminModalAccepted}
|
||||
closeBtn
|
||||
header={`Souhaitez-vous retirer ${
|
||||
header={`Souhaitez-vous ${adminModalType === "add" ? "ajouter" : "retirer"} ${
|
||||
userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name
|
||||
} de la liste des Super Administrateurs ?`}
|
||||
confirmText={"Attribuer un vote"}
|
||||
} aux administrateurs de son office ?`}
|
||||
confirmText={adminModalType === "add" ? "Ajouter" : "Retirer"}
|
||||
cancelText={"Annuler"}>
|
||||
<div className={classes["modal-content"]}>
|
||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
||||
Retirer un collaborateur du rôle de Super Administrateur nécessite 3 votes de super administrateurs existants.
|
||||
Souhaitez-vous attribuer un vote ?
|
||||
</Typography>
|
||||
</div>
|
||||
<div className={classes["modal-content"]}></div>
|
||||
</Confirm>
|
||||
</div>
|
||||
</DefaultUserDashboard>
|
||||
|
Loading…
x
Reference in New Issue
Block a user