✨ Super admin page users
This commit is contained in:
parent
a5d74176d5
commit
9332016dc1
91
src/front/Api/LeCoffreApi/Admin/Users/Users.ts
Normal file
91
src/front/Api/LeCoffreApi/Admin/Users/Users.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import User from "le-coffre-resources/dist/SuperAdmin";
|
||||
import BaseAdmin from "../BaseAdmin";
|
||||
|
||||
// TODO Type get query params -> Where + inclue + orderby
|
||||
export interface IGetUsersparams {
|
||||
where?: {};
|
||||
include?: {};
|
||||
select?: {};
|
||||
}
|
||||
|
||||
// TODO Type getbyuid query params
|
||||
|
||||
export type IPutUsersParams = {
|
||||
uid?: User["uid"];
|
||||
idNot?: User["idNot"];
|
||||
contact?: User["contact"];
|
||||
office_membership?: User["office_membership"];
|
||||
documents?: User["documents"];
|
||||
};
|
||||
|
||||
export default class Users extends BaseAdmin {
|
||||
private static instance: Users;
|
||||
private readonly baseURl = this.namespaceUrl.concat("/users");
|
||||
|
||||
private constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static getInstance() {
|
||||
if (!this.instance) {
|
||||
return new this();
|
||||
} else {
|
||||
return this.instance;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Get all Users
|
||||
*/
|
||||
public async get(q: IGetUsersparams): Promise<User[]> {
|
||||
const url = new URL(this.baseURl);
|
||||
const query = { q };
|
||||
Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
|
||||
try {
|
||||
return await this.getRequest<User[]>(url);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Get a folder by uid
|
||||
*/
|
||||
public async getByUid(uid: string, q?: any): Promise<User> {
|
||||
const url = new URL(this.baseURl.concat(`/${uid}`));
|
||||
if (q) Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
|
||||
try {
|
||||
return await this.getRequest<User>(url);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description : Create a User
|
||||
*/
|
||||
// public async post(body: IPostDeedsParams): Promise<OfficeFolder> {
|
||||
// const url = new URL(this.baseURl);
|
||||
// try {
|
||||
// return await this.postRequest<OfficeFolder>(url, body);
|
||||
// } catch (err) {
|
||||
// this.onError(err);
|
||||
// return Promise.reject(err);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* @description : Update the folder description
|
||||
*/
|
||||
public async put(uid: string, body: IPutUsersParams): Promise<User> {
|
||||
const url = new URL(this.baseURl.concat(`/${uid}`));
|
||||
try {
|
||||
return await this.putRequest<User>(url, body);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@ import Image from "next/image";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
|
||||
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/Admin/Users/Users";
|
||||
import User from "le-coffre-resources/dist/Notary";
|
||||
import CollaboratorListContainer from "./CollaboratorListContainer";
|
||||
|
||||
@ -88,7 +88,7 @@ export default class DefaultCollaboratorDashboard extends React.Component<IProps
|
||||
public override async componentDidMount() {
|
||||
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
|
||||
const query: IGetUsersparams = {
|
||||
where: { office_uid: "6981326f-8a0a-4437-b15c-4cd5c4d80f6e" },
|
||||
where: { office_uid: "2af8694e-4dac-4e0d-854a-acb7fed8aa7d" },
|
||||
include: { contact: true },
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
@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 {
|
||||
height: 100%;
|
||||
border-right: 1px solid var(--grey-medium);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
import BlockList, { IBlock } from "@Front/Components/DesignSystem/BlockList";
|
||||
import SearchBar from "@Front/Components/DesignSystem/SearchBar";
|
||||
import Module from "@Front/Config/Module";
|
||||
import User from "le-coffre-resources/dist/Notary";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useCallback, useState } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
|
||||
type IProps = {
|
||||
users: User[];
|
||||
onSelectedUser?: (user: User) => void;
|
||||
onCloseLeftSide?: () => void;
|
||||
};
|
||||
|
||||
export default function UserListContainer(props: IProps) {
|
||||
const [filteredUsers, setFilteredUsers] = useState<User[]>(props.users);
|
||||
const router = useRouter();
|
||||
|
||||
const { userUid } = router.query;
|
||||
const filterUsers = useCallback(
|
||||
(input: string) => {
|
||||
const filteredUsers = props.users.filter((user) => {
|
||||
return (
|
||||
user.contact?.first_name?.toLowerCase().includes(input.toLowerCase()) ||
|
||||
user.contact?.last_name?.toLowerCase().includes(input.toLowerCase())
|
||||
);
|
||||
});
|
||||
setFilteredUsers(filteredUsers);
|
||||
},
|
||||
[props.users],
|
||||
);
|
||||
|
||||
const onSelectedBlock = useCallback(
|
||||
(block: IBlock) => {
|
||||
props.onCloseLeftSide && props.onCloseLeftSide();
|
||||
const redirectPath = Module.getInstance().get().modules.pages.Users.pages.UsersInformations.props.path;
|
||||
router.push(redirectPath.replace("[uid]", block.id));
|
||||
},
|
||||
[props, router],
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["header"]}>
|
||||
<div className={classes["searchbar"]}>
|
||||
<SearchBar onChange={filterUsers} placeholder="Chercher un utilisateur" />
|
||||
</div>
|
||||
<div className={classes["folderlist-container"]}>
|
||||
<BlockList
|
||||
blocks={filteredUsers.map((user) => {
|
||||
return {
|
||||
name: user.contact?.first_name + " " + user.contact?.last_name,
|
||||
id: user.uid!,
|
||||
selected: user.uid === userUid,
|
||||
};
|
||||
})}
|
||||
onSelectedBlock={onSelectedBlock}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
@keyframes growWidth {
|
||||
0% {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
100% {
|
||||
width: 200%;
|
||||
}
|
||||
}
|
||||
|
||||
.root {
|
||||
.content {
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
height: calc(100vh - 83px);
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--white);
|
||||
opacity: 0.5;
|
||||
z-index: 2;
|
||||
transition: all 0.3s $custom-easing;
|
||||
}
|
||||
|
||||
.left-side {
|
||||
background-color: $white;
|
||||
z-index: 3;
|
||||
display: flex;
|
||||
width: 389px;
|
||||
min-width: 389px;
|
||||
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: 389px;
|
||||
min-width: 389px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
width: 0px;
|
||||
min-width: 0px;
|
||||
|
||||
&.opened {
|
||||
width: 100vw;
|
||||
min-width: 100vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.closable-left-side {
|
||||
position: absolute;
|
||||
background-color: $white;
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-width: 56px;
|
||||
max-width: 56px;
|
||||
height: calc(100vh - 83px);
|
||||
border-right: 1px $grey-medium 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: 64px 48px;
|
||||
overflow-y: auto;
|
||||
|
||||
@media (max-width: ($screen-m - 1px)) {
|
||||
min-width: calc(100vw - 56px);
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
padding: 40px 16px 64px 16px;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,115 @@
|
||||
import ChevronIcon from "@Assets/Icons/chevron.svg";
|
||||
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
|
||||
import Button, { 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 User from "le-coffre-resources/dist/Notary";
|
||||
import Image from "next/image";
|
||||
import React, { ReactNode } from "react";
|
||||
|
||||
import classes from "./classes.module.scss";
|
||||
import UserListContainer from "./UserListContainer";
|
||||
|
||||
type IProps = {
|
||||
title: string;
|
||||
children?: ReactNode;
|
||||
onSelectedUser: (user: User) => void;
|
||||
hasBackArrow: boolean;
|
||||
backArrowUrl?: string;
|
||||
mobileBackText?: string;
|
||||
};
|
||||
type IState = {
|
||||
users: User[] | null;
|
||||
isLeftSideOpen: boolean;
|
||||
leftSideCanBeClosed: boolean;
|
||||
};
|
||||
|
||||
export default class DefaultUserDashboard extends React.Component<IProps, IState> {
|
||||
private onWindowResize = () => {};
|
||||
public static defaultProps: Partial<IProps> = {
|
||||
hasBackArrow: false,
|
||||
};
|
||||
|
||||
public constructor(props: IProps) {
|
||||
super(props);
|
||||
this.state = {
|
||||
users: 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.users && <UserListContainer users={this.state.users} 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
|
||||
icon={ChevronIcon}
|
||||
iconposition={"left"}
|
||||
iconstyle={{ transform: "rotate(180deg)", width: "22px", height: "22px" }}
|
||||
variant={EButtonVariant.LINE}
|
||||
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));
|
||||
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 });
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
.root {
|
||||
.user-infos {
|
||||
background-color: var(--grey-soft);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 24px;
|
||||
|
||||
margin-top: 32px;
|
||||
|
||||
@media (max-width: $screen-l) {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
@media (max-width: $screen-s) {
|
||||
grid-template-columns: repeat(1, 1fr);
|
||||
}
|
||||
|
||||
.user-infos-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.role-container {
|
||||
padding: 32px 16px;
|
||||
border: 1px solid var(--grey);
|
||||
|
||||
margin-top: 32px;
|
||||
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
.part {
|
||||
flex: 1;
|
||||
.first-line {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.second-line {
|
||||
margin-top: 32px;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
.third-line {
|
||||
margin-top: 32px;
|
||||
}
|
||||
}
|
||||
}
|
117
src/front/Components/Layouts/Users/UserInformations/index.tsx
Normal file
117
src/front/Components/Layouts/Users/UserInformations/index.tsx
Normal file
@ -0,0 +1,117 @@
|
||||
import Users from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
|
||||
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
|
||||
import SelectField, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
|
||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
import DefaultUserDashboard from "@Front/Components/LayoutTemplates/DefaultUserDashboard";
|
||||
import User from "le-coffre-resources/dist/Notary";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useState } from "react";
|
||||
import classes from "./classes.module.scss";
|
||||
import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
|
||||
|
||||
type IProps = {};
|
||||
export default function UserInformations(props: IProps) {
|
||||
const router = useRouter();
|
||||
let { userUid } = router.query;
|
||||
|
||||
const [userSelected, setUserSelected] = useState<User | null>(null);
|
||||
const [availableRoles, setAvailableRoles] = useState<IOption[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
async function getUser() {
|
||||
if (!userUid) return;
|
||||
const user = await Users.getInstance().getByUid(userUid as string, {
|
||||
q: {
|
||||
contact: true,
|
||||
office_role: true,
|
||||
},
|
||||
});
|
||||
if (!user) return;
|
||||
|
||||
const roles = await OfficeRoles.getInstance().get();
|
||||
if (!roles) return;
|
||||
setAvailableRoles(roles.map((role) => ({ value: role.uid, label: role.name })));
|
||||
setUserSelected(user);
|
||||
}
|
||||
|
||||
getUser();
|
||||
}, [userUid]);
|
||||
|
||||
return (
|
||||
<DefaultUserDashboard mobileBackText={"Liste des collaborateurs"}>
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["folder-header"]}>
|
||||
<Typography typo={ITypo.H1Bis}>{userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name}</Typography>
|
||||
</div>
|
||||
<div className={classes["user-infos"]}>
|
||||
<div className={classes["user-infos-row"]}>
|
||||
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
|
||||
Nom
|
||||
</Typography>
|
||||
<Typography typo={ITypo.P_18}>{userSelected?.contact?.first_name}</Typography>
|
||||
</div>
|
||||
<div className={classes["user-infos-row"]}>
|
||||
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
|
||||
Prénom
|
||||
</Typography>
|
||||
<Typography typo={ITypo.P_18}>{userSelected?.contact?.last_name}</Typography>
|
||||
</div>
|
||||
<div className={classes["user-infos-row"]}>
|
||||
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
|
||||
Numéro de téléphone
|
||||
</Typography>
|
||||
<Typography typo={ITypo.P_18}>{userSelected?.contact?.phone_number}</Typography>
|
||||
</div>
|
||||
<div className={classes["user-infos-row"]}>
|
||||
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
|
||||
Email
|
||||
</Typography>
|
||||
<Typography typo={ITypo.P_18}>{userSelected?.contact?.email}</Typography>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={classes["role-container"]}>
|
||||
<div className={classes["part"]}>
|
||||
<div className={classes["first-line"]}>
|
||||
<Typography typo={ITypo.P_SB_18}>Rôle au sein de son office</Typography>
|
||||
</div>
|
||||
<div className={classes["second-line"]}>
|
||||
<SelectField
|
||||
placeholder="Rôle"
|
||||
name="role"
|
||||
options={availableRoles}
|
||||
selectedOption={{
|
||||
value: userSelected?.office_role?.uid,
|
||||
label: userSelected?.office_role?.name!,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className={classes["part"]}>
|
||||
<div className={classes["first-line"]}>
|
||||
<Typography typo={ITypo.P_SB_18}>Attribuer un titre</Typography>
|
||||
</div>
|
||||
<div className={classes["second-line"]}>
|
||||
<CheckBox
|
||||
option={{
|
||||
label: "Nommer admin de son office",
|
||||
value: "title",
|
||||
}}
|
||||
name="admin"
|
||||
toolTip="tooltip"
|
||||
/>
|
||||
<CheckBox
|
||||
option={{
|
||||
label: "Nommer super admin LEcoffre.io",
|
||||
value: "title",
|
||||
}}
|
||||
name="superadmin"
|
||||
toolTip="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DefaultUserDashboard>
|
||||
);
|
||||
}
|
72
src/front/Components/Layouts/Users/classes.module.scss
Normal file
72
src/front/Components/Layouts/Users/classes.module.scss
Normal file
@ -0,0 +1,72 @@
|
||||
@import "@Themes/constants.scss";
|
||||
|
||||
.root {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
min-height: 100%;
|
||||
|
||||
.no-folder-selected {
|
||||
width: 100%;
|
||||
|
||||
.choose-a-folder {
|
||||
margin-top: 96px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.folder-informations {
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
|
||||
.folder-header {
|
||||
width: 100%;
|
||||
|
||||
.header {
|
||||
margin-bottom: 32px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.second-box {
|
||||
margin-top: 24px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
:first-child {
|
||||
margin-right: 12px;
|
||||
}
|
||||
> * {
|
||||
margin: auto;
|
||||
}
|
||||
@media (max-width: $screen-m) {
|
||||
:first-child {
|
||||
margin-right: 0;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
> * {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.modal-title {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
}
|
26
src/front/Components/Layouts/Users/index.tsx
Normal file
26
src/front/Components/Layouts/Users/index.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
|
||||
|
||||
import BasePage from "../Base";
|
||||
import classes from "./classes.module.scss";
|
||||
import DefaultUserDashboard from "@Front/Components/LayoutTemplates/DefaultUserDashboard";
|
||||
|
||||
type IProps = {};
|
||||
type IState = {};
|
||||
export default class Users extends BasePage<IProps, IState> {
|
||||
public override render(): JSX.Element {
|
||||
return (
|
||||
<DefaultUserDashboard title={"Dossier"} mobileBackText={"Liste des utilisateurs"}>
|
||||
<div className={classes["root"]}>
|
||||
<div className={classes["no-folder-selected"]}>
|
||||
<Typography typo={ITypo.H1Bis}>Informations des utilisateurs</Typography>
|
||||
<div className={classes["choose-a-folder"]}>
|
||||
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
|
||||
Sélectionnez un utilisateur
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DefaultUserDashboard>
|
||||
);
|
||||
}
|
||||
}
|
@ -181,6 +181,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Users": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/users",
|
||||
"labelKey": "users"
|
||||
},
|
||||
"pages": {
|
||||
"UsersInformations": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/users/[uid]",
|
||||
"labelKey": "users_informations"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
|
@ -181,6 +181,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Users": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/users",
|
||||
"labelKey": "users"
|
||||
},
|
||||
"pages": {
|
||||
"UsersInformations": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/users/[uid]",
|
||||
"labelKey": "users_informations"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
|
@ -181,6 +181,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Users": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/users",
|
||||
"labelKey": "users"
|
||||
},
|
||||
"pages": {
|
||||
"UsersInformations": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/users/[uid]",
|
||||
"labelKey": "users_informations"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
|
@ -181,6 +181,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Users": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/users",
|
||||
"labelKey": "users"
|
||||
},
|
||||
"pages": {
|
||||
"UsersInformations": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
"path": "/users/[uid]",
|
||||
"labelKey": "users_informations"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"enabled": true,
|
||||
"props": {
|
||||
|
5
src/pages/users/[userUid]/index.tsx
Normal file
5
src/pages/users/[userUid]/index.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import UserInformations from "@Front/Components/Layouts/Users/UserInformations";
|
||||
|
||||
export default function Route() {
|
||||
return <UserInformations />;
|
||||
}
|
5
src/pages/users/index.tsx
Normal file
5
src/pages/users/index.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import Users from "@Front/Components/Layouts/Users";
|
||||
|
||||
export default function Route() {
|
||||
return <Users />;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user