:sparkes: mobile menu working

This commit is contained in:
Maxime Lalo 2024-04-09 17:01:43 +02:00
parent eec89e13b0
commit a71a9582e3
7 changed files with 200 additions and 95 deletions

View File

@ -0,0 +1,18 @@
@import "@Themes/constants.scss";
.root {
.content {
display: flex;
gap: 8px;
align-items: center;
justify-content: center;
}
.sub-menu {
padding: 24px;
text-align: center;
gap: 24px;
display: flex;
flex-direction: column;
}
}

View File

@ -0,0 +1,54 @@
import classNames from "classnames";
import { useRouter } from "next/router";
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 Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import HeaderSubmenuLink from "../../../HeaderSubmenu/HeaderSubmenuLink";
import useToggle from "@Front/Hooks/useToggle";
import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/outline";
type IProps = {
text: string | JSX.Element;
links: (IHeaderLinkProps & {
rules?: IAppRule[];
})[];
};
export default function HeaderSubmenu(props: IProps) {
const router = useRouter();
const { pathname } = router;
const [isActive, setIsActive] = useState(true);
const { active: isSubmenuOpened, toggle } = useToggle(true);
useEffect(() => {
setIsActive(false);
if (props.links.some((link) => link.path === pathname)) setIsActive(true);
if (props.links.some((link) => link.routesActive?.some((routeActive) => pathname.includes(routeActive)))) setIsActive(true);
}, [isActive, pathname, props.links]);
return (
<Rules mode={RulesMode.OPTIONAL} rules={props.links.flatMap((link) => link.rules ?? [])}>
<div className={classes["container"]}>
<div className={classNames(classes["root"], (isActive || isSubmenuOpened) && classes["active"])}>
<div className={classes["content"]} onClick={toggle}>
<Typography typo={isActive || isSubmenuOpened ? ITypo.P_SB_18 : ITypo.NAV_HEADER_18}>{props.text}</Typography>
{isSubmenuOpened ? <ChevronUpIcon height="20" width="20" /> : <ChevronDownIcon height="20" width="20" />}
</div>
<div className={classes["underline"]} data-active={(isActive || isSubmenuOpened).toString()} />
{isSubmenuOpened && (
<div className={classes["sub-menu"]}>
{props.links.map((link) => (
<Rules mode={RulesMode.NECESSARY} rules={link.rules ?? []} key={link.path}>
<HeaderSubmenuLink {...link} />
</Rules>
))}
</div>
)}
</div>
</div>
</Rules>
);
}

View File

@ -4,8 +4,8 @@ import React from "react";
import NavigationLink from "../../NavigationLink"; import NavigationLink from "../../NavigationLink";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import Rules, { RulesMode } from "@Front/Components/Elements/Rules";
import { AppRuleActions, AppRuleNames } from "@Front/Api/Entities/rule"; import { AppRuleActions, AppRuleNames } from "@Front/Api/Entities/rule";
import BurgerModalSubmenu from "./BurgerModalSubmenu";
type IProps = { type IProps = {
isOpen: boolean; isOpen: boolean;
@ -34,111 +34,120 @@ export default class BurgerModal extends React.Component<IProps, IState> {
text="Dossiers archivés" text="Dossiers archivés"
routesActive={[Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path]} routesActive={[Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path]}
/> />
<Rules <div className={classes["separator"]} />
mode={RulesMode.NECESSARY}
rules={[ <BurgerModalSubmenu
text={"Espace super admin"}
links={[
{
text: "Gestion des utilisateurs",
path: 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,
},
],
},
{
text: "Gestion des offices",
path: 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,
},
],
},
]}
/>
<BurgerModalSubmenu
text="Espace office"
links={[
{
text: "Collaborateurs",
path: 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.read,
name: AppRuleNames.users,
},
],
},
{
text: "Gestion des rôles",
path: 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, action: AppRuleActions.update,
name: AppRuleNames.officeRoles, name: AppRuleNames.officeRoles,
}, },
]}> ],
<NavigationLink },
path={Module.getInstance().get().modules.pages.Collaborators.props.path} {
text="Collaborateurs" text: "Paramétrage des listes de pièces",
routesActive={[Module.getInstance().get().modules.pages.Collaborators.props.path]} path: Module.getInstance().get().modules.pages.DeedTypes.props.path,
/> routesActive: [
</Rules> Module.getInstance().get().modules.pages.DeedTypes.pages.Create.props.path,
<Rules Module.getInstance().get().modules.pages.DeedTypes.pages.Edit.props.path,
mode={RulesMode.NECESSARY} Module.getInstance().get().modules.pages.DeedTypes.props.path,
rules={[ 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, action: AppRuleActions.update,
name: AppRuleNames.deedTypes, name: AppRuleNames.deedTypes,
}, },
]}> ],
<NavigationLink
path={Module.getInstance().get().modules.pages.DeedTypes.props.path}
text="Paramétrage des listes de pièces"
routesActive={[
Module.getInstance().get().modules.pages.DeedTypes.props.path,
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,
]}
/>
</Rules>
<Rules
mode={RulesMode.NECESSARY}
rules={[
{
action: AppRuleActions.update,
name: AppRuleNames.officeRoles,
}, },
]}>
<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,
]}
/>
</Rules>
<Rules
mode={RulesMode.NECESSARY}
rules={[
{ {
action: AppRuleActions.update, text: "RIB Office",
name: AppRuleNames.offices, path: Module.getInstance().get().modules.pages.OfficesRib.props.path,
}, rules: [
]}>
<NavigationLink
path={Module.getInstance().get().modules.pages.Users.props.path}
text="Gestion des utilisateurs"
routesActive={[
Module.getInstance().get().modules.pages.Users.props.path,
Module.getInstance().get().modules.pages.Users.pages.UsersInformations.props.path,
]}
/>
</Rules>
<Rules
mode={RulesMode.NECESSARY}
rules={[
{
action: AppRuleActions.update,
name: AppRuleNames.offices,
},
]}>
<NavigationLink
path={Module.getInstance().get().modules.pages.Offices.props.path}
text="Gestion des offices"
routesActive={[
Module.getInstance().get().modules.pages.Offices.props.path,
Module.getInstance().get().modules.pages.Offices.pages.OfficesInformations.props.path,
]}
/>
</Rules>
<Rules
mode={RulesMode.NECESSARY}
rules={[
{ {
action: AppRuleActions.update, action: AppRuleActions.update,
name: AppRuleNames.rib, name: AppRuleNames.rib,
}, },
]}> ],
<NavigationLink },
path={Module.getInstance().get().modules.pages.OfficesRib.props.path} {
text="Gestion du RIB" text: "Abonnement",
routesActive={[Module.getInstance().get().modules.pages.OfficesRib.props.path]} path: 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> <div className={classes["separator"]} />
<NavigationLink path={Module.getInstance().get().modules.pages.MyAccount.props.path} text="Mon compte" /> <NavigationLink path={Module.getInstance().get().modules.pages.MyAccount.props.path} text="Mon compte" />
<NavigationLink target="_blank" path="/CGU_LeCoffre_io.pdf" text="CGU" /> <NavigationLink target="_blank" path="/CGU_LeCoffre_io.pdf" text="CGU" />
<div className={classes["separator"]} />
<LogOutButton /> <LogOutButton />
</div> </div>
</> </>

View File

@ -5,7 +5,7 @@ import React, { useEffect } from "react";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import useHoverable from "@Front/Hooks/useHoverable"; import useHoverable from "@Front/Hooks/useHoverable";
export type IHeaderLinkProps = { type IHeaderLinkProps = {
text: string | JSX.Element; text: string | JSX.Element;
path: string; path: string;
routesActive?: string[]; routesActive?: string[];

View File

@ -117,7 +117,7 @@ export default function Navigation() {
], ],
}, },
{ {
text: "Paramétrage types d'actes", text: "Paramétrage des listes de pièces",
path: Module.getInstance().get().modules.pages.DeedTypes.props.path, path: Module.getInstance().get().modules.pages.DeedTypes.props.path,
routesActive: [ routesActive: [
Module.getInstance().get().modules.pages.DeedTypes.pages.Create.props.path, Module.getInstance().get().modules.pages.DeedTypes.pages.Create.props.path,

View File

@ -22,7 +22,7 @@ export const collaboratorPrice = 6.99;
export const forfeitsPrices: Record<EForfeitType, number> = { export const forfeitsPrices: Record<EForfeitType, number> = {
[EForfeitType.standard]: 99, [EForfeitType.standard]: 99,
[EForfeitType.unlimited]: 249, [EForfeitType.unlimited]: 199,
}; };
export default function SubscriptionFacturation() { export default function SubscriptionFacturation() {
const router = useRouter(); const router = useRouter();

View File

@ -0,0 +1,24 @@
import { useCallback, useState } from "react";
export default function useToggle(defaultValue: boolean = false) {
const [active, setActive] = useState(defaultValue);
const toggle = useCallback(() => {
setActive((prev) => !prev);
}, []);
const activate = useCallback(() => {
setActive(true);
}, []);
const deactivate = useCallback(() => {
setActive(false);
}, []);
return {
active,
toggle,
activate,
deactivate,
};
}