From 406ebeb2ccfcf6849157ef24926f595db2b4a26e Mon Sep 17 00:00:00 2001 From: Maxime Lalo Date: Tue, 25 Jul 2023 16:50:16 +0200 Subject: [PATCH 1/5] :sparkles: Admin office role add/remove --- .../CollaboratorInformations/index.tsx | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx index f2c5a7ac..ae31697a 100644 --- a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx +++ b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx @@ -26,7 +26,7 @@ export default function CollaboratorInformations(props: IProps) { const [roleModalOpened, setRoleModalOpened] = useState(false); const [adminModalOpened, setAdminModalOpened] = useState(false); - + const [adminRoleType, setAdminRoleType] = useState<"add" | "remove">("add"); const [selectedOption, setSelectedOption] = useState(null); const handleRoleChange = useCallback((option: IOption) => { @@ -56,25 +56,31 @@ export default function CollaboratorInformations(props: IProps) { }, [selectedOption, userSelected]); const changeAdmin = useCallback(async () => { - const adminRole = await Roles.getInstance().getOne({ - where: { - name: "admin", - }, - }); + 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({ - uid: userSelected?.uid as string, - office_role: undefined, - role: adminRole, - }), - ); + if (!adminRole) return; + await Users.getInstance().put( + userSelected?.uid as string, + User.hydrate({ + uid: userSelected?.uid as string, + office_role: undefined, + role: adminRole, + }), + ); + } else { + // retirer rôle admin + } setRoleModalOpened(false); - }, [userSelected]); + }, [adminRoleType, userSelected]); - const openAdminModal = useCallback(() => { + const openAdminModal = useCallback((e: React.ChangeEvent) => { + if (e.target.checked) setAdminRoleType("add"); + else setAdminRoleType("remove"); setAdminModalOpened(true); }, []); @@ -189,7 +195,7 @@ export default function CollaboratorInformations(props: IProps) { cancelText={"Annuler"}>
- Attributer le rôle de {selectedOption?.label} à{" "} + Attribuer le rôle de {selectedOption?.label} à{" "} {userSelected?.contact?.first_name} {userSelected?.contact?.last_name} ?
@@ -204,7 +210,8 @@ export default function CollaboratorInformations(props: IProps) { cancelText={"Annuler"}>
- 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} ?
From 1179d888112a596664bbfd67722641216e19891b Mon Sep 17 00:00:00 2001 From: Maxime Lalo Date: Wed, 26 Jul 2023 11:10:07 +0200 Subject: [PATCH 2/5] :bug: Small bug fixes --- .../CollaboratorInformations/index.tsx | 40 ++++++++++--------- .../Layouts/Collaborators/index.tsx | 4 +- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx index ae31697a..617838d6 100644 --- a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx +++ b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx @@ -56,26 +56,30 @@ export default function CollaboratorInformations(props: IProps) { }, [selectedOption, userSelected]); const changeAdmin = useCallback(async () => { - if (adminRoleType === "add") { - 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({ - uid: userSelected?.uid as string, - office_role: undefined, - role: adminRole, - }), - ); - } else { - // retirer rôle admin + if (!adminRole) return; + await Users.getInstance().put( + userSelected?.uid as string, + User.hydrate({ + uid: userSelected?.uid as string, + office_role: undefined, + role: adminRole, + }), + ); + } else { + // retirer rôle admin + } + setAdminModalOpened(false); + } catch (e) { + console.error(e); } - setRoleModalOpened(false); }, [adminRoleType, userSelected]); const openAdminModal = useCallback((e: React.ChangeEvent) => { diff --git a/src/front/Components/Layouts/Collaborators/index.tsx b/src/front/Components/Layouts/Collaborators/index.tsx index 90e43453..00314e81 100644 --- a/src/front/Components/Layouts/Collaborators/index.tsx +++ b/src/front/Components/Layouts/Collaborators/index.tsx @@ -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 {
- Informations du collaboraeur + Informations du collaborateur
Sélectionnez un collaborateur From 56a689c46d2fd66a5102827a860a6d799ba1f54f Mon Sep 17 00:00:00 2001 From: Maxime Lalo Date: Wed, 26 Jul 2023 13:30:22 +0200 Subject: [PATCH 3/5] :sparkles: Switch and popups working on users page --- .../DesignSystem/Switch/classes.module.scss | 35 +++++ .../Components/DesignSystem/Switch/index.tsx | 33 +++++ .../CollaboratorInformations/index.tsx | 27 ++-- .../Layouts/Users/UserInformations/index.tsx | 134 ++++++++++-------- 4 files changed, 155 insertions(+), 74 deletions(-) create mode 100644 src/front/Components/DesignSystem/Switch/classes.module.scss create mode 100644 src/front/Components/DesignSystem/Switch/index.tsx diff --git a/src/front/Components/DesignSystem/Switch/classes.module.scss b/src/front/Components/DesignSystem/Switch/classes.module.scss new file mode 100644 index 00000000..9639f5cc --- /dev/null +++ b/src/front/Components/DesignSystem/Switch/classes.module.scss @@ -0,0 +1,35 @@ +.root { + display: flex; + gap: 16px; + .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; + } + } +} diff --git a/src/front/Components/DesignSystem/Switch/index.tsx b/src/front/Components/DesignSystem/Switch/index.tsx new file mode 100644 index 00000000..3b911bb7 --- /dev/null +++ b/src/front/Components/DesignSystem/Switch/index.tsx @@ -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(checked ? checked : false); + + useEffect(() => { + setIsChecked(checked ? checked : false); + }, [checked]); + + const handleChange = useCallback(() => { + setIsChecked(!isChecked); + onChange?.(!isChecked); + }, [isChecked, onChange]); + + return ( +
+
+
+
+ + {label} + +
+ ); +} diff --git a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx index 617838d6..f5730d3c 100644 --- a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx +++ b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx @@ -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"; @@ -29,6 +29,13 @@ export default function CollaboratorInformations(props: IProps) { const [adminRoleType, setAdminRoleType] = useState<"add" | "remove">("add"); const [selectedOption, setSelectedOption] = useState(null); + const [isAdminChecked, setIsAdminChecked] = useState(false); + + useEffect(() => { + if (!userSelected) return; + setIsAdminChecked(userSelected.role?.name === "admin" && !userSelected.office_role); + }, [userSelected]); + const handleRoleChange = useCallback((option: IOption) => { setSelectedOption(option); setRoleModalOpened(true); @@ -82,15 +89,17 @@ export default function CollaboratorInformations(props: IProps) { } }, [adminRoleType, userSelected]); - const openAdminModal = useCallback((e: React.ChangeEvent) => { - if (e.target.checked) setAdminRoleType("add"); + 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() { @@ -177,15 +186,7 @@ export default function CollaboratorInformations(props: IProps) {
{userSelected?.role?.name !== "super-admin" && (
- +
)}
diff --git a/src/front/Components/Layouts/Users/UserInformations/index.tsx b/src/front/Components/Layouts/Users/UserInformations/index.tsx index 22ebaf28..0348d001 100644 --- a/src/front/Components/Layouts/Users/UserInformations/index.tsx +++ b/src/front/Components/Layouts/Users/UserInformations/index.tsx @@ -1,15 +1,15 @@ 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 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 +21,74 @@ export default function UserInformations(props: IProps) { const [userSelected, setUserSelected] = useState(null); const [availableRoles, setAvailableRoles] = useState([]); - const [addSuperAdminModalOpened, setAddSuperAdminModalOpened] = useState(false); - const [removeSuperAdminModalOpened, setRemoveSuperAdminModalOpened] = useState(false); + const [isSuperAdminModalOpened, setIsSuperAdminModalOpened] = useState(false); + const [superAdminModalType, setSuperAdminModalType] = useState<"add" | "remove">("add"); + const [adminModalType, setAdminModalType] = useState<"add" | "remove">("add"); - const openAddSuperAdminModal = () => { - setAddSuperAdminModalOpened(true); + const [isSuperAdminChecked, setIsSuperAdminChecked] = useState(false); + const [isAdminChecked, setIsAdminChecked] = useState(false); + const [isAdminModalOpened, setIsAdminModalOpened] = useState(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) => { - 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") { + // add super admin + } else { + // 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 +169,8 @@ export default function UserInformations(props: IProps) { Attribuer un titre
- - + +
warning @@ -174,38 +191,33 @@ export default function UserInformations(props: IProps) {
- 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 ?
-
- - Retirer un collaborateur du rôle de Super Administrateur nécessite 3 votes de super administrateurs existants. - Souhaitez-vous attribuer un vote ? - -
+
From 00f1928f4303e595b0ac9861e5824bbba69b83aa Mon Sep 17 00:00:00 2001 From: Maxime Lalo Date: Wed, 26 Jul 2023 14:34:44 +0200 Subject: [PATCH 4/5] :bug: Forgot cursor pointer on switches --- src/front/Components/DesignSystem/Switch/classes.module.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/front/Components/DesignSystem/Switch/classes.module.scss b/src/front/Components/DesignSystem/Switch/classes.module.scss index 9639f5cc..c900ab5e 100644 --- a/src/front/Components/DesignSystem/Switch/classes.module.scss +++ b/src/front/Components/DesignSystem/Switch/classes.module.scss @@ -1,6 +1,8 @@ .root { display: flex; gap: 16px; + cursor: pointer; + width: fit-content; .switch-container { position: relative; width: 46px; From 8e293082952468ede458ff1db0b1447bfc22df69 Mon Sep 17 00:00:00 2001 From: Maxime Lalo Date: Wed, 26 Jul 2023 15:12:35 +0200 Subject: [PATCH 5/5] :bug: Small bug fixes --- .../DesignSystem/Header/Notifications/index.tsx | 9 +++++---- .../Header/Profile/ProfileModal/index.tsx | 13 ++++++++++++- .../Layouts/Users/UserInformations/index.tsx | 9 +++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/front/Components/DesignSystem/Header/Notifications/index.tsx b/src/front/Components/DesignSystem/Header/Notifications/index.tsx index 88b0cabf..cfebdfbe 100644 --- a/src/front/Components/DesignSystem/Header/Notifications/index.tsx +++ b/src/front/Components/DesignSystem/Header/Notifications/index.tsx @@ -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; diff --git a/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx b/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx index 6612a016..b871b131 100644 --- a/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx +++ b/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx @@ -20,7 +20,14 @@ export default class ProfileModal extends React.Component {
- + { 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, ]} /> { 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);