Merge branch 'dev' of github.com:smart-chain-fr/leCoffre-front into dev
This commit is contained in:
commit
d99148d3bd
@ -1,7 +0,0 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
.root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
import Module from "@Front/Config/Module";
|
||||
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||
import { EDocumentStatus } from "le-coffre-resources/dist/Notary/Document";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import { IBlock } from "../SearchBlockList/BlockList/Block";
|
||||
import SearchBlockList from "../SearchBlockList";
|
||||
|
||||
type IProps = {
|
||||
folders: OfficeFolder[];
|
||||
isArchived: boolean;
|
||||
};
|
||||
|
||||
export default function FolderListContainer(props: IProps) {
|
||||
const router = useRouter();
|
||||
const { folderUid } = router.query;
|
||||
const { folders, isArchived } = props;
|
||||
|
||||
const redirectPath: string = isArchived
|
||||
? Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.pages.FolderInformation.props.path
|
||||
: Module.getInstance().get().modules.pages.Folder.pages.FolderInformation.props.path;
|
||||
|
||||
const getBlocks = useCallback(
|
||||
(folders: OfficeFolder[]): IBlock[] => {
|
||||
const pendingFolders = folders
|
||||
.filter((folder) => {
|
||||
const pendingDocuments = (folder.documents ?? []).filter(
|
||||
(document) => document.document_status === EDocumentStatus.DEPOSITED,
|
||||
);
|
||||
return pendingDocuments.length >= 1;
|
||||
})
|
||||
.sort((folder1, folder2) => {
|
||||
return folder1.created_at! > folder2.created_at! ? -1 : 1;
|
||||
});
|
||||
|
||||
const otherFolders = folders
|
||||
.filter((folder) => {
|
||||
const pendingDocuments = (folder.documents ?? []).filter(
|
||||
(document) => document.document_status === EDocumentStatus.DEPOSITED,
|
||||
);
|
||||
return pendingDocuments.length === 0;
|
||||
})
|
||||
.sort((folder1, folder2) => {
|
||||
return folder1.created_at! > folder2.created_at! ? -1 : 1;
|
||||
});
|
||||
|
||||
return [...pendingFolders, ...otherFolders].map((folder) => {
|
||||
return {
|
||||
id: folder.uid!,
|
||||
primaryText: folder.name,
|
||||
secondaryText: folder.folder_number,
|
||||
isActive: folderUid === folder.uid,
|
||||
showAlert: folder.documents?.some((document) => document.document_status === EDocumentStatus.DEPOSITED),
|
||||
};
|
||||
});
|
||||
},
|
||||
[folderUid],
|
||||
);
|
||||
|
||||
const [blocks, setBlocks] = React.useState<IBlock[]>(getBlocks(folders));
|
||||
|
||||
const onSelectedFolder = (block: IBlock) => {
|
||||
const folder = folders.find((folder) => folder.uid === block.id);
|
||||
if (!folder) return;
|
||||
const path = redirectPath.replace("[folderUid]", folder.uid ?? "");
|
||||
router.push(path);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setBlocks(getBlocks(folders));
|
||||
}, [folders, getBlocks]);
|
||||
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<SearchBlockList
|
||||
blocks={blocks}
|
||||
onSelectedBlock={onSelectedFolder}
|
||||
bottomButton={{
|
||||
link: Module.getInstance().get().modules.pages.Folder.pages.CreateFolder.props.path,
|
||||
text: "Créer un dossier",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -8,13 +8,12 @@
|
||||
font-size: 12px;
|
||||
font-weight: var(--font-text-weight-regular, 400);
|
||||
letter-spacing: 0.06px;
|
||||
|
||||
.sub-root {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--Radius-lg, 16px);
|
||||
white-space: nowrap;
|
||||
padding: 0 360px;
|
||||
padding: var(--spacing-1-5, 12px) var(--Radius-xl, 24px);
|
||||
//make it sticky
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
|
@ -1,20 +1,25 @@
|
||||
import React from "react";
|
||||
import classes from "./classes.module.scss";
|
||||
import Link from "next/link";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { ELegalOptions } from "@Front/Components/LayoutTemplates/DefaultLegalDashboard";
|
||||
|
||||
type IProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const legalPages = Module.getInstance().get().modules.pages.Legal.pages.LegalInformations.props.path;
|
||||
|
||||
export default function Desktop({ className }: IProps) {
|
||||
return (
|
||||
<div className={[classes["sub-root"], className].join(" ")}>
|
||||
<span>© Copyright lecoffre 2024</span>
|
||||
<span className={classes["separator"]} />
|
||||
<a href="/terms">Conditions d'utilisation</a>
|
||||
<Link href={legalPages.replace("[legalUid]", ELegalOptions.CGU)}>Conditions d'utilisation</Link>
|
||||
<span className={classes["separator"]} />
|
||||
<a href="/privacy">Politique de confidentialité</a>
|
||||
<Link href={legalPages.replace("[legalUid]", ELegalOptions.POLITIQUE_DE_CONFIDENTIALITE)}>Politique de confidentialité</Link>
|
||||
<span className={classes["separator"]} />
|
||||
<a href="/cookies">Politique des cookies</a>
|
||||
<Link href={legalPages.replace("[legalUid]", ELegalOptions.POLITIQUE_DE_GESTION_DES_COOKIES)}>Politique des cookies</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import classes from "./classes.module.scss";
|
||||
import Mobile from "./mobile";
|
||||
import Desktop from "./desktop";
|
||||
@ -9,6 +9,9 @@ type IProps = {
|
||||
};
|
||||
|
||||
export default function Footer({ className }: IProps) {
|
||||
useEffect(() => {
|
||||
document.documentElement.style.setProperty("--footer-height", `43px`);
|
||||
});
|
||||
return (
|
||||
<footer className={[classes["root"], className].join(" ")}>
|
||||
<Mobile className={classes["mobile"]} />
|
||||
|
@ -1,18 +1,23 @@
|
||||
import React from "react";
|
||||
import classes from "./classes.module.scss";
|
||||
import Link from "next/link";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { ELegalOptions } from "@Front/Components/LayoutTemplates/DefaultLegalDashboard";
|
||||
|
||||
type IProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
const legalPages = Module.getInstance().get().modules.pages.Legal.pages.LegalInformations.props.path;
|
||||
|
||||
export default function Mobile({ className }: IProps) {
|
||||
return (
|
||||
<div className={[classes["sub-root"], className].join(" ")}>
|
||||
<span>© Lecoffre 2024</span>
|
||||
<span className={classes["separator"]} />
|
||||
<a href="/terms">Juridiques</a>
|
||||
<Link href={legalPages.replace("[legalUid]", ELegalOptions.LEGAL_MENTIONS)}>Juridiques</Link>
|
||||
<span className={classes["separator"]} />
|
||||
<a href="/cookies">Cookies</a>
|
||||
<Link href={legalPages.replace("[legalUid]", ELegalOptions.POLITIQUE_DE_GESTION_DES_COOKIES)}>Cookies</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,20 +1,24 @@
|
||||
import React from "react";
|
||||
import classes from "./classes.module.scss";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { ELegalOptions } from "@Front/Components/LayoutTemplates/DefaultLegalDashboard";
|
||||
import Link from "next/link";
|
||||
|
||||
type IProps = {
|
||||
className?: string;
|
||||
};
|
||||
const legalPages = Module.getInstance().get().modules.pages.Legal.pages.LegalInformations.props.path;
|
||||
|
||||
export default function Tablet({ className }: IProps) {
|
||||
return (
|
||||
<div className={[classes["sub-root"], className].join(" ")}>
|
||||
<span>© Lecoffre 2024</span>
|
||||
<span className={classes["separator"]} />
|
||||
<a href="/terms">Conditions d'utilisation</a>
|
||||
<Link href={legalPages.replace("[legalUid]", ELegalOptions.CGU)}>Conditions d'utilisation</Link>
|
||||
<span className={classes["separator"]} />
|
||||
<a href="/privacy">Politique de confidentialité</a>
|
||||
<Link href={legalPages.replace("[legalUid]", ELegalOptions.POLITIQUE_DE_CONFIDENTIALITE)}>Politique de confidentialité</Link>
|
||||
<span className={classes["separator"]} />
|
||||
<a href="/cookies">Politique des cookies</a>
|
||||
<Link href={legalPages.replace("[legalUid]", ELegalOptions.POLITIQUE_DE_GESTION_DES_COOKIES)}>Politique des cookies</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
@import "@Themes/constants.scss";
|
||||
.root {
|
||||
width: 336px;
|
||||
min-width: 336px;
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
|
||||
|
@ -7,7 +7,7 @@ import Button from "../Button";
|
||||
import { useRouter } from "next/router";
|
||||
import DropdownNavigation from "./DropdownNavigation";
|
||||
|
||||
type IProps = {
|
||||
export type ISearchBlockListProps = {
|
||||
blocks: IBlock[];
|
||||
onSelectedBlock: (block: IBlock) => void;
|
||||
bottomButton?: {
|
||||
@ -15,7 +15,7 @@ type IProps = {
|
||||
link: string;
|
||||
};
|
||||
};
|
||||
export default function SearchBlockList(props: IProps) {
|
||||
export default function SearchBlockList(props: ISearchBlockListProps) {
|
||||
const { blocks, onSelectedBlock, bottomButton } = props;
|
||||
|
||||
const [selectedBlock, setSelectedBlock] = useState<IBlock | null>(null);
|
||||
|
@ -1,23 +0,0 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
.root {
|
||||
width: calc(100vh - 83px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.header {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.searchbar {
|
||||
padding: 40px 24px 24px 24px;
|
||||
}
|
||||
|
||||
.folderlist-container {
|
||||
max-height: calc(100vh - 215px);
|
||||
height: 100%;
|
||||
border-right: 1px solid var(--color-neutral-200);
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import User from "le-coffre-resources/dist/Notary";
|
||||
import { useRouter } from "next/router";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import SearchBlockList from "@Front/Components/DesignSystem/SearchBlockList";
|
||||
|
||||
type IProps = {
|
||||
collaborators: User[];
|
||||
onSelectedCollaborator?: (user: User) => void;
|
||||
onCloseLeftSide?: () => void;
|
||||
};
|
||||
|
||||
export default function CollaboratorListContainer(props: IProps) {
|
||||
const router = useRouter();
|
||||
|
||||
const { collaboratorUid } = router.query;
|
||||
|
||||
const onSelectedBlock = useCallback(
|
||||
(block: IBlock) => {
|
||||
props.onCloseLeftSide && props.onCloseLeftSide();
|
||||
const redirectPath = Module.getInstance().get().modules.pages.Collaborators.pages.CollaboratorInformations.props.path;
|
||||
router.push(redirectPath.replace("[uid]", block.id));
|
||||
},
|
||||
[props, router],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<SearchBlockList
|
||||
blocks={props.collaborators.map((user) => {
|
||||
return {
|
||||
primaryText: user.contact?.first_name + " " + user.contact?.last_name,
|
||||
id: user.uid!,
|
||||
isActive: user.uid === collaboratorUid,
|
||||
};
|
||||
})}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
@keyframes growWidth {
|
||||
0% {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 200%;
|
||||
}
|
||||
}
|
||||
|
||||
.root {
|
||||
.content {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
height: calc(100vh - var(--header-height));
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--color-generic-white);
|
||||
opacity: 0.5;
|
||||
z-index: 2;
|
||||
transition: all 0.3s $custom-easing;
|
||||
}
|
||||
|
||||
.left-side {
|
||||
background-color: var(--color-generic-white);
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
width: 336px;
|
||||
min-width: 336px;
|
||||
transition: all 0.3s $custom-easing;
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-width: ($screen-m - 1px)) {
|
||||
width: 56px;
|
||||
min-width: 56px;
|
||||
transform: translateX(-389px);
|
||||
|
||||
&.opened {
|
||||
transform: translateX(0px);
|
||||
width: 336px;
|
||||
min-width: 336px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
width: 0px;
|
||||
min-width: 0px;
|
||||
|
||||
&.opened {
|
||||
width: 100vw;
|
||||
min-width: 100vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.closable-left-side {
|
||||
position: absolute;
|
||||
background-color: var(--color-generic-white);
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-width: 56px;
|
||||
max-width: 56px;
|
||||
height: calc(100vh - var(--header-height));
|
||||
border-right: 1px var(--color-neutral-200) solid;
|
||||
|
||||
@media (min-width: $screen-m) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chevron-icon {
|
||||
margin-top: 21px;
|
||||
transform: rotate(180deg);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.right-side {
|
||||
min-width: calc(100vw - 389px);
|
||||
padding: 24px;
|
||||
overflow-y: auto;
|
||||
|
||||
@media (max-width: ($screen-m - 1px)) {
|
||||
min-width: calc(100vw - 56px);
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
flex: 1;
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
.back-arrow-mobile {
|
||||
display: none;
|
||||
@media (max-width: $screen-s) {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.back-arrow-desktop {
|
||||
@media (max-width: $screen-s) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,93 +1,20 @@
|
||||
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
||||
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/Admin/Users/Users";
|
||||
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import Header from "@Front/Components/DesignSystem/Header";
|
||||
import Version from "@Front/Components/DesignSystem/Version";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList";
|
||||
import User from "le-coffre-resources/dist/Notary";
|
||||
import JwtService from "@Front/Services/JwtService/JwtService";
|
||||
import WindowStore from "@Front/Stores/WindowStore";
|
||||
import classNames from "classnames";
|
||||
import User from "le-coffre-resources/dist/Admin";
|
||||
import Image from "next/image";
|
||||
import React, { ReactNode } from "react";
|
||||
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/Admin/Users/Users";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import CollaboratorListContainer from "./CollaboratorListContainer";
|
||||
import { ChevronLeftIcon } from "@heroicons/react/24/solid";
|
||||
type IProps = IPropsDashboardWithList;
|
||||
|
||||
type IProps = {
|
||||
title: string;
|
||||
children?: ReactNode;
|
||||
onSelectedUser: (user: User) => void;
|
||||
hasBackArrow: boolean;
|
||||
backArrowUrl?: string;
|
||||
mobileBackText?: string;
|
||||
};
|
||||
type IState = {
|
||||
collaborators: User[] | null;
|
||||
isLeftSideOpen: boolean;
|
||||
leftSideCanBeClosed: boolean;
|
||||
};
|
||||
|
||||
export default class DefaultCollaboratorDashboard extends React.Component<IProps, IState> {
|
||||
private onWindowResize = () => {};
|
||||
public static defaultProps: Partial<IProps> = {
|
||||
hasBackArrow: false,
|
||||
};
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
collaborators: null,
|
||||
isLeftSideOpen: false,
|
||||
leftSideCanBeClosed: typeof window !== "undefined" ? window.innerWidth < 1024 : false,
|
||||
};
|
||||
this.onOpenLeftSide = this.onOpenLeftSide.bind(this);
|
||||
this.onCloseLeftSide = this.onCloseLeftSide.bind(this);
|
||||
}
|
||||
|
||||
public override render(): JSX.Element {
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<Header isUserConnected={true} />
|
||||
<div className={classes["content"]}>
|
||||
{this.state.isLeftSideOpen && <div className={classes["overlay"]} onClick={this.onCloseLeftSide} />}
|
||||
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
|
||||
{this.state.collaborators && (
|
||||
<CollaboratorListContainer collaborators={this.state.collaborators} onCloseLeftSide={this.onCloseLeftSide} />
|
||||
)}
|
||||
</div>
|
||||
<div className={classNames(classes["closable-left-side"])}>
|
||||
<Image alt="open side menu" src={ChevronIcon} className={classes["chevron-icon"]} onClick={this.onOpenLeftSide} />
|
||||
</div>
|
||||
|
||||
<div className={classes["right-side"]}>
|
||||
{this.props.hasBackArrow && (
|
||||
<div className={classes["back-arrow-desktop"]}>
|
||||
<BackArrow url={this.props.backArrowUrl ?? ""} />
|
||||
</div>
|
||||
)}
|
||||
{this.props.mobileBackText && (
|
||||
<div className={classes["back-arrow-mobile"]}>
|
||||
<Button
|
||||
leftIcon={<ChevronLeftIcon />}
|
||||
variant={EButtonVariant.PRIMARY}
|
||||
styletype={EButtonstyletype.TEXT}
|
||||
onClick={this.onOpenLeftSide}>
|
||||
{this.props.mobileBackText ?? "Retour"}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
<Version />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public override async componentDidMount() {
|
||||
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
|
||||
export default function DefaultCollaboratorDashboard(props: IProps) {
|
||||
const [collaborators, setCollaborators] = React.useState<User[] | null>(null);
|
||||
const router = useRouter();
|
||||
const { collaboratorUid } = router.query;
|
||||
useEffect(() => {
|
||||
const jwt = JwtService.getInstance().decodeJwt();
|
||||
if (!jwt) return;
|
||||
const query: IGetUsersparams = {
|
||||
@ -102,27 +29,31 @@ export default class DefaultCollaboratorDashboard extends React.Component<IProps
|
||||
},
|
||||
};
|
||||
|
||||
const collaborators = await Users.getInstance().get(query);
|
||||
this.setState({ collaborators });
|
||||
}
|
||||
public override componentWillUnmount() {
|
||||
this.onWindowResize();
|
||||
}
|
||||
Users.getInstance()
|
||||
.get(query)
|
||||
.then((users) => setCollaborators(users));
|
||||
}, []);
|
||||
|
||||
private onOpenLeftSide() {
|
||||
this.setState({ isLeftSideOpen: true });
|
||||
}
|
||||
const onSelectedBlock = (block: IBlock) => {
|
||||
router.push(
|
||||
Module.getInstance().get().modules.pages.Collaborators.pages.CollaboratorInformations.props.path.replace("[uid]", block.id),
|
||||
);
|
||||
};
|
||||
|
||||
private onCloseLeftSide() {
|
||||
if (!this.state.leftSideCanBeClosed) return;
|
||||
this.setState({ isLeftSideOpen: false });
|
||||
}
|
||||
|
||||
private onResize(window: Window) {
|
||||
if (window.innerWidth > 1023) {
|
||||
if (!this.state.leftSideCanBeClosed) return;
|
||||
this.setState({ leftSideCanBeClosed: false });
|
||||
}
|
||||
this.setState({ leftSideCanBeClosed: true });
|
||||
return (
|
||||
<DefaultDashboardWithList
|
||||
{...props}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
blocks={
|
||||
collaborators
|
||||
? collaborators.map((collaborator) => ({
|
||||
id: collaborator.uid!,
|
||||
primaryText: collaborator.contact?.first_name + " " + collaborator.contact?.last_name,
|
||||
isActive: collaborator.uid === collaboratorUid,
|
||||
secondaryText: collaborator.contact?.email,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -5,18 +5,33 @@
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
min-height: calc(100vh - var(--header-height));
|
||||
height: calc(100vh - var(--header-height));
|
||||
|
||||
@media (max-width: $screen-m) {
|
||||
flex-direction: column;
|
||||
}
|
||||
.right-side {
|
||||
min-width: calc(100% - 336px);
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: column;
|
||||
.right-side-content {
|
||||
overflow-y: auto;
|
||||
padding: var(--spacing-lg, 24px);
|
||||
height: calc(100% - var(--footer-height));
|
||||
}
|
||||
|
||||
&[data-no-padding="true"] {
|
||||
.right-side-content {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-m) {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
|
||||
.right-side {
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,33 +4,40 @@ import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import SearchBlockList from "@Front/Components/DesignSystem/SearchBlockList";
|
||||
import SearchBlockList, { ISearchBlockListProps } from "@Front/Components/DesignSystem/SearchBlockList";
|
||||
import Footer from "@Front/Components/DesignSystem/Footer";
|
||||
|
||||
export type IPropsDashboardWithList = {
|
||||
title?: string;
|
||||
children?: ReactNode;
|
||||
isArchived?: boolean;
|
||||
hasBackArrow?: boolean;
|
||||
backArrowUrl?: string;
|
||||
mobileBackText?: string;
|
||||
headerConnected?: boolean;
|
||||
noPadding?: boolean;
|
||||
};
|
||||
|
||||
type IProps = IPropsDashboardWithList & {
|
||||
blocksList: IBlock[];
|
||||
onSelectedBlock: (block: IBlock) => void;
|
||||
headerConnected?: boolean;
|
||||
};
|
||||
type IProps = IPropsDashboardWithList & ISearchBlockListProps;
|
||||
|
||||
export default function DefaultDashboardWithList(props: IProps) {
|
||||
const { hasBackArrow, backArrowUrl, children, blocksList, onSelectedBlock, headerConnected = true } = props;
|
||||
const {
|
||||
hasBackArrow,
|
||||
backArrowUrl,
|
||||
children,
|
||||
blocks,
|
||||
onSelectedBlock,
|
||||
headerConnected = true,
|
||||
bottomButton,
|
||||
noPadding = false,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<Header isUserConnected={headerConnected} />
|
||||
<div className={classes["content"]}>
|
||||
<SearchBlockList blocks={blocksList} onSelectedBlock={onSelectedBlock} />
|
||||
<div className={classes["right-side"]}>
|
||||
<SearchBlockList blocks={blocks} onSelectedBlock={onSelectedBlock} bottomButton={bottomButton} />
|
||||
<div className={classes["right-side"]} data-no-padding={noPadding}>
|
||||
<div className={classes["right-side-content"]}>
|
||||
{hasBackArrow && (
|
||||
<div className={classes["back-arrow-desktop"]}>
|
||||
<BackArrow url={backArrowUrl ?? ""} />
|
||||
@ -38,6 +45,8 @@ export default function DefaultDashboardWithList(props: IProps) {
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
<Version />
|
||||
</div>
|
||||
|
@ -1,32 +0,0 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
.root {
|
||||
width: calc(100vh - 83px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
position: relative;
|
||||
|
||||
.header {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.searchbar {
|
||||
padding: 40px 24px 24px 24px;
|
||||
}
|
||||
|
||||
.folderlist-container {
|
||||
max-height: calc(100vh - 290px);
|
||||
height: calc(100vh - 290px);
|
||||
overflow: auto;
|
||||
border-right: 1px solid var(--color-neutral-200);
|
||||
}
|
||||
|
||||
.create-container {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
import DeedTypes from "@Front/Api/LeCoffreApi/Admin/DeedTypes/DeedTypes";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { DeedType } from "le-coffre-resources/dist/Admin";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import SearchBlockList from "@Front/Components/DesignSystem/SearchBlockList";
|
||||
|
||||
type IProps = {
|
||||
deedTypes: DeedType[];
|
||||
onSelectedDeed?: (deed: DeedTypes) => void;
|
||||
onCloseLeftSide?: () => void;
|
||||
};
|
||||
|
||||
export default function DeedListContainer(props: IProps) {
|
||||
const router = useRouter();
|
||||
const { deedTypeUid } = router.query;
|
||||
|
||||
const onSelectedBlock = useCallback(
|
||||
(block: IBlock) => {
|
||||
props.onCloseLeftSide && props.onCloseLeftSide();
|
||||
const redirectPath = Module.getInstance().get().modules.pages.DeedTypes.pages.DeedTypesInformations.props.path;
|
||||
router.push(redirectPath.replace("[uid]", block.id));
|
||||
},
|
||||
[props, router],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<SearchBlockList
|
||||
blocks={props.deedTypes.map((deed) => {
|
||||
return {
|
||||
primaryText: deed.name,
|
||||
id: deed.uid!,
|
||||
isActive: deedTypeUid === deed.uid,
|
||||
};
|
||||
})}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
bottomButton={{
|
||||
link: Module.getInstance().get().modules.pages.DeedTypes.pages.Create.props.path,
|
||||
text: "Créer un type d'acte",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
@keyframes growWidth {
|
||||
0% {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 200%;
|
||||
}
|
||||
}
|
||||
|
||||
.root {
|
||||
.content {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
height: calc(100vh - var(--header-height));
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--color-generic-white);
|
||||
opacity: 0.5;
|
||||
z-index: 2;
|
||||
transition: all 0.3s $custom-easing;
|
||||
}
|
||||
|
||||
.left-side {
|
||||
background-color: var(--color-generic-white);
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
width: 336px;
|
||||
min-width: 336px;
|
||||
transition: all 0.3s $custom-easing;
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-width: ($screen-m - 1px)) {
|
||||
width: 56px;
|
||||
min-width: 56px;
|
||||
transform: translateX(-389px);
|
||||
|
||||
&.opened {
|
||||
transform: translateX(0px);
|
||||
width: 336px;
|
||||
min-width: 336px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
width: 0px;
|
||||
min-width: 0px;
|
||||
|
||||
&.opened {
|
||||
width: 100vw;
|
||||
min-width: 100vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.closable-left-side {
|
||||
position: absolute;
|
||||
background-color: var(--color-generic-white);
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-width: 56px;
|
||||
max-width: 56px;
|
||||
height: calc(100vh - var(--header-height));
|
||||
border-right: 1px var(--color-neutral-200) solid;
|
||||
|
||||
@media (min-width: $screen-m) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chevron-icon {
|
||||
margin-top: 21px;
|
||||
transform: rotate(180deg);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.right-side {
|
||||
min-width: calc(100vw - 389px);
|
||||
padding: 24px;
|
||||
overflow-y: auto;
|
||||
|
||||
@media (max-width: ($screen-m - 1px)) {
|
||||
min-width: calc(100vw - 56px);
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
flex: 1;
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
.back-arrow-mobile {
|
||||
display: none;
|
||||
@media (max-width: $screen-s) {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.back-arrow-desktop {
|
||||
@media (max-width: $screen-s) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,92 +1,19 @@
|
||||
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList";
|
||||
import { DeedType } from "le-coffre-resources/dist/Notary";
|
||||
import DeedTypes, { IGetDeedTypesParams } from "@Front/Api/LeCoffreApi/Notary/DeedTypes/DeedTypes";
|
||||
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import Header from "@Front/Components/DesignSystem/Header";
|
||||
import Version from "@Front/Components/DesignSystem/Version";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import WindowStore from "@Front/Stores/WindowStore";
|
||||
import classNames from "classnames";
|
||||
import { Deed, DeedType } from "le-coffre-resources/dist/Notary";
|
||||
import Image from "next/image";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import DeedListContainer from "./DeedTypeListContainer";
|
||||
import { ChevronLeftIcon } from "@heroicons/react/24/solid";
|
||||
type IProps = IPropsDashboardWithList;
|
||||
|
||||
type IProps = {
|
||||
title: string;
|
||||
children?: ReactNode;
|
||||
onSelectedDeed: (deed: Deed) => void;
|
||||
hasBackArrow: boolean;
|
||||
backArrowUrl?: string;
|
||||
mobileBackText?: string;
|
||||
};
|
||||
type IState = {
|
||||
deedTypes: DeedType[] | null;
|
||||
isLeftSideOpen: boolean;
|
||||
leftSideCanBeClosed: boolean;
|
||||
};
|
||||
|
||||
export default class DefaultDeedTypesDashboard extends React.Component<IProps, IState> {
|
||||
private onWindowResize = () => {};
|
||||
public static defaultProps: Partial<IProps> = {
|
||||
hasBackArrow: false,
|
||||
};
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
deedTypes: null,
|
||||
isLeftSideOpen: false,
|
||||
leftSideCanBeClosed: typeof window !== "undefined" ? window.innerWidth < 1024 : false,
|
||||
};
|
||||
this.onOpenLeftSide = this.onOpenLeftSide.bind(this);
|
||||
this.onCloseLeftSide = this.onCloseLeftSide.bind(this);
|
||||
}
|
||||
|
||||
public override render(): JSX.Element {
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<Header isUserConnected={true} />
|
||||
<div className={classes["content"]}>
|
||||
{this.state.isLeftSideOpen && <div className={classes["overlay"]} onClick={this.onCloseLeftSide} />}
|
||||
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
|
||||
{this.state.deedTypes && (
|
||||
<DeedListContainer deedTypes={this.state.deedTypes} onCloseLeftSide={this.onCloseLeftSide} />
|
||||
)}
|
||||
</div>
|
||||
<div className={classNames(classes["closable-left-side"])}>
|
||||
<Image alt="open side menu" src={ChevronIcon} className={classes["chevron-icon"]} onClick={this.onOpenLeftSide} />
|
||||
</div>
|
||||
|
||||
<div className={classes["right-side"]}>
|
||||
{this.props.hasBackArrow && (
|
||||
<div className={classes["back-arrow-desktop"]}>
|
||||
<BackArrow url={this.props.backArrowUrl ?? ""} />
|
||||
</div>
|
||||
)}
|
||||
{this.props.mobileBackText && (
|
||||
<div className={classes["back-arrow-mobile"]}>
|
||||
<Button
|
||||
leftIcon={<ChevronLeftIcon />}
|
||||
variant={EButtonVariant.PRIMARY}
|
||||
styletype={EButtonstyletype.TEXT}
|
||||
onClick={this.onOpenLeftSide}>
|
||||
{this.props.mobileBackText ?? "Retour"}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
<Version />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public override async componentDidMount() {
|
||||
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
|
||||
export default function DefaultDeedTypeDashboard(props: IProps) {
|
||||
const [deedTypes, setDeedTypes] = React.useState<DeedType[] | null>(null);
|
||||
const router = useRouter();
|
||||
const { deedTypeUid } = router.query;
|
||||
useEffect(() => {
|
||||
const query: IGetDeedTypesParams = {
|
||||
where: {
|
||||
archived_at: null,
|
||||
@ -96,28 +23,32 @@ export default class DefaultDeedTypesDashboard extends React.Component<IProps, I
|
||||
},
|
||||
};
|
||||
|
||||
const deedTypes = await DeedTypes.getInstance().get(query);
|
||||
this.setState({ deedTypes });
|
||||
}
|
||||
DeedTypes.getInstance()
|
||||
.get(query)
|
||||
.then((deedTypes) => setDeedTypes(deedTypes));
|
||||
}, []);
|
||||
|
||||
public override componentWillUnmount() {
|
||||
this.onWindowResize();
|
||||
}
|
||||
const onSelectedBlock = (block: IBlock) => {
|
||||
router.push(Module.getInstance().get().modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", block.id));
|
||||
};
|
||||
|
||||
private onOpenLeftSide() {
|
||||
this.setState({ isLeftSideOpen: true });
|
||||
}
|
||||
|
||||
private onCloseLeftSide() {
|
||||
if (!this.state.leftSideCanBeClosed) return;
|
||||
this.setState({ isLeftSideOpen: false });
|
||||
}
|
||||
|
||||
private onResize(window: Window) {
|
||||
if (window.innerWidth > 1023) {
|
||||
if (!this.state.leftSideCanBeClosed) return;
|
||||
this.setState({ leftSideCanBeClosed: false });
|
||||
}
|
||||
this.setState({ leftSideCanBeClosed: true });
|
||||
return (
|
||||
<DefaultDashboardWithList
|
||||
{...props}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
blocks={
|
||||
deedTypes
|
||||
? deedTypes.map((deedTypes) => ({
|
||||
id: deedTypes.uid!,
|
||||
primaryText: deedTypes.name,
|
||||
isActive: deedTypes.uid === deedTypeUid,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
bottomButton={{
|
||||
link: Module.getInstance().get().modules.pages.DeedTypes.pages.Create.props.path,
|
||||
text: "Créer une liste de pièces",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -1,30 +0,0 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
.root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
position: relative;
|
||||
.header {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.searchbar {
|
||||
padding: 40px 24px 24px 24px;
|
||||
}
|
||||
|
||||
.folderlist-container {
|
||||
max-height: calc(100vh - 290px);
|
||||
height: calc(100vh - 290px);
|
||||
overflow: auto;
|
||||
border-right: 1px solid var(--color-neutral-200);
|
||||
}
|
||||
|
||||
.create-container {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
import Module from "@Front/Config/Module";
|
||||
import { DocumentType } from "le-coffre-resources/dist/SuperAdmin";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import SearchBlockList from "@Front/Components/DesignSystem/SearchBlockList";
|
||||
|
||||
type IProps = {
|
||||
documentTypes: DocumentType[];
|
||||
onSelectedDocumentType?: (documentType: DocumentType) => void;
|
||||
onCloseLeftSide?: () => void;
|
||||
};
|
||||
|
||||
export default function DocumentTypeListContainer(props: IProps) {
|
||||
const router = useRouter();
|
||||
|
||||
const { documentTypeUid } = router.query;
|
||||
|
||||
const onSelectedBlock = useCallback(
|
||||
(block: IBlock) => {
|
||||
props.onCloseLeftSide && props.onCloseLeftSide();
|
||||
const redirectPath = Module.getInstance().get().modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path;
|
||||
router.push(redirectPath.replace("[uid]", block.id));
|
||||
},
|
||||
[props, router],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<SearchBlockList
|
||||
blocks={props.documentTypes.map((documentType) => {
|
||||
return {
|
||||
primaryText: documentType.name,
|
||||
id: documentType.uid!,
|
||||
isActive: documentType.uid === documentTypeUid,
|
||||
};
|
||||
})}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
bottomButton={{
|
||||
link: Module.getInstance().get().modules.pages.DocumentTypes.pages.Create.props.path,
|
||||
text: "Créer un type de document",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
@keyframes growWidth {
|
||||
0% {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 200%;
|
||||
}
|
||||
}
|
||||
|
||||
.root {
|
||||
.content {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
height: calc(100vh - var(--header-height));
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--color-generic-white);
|
||||
opacity: 0.5;
|
||||
z-index: 2;
|
||||
transition: all 0.3s $custom-easing;
|
||||
}
|
||||
|
||||
.left-side {
|
||||
background-color: var(--color-generic-white);
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
width: 336px;
|
||||
min-width: 336px;
|
||||
transition: all 0.3s $custom-easing;
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-width: ($screen-m - 1px)) {
|
||||
width: 56px;
|
||||
min-width: 56px;
|
||||
transform: translateX(-389px);
|
||||
|
||||
&.opened {
|
||||
transform: translateX(0px);
|
||||
width: 336px;
|
||||
min-width: 336px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
width: 0px;
|
||||
min-width: 0px;
|
||||
|
||||
&.opened {
|
||||
width: 100vw;
|
||||
min-width: 100vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.closable-left-side {
|
||||
position: absolute;
|
||||
background-color: var(--color-generic-white);
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-width: 56px;
|
||||
max-width: 56px;
|
||||
height: calc(100vh - var(--header-height));
|
||||
border-right: 1px var(--color-neutral-200) solid;
|
||||
|
||||
@media (min-width: $screen-m) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chevron-icon {
|
||||
margin-top: 21px;
|
||||
transform: rotate(180deg);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.right-side {
|
||||
min-width: calc(100vw - 389px);
|
||||
padding: 24px;
|
||||
overflow-y: auto;
|
||||
|
||||
@media (max-width: ($screen-m - 1px)) {
|
||||
min-width: calc(100vw - 56px);
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
flex: 1;
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
.back-arrow-mobile {
|
||||
display: none;
|
||||
@media (max-width: $screen-s) {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.back-arrow-desktop {
|
||||
@media (max-width: $screen-s) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,124 +1,57 @@
|
||||
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
||||
import DocumentTypes from "@Front/Api/LeCoffreApi/Notary/DocumentTypes/DocumentTypes";
|
||||
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import Header from "@Front/Components/DesignSystem/Header";
|
||||
import Version from "@Front/Components/DesignSystem/Version";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList";
|
||||
import JwtService from "@Front/Services/JwtService/JwtService";
|
||||
import WindowStore from "@Front/Stores/WindowStore";
|
||||
import classNames from "classnames";
|
||||
import DocumentTypes from "@Front/Api/LeCoffreApi/Notary/DocumentTypes/DocumentTypes";
|
||||
import { DocumentType } from "le-coffre-resources/dist/Notary";
|
||||
import Image from "next/image";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import DocumentTypeListContainer from "./DocumentTypeListContainer";
|
||||
import { ChevronLeftIcon } from "@heroicons/react/24/solid";
|
||||
type IProps = IPropsDashboardWithList;
|
||||
|
||||
type IProps = {
|
||||
title: string;
|
||||
children?: ReactNode;
|
||||
onSelectedDocumentType: (documentType: DocumentType) => void;
|
||||
hasBackArrow: boolean;
|
||||
backArrowUrl?: string;
|
||||
mobileBackText?: string;
|
||||
};
|
||||
type IState = {
|
||||
documentTypes: DocumentType[] | null;
|
||||
isLeftSideOpen: boolean;
|
||||
leftSideCanBeClosed: boolean;
|
||||
};
|
||||
|
||||
export default class DefaultDocumentTypesDashboard extends React.Component<IProps, IState> {
|
||||
private onWindowResize = () => {};
|
||||
public static defaultProps: Partial<IProps> = {
|
||||
hasBackArrow: false,
|
||||
};
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
documentTypes: null,
|
||||
isLeftSideOpen: false,
|
||||
leftSideCanBeClosed: typeof window !== "undefined" ? window.innerWidth < 1024 : false,
|
||||
};
|
||||
this.onOpenLeftSide = this.onOpenLeftSide.bind(this);
|
||||
this.onCloseLeftSide = this.onCloseLeftSide.bind(this);
|
||||
}
|
||||
|
||||
public override render(): JSX.Element {
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<Header isUserConnected={true} />
|
||||
<div className={classes["content"]}>
|
||||
{this.state.isLeftSideOpen && <div className={classes["overlay"]} onClick={this.onCloseLeftSide} />}
|
||||
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
|
||||
{this.state.documentTypes && (
|
||||
<DocumentTypeListContainer documentTypes={this.state.documentTypes} onCloseLeftSide={this.onCloseLeftSide} />
|
||||
)}
|
||||
</div>
|
||||
<div className={classNames(classes["closable-left-side"])}>
|
||||
<Image alt="open side menu" src={ChevronIcon} className={classes["chevron-icon"]} onClick={this.onOpenLeftSide} />
|
||||
</div>
|
||||
|
||||
<div className={classes["right-side"]}>
|
||||
{this.props.hasBackArrow && (
|
||||
<div className={classes["back-arrow-desktop"]}>
|
||||
<BackArrow url={this.props.backArrowUrl ?? ""} />
|
||||
</div>
|
||||
)}
|
||||
{this.props.mobileBackText && (
|
||||
<div className={classes["back-arrow-mobile"]}>
|
||||
<Button
|
||||
leftIcon={<ChevronLeftIcon />}
|
||||
variant={EButtonVariant.PRIMARY}
|
||||
styletype={EButtonstyletype.TEXT}
|
||||
onClick={this.onOpenLeftSide}>
|
||||
{this.props.mobileBackText ?? "Retour"}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
<Version />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public override async componentDidMount() {
|
||||
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
|
||||
export default function DefaultDocumentTypeDashboard(props: IProps) {
|
||||
const [documentTypes, setDocumentTypes] = React.useState<DocumentType[] | null>(null);
|
||||
const router = useRouter();
|
||||
const { documentTypeUid } = router.query;
|
||||
useEffect(() => {
|
||||
const jwt = JwtService.getInstance().decodeJwt();
|
||||
if (!jwt) return;
|
||||
const documentTypes = await DocumentTypes.getInstance().get({
|
||||
DocumentTypes.getInstance()
|
||||
.get({
|
||||
where: {
|
||||
office_uid: jwt.office_Id,
|
||||
},
|
||||
orderBy: {
|
||||
name: "asc",
|
||||
},
|
||||
});
|
||||
this.setState({ documentTypes });
|
||||
}
|
||||
})
|
||||
.then((documentTypes) => setDocumentTypes(documentTypes));
|
||||
}, []);
|
||||
|
||||
public override componentWillUnmount() {
|
||||
this.onWindowResize();
|
||||
}
|
||||
const onSelectedBlock = (block: IBlock) => {
|
||||
router.push(
|
||||
Module.getInstance().get().modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path.replace("[uid]", block.id),
|
||||
);
|
||||
};
|
||||
|
||||
private onOpenLeftSide() {
|
||||
this.setState({ isLeftSideOpen: true });
|
||||
}
|
||||
|
||||
private onCloseLeftSide() {
|
||||
if (!this.state.leftSideCanBeClosed) return;
|
||||
this.setState({ isLeftSideOpen: false });
|
||||
}
|
||||
|
||||
private onResize(window: Window) {
|
||||
if (window.innerWidth > 1023) {
|
||||
if (!this.state.leftSideCanBeClosed) return;
|
||||
this.setState({ leftSideCanBeClosed: false });
|
||||
}
|
||||
this.setState({ leftSideCanBeClosed: true });
|
||||
return (
|
||||
<DefaultDashboardWithList
|
||||
{...props}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
blocks={
|
||||
documentTypes
|
||||
? documentTypes.map((documentType) => ({
|
||||
id: documentType.uid!,
|
||||
primaryText: documentType.name,
|
||||
isActive: documentType.uid === documentTypeUid,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
bottomButton={{
|
||||
link: Module.getInstance().get().modules.pages.DocumentTypes.pages.Create.props.path,
|
||||
text: "Créer un type de document",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import { useRouter } from "next/router";
|
||||
import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList";
|
||||
import { useMemo } from "react";
|
||||
import Module from "@Front/Config/Module";
|
||||
|
||||
type IProps = IPropsDashboardWithList;
|
||||
|
||||
export enum ELegalOptions {
|
||||
LEGAL_MENTIONS = "mentions-legales",
|
||||
CGU = "cgu",
|
||||
CGS = "cgs",
|
||||
POLITIQUE_DE_CONFIDENTIALITE = "politique-de-confidentialite",
|
||||
POLITIQUE_DE_GESTION_DES_COOKIES = "politique-de-gestion-des-cookies",
|
||||
}
|
||||
|
||||
export default function DefaultLegalDashboard(props: IProps) {
|
||||
const router = useRouter();
|
||||
const { legalUid } = router.query;
|
||||
|
||||
const onSelectedBlock = (block: IBlock) => {
|
||||
router.push(Module.getInstance().get().modules.pages.Legal.pages.LegalInformations.props.path.replace("[legalUid]", block.id));
|
||||
};
|
||||
|
||||
const blocks: IBlock[] = useMemo<IBlock[]>(
|
||||
() => [
|
||||
{
|
||||
id: ELegalOptions.LEGAL_MENTIONS,
|
||||
primaryText: "Mentions légales",
|
||||
isActive: legalUid === ELegalOptions.LEGAL_MENTIONS,
|
||||
},
|
||||
{
|
||||
id: ELegalOptions.CGU,
|
||||
primaryText: "CGU",
|
||||
isActive: legalUid === ELegalOptions.CGU,
|
||||
},
|
||||
{
|
||||
id: ELegalOptions.CGS,
|
||||
primaryText: "CGS",
|
||||
isActive: legalUid === ELegalOptions.CGS,
|
||||
},
|
||||
{
|
||||
id: ELegalOptions.POLITIQUE_DE_CONFIDENTIALITE,
|
||||
primaryText: "Politique de confidentialité",
|
||||
isActive: legalUid === ELegalOptions.POLITIQUE_DE_CONFIDENTIALITE,
|
||||
},
|
||||
{
|
||||
id: ELegalOptions.POLITIQUE_DE_GESTION_DES_COOKIES,
|
||||
primaryText: "Politique de gestion des cookies",
|
||||
isActive: legalUid === ELegalOptions.POLITIQUE_DE_GESTION_DES_COOKIES,
|
||||
},
|
||||
],
|
||||
[legalUid],
|
||||
);
|
||||
|
||||
return <DefaultDashboardWithList {...props} onSelectedBlock={onSelectedBlock} blocks={blocks} noPadding />;
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
.root {
|
||||
position: relative;
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
height: calc(100vh - var(--header-height));
|
||||
|
||||
@media (max-width: $screen-m) {
|
||||
flex-direction: column;
|
||||
}
|
||||
.right-side {
|
||||
min-width: calc(100% - 336px);
|
||||
overflow-y: auto;
|
||||
padding: var(--spacing-lg, 24px);
|
||||
|
||||
@media (max-width: $screen-m) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +1,77 @@
|
||||
import Folders, { IGetFoldersParams } from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
|
||||
import FolderListContainer from "@Front/Components/DesignSystem/FolderListContainer";
|
||||
import Header from "@Front/Components/DesignSystem/Header";
|
||||
import Version from "@Front/Components/DesignSystem/Version";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus";
|
||||
import { OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||
import React, { ReactNode, useEffect } from "react";
|
||||
import React, { useCallback, useEffect } from "react";
|
||||
import { EDocumentStatus } from "le-coffre-resources/dist/Notary/Document";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import { useRouter } from "next/router";
|
||||
import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList";
|
||||
|
||||
type IProps = {
|
||||
title: string;
|
||||
children?: ReactNode;
|
||||
type IProps = IPropsDashboardWithList & {
|
||||
isArchived?: boolean;
|
||||
hasBackArrow?: boolean;
|
||||
backArrowUrl?: string;
|
||||
mobileBackText?: string;
|
||||
};
|
||||
|
||||
export default function DefaultNotaryDashboard(props: IProps) {
|
||||
const { hasBackArrow, backArrowUrl, children, isArchived } = props;
|
||||
|
||||
const { isArchived = false } = props;
|
||||
const router = useRouter();
|
||||
const [folders, setFolders] = React.useState<OfficeFolder[]>([]);
|
||||
const { folderUid } = router.query;
|
||||
|
||||
const redirectPath: string = isArchived
|
||||
? Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.pages.FolderInformation.props.path
|
||||
: Module.getInstance().get().modules.pages.Folder.pages.FolderInformation.props.path;
|
||||
|
||||
const getBlocks = useCallback(
|
||||
(folders: OfficeFolder[]): IBlock[] => {
|
||||
const pendingFolders = folders
|
||||
.filter((folder) => {
|
||||
const pendingDocuments = (folder.documents ?? []).filter(
|
||||
(document) => document.document_status === EDocumentStatus.DEPOSITED,
|
||||
);
|
||||
return pendingDocuments.length >= 1;
|
||||
})
|
||||
.sort((folder1, folder2) => {
|
||||
return folder1.created_at! > folder2.created_at! ? -1 : 1;
|
||||
});
|
||||
|
||||
const otherFolders = folders
|
||||
.filter((folder) => {
|
||||
const pendingDocuments = (folder.documents ?? []).filter(
|
||||
(document) => document.document_status === EDocumentStatus.DEPOSITED,
|
||||
);
|
||||
return pendingDocuments.length === 0;
|
||||
})
|
||||
.sort((folder1, folder2) => {
|
||||
return folder1.created_at! > folder2.created_at! ? -1 : 1;
|
||||
});
|
||||
|
||||
return [...pendingFolders, ...otherFolders].map((folder) => {
|
||||
return {
|
||||
id: folder.uid!,
|
||||
primaryText: folder.name,
|
||||
secondaryText: folder.folder_number,
|
||||
isActive: folderUid === folder.uid,
|
||||
showAlert: folder.documents?.some((document) => document.document_status === EDocumentStatus.DEPOSITED),
|
||||
};
|
||||
});
|
||||
},
|
||||
[folderUid],
|
||||
);
|
||||
|
||||
const [blocks, setBlocks] = React.useState<IBlock[]>(getBlocks(folders));
|
||||
|
||||
const onSelectedBlock = (block: IBlock) => {
|
||||
const folder = folders.find((folder) => folder.uid === block.id);
|
||||
if (!folder) return;
|
||||
const path = redirectPath.replace("[folderUid]", folder.uid ?? "");
|
||||
router.push(path);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setBlocks(getBlocks(folders));
|
||||
}, [folders, getBlocks]);
|
||||
|
||||
useEffect(() => {
|
||||
let targetedStatus: EFolderStatus = EFolderStatus["LIVE" as keyof typeof EFolderStatus];
|
||||
@ -63,20 +113,14 @@ export default function DefaultNotaryDashboard(props: IProps) {
|
||||
}, [isArchived]);
|
||||
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<Header isUserConnected={true} />
|
||||
<div className={classes["content"]}>
|
||||
<FolderListContainer folders={folders} isArchived={isArchived ?? false} />
|
||||
<div className={classes["right-side"]}>
|
||||
{hasBackArrow && (
|
||||
<div className={classes["back-arrow-desktop"]}>
|
||||
<BackArrow url={backArrowUrl ?? ""} />
|
||||
</div>
|
||||
)}
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
<Version />
|
||||
</div>
|
||||
<DefaultDashboardWithList
|
||||
{...props}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
blocks={blocks}
|
||||
bottomButton={{
|
||||
link: Module.getInstance().get().modules.pages.Folder.pages.CreateFolder.props.path,
|
||||
text: "Créer un dossier",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export default function DefaultOfficeDashboard(props: IProps) {
|
||||
<DefaultDashboardWithList
|
||||
{...props}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
blocksList={
|
||||
blocks={
|
||||
offices
|
||||
? offices.map((office) => ({
|
||||
id: office.uid!,
|
||||
|
@ -1,32 +0,0 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
.root {
|
||||
width: calc(100vh - 83px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
position: relative;
|
||||
|
||||
.header {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.searchbar {
|
||||
padding: 40px 24px 24px 24px;
|
||||
}
|
||||
|
||||
.folderlist-container {
|
||||
max-height: calc(100vh - 215px);
|
||||
height: calc(100vh - 215px);
|
||||
overflow: auto;
|
||||
border-right: 1px solid var(--color-neutral-200);
|
||||
}
|
||||
|
||||
.create-container {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
import Module from "@Front/Config/Module";
|
||||
import { OfficeRole } from "le-coffre-resources/dist/Admin";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useCallback } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import SearchBlockList from "@Front/Components/DesignSystem/SearchBlockList";
|
||||
|
||||
type IProps = {
|
||||
roles: OfficeRole[];
|
||||
onSelectedRole?: (role: OfficeRole) => void;
|
||||
onCloseLeftSide?: () => void;
|
||||
};
|
||||
|
||||
export default function RoleListContainer(props: IProps) {
|
||||
const router = useRouter();
|
||||
|
||||
const { roleUid } = router.query;
|
||||
|
||||
const onSelectedBlock = useCallback(
|
||||
(block: IBlock) => {
|
||||
props.onCloseLeftSide && props.onCloseLeftSide();
|
||||
const redirectPath = Module.getInstance().get().modules.pages.Roles.pages.RolesInformations.props.path;
|
||||
router.push(redirectPath.replace("[uid]", block.id));
|
||||
},
|
||||
[props, router],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<SearchBlockList
|
||||
blocks={props.roles
|
||||
.filter((role) => {
|
||||
if (role.name === "admin") return false;
|
||||
return true;
|
||||
})
|
||||
.map((role) => {
|
||||
return {
|
||||
primaryText: role.name,
|
||||
id: role.uid!,
|
||||
isActive: role.uid === roleUid,
|
||||
};
|
||||
})}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
bottomButton={{
|
||||
link: Module.getInstance().get().modules.pages.Roles.pages.Create.props.path,
|
||||
text: "Créer un rôle",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
@keyframes growWidth {
|
||||
0% {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 200%;
|
||||
}
|
||||
}
|
||||
|
||||
.root {
|
||||
.content {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
height: calc(100vh - var(--header-height));
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--color-generic-white);
|
||||
opacity: 0.5;
|
||||
z-index: 2;
|
||||
transition: all 0.3s $custom-easing;
|
||||
}
|
||||
|
||||
.left-side {
|
||||
background-color: var(--color-generic-white);
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
width: 336px;
|
||||
min-width: 336px;
|
||||
transition: all 0.3s $custom-easing;
|
||||
overflow: hidden;
|
||||
|
||||
@media (max-width: ($screen-m - 1px)) {
|
||||
width: 56px;
|
||||
min-width: 56px;
|
||||
transform: translateX(-389px);
|
||||
|
||||
&.opened {
|
||||
transform: translateX(0px);
|
||||
width: 336px;
|
||||
min-width: 336px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
width: 0px;
|
||||
min-width: 0px;
|
||||
|
||||
&.opened {
|
||||
width: 100vw;
|
||||
min-width: 100vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.closable-left-side {
|
||||
position: absolute;
|
||||
background-color: var(--color-generic-white);
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-width: 56px;
|
||||
max-width: 56px;
|
||||
height: calc(100vh - var(--header-height));
|
||||
border-right: 1px var(--color-neutral-200) solid;
|
||||
|
||||
@media (min-width: $screen-m) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chevron-icon {
|
||||
margin-top: 21px;
|
||||
transform: rotate(180deg);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.right-side {
|
||||
min-width: calc(100vw - 389px);
|
||||
padding: 24px;
|
||||
overflow-y: auto;
|
||||
|
||||
@media (max-width: ($screen-m - 1px)) {
|
||||
min-width: calc(100vw - 56px);
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
flex: 1;
|
||||
min-width: unset;
|
||||
}
|
||||
|
||||
.back-arrow-mobile {
|
||||
display: none;
|
||||
@media (max-width: $screen-s) {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.back-arrow-desktop {
|
||||
@media (max-width: $screen-s) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,117 +1,49 @@
|
||||
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
import { useRouter } from "next/router";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||
import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList";
|
||||
import { OfficeRole } from "le-coffre-resources/dist/Notary";
|
||||
import OfficeRoles, { IGetRolesParams } from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
|
||||
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import Header from "@Front/Components/DesignSystem/Header";
|
||||
import Version from "@Front/Components/DesignSystem/Version";
|
||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||
import WindowStore from "@Front/Stores/WindowStore";
|
||||
import classNames from "classnames";
|
||||
import { OfficeRole } from "le-coffre-resources/dist/Admin";
|
||||
import Image from "next/image";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import RoleListContainer from "./RoleListContainer";
|
||||
import { ChevronLeftIcon } from "@heroicons/react/24/outline";
|
||||
type IProps = IPropsDashboardWithList;
|
||||
|
||||
type IProps = {
|
||||
title: string;
|
||||
children?: ReactNode;
|
||||
onSelectedRole: (role: OfficeRole) => void;
|
||||
hasBackArrow: boolean;
|
||||
backArrowUrl?: string;
|
||||
mobileBackText?: string;
|
||||
};
|
||||
type IState = {
|
||||
roles: OfficeRole[] | null;
|
||||
isLeftSideOpen: boolean;
|
||||
leftSideCanBeClosed: boolean;
|
||||
};
|
||||
|
||||
export default class DefaultRoleDashboard extends React.Component<IProps, IState> {
|
||||
private onWindowResize = () => {};
|
||||
public static defaultProps: Partial<IProps> = {
|
||||
hasBackArrow: false,
|
||||
};
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
roles: null,
|
||||
isLeftSideOpen: false,
|
||||
leftSideCanBeClosed: typeof window !== "undefined" ? window.innerWidth < 1024 : false,
|
||||
};
|
||||
this.onOpenLeftSide = this.onOpenLeftSide.bind(this);
|
||||
this.onCloseLeftSide = this.onCloseLeftSide.bind(this);
|
||||
}
|
||||
|
||||
public override render(): JSX.Element {
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<Header isUserConnected={true} />
|
||||
<div className={classes["content"]}>
|
||||
{this.state.isLeftSideOpen && <div className={classes["overlay"]} onClick={this.onCloseLeftSide} />}
|
||||
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
|
||||
{this.state.roles && <RoleListContainer roles={this.state.roles} onCloseLeftSide={this.onCloseLeftSide} />}
|
||||
</div>
|
||||
<div className={classNames(classes["closable-left-side"])}>
|
||||
<Image alt="open side menu" src={ChevronIcon} className={classes["chevron-icon"]} onClick={this.onOpenLeftSide} />
|
||||
</div>
|
||||
|
||||
<div className={classes["right-side"]}>
|
||||
{this.props.hasBackArrow && (
|
||||
<div className={classes["back-arrow-desktop"]}>
|
||||
<BackArrow url={this.props.backArrowUrl ?? ""} />
|
||||
</div>
|
||||
)}
|
||||
{this.props.mobileBackText && (
|
||||
<div className={classes["back-arrow-mobile"]}>
|
||||
<Button
|
||||
leftIcon={<ChevronLeftIcon />}
|
||||
variant={EButtonVariant.PRIMARY}
|
||||
styletype={EButtonstyletype.TEXT}
|
||||
onClick={this.onOpenLeftSide}>
|
||||
{this.props.mobileBackText ?? "Retour"}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
<Version />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
public override async componentDidMount() {
|
||||
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
|
||||
export default function DefaultRoleDashboard(props: IProps) {
|
||||
const [roles, setRoles] = React.useState<OfficeRole[] | null>(null);
|
||||
const router = useRouter();
|
||||
const { roleUid } = router.query;
|
||||
useEffect(() => {
|
||||
const query: IGetRolesParams = {
|
||||
include: { rules: true },
|
||||
};
|
||||
|
||||
const roles = await OfficeRoles.getInstance().get(query);
|
||||
OfficeRoles.getInstance()
|
||||
.get(query)
|
||||
.then((roles) => setRoles(roles));
|
||||
}, []);
|
||||
|
||||
this.setState({ roles });
|
||||
}
|
||||
const onSelectedBlock = (block: IBlock) => {
|
||||
router.push(Module.getInstance().get().modules.pages.Roles.pages.RolesInformations.props.path.replace("[uid]", block.id));
|
||||
};
|
||||
|
||||
public override componentWillUnmount() {
|
||||
this.onWindowResize();
|
||||
}
|
||||
|
||||
private onOpenLeftSide() {
|
||||
this.setState({ isLeftSideOpen: true });
|
||||
}
|
||||
|
||||
private onCloseLeftSide() {
|
||||
if (!this.state.leftSideCanBeClosed) return;
|
||||
this.setState({ isLeftSideOpen: false });
|
||||
}
|
||||
|
||||
private onResize(window: Window) {
|
||||
if (window.innerWidth > 1023) {
|
||||
if (!this.state.leftSideCanBeClosed) return;
|
||||
this.setState({ leftSideCanBeClosed: false });
|
||||
}
|
||||
this.setState({ leftSideCanBeClosed: true });
|
||||
return (
|
||||
<DefaultDashboardWithList
|
||||
{...props}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
blocks={
|
||||
roles
|
||||
? roles.map((role) => ({
|
||||
id: role.uid!,
|
||||
primaryText: role.name,
|
||||
isActive: role.uid === roleUid,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
bottomButton={{
|
||||
link: Module.getInstance().get().modules.pages.Roles.pages.Create.props.path,
|
||||
text: "Créer un rôle",
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ export default function DefaultUserDashboard(props: IProps) {
|
||||
<DefaultDashboardWithList
|
||||
{...props}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
blocksList={
|
||||
blocks={
|
||||
users
|
||||
? users.map((user) => ({
|
||||
id: user.uid!,
|
||||
|
@ -0,0 +1,11 @@
|
||||
.pdf-viewer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
min-width: 100%;
|
||||
|
||||
.no-pdf-text {
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
import { useRouter } from "next/router";
|
||||
import React from "react";
|
||||
import classes from "./classes.module.scss";
|
||||
import DefaultLegalDashboard, { ELegalOptions } from "@Front/Components/LayoutTemplates/DefaultLegalDashboard";
|
||||
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import Link from "next/link";
|
||||
|
||||
const pdfLinks: Record<ELegalOptions, string> = {
|
||||
"mentions-legales": "https://s3.fr-par.scw.cloud/lecoffre.io-bucket/footer/mentions_legales.pdf",
|
||||
"politique-de-confidentialite": "https://s3.fr-par.scw.cloud/lecoffre.io-bucket/footer/politique_confidentialite.pdf",
|
||||
"politique-de-gestion-des-cookies": "https://s3.fr-par.scw.cloud/lecoffre.io-bucket/footer/politique_cookies.pdf",
|
||||
cgs: "https://s3.fr-par.scw.cloud/lecoffre.io-bucket/footer/cgs.pdf",
|
||||
cgu: "https://s3.fr-par.scw.cloud/lecoffre.io-bucket/footer/cgu.pdf",
|
||||
};
|
||||
|
||||
export default function LegalInformations() {
|
||||
const router = useRouter();
|
||||
let { legalUid } = router.query;
|
||||
const legalUidTyped = legalUid as ELegalOptions;
|
||||
return (
|
||||
<DefaultLegalDashboard>
|
||||
<object data={pdfLinks[legalUidTyped]} type="application/pdf" width="100%" height="100%" className={classes["pdf-viewer"]}>
|
||||
<Typography typo={ETypo.TEXT_LG_LIGHT} className={classes["no-pdf-text"]}>
|
||||
Votre navigateur ne prend pas en charge l'affichage des pdf
|
||||
<Typography typo={ETypo.TEXT_LG_LIGHT} type="span">
|
||||
<Link href={pdfLinks[legalUidTyped]} target="_blank" style={{ color: `var(${ETypoColor.COLOR_PRIMARY_500})` }}>
|
||||
cliquez ici pour télécharger le pdf.
|
||||
</Link>
|
||||
</Typography>
|
||||
</Typography>
|
||||
</object>
|
||||
</DefaultLegalDashboard>
|
||||
);
|
||||
}
|
23
src/front/Components/Layouts/Legal/index.tsx
Normal file
23
src/front/Components/Layouts/Legal/index.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import DefaultLegalDashboard, { ELegalOptions } from "@Front/Components/LayoutTemplates/DefaultLegalDashboard";
|
||||
import { useRouter } from "next/router";
|
||||
import Module from "@Front/Config/Module";
|
||||
import { useEffect } from "react";
|
||||
|
||||
type IProps = {};
|
||||
|
||||
export default function Legal(props: IProps) {
|
||||
const router = useRouter();
|
||||
const { legalUid } = router.query;
|
||||
|
||||
useEffect(() => {
|
||||
if (!legalUid && router.isReady) {
|
||||
router.push(
|
||||
Module.getInstance()
|
||||
.get()
|
||||
.modules.pages.Legal.pages.LegalInformations.props.path.replace("[legalUid]", ELegalOptions.LEGAL_MENTIONS),
|
||||
);
|
||||
}
|
||||
}, [legalUid, router]);
|
||||
|
||||
return <DefaultLegalDashboard />;
|
||||
}
|
@ -390,6 +390,22 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Legal": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/legal",
|
||||
"labelKey": "legal"
|
||||
},
|
||||
"pages": {
|
||||
"LegalInformations": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/legal/[legalUid]",
|
||||
"labelKey": "legal_informations"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -390,6 +390,22 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Legal": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/legal",
|
||||
"labelKey": "legal"
|
||||
},
|
||||
"pages": {
|
||||
"LegalInformations": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/legal/[legalUid]",
|
||||
"labelKey": "legal_informations"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -390,6 +390,22 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Legal": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/legal",
|
||||
"labelKey": "legal"
|
||||
},
|
||||
"pages": {
|
||||
"LegalInformations": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/legal/[legalUid]",
|
||||
"labelKey": "legal_informations"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -390,6 +390,22 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Legal": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/legal",
|
||||
"labelKey": "legal"
|
||||
},
|
||||
"pages": {
|
||||
"LegalInformations": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/legal/[legalUid]",
|
||||
"labelKey": "legal_informations"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
5
src/pages/legal/[legalUid]/index.tsx
Normal file
5
src/pages/legal/[legalUid]/index.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import LegalInformations from "@Front/Components/Layouts/Legal/LegalInformations";
|
||||
|
||||
export default function Route() {
|
||||
return <LegalInformations />;
|
||||
}
|
5
src/pages/legal/index.tsx
Normal file
5
src/pages/legal/index.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import Legal from "@Front/Components/Layouts/Legal";
|
||||
|
||||
export default function Route() {
|
||||
return <Legal />;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user