From a5f3018211343a72f12ea5d9f10c43674ffee0eb Mon Sep 17 00:00:00 2001 From: Maxime Lalo Date: Wed, 24 Jul 2024 17:53:37 +0200 Subject: [PATCH 1/3] :bug: trying to fix font --- src/pages/_app.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index c2205983..4776411b 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,6 +1,6 @@ +import "@Front/index.scss"; import { DefaultLayout } from "@Front/Components/LayoutTemplates/DefaultLayout"; import { FrontendVariables } from "@Front/Config/VariablesFront"; -import "@Front/index.scss"; import type { NextPage } from "next"; import type { AppType, AppProps } from "next/app"; import { useEffect, type ReactElement, type ReactNode } from "react"; From baba1c08ebd8a346c8c308bd43d760a585d3c2d5 Mon Sep 17 00:00:00 2001 From: Maxime Sallerin <97036207+maxime-sallerin@users.noreply.github.com> Date: Wed, 24 Jul 2024 18:11:52 +0200 Subject: [PATCH 2/3] Feature/header (#177) --- src/front/Assets/Icons/bell-notif.svg | 4 + .../BurgerModal/BurgerModalSubmenu/index.tsx | 2 +- .../Header/BurgerMenu/classes.module.scss | 5 - .../DesignSystem/Header/BurgerMenu/index.tsx | 62 ++-- .../Header/ButtonHeader/classes.module.scss | 27 ++ .../Header/ButtonHeader/index.tsx | 71 +++++ .../Header/HeaderLink/classes.module.scss | 30 -- .../DesignSystem/Header/HeaderLink/index.tsx | 60 ---- .../Header/HeaderSubmenu/index.tsx | 2 +- .../Header/Navigation/classes.module.scss | 4 +- .../DesignSystem/Header/Navigation/index.tsx | 284 ++++++++++-------- .../Header/Notifications/classes.module.scss | 14 - .../Header/Notifications/index.tsx | 93 +++--- .../Header/Profile/classes.module.scss | 6 +- .../DesignSystem/Header/Profile/index.tsx | 49 +-- .../DesignSystem/Header/classes.module.scss | 63 ++-- .../Components/DesignSystem/Header/index.tsx | 236 +++++---------- .../Menu/MenuItem}/classes.module.scss | 2 +- .../DesignSystem/Menu/MenuItem/index.tsx | 65 ++++ .../Menu}/classes.module.scss | 24 +- .../Components/DesignSystem/Menu/index.tsx | 91 ++++++ .../DesignSystem/Typography/index.tsx | 1 + .../ButtonWithSubMenu/SubMenuItem/index.tsx | 50 --- .../Elements/ButtonWithSubMenu/index.tsx | 78 ----- src/front/Components/Elements/Rules/index.tsx | 2 +- .../Components/Layouts/DesignSystem/index.tsx | 12 +- .../ClientView/ClientBox/index.tsx | 25 +- .../InformationSection/index.tsx | 15 +- 28 files changed, 652 insertions(+), 725 deletions(-) create mode 100644 src/front/Assets/Icons/bell-notif.svg create mode 100644 src/front/Components/DesignSystem/Header/ButtonHeader/classes.module.scss create mode 100644 src/front/Components/DesignSystem/Header/ButtonHeader/index.tsx delete mode 100644 src/front/Components/DesignSystem/Header/HeaderLink/classes.module.scss delete mode 100644 src/front/Components/DesignSystem/Header/HeaderLink/index.tsx rename src/front/Components/{Elements/ButtonWithSubMenu/SubMenuItem => DesignSystem/Menu/MenuItem}/classes.module.scss (94%) create mode 100644 src/front/Components/DesignSystem/Menu/MenuItem/index.tsx rename src/front/Components/{Elements/ButtonWithSubMenu => DesignSystem/Menu}/classes.module.scss (68%) create mode 100644 src/front/Components/DesignSystem/Menu/index.tsx delete mode 100644 src/front/Components/Elements/ButtonWithSubMenu/SubMenuItem/index.tsx delete mode 100644 src/front/Components/Elements/ButtonWithSubMenu/index.tsx diff --git a/src/front/Assets/Icons/bell-notif.svg b/src/front/Assets/Icons/bell-notif.svg new file mode 100644 index 00000000..8fda6cce --- /dev/null +++ b/src/front/Assets/Icons/bell-notif.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/BurgerModalSubmenu/index.tsx b/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/BurgerModalSubmenu/index.tsx index 0e150e16..7b1adba8 100644 --- a/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/BurgerModalSubmenu/index.tsx +++ b/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/BurgerModalSubmenu/index.tsx @@ -4,7 +4,7 @@ import React, { useEffect, useState } from "react"; import classes from "./classes.module.scss"; import { IAppRule } from "@Front/Api/Entities/rule"; import Rules, { RulesMode } from "@Front/Components/Elements/Rules"; -import { IHeaderLinkProps } from "../../../HeaderLink"; +import { IHeaderLinkProps } from "../../../ButtonHeader"; import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography"; import HeaderSubmenuLink from "../../../HeaderSubmenu/HeaderSubmenuLink"; import useToggle from "@Front/Hooks/useToggle"; diff --git a/src/front/Components/DesignSystem/Header/BurgerMenu/classes.module.scss b/src/front/Components/DesignSystem/Header/BurgerMenu/classes.module.scss index 5d2c84dc..f68b3ab0 100644 --- a/src/front/Components/DesignSystem/Header/BurgerMenu/classes.module.scss +++ b/src/front/Components/DesignSystem/Header/BurgerMenu/classes.module.scss @@ -1,9 +1,4 @@ @import "@Themes/constants.scss"; .root { - .burger-icon { - cursor: pointer; - height: 24px; - width: 24px; - } } diff --git a/src/front/Components/DesignSystem/Header/BurgerMenu/index.tsx b/src/front/Components/DesignSystem/Header/BurgerMenu/index.tsx index 63f5d864..be735ba1 100644 --- a/src/front/Components/DesignSystem/Header/BurgerMenu/index.tsx +++ b/src/front/Components/DesignSystem/Header/BurgerMenu/index.tsx @@ -1,35 +1,37 @@ -import React from "react"; -import classes from "./classes.module.scss"; -import Image from "next/image"; -import BurgerIcon from "@Assets/Icons/burger.svg"; -import CrossIcon from "@Assets/Icons/cross.svg"; +import useOpenable from "@Front/Hooks/useOpenable"; +import { Bars3BottomRightIcon, XMarkIcon } from "@heroicons/react/24/outline"; +import React, { useEffect } from "react"; + +import IconButton from "../../IconButton"; import BurgerModal from "./BurgerModal"; +import classes from "./classes.module.scss"; +import WindowStore from "@Front/Stores/WindowStore"; -type IProps = { - isModalOpen: boolean; - openBurgerMenu: () => void; - closeBurgerMenu: () => void; -}; -type IState = { - // isModalOpen: boolean; -}; +const headerBreakpoint = 1023; -export default class BurgerMenu extends React.Component { - constructor(props: IProps) { - super(props); - } +export default function BurgerMenu() { + const { isOpen, toggle, close } = useOpenable(); - public override render(): JSX.Element { - return ( -
- burger - {this.props.isModalOpen && } -
- ); - } + useEffect(() => { + const onResize = (window: Window) => { + if (window.innerWidth > headerBreakpoint && isOpen) close(); + }; + + const windowResizeSubscription = WindowStore.getInstance().onResize((window) => onResize(window)); + + return () => { + windowResizeSubscription(); + }; + }, [close, isOpen]); + + return ( +
+ {isOpen ? ( + } onClick={toggle} /> + ) : ( + } onClick={toggle} /> + )} + +
+ ); } diff --git a/src/front/Components/DesignSystem/Header/ButtonHeader/classes.module.scss b/src/front/Components/DesignSystem/Header/ButtonHeader/classes.module.scss new file mode 100644 index 00000000..d06746e6 --- /dev/null +++ b/src/front/Components/DesignSystem/Header/ButtonHeader/classes.module.scss @@ -0,0 +1,27 @@ +@import "@Themes/constants.scss"; + +.root { + position: relative; + align-self: center; + display: flex; + justify-content: center; + align-items: center; + height: fit-content; + + padding: var(--spacing-lg, 24px) var(--spacing-md, 16px); + + border-radius: var(--menu-radius, 0px); + border-bottom: 1px solid var(--menu-border, #d7dce0); + background: var(--button-header-background, #fff); + + user-select: none; + cursor: pointer; + + &.active { + border-bottom: 2px solid var(--button-header-border, #ff4617); + } + + &.desactivated { + cursor: not-allowed; + } +} diff --git a/src/front/Components/DesignSystem/Header/ButtonHeader/index.tsx b/src/front/Components/DesignSystem/Header/ButtonHeader/index.tsx new file mode 100644 index 00000000..183baa8d --- /dev/null +++ b/src/front/Components/DesignSystem/Header/ButtonHeader/index.tsx @@ -0,0 +1,71 @@ +import classNames from "classnames"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import React, { useEffect } from "react"; + +import Typography, { ETypo, ETypoColor } from "../../Typography"; +import classes from "./classes.module.scss"; +import useHoverable from "@Front/Hooks/useHoverable"; + +export type IHeaderLinkProps = { + text: string | JSX.Element; + path: string; + routesActive?: string[]; + disabledLink?: boolean; +}; + +export default function ButtonHeader(props: IHeaderLinkProps) { + const { disabledLink, path, text, routesActive } = props; + const router = useRouter(); + const { pathname } = router; + const [isActive, setIsActive] = React.useState(path === pathname); + const { handleMouseLeave, handleMouseEnter, isHovered } = useHoverable(); + + useEffect(() => { + if (path === pathname) setIsActive(true); + if (routesActive) { + for (const routeActive of routesActive) { + if (isActive) break; + if (pathname.includes(routeActive)) setIsActive(true); + } + } + }, [isActive, pathname, path, routesActive]); + + if (path !== "" && path !== undefined && !disabledLink) { + return ( + + + {text} + + + ); + } + if (disabledLink) { + return ( +
+ + {text} + +
+ ); + } + + return ( +
+ + {text} + +
+ ); +} diff --git a/src/front/Components/DesignSystem/Header/HeaderLink/classes.module.scss b/src/front/Components/DesignSystem/Header/HeaderLink/classes.module.scss deleted file mode 100644 index bc36281f..00000000 --- a/src/front/Components/DesignSystem/Header/HeaderLink/classes.module.scss +++ /dev/null @@ -1,30 +0,0 @@ -@import "@Themes/constants.scss"; - -.root { - display: flex; - position: relative; - width: fit-content; - margin: auto; - height: 83px; - padding: 10px 16px; - - .content { - margin: auto; - } - .underline { - width: 100%; - height: 3px; - background-color: var(--color-generic-white); - position: absolute; - bottom: 0; - left: 0; - - &[data-active="true"] { - background-color: var(--color-generic-black); - } - } - - &.desactivated { - cursor: not-allowed; - } -} diff --git a/src/front/Components/DesignSystem/Header/HeaderLink/index.tsx b/src/front/Components/DesignSystem/Header/HeaderLink/index.tsx deleted file mode 100644 index a89275dc..00000000 --- a/src/front/Components/DesignSystem/Header/HeaderLink/index.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import classNames from "classnames"; -import Link from "next/link"; -import { useRouter } from "next/router"; -import React, { useEffect } from "react"; - -import Typography, { ETypo, ETypoColor } from "../../Typography"; -import classes from "./classes.module.scss"; -import useHoverable from "@Front/Hooks/useHoverable"; - -export type IHeaderLinkProps = { - text: string | JSX.Element; - path: string; - routesActive?: string[]; -}; - -export default function HeaderLink(props: IHeaderLinkProps) { - const router = useRouter(); - const { pathname } = router; - const [isActive, setIsActive] = React.useState(props.path === pathname); - const { handleMouseLeave, handleMouseEnter, isHovered } = useHoverable(); - - useEffect(() => { - if (props.path === pathname) setIsActive(true); - if (props.routesActive) { - for (const routeActive of props.routesActive) { - if (isActive) break; - if (pathname.includes(routeActive)) setIsActive(true); - } - } - }, [isActive, pathname, props.path, props.routesActive]); - - if (props.path !== "" && props.path !== undefined) { - return ( - -
- - {props.text} - -
-
- - ); - } else { - return ( -
-
- - {props.text} - -
-
- ); - } -} diff --git a/src/front/Components/DesignSystem/Header/HeaderSubmenu/index.tsx b/src/front/Components/DesignSystem/Header/HeaderSubmenu/index.tsx index 65312b35..1f6a939d 100644 --- a/src/front/Components/DesignSystem/Header/HeaderSubmenu/index.tsx +++ b/src/front/Components/DesignSystem/Header/HeaderSubmenu/index.tsx @@ -1,7 +1,7 @@ import classNames from "classnames"; import { useRouter } from "next/router"; import React, { useEffect, useState } from "react"; -import { IHeaderLinkProps } from "../HeaderLink"; +import { IHeaderLinkProps } from "../ButtonHeader"; import Typography, { ETypo, ETypoColor } from "../../Typography"; import classes from "./classes.module.scss"; diff --git a/src/front/Components/DesignSystem/Header/Navigation/classes.module.scss b/src/front/Components/DesignSystem/Header/Navigation/classes.module.scss index 1a02a0fc..46c147bd 100644 --- a/src/front/Components/DesignSystem/Header/Navigation/classes.module.scss +++ b/src/front/Components/DesignSystem/Header/Navigation/classes.module.scss @@ -2,7 +2,5 @@ .root { display: inline-flex; - @media screen and (max-width: $screen-ls) { - display: none; - } + align-items: center; } diff --git a/src/front/Components/DesignSystem/Header/Navigation/index.tsx b/src/front/Components/DesignSystem/Header/Navigation/index.tsx index e98b6a9e..5e4244d3 100644 --- a/src/front/Components/DesignSystem/Header/Navigation/index.tsx +++ b/src/front/Components/DesignSystem/Header/Navigation/index.tsx @@ -1,15 +1,17 @@ +import { AppRuleActions, AppRuleNames } from "@Front/Api/Entities/rule"; +import Notifications from "@Front/Api/LeCoffreApi/Notary/Notifications/Notifications"; +import OfficeFolderAnchors from "@Front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors"; +import Rules, { RulesMode } from "@Front/Components/Elements/Rules"; import Module from "@Front/Config/Module"; +import Toasts from "@Front/Stores/Toasts"; +import { AdjustmentsVerticalIcon, BanknotesIcon, Square3Stack3DIcon, TagIcon, UsersIcon } from "@heroicons/react/24/outline"; +import { usePathname } from "next/navigation"; import React, { useCallback, useEffect } from "react"; -import HeaderLink from "../HeaderLink"; +import Menu, { IItem } from "../../Menu"; +import ButtonHeader from "../ButtonHeader"; import classes from "./classes.module.scss"; -import Rules, { RulesMode } from "@Front/Components/Elements/Rules"; -import { AppRuleActions, AppRuleNames } from "@Front/Api/Entities/rule"; -import { usePathname } from "next/navigation"; -import Notifications from "@Front/Api/LeCoffreApi/Notary/Notifications/Notifications"; -import Toasts from "@Front/Stores/Toasts"; -import OfficeFolderAnchors from "@Front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors"; -import HeaderSubmenu from "../HeaderSubmenu"; + export default function Navigation() { const pathname = usePathname(); @@ -73,7 +75,7 @@ export default function Navigation() { }, ]}> <> - - - - - + item.routesActive ?? [])} + disabledLink + /> + + - {/* */} - - + ]}> + + item.routesActive ?? [])} + disabledLink + /> + + +
); } + +const officeItems: IItem[] = [ + { + icon: , + text: "Collaborateurs", + link: Module.getInstance().get().modules.pages.Collaborators.props.path, + routesActive: [ + Module.getInstance().get().modules.pages.Collaborators.pages.CollaboratorInformations.props.path, + Module.getInstance().get().modules.pages.Collaborators.props.path, + ], + rules: [ + { + action: AppRuleActions.update, + name: AppRuleNames.users, + }, + ], + }, + { + icon: , + text: "Gestion des rôles", + link: Module.getInstance().get().modules.pages.Roles.props.path, + routesActive: [ + Module.getInstance().get().modules.pages.Roles.pages.Create.props.path, + Module.getInstance().get().modules.pages.Roles.pages.RolesInformations.props.path, + Module.getInstance().get().modules.pages.Roles.props.path, + ], + rules: [ + { + action: AppRuleActions.update, + name: AppRuleNames.officeRoles, + }, + ], + }, + { + icon: , + text: "Paramétrage des listes de pièces", + link: Module.getInstance().get().modules.pages.DeedTypes.props.path, + routesActive: [ + Module.getInstance().get().modules.pages.DeedTypes.pages.Create.props.path, + Module.getInstance().get().modules.pages.DeedTypes.pages.Edit.props.path, + Module.getInstance().get().modules.pages.DeedTypes.props.path, + Module.getInstance().get().modules.pages.DocumentTypes.props.path, + Module.getInstance().get().modules.pages.DocumentTypes.pages.Create.props.path, + Module.getInstance().get().modules.pages.DocumentTypes.pages.Edit.props.path, + Module.getInstance().get().modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path, + ], + rules: [ + { + action: AppRuleActions.update, + name: AppRuleNames.deedTypes, + }, + ], + }, + { + icon: , + text: "RIB Office", + link: Module.getInstance().get().modules.pages.OfficesRib.props.path, + rules: [ + { + action: AppRuleActions.update, + name: AppRuleNames.rib, + }, + ], + }, + { + icon: , + text: "Abonnement", + link: Module.getInstance().get().modules.pages.Subscription.pages.Manage.props.path, + routesActive: [ + Module.getInstance().get().modules.pages.Subscription.pages.Error.props.path, + Module.getInstance().get().modules.pages.Subscription.pages.Success.props.path, + Module.getInstance().get().modules.pages.Subscription.pages.Invite.props.path, + Module.getInstance().get().modules.pages.Subscription.pages.Manage.props.path, + Module.getInstance().get().modules.pages.Subscription.pages.ManageCollaborators.props.path, + Module.getInstance().get().modules.pages.Subscription.pages.New.props.path, + Module.getInstance().get().modules.pages.Subscription.pages.Subscribe.props.path, + ], + rules: [ + { + action: AppRuleActions.update, + name: AppRuleNames.subscriptions, + }, + ], + }, +]; + +const superAdminItems: IItem[] = [ + { + icon: , + text: "Gestion des utilisateurs", + link: Module.getInstance().get().modules.pages.Users.props.path, + routesActive: [ + Module.getInstance().get().modules.pages.Users.pages.UsersInformations.props.path, + Module.getInstance().get().modules.pages.Users.props.path, + ], + rules: [ + { + action: AppRuleActions.update, + name: AppRuleNames.offices, + }, + ], + }, + { + icon: , + text: "Gestion des offices", + link: Module.getInstance().get().modules.pages.Offices.props.path, + routesActive: [ + Module.getInstance().get().modules.pages.Offices.pages.OfficesInformations.props.path, + Module.getInstance().get().modules.pages.Offices.props.path, + ], + rules: [ + { + action: AppRuleActions.update, + name: AppRuleNames.offices, + }, + ], + }, +]; diff --git a/src/front/Components/DesignSystem/Header/Notifications/classes.module.scss b/src/front/Components/DesignSystem/Header/Notifications/classes.module.scss index f93076cb..f68b3ab0 100644 --- a/src/front/Components/DesignSystem/Header/Notifications/classes.module.scss +++ b/src/front/Components/DesignSystem/Header/Notifications/classes.module.scss @@ -1,18 +1,4 @@ @import "@Themes/constants.scss"; .root { - .icon-container { - position: relative; - cursor: pointer; - - .notification-icon { - height: 24px; - width: 24px; - } - .notification-dot { - position: absolute; - top: 0; - right: 0; - } - } } diff --git a/src/front/Components/DesignSystem/Header/Notifications/index.tsx b/src/front/Components/DesignSystem/Header/Notifications/index.tsx index cfebdfbe..f030ceb7 100644 --- a/src/front/Components/DesignSystem/Header/Notifications/index.tsx +++ b/src/front/Components/DesignSystem/Header/Notifications/index.tsx @@ -1,63 +1,54 @@ -import InfoIcon from "@Assets/Icons/info.svg"; -import NotificationIcon from "@Assets/Icons/notification.svg"; +import useOpenable from "@Front/Hooks/useOpenable"; import Toasts, { IToast } from "@Front/Stores/Toasts"; -import Image from "next/image"; -import React from "react"; +import { BellIcon } from "@heroicons/react/24/outline"; +import React, { useEffect, useState } from "react"; +import IconButton from "../../IconButton"; import classes from "./classes.module.scss"; import NotificationModal from "./NotificationModal"; -type IProps = { - isModalOpen: boolean; - openNotificationModal: () => void; - closeNotificationModal: () => void; -}; -type IState = { - hasNotifications: boolean; - toastList: IToast[] | null; -}; +export default function Notifications() { + const [_toastList, setToastList] = useState(Toasts.getInstance().toasts); + const [hasNotifications, setHasNotifications] = useState(Toasts.getInstance().toasts.length > 0); + const { isOpen, close, toggle } = useOpenable(); -export default class Notifications extends React.Component { - private removeOnToastChange: () => void = () => {}; - - constructor(props: IProps) { - super(props); - this.state = { - toastList: Toasts.getInstance().toasts, //TODO : Get from bbd - hasNotifications: Toasts.getInstance().toasts.length > 0, // TODO: Change this when we have notification stored in bbd, unread notifications + useEffect(() => { + const handleToastChange = (newToastList: IToast[] | null) => { + setToastList(newToastList); + setHasNotifications(newToastList ? newToastList.length > 0 : false); }; - this.handleToastChange = this.handleToastChange.bind(this); - } - public override render(): JSX.Element { - return ( -
-
- notifications - {this.state.hasNotifications && ( - Unread notification - )} -
+ const removeOnToastChange = Toasts.getInstance().onChange(handleToastChange); - {this.props.isModalOpen && ( - - )} -
- ); - } + return () => { + removeOnToastChange(); + }; + }, []); - public override componentDidMount() { - this.removeOnToastChange = Toasts.getInstance().onChange(this.handleToastChange); - } + return ( +
+ {hasNotifications ? ( + } onClick={toggle} /> + ) : ( + } onClick={toggle} /> + )} - public override componentWillUnmount() { - this.removeOnToastChange(); - } - - private handleToastChange(toastList: IToast[] | null) { - this.setState({ - toastList, - hasNotifications: toastList ? toastList.length > 0 : false, - }); - } + +
+ ); +} + +function BellNotifIcon() { + return ( + + + + + ); } diff --git a/src/front/Components/DesignSystem/Header/Profile/classes.module.scss b/src/front/Components/DesignSystem/Header/Profile/classes.module.scss index faf25134..97b000ca 100644 --- a/src/front/Components/DesignSystem/Header/Profile/classes.module.scss +++ b/src/front/Components/DesignSystem/Header/Profile/classes.module.scss @@ -1,9 +1,5 @@ @import "@Themes/constants.scss"; .root { - .profile-icon { - cursor: pointer; - height: 24px; - width: 24px; - } + } diff --git a/src/front/Components/DesignSystem/Header/Profile/index.tsx b/src/front/Components/DesignSystem/Header/Profile/index.tsx index 2e74938f..e2d66719 100644 --- a/src/front/Components/DesignSystem/Header/Profile/index.tsx +++ b/src/front/Components/DesignSystem/Header/Profile/index.tsx @@ -1,30 +1,33 @@ -import React from "react"; +import useOpenable from "@Front/Hooks/useOpenable"; +import WindowStore from "@Front/Stores/WindowStore"; +import { UserIcon } from "@heroicons/react/24/outline"; +import React, { useEffect } from "react"; + +import IconButton from "../../IconButton"; import classes from "./classes.module.scss"; -import Image from "next/image"; -import ProfileIcon from "@Assets/Icons/user.svg"; import ProfileModal from "./ProfileModal"; -type IProps = { - isModalOpen: boolean; - openProfileModal: () => void; - closeProfileModal: () => void; -}; -type IState = {}; +const headerBreakpoint = 1023; -export default class Profile extends React.Component { - constructor(props: IProps) { - super(props); - this.state = { - isModalOpen: false, +export default function Profile() { + const { isOpen, toggle, close } = useOpenable(); + + useEffect(() => { + const onResize = (window: Window) => { + if (window.innerWidth < headerBreakpoint && isOpen) close(); }; - } - public override render(): JSX.Element { - return ( -
- profile - {this.props.isModalOpen && } -
- ); - } + const windowResizeSubscription = WindowStore.getInstance().onResize((window) => onResize(window)); + + return () => { + windowResizeSubscription(); + }; + }, [close, isOpen]); + + return ( +
+ } onClick={toggle} /> + +
+ ); } diff --git a/src/front/Components/DesignSystem/Header/classes.module.scss b/src/front/Components/DesignSystem/Header/classes.module.scss index bfcf4e6c..929a37be 100644 --- a/src/front/Components/DesignSystem/Header/classes.module.scss +++ b/src/front/Components/DesignSystem/Header/classes.module.scss @@ -2,24 +2,20 @@ .root { display: flex; - align-items: center; justify-content: space-between; - height: 83px; - background-color: var(--color-generic-white); - box-shadow: $shadow-nav; - padding: 0 48px; + align-items: center; + flex-shrink: 0; + + height: 75px; + padding: 0px var(--spacing-lg, 24px); + + border-bottom: 1px solid var(--menu-border, #d7dce0); + background: var(--menu-background, #fff); + position: sticky; top: 0; z-index: 4; - @media (max-width: $screen-m) { - transition: transform 500ms ease-out; - - &[data-open="closed"] { - transform: translateY(-85px); - } - } - .logo-container { > a { cursor: pointer !important; @@ -31,45 +27,22 @@ } .right-section { - .profile-section { - display: inline-flex; + display: flex; + align-items: center; + gap: var(--spacing-md); + } - @media (max-width: $screen-ls) { - display: none; - } - } - - .notification-section { - display: inline-flex; - - > :first-child { - margin-right: 32px; - } - } - - .help-section { - display: inline-flex; - cursor: pointer; - > :first-child { - margin-right: 32px; - } - - @media (max-width: $screen-s) { - display: none; - } + .desktop { + @media (max-width: $screen-m) { + display: none; } } - .burger-menu { + .mobile { display: none; - @media (max-width: $screen-ls) { + @media (max-width: $screen-m) { display: inline-flex; - - .icon { - width: 24px; - height: 24px; - } } } } diff --git a/src/front/Components/DesignSystem/Header/index.tsx b/src/front/Components/DesignSystem/Header/index.tsx index 7e67d618..b0efedca 100644 --- a/src/front/Components/DesignSystem/Header/index.tsx +++ b/src/front/Components/DesignSystem/Header/index.tsx @@ -1,183 +1,95 @@ -import React from "react"; -import classes from "./classes.module.scss"; -import Image from "next/image"; import LogoIcon from "@Assets/logo_standard_neutral.svg"; +import Stripe from "@Front/Api/LeCoffreApi/Admin/Stripe/Stripe"; +import Subscriptions from "@Front/Api/LeCoffreApi/Admin/Subscriptions/Subscriptions"; +import Module from "@Front/Config/Module"; +import JwtService from "@Front/Services/JwtService/JwtService"; +import { InformationCircleIcon, LifebuoyIcon } from "@heroicons/react/24/outline"; +import Head from "next/head"; +import Image from "next/image"; import Link from "next/link"; +import { useRouter } from "next/router"; +import React, { useCallback, useEffect, useState } from "react"; + +import IconButton from "../IconButton"; +import Typography, { ETypo, ETypoColor } from "../Typography"; +import BurgerMenu from "./BurgerMenu"; +import classes from "./classes.module.scss"; +import LogoCielNatureIcon from "./logo-ciel-notaires.jpeg"; import Navigation from "./Navigation"; import Notifications from "./Notifications"; import Profile from "./Profile"; -import BurgerMenu from "./BurgerMenu"; -import WindowStore from "@Front/Stores/WindowStore"; -import Module from "@Front/Config/Module"; -import Head from "next/head"; -import { useRouter } from "next/router"; -import LogoCielNatureIcon from "./logo-ciel-notaires.jpeg"; -import LifeBuoy from "@Assets/Icons/life_buoy.svg"; -import Stripe from "@Front/Api/LeCoffreApi/Admin/Stripe/Stripe"; -import JwtService from "@Front/Services/JwtService/JwtService"; -import Subscriptions from "@Front/Api/LeCoffreApi/Admin/Subscriptions/Subscriptions"; -import Typography, { ETypo, ETypoColor } from "../Typography"; -import { InformationCircleIcon } from "@heroicons/react/24/outline"; - -enum EHeaderOpeningState { - OPEN = "open", - CLOSED = "closed", - IDLE = "idle", -} type IProps = { isUserConnected: boolean; }; -type IPropsClass = IProps & { - isOnCustomerLoginPage: boolean; -}; +export default function Header(props: IProps) { + const { isUserConnected } = props; -type IState = { - open: EHeaderOpeningState; - isBurgerMenuOpen: boolean; - isNotificationMenuOpen: boolean; - isProfileMenuOpen: boolean; - cancelAt: Date | null; -}; + const router = useRouter(); + const { pathname } = router; + const isOnCustomerLoginPage = Module.getInstance().get().modules.pages.CustomersLogin.props.path === pathname; -class HeaderClass extends React.Component { - private onWindowResize = () => {}; - private headerBreakpoint = 1300; + const [cancelAt, setCancelAt] = useState(null); - constructor(props: IPropsClass) { - super(props); - - this.state = { - open: EHeaderOpeningState.OPEN, - isBurgerMenuOpen: false, - isNotificationMenuOpen: false, - isProfileMenuOpen: false, - cancelAt: null, - }; - this.openBurgerMenu = this.openBurgerMenu.bind(this); - this.closeBurgerMenu = this.closeBurgerMenu.bind(this); - this.openNotificationMenu = this.openNotificationMenu.bind(this); - this.closeNotificationMenu = this.closeNotificationMenu.bind(this); - this.closeProfileMenu = this.closeProfileMenu.bind(this); - this.openProfileMenu = this.openProfileMenu.bind(this); - this.loadSubscription = this.loadSubscription.bind(this); - } - - public override render(): JSX.Element { - return ( - <> -
- - - -
- - logo - -
- {this.props.isUserConnected && ( - <> - -
-
- - help - -
-
- -
-
- -
-
- -
-
- - )} - {this.props.isOnCustomerLoginPage && ciel-nature} -
- {this.state.cancelAt && ( -
- ; - - Assurez vous de sauvegarder tout ce dont vous avez besoin avant la fin de votre abonnement le{" "} - {this.state.cancelAt.toLocaleDateString()}. - -
- )} - - ); - } - - public override componentDidMount() { - this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window)); - this.loadSubscription(); - } - - public override componentWillUnmount() { - this.onWindowResize(); - } - - public async loadSubscription() { + const loadSubscription = useCallback(async () => { const jwt = JwtService.getInstance().decodeJwt(); const subscription = await Subscriptions.getInstance().get({ where: { office: { uid: jwt?.office_Id } } }); if (subscription[0]) { const stripeSubscription = await Stripe.getInstance().getStripeSubscriptionByUid(subscription[0].stripe_subscription_id!); - if (stripeSubscription.cancel_at !== null) - this.setState({ - ...this.state, - cancelAt: new Date(stripeSubscription.cancel_at! * 1000), - }); + if (stripeSubscription.cancel_at !== null) { + setCancelAt(new Date(stripeSubscription.cancel_at! * 1000)); + } } - } - private onResize(window: Window) { - if (window.innerWidth > this.headerBreakpoint && this.state.isBurgerMenuOpen) this.setState({ isBurgerMenuOpen: false }); - if (window.innerWidth < this.headerBreakpoint && this.state.isProfileMenuOpen) this.setState({ isProfileMenuOpen: false }); - } + }, []); - private openBurgerMenu() { - this.setState({ isBurgerMenuOpen: true }); - } + useEffect(() => { + loadSubscription(); + }, [loadSubscription]); - private closeBurgerMenu() { - this.setState({ isBurgerMenuOpen: false }); - } - - private openNotificationMenu() { - this.setState({ isNotificationMenuOpen: true }); - } - - private closeNotificationMenu() { - this.setState({ isNotificationMenuOpen: false }); - } - - private openProfileMenu() { - this.setState({ isProfileMenuOpen: true }); - } - - private closeProfileMenu() { - this.setState({ isProfileMenuOpen: false }); - } -} - -export default function Header(props: IProps) { - const router = useRouter(); - const { pathname } = router; - let isActive = Module.getInstance().get().modules.pages.CustomersLogin.props.path === pathname; - return ; + return ( + <> +
+ + + +
+ + logo + +
+ {isUserConnected && ( + <> +
+ +
+
+
+ + } /> + +
+ +
+ +
+
+ +
+
+ + )} + {isOnCustomerLoginPage && ciel-nature} +
+ {cancelAt && ( +
+ + + Assurez vous de sauvegarder tout ce dont vous avez besoin avant la fin de votre abonnement le{" "} + {cancelAt.toLocaleDateString()}. + +
+ )} + + ); } diff --git a/src/front/Components/Elements/ButtonWithSubMenu/SubMenuItem/classes.module.scss b/src/front/Components/DesignSystem/Menu/MenuItem/classes.module.scss similarity index 94% rename from src/front/Components/Elements/ButtonWithSubMenu/SubMenuItem/classes.module.scss rename to src/front/Components/DesignSystem/Menu/MenuItem/classes.module.scss index 3231922d..715b9ccf 100644 --- a/src/front/Components/Elements/ButtonWithSubMenu/SubMenuItem/classes.module.scss +++ b/src/front/Components/DesignSystem/Menu/MenuItem/classes.module.scss @@ -1,4 +1,4 @@ -.menu-item-wrapper { +.root { width: 100%; .menu-item { display: flex; diff --git a/src/front/Components/DesignSystem/Menu/MenuItem/index.tsx b/src/front/Components/DesignSystem/Menu/MenuItem/index.tsx new file mode 100644 index 00000000..72e0c830 --- /dev/null +++ b/src/front/Components/DesignSystem/Menu/MenuItem/index.tsx @@ -0,0 +1,65 @@ +import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography"; +import classes from "./classes.module.scss"; +import { useRouter } from "next/router"; +import React, { useCallback, useEffect } from "react"; +import useHoverable from "@Front/Hooks/useHoverable"; +import { IItem } from ".."; +import classNames from "classnames"; + +type IProps = { + item: IItem; + closeMenuCb: () => void; +}; +export default function MenuItem(props: IProps) { + const { item, closeMenuCb } = props; + const router = useRouter(); + const { pathname } = router; + const [isActive, setIsActive] = React.useState(item.link === pathname); + + const handleClickElement = useCallback( + (e: React.MouseEvent) => { + closeMenuCb(); + const link = e.currentTarget.getAttribute("data-link"); + if (link) router.push(link); + if (item.onClick) item.onClick(); + }, + [closeMenuCb, item, router], + ); + + const { handleMouseEnter, handleMouseLeave, isHovered } = useHoverable(); + + const getColor = useCallback(() => { + if (isActive) return ETypoColor.CONTRAST_ACTIVED; + if (isHovered && item.color !== ETypoColor.ERROR_WEAK_CONTRAST) return ETypoColor.CONTRAST_HOVERED; + if (item.color) return item.color; + if (isHovered) return ETypoColor.CONTRAST_DEFAULT; + return ETypoColor.CONTRAST_DEFAULT; + }, [isActive, isHovered, item.color]); + + useEffect(() => { + if (item.link === pathname) setIsActive(true); + if (item.routesActive) { + for (const routeActive of item.routesActive) { + if (isActive) break; + if (pathname.includes(routeActive)) setIsActive(true); + } + } + }, [isActive, item.link, item.routesActive, pathname]); + + return ( +
+
+ {React.cloneElement(item.icon, { color: `var(${getColor()})` })} + + {item.text} + +
+ {item.hasSeparator &&
} +
+ ); +} diff --git a/src/front/Components/Elements/ButtonWithSubMenu/classes.module.scss b/src/front/Components/DesignSystem/Menu/classes.module.scss similarity index 68% rename from src/front/Components/Elements/ButtonWithSubMenu/classes.module.scss rename to src/front/Components/DesignSystem/Menu/classes.module.scss index 28ddf217..74edfda9 100644 --- a/src/front/Components/Elements/ButtonWithSubMenu/classes.module.scss +++ b/src/front/Components/DesignSystem/Menu/classes.module.scss @@ -5,25 +5,35 @@ .sub-menu { position: absolute; top: 48px; + display: inline-flex; - padding: var(--spacing-05, 4px) var(--spacing-2, 16px); flex-direction: column; align-items: flex-start; - border-radius: var(--menu-radius, 0px); + + padding: var(--spacing-05, 4px) var(--spacing-2, 16px); + + border-radius: var(--menu-radius, 0); border: 1px solid var(--menu-border, #d7dce0); background: var(--color-generic-white, #fff); + text-wrap: nowrap; - /* shadow/sm */ - box-shadow: 0px 4px 16px 0px rgba(0, 0, 0, 0.1); - z-index: 2; + + box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.1); + z-index: 3; + &[data-opening-side="left"] { left: auto; - right: 0px; + right: 0; } &[data-opening-side="right"] { - left: 0px; + left: 0; right: auto; } + + &[data-opening-side="center"] { + transform: translateX(-25%); + top: 90px; + } } } diff --git a/src/front/Components/DesignSystem/Menu/index.tsx b/src/front/Components/DesignSystem/Menu/index.tsx new file mode 100644 index 00000000..f0dca424 --- /dev/null +++ b/src/front/Components/DesignSystem/Menu/index.tsx @@ -0,0 +1,91 @@ +import { IAppRule } from "@Front/Api/Entities/rule"; +import { ETypoColor } from "@Front/Components/DesignSystem/Typography"; +import Rules, { RulesMode } from "@Front/Components/Elements/Rules"; +import useHoverable from "@Front/Hooks/useHoverable"; +import useOpenable from "@Front/Hooks/useOpenable"; +import React, { useEffect, useRef } from "react"; + +import classes from "./classes.module.scss"; +import MenuItem from "./MenuItem"; + +type IItemBase = { + icon: JSX.Element; + text: string; + hasSeparator?: boolean; + color?: ETypoColor; +}; + +type IItemWithLink = IItemBase & { + link: string; + rules?: IAppRule[]; + routesActive?: string[]; + onClick?: never; +}; + +type IItemWithOnClick = IItemBase & { + onClick: () => void; + link?: never; + rules?: never; + routesActive?: never; +}; + +export type IItem = IItemWithLink | IItemWithOnClick; + +type IProps = { + children: React.ReactNode; + items: IItem[]; + openingSide?: "left" | "right" | "center"; + openOnHover?: boolean; +}; + +export default function Menu(props: IProps) { + const { openingSide = "left", items, children, openOnHover } = props; + + const { handleMouseLeave, handleMouseEnter, isHovered } = useHoverable(100); + + const { isOpen, toggle, close } = useOpenable(); + + const subMenuRef = useRef(null); + const iconRef = useRef(null); + + useEffect(() => { + const handleClickOutside = (e: MouseEvent) => { + if ( + subMenuRef.current && + !subMenuRef.current.contains(e.target as Node) && + iconRef.current && + !iconRef.current.contains(e.target as Node) + ) { + close(); + } + }; + document.addEventListener("mousedown", handleClickOutside); + return () => document.removeEventListener("mousedown", handleClickOutside); + }, [close]); + + return ( + item?.rules ?? [])}> +
+
+ {children} +
+ + {((!openOnHover && isOpen) || (openOnHover && isHovered)) && ( +
+ {items.map((item, index) => { + return ( + + + + ); + })} +
+ )} +
+
+ ); +} diff --git a/src/front/Components/DesignSystem/Typography/index.tsx b/src/front/Components/DesignSystem/Typography/index.tsx index fd0d019f..2aaeec59 100644 --- a/src/front/Components/DesignSystem/Typography/index.tsx +++ b/src/front/Components/DesignSystem/Typography/index.tsx @@ -153,6 +153,7 @@ export enum ETypoColor { CONTRAST_DEFAULT = "--contrast-default", CONTRAST_HOVERED = "--contrast-hovered", ERROR_WEAK_CONTRAST = "--error-weak-contrast", + CONTRAST_ACTIVED = "--contrast-actived", NAVIGATION_BUTTON_CONTRAST_DEFAULT = "--navigation-button-contrast-default", NAVIGATION_BUTTON_CONTRAST_ACTIVE = "--navigation-button-contrast-active", } diff --git a/src/front/Components/Elements/ButtonWithSubMenu/SubMenuItem/index.tsx b/src/front/Components/Elements/ButtonWithSubMenu/SubMenuItem/index.tsx deleted file mode 100644 index 81071a54..00000000 --- a/src/front/Components/Elements/ButtonWithSubMenu/SubMenuItem/index.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography"; -import classes from "./classes.module.scss"; -import { useRouter } from "next/router"; -import React, { useCallback } from "react"; -import useHoverable from "@Front/Hooks/useHoverable"; -import { ISubElement } from ".."; - -type IProps = { - element: ISubElement; - closeMenuCb: () => void; -}; -export default function SubMenuItem(props: IProps) { - const { element, closeMenuCb } = props; - const router = useRouter(); - const handleClickElement = useCallback( - (e: React.MouseEvent) => { - closeMenuCb(); - const link = e.currentTarget.getAttribute("data-link"); - if (link) router.push(link); - if (element.onClick) element.onClick(); - }, - [closeMenuCb, element, router], - ); - - const { handleMouseEnter, handleMouseLeave, isHovered } = useHoverable(); - - // The element has a link or an onClick but not both, if it has a link, show it has a link, if it has an onClick, show it has an onClick - const getColor = useCallback(() => { - if (isHovered && element.color !== ETypoColor.ERROR_WEAK_CONTRAST) return ETypoColor.CONTRAST_HOVERED; - if (element.color) return element.color; - return ETypoColor.CONTRAST_DEFAULT; - }, [element.color, isHovered]); - - return ( -
-
- {React.cloneElement(element.icon, { color: `var(${getColor()})` })} - - {element.text} - -
- {element.hasSeparator &&
} -
- ); -} diff --git a/src/front/Components/Elements/ButtonWithSubMenu/index.tsx b/src/front/Components/Elements/ButtonWithSubMenu/index.tsx deleted file mode 100644 index 1ef1a471..00000000 --- a/src/front/Components/Elements/ButtonWithSubMenu/index.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import IconButton, { EIconButtonVariant } from "@Front/Components/DesignSystem/IconButton"; -import classes from "./classes.module.scss"; -import { ETypoColor } from "@Front/Components/DesignSystem/Typography"; -import React, { useEffect, useRef, useState } from "react"; -import SubMenuItem from "./SubMenuItem"; - -type ISubElementBase = { - icon: JSX.Element; - text: string; - hasSeparator?: boolean; - color?: ETypoColor; -}; - -type ISubElementWithLink = ISubElementBase & { - link: string; - onClick?: never; -}; - -type ISubElementWithOnClick = ISubElementBase & { - onClick: () => void; - link?: never; -}; - -export type ISubElement = ISubElementWithLink | ISubElementWithOnClick; - -type IProps = { - icon: React.ReactNode; - text?: string; - subElements: ISubElement[]; - openingSide?: "left" | "right"; -}; - -export default function ButtonWithSubMenu(props: IProps) { - const { openingSide = "left" } = props; - - const [isSubMenuOpened, setIsSubMenuOpened] = useState(false); - - const subMenuRef = useRef(null); - const iconRef = useRef(null); - - const handleClick = () => { - setIsSubMenuOpened((prev) => !prev); - }; - - const closeMenu = () => { - setIsSubMenuOpened(false); - }; - - useEffect(() => { - const handleClickOutside = (e: MouseEvent) => { - if ( - subMenuRef.current && - !subMenuRef.current.contains(e.target as Node) && - iconRef.current && - !iconRef.current.contains(e.target as Node) - ) { - setIsSubMenuOpened(false); - } - }; - document.addEventListener("mousedown", handleClickOutside); - return () => document.removeEventListener("mousedown", handleClickOutside); - }, []); - return ( -
-
- -
- - {isSubMenuOpened && ( -
- {props.subElements.map((element, index) => { - return ; - })} -
- )} -
- ); -} diff --git a/src/front/Components/Elements/Rules/index.tsx b/src/front/Components/Elements/Rules/index.tsx index ecf66840..7f0defba 100644 --- a/src/front/Components/Elements/Rules/index.tsx +++ b/src/front/Components/Elements/Rules/index.tsx @@ -26,7 +26,7 @@ export default function Rules(props: IProps) { if (props.mode === RulesMode.NECESSARY) { return props.rules.every((rule) => JwtService.getInstance().hasRule(rule.name, rule.action)); } - return !!props.rules.find((rule) => JwtService.getInstance().hasRule(rule.name, rule.action)); + return props.rules.length === 0 || !!props.rules.find((rule) => JwtService.getInstance().hasRule(rule.name, rule.action)); }, [props.mode, props.rules]); useEffect(() => { diff --git a/src/front/Components/Layouts/DesignSystem/index.tsx b/src/front/Components/Layouts/DesignSystem/index.tsx index 4da7b128..13d4ae9f 100644 --- a/src/front/Components/Layouts/DesignSystem/index.tsx +++ b/src/front/Components/Layouts/DesignSystem/index.tsx @@ -27,7 +27,7 @@ import { import { useCallback, useMemo, useState } from "react"; import classes from "./classes.module.scss"; -import ButtonWithSubMenu from "@Front/Components/Elements/ButtonWithSubMenu"; +import Menu from "@Front/Components/DesignSystem/Menu"; export default function DesignSystem() { const { isOpen, open, close } = useOpenable(); @@ -80,9 +80,8 @@ export default function DesignSystem() {
Button icon with menu - } - subElements={[ + , text: "Modifier les collaborateurs", @@ -101,8 +100,9 @@ export default function DesignSystem() { link: "/", color: ETypoColor.ERROR_WEAK_CONTRAST, }, - ]} - /> + ]}> + } variant={EIconButtonVariant.NEUTRAL} /> + Inputs Number picker avec min à 1 et max à 10 {}} min={1} max={10} /> diff --git a/src/front/Components/Layouts/Folder/FolderInformation/ClientView/ClientBox/index.tsx b/src/front/Components/Layouts/Folder/FolderInformation/ClientView/ClientBox/index.tsx index 4cd16cce..882aaaaf 100644 --- a/src/front/Components/Layouts/Folder/FolderInformation/ClientView/ClientBox/index.tsx +++ b/src/front/Components/Layouts/Folder/FolderInformation/ClientView/ClientBox/index.tsx @@ -1,17 +1,18 @@ import Button, { EButtonSize, EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button"; +import IconButton, { EIconButtonVariant } from "@Front/Components/DesignSystem/IconButton"; +import Menu from "@Front/Components/DesignSystem/Menu"; +import Modal from "@Front/Components/DesignSystem/Modal"; import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography"; +import Module from "@Front/Config/Module"; import useOpenable from "@Front/Hooks/useOpenable"; import { PencilSquareIcon, TrashIcon, UsersIcon } from "@heroicons/react/24/outline"; +import { Note } from "le-coffre-resources/dist/Customer"; +import { useCallback } from "react"; import { ICustomer } from ".."; import { AnchorStatus } from "../.."; import classes from "./classes.module.scss"; import DeleteCustomerModal from "./DeleteCustomerModal"; -import Module from "@Front/Config/Module"; -import { useCallback } from "react"; -import { Note } from "le-coffre-resources/dist/Customer"; -import ButtonWithSubMenu from "@Front/Components/Elements/ButtonWithSubMenu"; -import Modal from "@Front/Components/DesignSystem/Modal"; type IProps = { customer: ICustomer; @@ -56,10 +57,9 @@ export default function ClientBox(props: IProps) { {customer.contact?.first_name} {customer.contact?.last_name} {anchorStatus === AnchorStatus.NOT_ANCHORED && ( - } + , text: "Modifier les informations", @@ -74,12 +74,9 @@ export default function ClientBox(props: IProps) { text: "Modifier la note", link: createOrUpdateNotePath, }, - ]} - /> - // - // - // + ]}> + } variant={EIconButtonVariant.NEUTRAL} /> + )}
diff --git a/src/front/Components/Layouts/Folder/FolderInformation/InformationSection/index.tsx b/src/front/Components/Layouts/Folder/FolderInformation/InformationSection/index.tsx index 4e60f216..ef264e44 100644 --- a/src/front/Components/Layouts/Folder/FolderInformation/InformationSection/index.tsx +++ b/src/front/Components/Layouts/Folder/FolderInformation/InformationSection/index.tsx @@ -1,15 +1,16 @@ import CircleProgress from "@Front/Components/DesignSystem/CircleProgress"; +import IconButton, { EIconButtonVariant } from "@Front/Components/DesignSystem/IconButton"; +import Menu, { IItem } from "@Front/Components/DesignSystem/Menu"; import Tag, { ETagColor } from "@Front/Components/DesignSystem/Tag"; import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography"; import Module from "@Front/Config/Module"; import { ArchiveBoxIcon, EllipsisHorizontalIcon, PencilSquareIcon, UsersIcon } from "@heroicons/react/24/outline"; import { OfficeFolder } from "le-coffre-resources/dist/Notary"; - -import classes from "./classes.module.scss"; -import { AnchorStatus } from ".."; -import ButtonWithSubMenu, { ISubElement } from "@Front/Components/Elements/ButtonWithSubMenu"; import { useCallback } from "react"; +import { AnchorStatus } from ".."; +import classes from "./classes.module.scss"; + type IProps = { folder: OfficeFolder | null; progress: number; @@ -22,7 +23,7 @@ export default function InformationSection(props: IProps) { const { folder, progress, onArchive, anchorStatus, isArchived } = props; const getSubMenuElement = useCallback(() => { - let elements: ISubElement[] = []; + let elements: IItem[] = []; // Creating the three elements and adding them conditionnally const modifyCollaboratorsElement = { @@ -86,7 +87,9 @@ export default function InformationSection(props: IProps) {
- } subElements={getSubMenuElement()} /> + + } variant={EIconButtonVariant.NEUTRAL} /> +
From cd84395308069418a37c5a42372efa6a9202b695 Mon Sep 17 00:00:00 2001 From: Max S Date: Wed, 24 Jul 2024 18:27:43 +0200 Subject: [PATCH 3/3] fix layout --- .../DefaultCollaboratorDashboard/classes.module.scss | 11 +++++------ .../DefaultDeedTypeDashboard/classes.module.scss | 11 +++++------ .../DefaultDocumentTypesDashboard/classes.module.scss | 11 +++++------ .../DefaultNotaryDashboard/classes.module.scss | 11 +++++------ .../DefaultOfficeDashboard/classes.module.scss | 11 +++++------ .../DefaultRoleDashboard/classes.module.scss | 11 +++++------ .../DefaultUserDashboard/classes.module.scss | 11 +++++------ 7 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/classes.module.scss index 9b23977b..c4e19f2a 100644 --- a/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/classes.module.scss +++ b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/classes.module.scss @@ -30,8 +30,8 @@ background-color: var(--color-generic-white); z-index: 3; display: flex; - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; transition: all 0.3s $custom-easing; overflow: hidden; @@ -42,8 +42,8 @@ &.opened { transform: translateX(0px); - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; } } @@ -86,7 +86,7 @@ .right-side { min-width: calc(100vw - 389px); - padding: 64px 48px; + padding: 24px; overflow-y: auto; @media (max-width: ($screen-m - 1px)) { @@ -94,7 +94,6 @@ } @media (max-width: $screen-s) { - padding: 40px 16px 64px 16px; flex: 1; min-width: unset; } diff --git a/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/classes.module.scss index 9b23977b..c4e19f2a 100644 --- a/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/classes.module.scss +++ b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/classes.module.scss @@ -30,8 +30,8 @@ background-color: var(--color-generic-white); z-index: 3; display: flex; - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; transition: all 0.3s $custom-easing; overflow: hidden; @@ -42,8 +42,8 @@ &.opened { transform: translateX(0px); - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; } } @@ -86,7 +86,7 @@ .right-side { min-width: calc(100vw - 389px); - padding: 64px 48px; + padding: 24px; overflow-y: auto; @media (max-width: ($screen-m - 1px)) { @@ -94,7 +94,6 @@ } @media (max-width: $screen-s) { - padding: 40px 16px 64px 16px; flex: 1; min-width: unset; } diff --git a/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/classes.module.scss index 9b23977b..c4e19f2a 100644 --- a/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/classes.module.scss +++ b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/classes.module.scss @@ -30,8 +30,8 @@ background-color: var(--color-generic-white); z-index: 3; display: flex; - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; transition: all 0.3s $custom-easing; overflow: hidden; @@ -42,8 +42,8 @@ &.opened { transform: translateX(0px); - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; } } @@ -86,7 +86,7 @@ .right-side { min-width: calc(100vw - 389px); - padding: 64px 48px; + padding: 24px; overflow-y: auto; @media (max-width: ($screen-m - 1px)) { @@ -94,7 +94,6 @@ } @media (max-width: $screen-s) { - padding: 40px 16px 64px 16px; flex: 1; min-width: unset; } diff --git a/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/classes.module.scss index c14e500d..69cef63d 100644 --- a/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/classes.module.scss +++ b/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/classes.module.scss @@ -31,8 +31,8 @@ background-color: var(--color-generic-white); z-index: 3; display: flex; - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; transition: all 0.3s $custom-easing; overflow: hidden; @@ -43,8 +43,8 @@ &.opened { transform: translateX(0px); - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; } } @@ -87,7 +87,7 @@ .right-side { min-width: calc(100vw - 389px); - padding: 64px 48px; + padding: 24px; overflow-y: auto; @media (max-width: ($screen-m - 1px)) { @@ -95,7 +95,6 @@ } @media (max-width: $screen-s) { - padding: 40px 16px 64px 16px; flex: 1; min-width: unset; } diff --git a/src/front/Components/LayoutTemplates/DefaultOfficeDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultOfficeDashboard/classes.module.scss index 9b23977b..c4e19f2a 100644 --- a/src/front/Components/LayoutTemplates/DefaultOfficeDashboard/classes.module.scss +++ b/src/front/Components/LayoutTemplates/DefaultOfficeDashboard/classes.module.scss @@ -30,8 +30,8 @@ background-color: var(--color-generic-white); z-index: 3; display: flex; - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; transition: all 0.3s $custom-easing; overflow: hidden; @@ -42,8 +42,8 @@ &.opened { transform: translateX(0px); - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; } } @@ -86,7 +86,7 @@ .right-side { min-width: calc(100vw - 389px); - padding: 64px 48px; + padding: 24px; overflow-y: auto; @media (max-width: ($screen-m - 1px)) { @@ -94,7 +94,6 @@ } @media (max-width: $screen-s) { - padding: 40px 16px 64px 16px; flex: 1; min-width: unset; } diff --git a/src/front/Components/LayoutTemplates/DefaultRoleDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/classes.module.scss index 9b23977b..c4e19f2a 100644 --- a/src/front/Components/LayoutTemplates/DefaultRoleDashboard/classes.module.scss +++ b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/classes.module.scss @@ -30,8 +30,8 @@ background-color: var(--color-generic-white); z-index: 3; display: flex; - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; transition: all 0.3s $custom-easing; overflow: hidden; @@ -42,8 +42,8 @@ &.opened { transform: translateX(0px); - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; } } @@ -86,7 +86,7 @@ .right-side { min-width: calc(100vw - 389px); - padding: 64px 48px; + padding: 24px; overflow-y: auto; @media (max-width: ($screen-m - 1px)) { @@ -94,7 +94,6 @@ } @media (max-width: $screen-s) { - padding: 40px 16px 64px 16px; flex: 1; min-width: unset; } diff --git a/src/front/Components/LayoutTemplates/DefaultUserDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultUserDashboard/classes.module.scss index 356d936e..f4e58c6d 100644 --- a/src/front/Components/LayoutTemplates/DefaultUserDashboard/classes.module.scss +++ b/src/front/Components/LayoutTemplates/DefaultUserDashboard/classes.module.scss @@ -30,8 +30,8 @@ background-color: var(--color-generic-white); z-index: 3; display: flex; - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; transition: all 0.3s $custom-easing; overflow: hidden; @@ -42,8 +42,8 @@ &.opened { transform: translateX(0px); - width: 389px; - min-width: 389px; + width: 336px; + min-width: 336px; } } @@ -86,7 +86,7 @@ .right-side { min-width: calc(100vw - 389px); - padding: 64px 48px; + padding: 24px; overflow-y: auto; @media (max-width: ($screen-m - 1px)) { @@ -94,7 +94,6 @@ } @media (max-width: $screen-s) { - padding: 40px 16px 64px 16px; flex: 1; min-width: unset; }