✨ Refacto users super admin
This commit is contained in:
parent
791aeacfc4
commit
6870ffd47c
@ -16,6 +16,16 @@ export default function DropdownNavigation({ blocks, onSelectedBlock, defaultSel
|
|||||||
if (defaultSelectedBlock) setSelectedBlock(defaultSelectedBlock);
|
if (defaultSelectedBlock) setSelectedBlock(defaultSelectedBlock);
|
||||||
}, [defaultSelectedBlock]);
|
}, [defaultSelectedBlock]);
|
||||||
|
|
||||||
|
const handleDropDownSelect = (option: IOption) => {
|
||||||
|
const block = blocks.find((block) => block.id === option.id);
|
||||||
|
if (block) {
|
||||||
|
setSelectedBlock(block);
|
||||||
|
onSelectedBlock
|
||||||
|
? onSelectedBlock(block)
|
||||||
|
: console.error("DropdownNavigation: onSelectedBlock prop is required to handle block selection");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes["root"]}>
|
<div className={classes["root"]}>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
@ -28,6 +38,7 @@ export default function DropdownNavigation({ blocks, onSelectedBlock, defaultSel
|
|||||||
},
|
},
|
||||||
} as IOption;
|
} as IOption;
|
||||||
})}
|
})}
|
||||||
|
onSelect={handleDropDownSelect}
|
||||||
selectedOption={selectedBlock ? { id: selectedBlock.id, label: selectedBlock.primaryText } : undefined}
|
selectedOption={selectedBlock ? { id: selectedBlock.id, label: selectedBlock.primaryText } : undefined}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
|
||||||
@media (max-width: $screen-m) {
|
@media (max-width: $screen-m) {
|
||||||
|
height: auto;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
padding: var(--spacing-lg, 24px);
|
padding: var(--spacing-lg, 24px);
|
||||||
width: auto;
|
width: auto;
|
||||||
|
@ -1,115 +1,22 @@
|
|||||||
@import "@Themes/constants.scss";
|
@import "@Themes/constants.scss";
|
||||||
|
|
||||||
@keyframes growWidth {
|
|
||||||
0% {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
width: 200%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.root {
|
.root {
|
||||||
|
position: relative;
|
||||||
.content {
|
.content {
|
||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
justify-content: flex-start;
|
||||||
height: calc(100vh - var(--header-height));
|
height: calc(100vh - var(--header-height));
|
||||||
|
|
||||||
.overlay {
|
@media (max-width: $screen-m) {
|
||||||
position: absolute;
|
flex-direction: column;
|
||||||
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 {
|
.right-side {
|
||||||
min-width: calc(100vw - 389px);
|
min-width: calc(100% - 336px);
|
||||||
padding: 24px;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
padding: var(--spacing-lg, 24px);
|
||||||
|
|
||||||
@media (max-width: ($screen-m - 1px)) {
|
@media (max-width: $screen-m) {
|
||||||
min-width: calc(100vw - 56px);
|
width: 100%;
|
||||||
}
|
|
||||||
|
|
||||||
@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,115 +1,67 @@
|
|||||||
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
|
||||||
import { ChevronLeftIcon } from "@heroicons/react/20/solid";
|
|
||||||
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
|
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
|
||||||
import Button, { EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
|
||||||
import Header from "@Front/Components/DesignSystem/Header";
|
import Header from "@Front/Components/DesignSystem/Header";
|
||||||
import Version from "@Front/Components/DesignSystem/Version";
|
import Version from "@Front/Components/DesignSystem/Version";
|
||||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||||
import WindowStore from "@Front/Stores/WindowStore";
|
|
||||||
import classNames from "classnames";
|
|
||||||
import User from "le-coffre-resources/dist/SuperAdmin";
|
import User from "le-coffre-resources/dist/SuperAdmin";
|
||||||
import Image from "next/image";
|
import React, { ReactNode, useEffect } from "react";
|
||||||
import React, { ReactNode } from "react";
|
|
||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import UserListContainer from "./UserListContainer";
|
import SearchBlockList from "@Front/Components/DesignSystem/SearchBlockList";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import Module from "@Front/Config/Module";
|
||||||
|
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
title: string;
|
title: string;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
onSelectedUser: (user: User) => void;
|
hasBackArrow?: boolean;
|
||||||
hasBackArrow: boolean;
|
|
||||||
backArrowUrl?: string;
|
backArrowUrl?: string;
|
||||||
mobileBackText?: string;
|
|
||||||
};
|
|
||||||
type IState = {
|
|
||||||
users: User[] | null;
|
|
||||||
isLeftSideOpen: boolean;
|
|
||||||
leftSideCanBeClosed: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class DefaultUserDashboard extends React.Component<IProps, IState> {
|
export default function DefaultUserDashboard(props: IProps) {
|
||||||
private onWindowResize = () => {};
|
const { hasBackArrow, children, backArrowUrl } = props;
|
||||||
public static defaultProps: Partial<IProps> = {
|
const [users, setUsers] = React.useState<User[] | null>(null);
|
||||||
hasBackArrow: false,
|
const router = useRouter();
|
||||||
|
useEffect(() => {
|
||||||
|
const query: IGetUsersparams = {
|
||||||
|
include: { contact: true },
|
||||||
};
|
};
|
||||||
|
|
||||||
public constructor(props: IProps) {
|
Users.getInstance()
|
||||||
super(props);
|
.get(query)
|
||||||
this.state = {
|
.then((users) => setUsers(users));
|
||||||
users: null,
|
}, []);
|
||||||
isLeftSideOpen: false,
|
|
||||||
leftSideCanBeClosed: typeof window !== "undefined" ? window.innerWidth < 1024 : false,
|
const onSelectedBlock = (block: IBlock) => {
|
||||||
};
|
router.push(Module.getInstance().get().modules.pages.Users.pages.UsersInformations.props.path.replace("[uid]", block.id));
|
||||||
this.onOpenLeftSide = this.onOpenLeftSide.bind(this);
|
};
|
||||||
this.onCloseLeftSide = this.onCloseLeftSide.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override render(): JSX.Element {
|
|
||||||
return (
|
return (
|
||||||
<div className={classes["root"]}>
|
<div className={classes["root"]}>
|
||||||
<Header isUserConnected={true} />
|
<Header isUserConnected={true} />
|
||||||
<div className={classes["content"]}>
|
<div className={classes["content"]}>
|
||||||
{this.state.isLeftSideOpen && <div className={classes["overlay"]} onClick={this.onCloseLeftSide} />}
|
{users && (
|
||||||
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
|
<SearchBlockList
|
||||||
{this.state.users && <UserListContainer users={this.state.users} onCloseLeftSide={this.onCloseLeftSide} />}
|
blocks={users.map((user) => {
|
||||||
</div>
|
return {
|
||||||
<div className={classNames(classes["closable-left-side"])}>
|
id: user.uid,
|
||||||
<Image alt="open side menu" src={ChevronIcon} className={classes["chevron-icon"]} onClick={this.onOpenLeftSide} />
|
primaryText: user.contact?.first_name + " " + user.contact?.last_name,
|
||||||
</div>
|
secondaryText: user.contact?.email,
|
||||||
|
} as IBlock;
|
||||||
|
})}
|
||||||
|
onSelectedBlock={onSelectedBlock}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<div className={classes["right-side"]}>
|
<div className={classes["right-side"]}>
|
||||||
{this.props.hasBackArrow && (
|
{hasBackArrow && (
|
||||||
<div className={classes["back-arrow-desktop"]}>
|
<div className={classes["back-arrow-desktop"]}>
|
||||||
<BackArrow url={this.props.backArrowUrl ?? ""} />
|
<BackArrow url={backArrowUrl ?? ""} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{this.props.mobileBackText && (
|
{children}
|
||||||
<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>
|
||||||
</div>
|
</div>
|
||||||
<Version />
|
<Version />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async componentDidMount() {
|
|
||||||
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
|
|
||||||
const query: IGetUsersparams = {
|
|
||||||
include: { contact: true },
|
|
||||||
};
|
|
||||||
|
|
||||||
const users = await Users.getInstance().get(query);
|
|
||||||
this.setState({ users });
|
|
||||||
}
|
|
||||||
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 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,7 @@ type IState = {};
|
|||||||
export default class Users extends BasePage<IProps, IState> {
|
export default class Users extends BasePage<IProps, IState> {
|
||||||
public override render(): JSX.Element {
|
public override render(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<DefaultUserDashboard title={"Dossier"} mobileBackText={"Liste des utilisateurs"}>
|
<DefaultUserDashboard title={"Dossier"}>
|
||||||
<div className={classes["root"]}>
|
<div className={classes["root"]}>
|
||||||
<div className={classes["no-folder-selected"]}>
|
<div className={classes["no-folder-selected"]}>
|
||||||
<Typography typo={ETypo.TITLE_H1}>Informations des utilisateurs</Typography>
|
<Typography typo={ETypo.TITLE_H1}>Informations des utilisateurs</Typography>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user