Merge Dev in Staging

This commit is contained in:
Arnaud D. Natali 2023-09-28 20:46:00 +02:00 committed by GitHub
commit 5a8e5573a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 227 additions and 176 deletions

2
package-lock.json generated
View File

@ -22,7 +22,7 @@
"eslint-config-next": "13.2.4", "eslint-config-next": "13.2.4",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"jwt-decode": "^3.1.2", "jwt-decode": "^3.1.2",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.83", "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.84",
"next": "13.2.4", "next": "13.2.4",
"prettier": "^2.8.7", "prettier": "^2.8.7",
"react": "18.2.0", "react": "18.2.0",

BIN
public/CGU_LeCoffre_io.pdf Normal file

Binary file not shown.

View File

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.2251 3.36088C13.4893 3.59571 13.5131 4.00024 13.2783 4.26442L6.4516 11.9444C6.33015 12.0811 6.15607 12.1592 5.97326 12.1592C5.79045 12.1592 5.61637 12.0811 5.49492 11.9444L2.08159 8.10442C1.84676 7.84024 1.87055 7.43571 2.13474 7.20088C2.39892 6.96606 2.80344 6.98985 3.03827 7.25403L5.97326 10.5559L12.3216 3.41403C12.5564 3.14985 12.9609 3.12606 13.2251 3.36088Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 497 B

View File

@ -18,7 +18,7 @@
} }
input[type="checkbox"]::before { input[type="checkbox"]::before {
content: url("../../../Assets/Icons/check.svg"); content: url("../../../Assets/Icons/check_white.svg");
place-content: flex-start; place-content: flex-start;
display: grid; display: grid;
width: 16px; width: 16px;

View File

@ -5,6 +5,7 @@
border: 1px dashed #e7e7e7; border: 1px dashed #e7e7e7;
height: fit-content; height: fit-content;
margin-top: 16px;
&[data-drag-over="true"] { &[data-drag-over="true"] {
border: 1px dashed var(--grey); border: 1px dashed var(--grey);

View File

@ -39,6 +39,7 @@ type IState = {
refusedReason?: string; refusedReason?: string;
isShowRefusedReasonModalVisible: boolean; isShowRefusedReasonModalVisible: boolean;
isAddDocumentModalVisible: boolean; isAddDocumentModalVisible: boolean;
isLoading: boolean;
}; };
export default class DepositOtherDocument extends React.Component<IProps, IState> { export default class DepositOtherDocument extends React.Component<IProps, IState> {
@ -54,6 +55,7 @@ export default class DepositOtherDocument extends React.Component<IProps, IState
isDragOver: false, isDragOver: false,
refusedReason: "", refusedReason: "",
isShowRefusedReasonModalVisible: false, isShowRefusedReasonModalVisible: false,
isLoading: false,
}; };
this.addDocument = this.addDocument.bind(this); this.addDocument = this.addDocument.bind(this);
@ -65,45 +67,17 @@ export default class DepositOtherDocument extends React.Component<IProps, IState
this.onAccept = this.onAccept.bind(this); this.onAccept = this.onAccept.bind(this);
} }
private async onAccept() {
const filesArray = this.state.currentFiles;
if (!filesArray) return;
const documentCreated = await Documents.getInstance().post({
folder: {
uid: this.props.folder_uid,
},
depositor: {
uid: this.props.customer_uid,
},
});
console.log(documentCreated);
filesArray.forEach(async (file) => {
const formData = new FormData();
formData.append("file", file.file, file.fileName);
const query = JSON.stringify({ document: { uid: documentCreated.uid } });
formData.append("q", query);
const newFile = await Files.getInstance().post(formData);
console.log(newFile);
});
this.props.onClose!();
}
public override render(): JSX.Element { public override render(): JSX.Element {
return ( return (
<Confirm <Confirm
isOpen={this.state.isAddDocumentModalVisible} isOpen={this.state.isAddDocumentModalVisible}
onClose={this.props.onClose!} onClose={() => {}}
onAccept={this.onAccept} onAccept={this.onAccept}
closeBtn closeBtn
header={"Ajouter un document"} header={"Ajouter un document"}
cancelText={"Annuler"} cancelText={"Annuler"}
confirmText={"Déposer le document"}> confirmText={this.state.isLoading ? "Chargement..." : "Déposer le document"}
canConfirm={!this.state.isLoading}>
<div className={classes["modal-content"]}> <div className={classes["modal-content"]}>
<div className={classes["container"]}> <div className={classes["container"]}>
<Typography typo={ITypo.P_16} className={classes["text"]}> <Typography typo={ITypo.P_16} className={classes["text"]}>
@ -140,7 +114,7 @@ export default class DepositOtherDocument extends React.Component<IProps, IState
</div> </div>
</Typography> </Typography>
<Typography color={ITypoColor.GREY} typo={ITypo.CAPTION_14}> <Typography color={ITypoColor.GREY} typo={ITypo.CAPTION_14}>
Sélectionnez des TEST documents .jpg, .pdf ou .png Sélectionnez des documents .jpg, .pdf ou .png
</Typography> </Typography>
</div> </div>
</div> </div>
@ -187,6 +161,38 @@ export default class DepositOtherDocument extends React.Component<IProps, IState
public override componentDidMount(): void {} public override componentDidMount(): void {}
private async onAccept() {
this.setState({
isLoading: true,
});
const filesArray = this.state.currentFiles;
if (!filesArray) return;
const documentCreated = await Documents.getInstance().post({
folder: {
uid: this.props.folder_uid,
},
depositor: {
uid: this.props.customer_uid,
},
});
for (let i = 0; i < filesArray.length; i++) {
const formData = new FormData();
formData.append("file", filesArray[i]!.file, filesArray[i]!.fileName);
const query = JSON.stringify({ document: { uid: documentCreated.uid } });
formData.append("q", query);
await Files.getInstance().post(formData);
}
this.setState({
isLoading: false,
});
this.props.onClose!();
}
private shortName(name: string): string { private shortName(name: string): string {
const maxLength = 20; const maxLength = 20;
if (name.length > maxLength) { if (name.length > maxLength) {

View File

@ -92,8 +92,8 @@ export default class BurgerModal extends React.Component<IProps, IState> {
mode={RulesMode.NECESSARY} mode={RulesMode.NECESSARY}
rules={[ rules={[
{ {
action: AppRuleActions.create, action: AppRuleActions.update,
name: AppRuleNames.officeRoles, name: AppRuleNames.offices,
}, },
]}> ]}>
<NavigationLink <NavigationLink
@ -123,7 +123,7 @@ export default class BurgerModal extends React.Component<IProps, IState> {
/> />
</Rules> </Rules>
<NavigationLink path={Module.getInstance().get().modules.pages.MyAccount.props.path} text="Mon compte" /> <NavigationLink path={Module.getInstance().get().modules.pages.MyAccount.props.path} text="Mon compte" />
<NavigationLink text="CGU" /> <NavigationLink target="_blank" path="/CGU_LeCoffre_io.pdf" text="CGU" />
<div className={classes["separator"]} /> <div className={classes["separator"]} />
<LogOutButton /> <LogOutButton />
</div> </div>

View File

@ -12,6 +12,7 @@ type IProps = {
isEnabled?: boolean; isEnabled?: boolean;
isActive?: boolean; isActive?: boolean;
routesActive?: string[]; routesActive?: string[];
target?: "blank" | "self" | "_blank";
}; };
type IPropsClass = IProps; type IPropsClass = IProps;
@ -25,7 +26,8 @@ class NavigationLinkClass extends React.Component<IPropsClass, IStateClass> {
<Link <Link
href={this.props.path ?? ""} href={this.props.path ?? ""}
className={classNames(classes["root"], this.props.isActive && [classes["active"]])} className={classNames(classes["root"], this.props.isActive && [classes["active"]])}
onClick={this.props.onClick}> onClick={this.props.onClick}
target={this.props.target}>
<div className={classes["content"]}> <div className={classes["content"]}>
<Typography typo={this.props.isActive ? ITypo.P_SB_18 : ITypo.NAV_HEADER_18}>{this.props.text}</Typography> <Typography typo={this.props.isActive ? ITypo.P_SB_18 : ITypo.NAV_HEADER_18}>{this.props.text}</Typography>
</div> </div>
@ -38,7 +40,7 @@ export default function NavigationLink(props: IProps) {
const router = useRouter(); const router = useRouter();
const { pathname } = router; const { pathname } = router;
let isActive = props.path === pathname; let isActive = props.path === pathname;
if(props.routesActive){ if (props.routesActive) {
for (const routeActive of props.routesActive) { for (const routeActive of props.routesActive) {
if (isActive) break; if (isActive) break;
isActive = pathname.includes(routeActive); isActive = pathname.includes(routeActive);

View File

@ -66,8 +66,8 @@ export default class ProfileModal extends React.Component<IProps, IState> {
mode={RulesMode.NECESSARY} mode={RulesMode.NECESSARY}
rules={[ rules={[
{ {
action: AppRuleActions.create, action: AppRuleActions.update,
name: AppRuleNames.officeRoles, name: AppRuleNames.offices,
}, },
]}> ]}>
<NavigationLink <NavigationLink
@ -96,7 +96,7 @@ export default class ProfileModal extends React.Component<IProps, IState> {
]} ]}
/> />
</Rules> </Rules>
<NavigationLink text="CGU" /> <NavigationLink target="_blank" path="/CGU_LeCoffre_io.pdf" text="CGU" />
<div className={classes["separator"]} /> <div className={classes["separator"]} />
<LogOutButton /> <LogOutButton />
</div> </div>

View File

@ -21,6 +21,9 @@
} }
.logo-container { .logo-container {
> a {
cursor: default !important;
}
.logo { .logo {
width: 174px; width: 174px;
height: 39px; height: 39px;
@ -57,4 +60,4 @@
} }
} }
} }
} }

View File

@ -61,7 +61,7 @@ class HeaderClass extends React.Component<IPropsClass, IState> {
<link rel="shortcut icon" href={"/favicon.svg"} /> <link rel="shortcut icon" href={"/favicon.svg"} />
</Head> </Head>
<div className={classes["logo-container"]}> <div className={classes["logo-container"]}>
<Link href={Module.getInstance().get().modules.pages.Home.props.path}> <Link href={"#"}>
<Image src={LogoIcon} alt="logo" className={classes["logo"]} /> <Image src={LogoIcon} alt="logo" className={classes["logo"]} />
</Link> </Link>
</div> </div>

View File

@ -24,48 +24,47 @@ export default function ClientDashboard(props: IProps) {
const [folder, setFolder] = useState<OfficeFolder | null>(null); const [folder, setFolder] = useState<OfficeFolder | null>(null);
const [isAddDocumentModalVisible, setIsAddDocumentModalVisible] = useState<boolean>(false); const [isAddDocumentModalVisible, setIsAddDocumentModalVisible] = useState<boolean>(false);
const onCloseModalAddDocument = useCallback(() => { const getDocuments = useCallback(async () => {
console.log("Closing"); let jwt;
if (typeof document !== "undefined") {
jwt = JwtService.getInstance().decodeJwt();
}
if (!jwt || !jwt.email) return;
const customers = await Customers.getInstance().get({
where: { contact: { email: jwt.email }, office_folders: { some: { uid: folderUid } } },
});
const actualCustomer: Customer = customers[0]!;
const query: IGetDocumentsparams = {
where: { depositor: { uid: actualCustomer.uid }, folder_uid: folderUid as string },
include: {
files: true,
document_history: true,
document_type: true,
depositor: true,
},
};
const documentList = await Documents.getInstance().get(query);
const folder = await Folders.getInstance().getByUid(folderUid as string, { q: { office: true } });
setFolder(folder);
setDocuments(documentList);
setCustomer(actualCustomer);
}, [folderUid]);
const onCloseModalAddDocument = useCallback(() => {
setIsAddDocumentModalVisible(false); setIsAddDocumentModalVisible(false);
}, []); getDocuments();
}, [getDocuments]);
const onOpenModalAddDocument = useCallback(() => { const onOpenModalAddDocument = useCallback(() => {
setIsAddDocumentModalVisible(true); setIsAddDocumentModalVisible(true);
}, []); }, []);
useEffect(() => { useEffect(() => {
async function getDocuments() {
let jwt;
if (typeof document !== "undefined") {
jwt = JwtService.getInstance().decodeJwt();
}
if (!jwt || !jwt.email) return;
const customers = await Customers.getInstance().get({
where: { contact: { email: jwt.email }, office_folders: { some: { uid: folderUid } } },
});
const actualCustomer: Customer = customers[0]!;
const query: IGetDocumentsparams = {
where: { depositor: { uid: actualCustomer.uid }, folder_uid: folderUid as string },
include: {
files: true,
document_history: true,
document_type: true,
depositor: true,
},
};
const documentList = await Documents.getInstance().get(query);
const folder = await Folders.getInstance().getByUid(folderUid as string, { q: { office: true } });
setFolder(folder);
setDocuments(documentList);
setCustomer(actualCustomer);
}
getDocuments(); getDocuments();
}, [folderUid]); }, [folderUid, getDocuments]);
const renderHeader = useCallback(() => { const renderHeader = useCallback(() => {
console.log("Dossier : ", customer); console.log("Dossier : ", customer);
@ -101,11 +100,9 @@ export default function ClientDashboard(props: IProps) {
</a> </a>
</div> </div>
); );
}, [customer]); }, [customer, folder?.folder_number, folder?.name, folder?.office?.name]);
const renderBox = useCallback(() => { const renderBox = useCallback(() => {
console.log(isAddDocumentModalVisible);
return ( return (
<DepositOtherDocument <DepositOtherDocument
folder_uid={folderUid!} folder_uid={folderUid!}
@ -114,7 +111,7 @@ export default function ClientDashboard(props: IProps) {
onClose={onCloseModalAddDocument} onClose={onCloseModalAddDocument}
document={Document.hydrate<Document>({ document={Document.hydrate<Document>({
document_type: DocumentType.hydrate<DocumentType>({ document_type: DocumentType.hydrate<DocumentType>({
name: "Document annexe", name: "Autres documents",
}), }),
})} })}
/> />

View File

@ -71,7 +71,7 @@ export default class ClientDashboard extends Base<IProps, IState> {
<DepositDocument <DepositDocument
document={Document.hydrate<Document>({ document={Document.hydrate<Document>({
document_type: DocumentType.hydrate<DocumentType>({ document_type: DocumentType.hydrate<DocumentType>({
name: "Document annexe", name: "Autres documents",
}), }),
})} })}
/> />

View File

@ -29,13 +29,15 @@ export default function DocumentTypesCreate(props: IProps) {
}); });
const documentToCreate = DocumentType.hydrate<DocumentType>({ const documentToCreate = DocumentType.hydrate<DocumentType>({
...values, ...values,
office: office office: office,
}); });
await validateOrReject(documentToCreate, { groups: ["createDocumentType"] }); await validateOrReject(documentToCreate, { groups: ["createDocumentType"] });
const documentTypeCreated = await DocumentTypes.getInstance().post(documentToCreate); const documentTypeCreated = await DocumentTypes.getInstance().post(documentToCreate);
router.push( router.push(
Module.getInstance().get().modules.pages.DocumentTypes.pages.Edit.props.path.replace("[uid]", documentTypeCreated.uid!), Module.getInstance()
.get()
.modules.pages.DocumentTypes.pages.DocumentTypesInformations.props.path.replace("[uid]", documentTypeCreated.uid!),
); );
} catch (e) { } catch (e) {
if (e instanceof Array) { if (e instanceof Array) {

View File

@ -67,7 +67,8 @@
} }
@media (max-width: $screen-m) { @media (max-width: $screen-m) {
display: block; display: flex;
flex-direction: column;
.delete-folder { .delete-folder {
margin-left: 0; margin-left: 0;

View File

@ -103,11 +103,11 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
)} )}
</div> </div>
<div className={classes["footer"]}> <div className={classes["footer"]}>
{this.state.document?.document_type?.name === "Document d'identité" && ( {/* {this.state.document?.document_type?.name === "Document d'identité" && (
<div className={classes["ocr-container"]}> <div className={classes["ocr-container"]}>
<OcrResult percentage={this.state.validatedPercentage} /> <OcrResult percentage={this.state.validatedPercentage} />
</div> </div>
)} )} */}
<div className={classes["buttons-container"]}> <div className={classes["buttons-container"]}>
{this.state.document?.document_status === EDocumentStatus.DEPOSITED && ( {this.state.document?.document_status === EDocumentStatus.DEPOSITED && (
@ -235,20 +235,32 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
private goToPrevious() { private goToPrevious() {
const index = this.state.selectedFileIndex - 1; const index = this.state.selectedFileIndex - 1;
if (this.hasPrevious()) { if (this.hasPrevious()) {
this.setState({ this.setState(
selectedFile: this.state.document!.files![index]!, {
selectedFileIndex: index, selectedFile: this.state.document!.files![index]!,
}); selectedFileIndex: index,
fileBlob: null,
},
() => {
this.getFilePreview();
},
);
} }
} }
private goToNext() { private goToNext() {
if (this.hasNext()) { if (this.hasNext()) {
const index = this.state.selectedFileIndex + 1; const index = this.state.selectedFileIndex + 1;
this.setState({ this.setState(
selectedFile: this.state.document!.files![index]!, {
selectedFileIndex: index, selectedFile: this.state.document!.files![index]!,
}); selectedFileIndex: index,
fileBlob: null,
},
() => {
this.getFilePreview();
},
);
} }
} }

View File

@ -10,6 +10,7 @@ import { useCallback } from "react";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import LandingImage from "./landing-connect.jpeg"; import LandingImage from "./landing-connect.jpeg";
import { FrontendVariables } from "@Front/Config/VariablesFront"; import { FrontendVariables } from "@Front/Config/VariablesFront";
import Link from "next/link";
export default function Login() { export default function Login() {
const router = useRouter(); const router = useRouter();
@ -36,7 +37,9 @@ export default function Login() {
<Typography typo={ITypo.P_18}> <Typography typo={ITypo.P_18}>
<div className={classes["forget-password"]}>Vous n'arrivez pas à vous connecter ?</div> <div className={classes["forget-password"]}>Vous n'arrivez pas à vous connecter ?</div>
</Typography> </Typography>
<Button variant={EButtonVariant.LINE}>Contacter l'administrateur</Button> <Link href="mailto:g.texier@notaires.fr">
<Button variant={EButtonVariant.LINE}>Contacter l'administrateur</Button>
</Link>
</div> </div>
</DefaultDoubleSidePage> </DefaultDoubleSidePage>
); );

View File

@ -11,6 +11,7 @@ import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Loader from "@Front/Components/DesignSystem/Loader"; import Loader from "@Front/Components/DesignSystem/Loader";
import UserStore from "@Front/Stores/UserStore"; import UserStore from "@Front/Stores/UserStore";
import Link from "next/link";
export default function LoginCallBack() { export default function LoginCallBack() {
const router = useRouter(); const router = useRouter();
@ -45,7 +46,9 @@ export default function LoginCallBack() {
<Typography typo={ITypo.P_18}> <Typography typo={ITypo.P_18}>
<div className={classes["forget-password"]}>Vous n'arrivez pas à vous connecter ?</div> <div className={classes["forget-password"]}>Vous n'arrivez pas à vous connecter ?</div>
</Typography> </Typography>
<Button variant={EButtonVariant.LINE}>Contacter l'administrateur</Button> <Link href="mailto:g.texier@notaires.fr">
<Button variant={EButtonVariant.LINE}>Contacter l'administrateur</Button>
</Link>
</div> </div>
</DefaultDoubleSidePage> </DefaultDoubleSidePage>
); );

View File

@ -15,13 +15,13 @@ import Loader from "@Front/Components/DesignSystem/Loader";
import Customers from "@Front/Api/LeCoffreApi/Id360/Customers/Customers"; import Customers from "@Front/Api/LeCoffreApi/Id360/Customers/Customers";
import CustomerStore from "@Front/Stores/CustomerStore"; import CustomerStore from "@Front/Stores/CustomerStore";
import Module from "@Front/Config/Module"; import Module from "@Front/Config/Module";
import Link from "next/link";
export default function LoginCallBack() { export default function LoginCallBack() {
const router = useRouter(); const router = useRouter();
useEffect(() => { useEffect(() => {
const getReport = async() => { const getReport = async () => {
const tokenid360 = router.query["token"]; const tokenid360 = router.query["token"];
if (!tokenid360) return; if (!tokenid360) return;
// const variables = FrontendVariables.getInstance(); // const variables = FrontendVariables.getInstance();
@ -31,9 +31,10 @@ export default function LoginCallBack() {
const token = await Customers.getInstance().loginCallback(tokenid360); const token = await Customers.getInstance().loginCallback(tokenid360);
CustomerStore.instance.connect(token.accessToken, token.refreshToken); CustomerStore.instance.connect(token.accessToken, token.refreshToken);
router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path); router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);
} };
getReport(); getReport();
}),[router]; }),
[router];
return ( return (
<DefaultDoubleSidePage title={"Login"} image={LandingImage}> <DefaultDoubleSidePage title={"Login"} image={LandingImage}>
@ -48,7 +49,9 @@ export default function LoginCallBack() {
<Typography typo={ITypo.P_18}> <Typography typo={ITypo.P_18}>
<div className={classes["forget-password"]}>Vous n'arrivez pas à vous connecter ?</div> <div className={classes["forget-password"]}>Vous n'arrivez pas à vous connecter ?</div>
</Typography> </Typography>
<Button variant={EButtonVariant.LINE}>Contacter l'administrateur</Button> <Link href="mailto:g.texier@notaires.fr">
<Button variant={EButtonVariant.LINE}>Contacter l'administrateur</Button>
</Link>
</div> </div>
</DefaultDoubleSidePage> </DefaultDoubleSidePage>
); );

View File

@ -9,6 +9,7 @@ import { useCallback } from "react";
import Customers from "@Front/Api/LeCoffreApi/Id360/Customers/Customers"; import Customers from "@Front/Api/LeCoffreApi/Id360/Customers/Customers";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import LandingImage from "./landing-connect.jpeg"; import LandingImage from "./landing-connect.jpeg";
import Link from "next/link";
export default function Login() { export default function Login() {
const router = useRouter(); const router = useRouter();
@ -36,7 +37,9 @@ export default function Login() {
<Typography typo={ITypo.P_18}> <Typography typo={ITypo.P_18}>
<div className={classes["forget-password"]}>Vous n'arrivez pas à vous connecter ?</div> <div className={classes["forget-password"]}>Vous n'arrivez pas à vous connecter ?</div>
</Typography> </Typography>
<Button variant={EButtonVariant.LINE}>Contacter l'administrateur</Button> <Link href="mailto:g.texier@notaires.fr">
<Button variant={EButtonVariant.LINE}>Contacter l'administrateur</Button>
</Link>
</div> </div>
</DefaultDoubleSidePage> </DefaultDoubleSidePage>
); );

View File

@ -90,7 +90,7 @@ export default class MyAccount extends Base<IProps, IState> {
/> />
<TextField <TextField
name="cp_address" name="cp_address"
placeholder="Adresse CP" placeholder="Adresse"
defaultValue={this.state.user?.office_membership?.address?.address} defaultValue={this.state.user?.office_membership?.address?.address}
disabled disabled
canCopy canCopy

View File

@ -5,18 +5,18 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
gap: 16px;
@media (max-width: $screen-s) { @media (max-width: $screen-s) {
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: flex-start;
gap: 16px;
} }
.header-right { .header-right {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 16px; gap: 16px;
width: 150px;
.round { .round {
width: 16px; width: 16px;
height: 16px; height: 16px;

View File

@ -3,7 +3,7 @@ import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Ty
import DefaultOfficeDashboard from "@Front/Components/LayoutTemplates/DefaultOfficeDashboard"; import DefaultOfficeDashboard from "@Front/Components/LayoutTemplates/DefaultOfficeDashboard";
import User, { Office } from "le-coffre-resources/dist/SuperAdmin"; import User, { Office } from "le-coffre-resources/dist/SuperAdmin";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
@ -13,6 +13,8 @@ export default function OfficeInformations(props: IProps) {
let { officeUid } = router.query; let { officeUid } = router.query;
const [officeSelected, setOfficeSelected] = useState<Office | null>(null); const [officeSelected, setOfficeSelected] = useState<Office | null>(null);
const [adminUsers, setAdminUsers] = useState<User[]>([]);
const [collaboratorUsers, setCollaboratorUsers] = useState<User[]>([]);
useEffect(() => { useEffect(() => {
async function getOffice() { async function getOffice() {
@ -31,54 +33,87 @@ export default function OfficeInformations(props: IProps) {
}); });
if (!office) return; if (!office) return;
setOfficeSelected(office); setOfficeSelected(office);
const adminUsers = office.users?.filter((user) => {
if (user.office_role && user.office_role.name === "admin") {
return true;
}
if (!user.office_role && user.role?.name === "admin") {
return true;
}
if (!user.office_role && user.role?.name === "super-admin") {
return true;
}
return false;
});
const collaboratorUsers = office.users?.filter((user) => {
if (user.office_role && user.office_role.name === "admin") {
return false;
}
if (!user.office_role && user.role?.name === "admin") {
return false;
}
if (!user.office_role && user.role?.name === "super-admin") {
return false;
}
return true;
});
setAdminUsers(adminUsers!);
setCollaboratorUsers(collaboratorUsers!);
} }
getOffice(); getOffice();
}, [officeUid]); }, [officeUid]);
const renderUser = (user: User) => ( const renderUser = useCallback(
<> (user: User) => (
<div key={user.uid} className={classes["user-line-desktop"]}> <>
<Typography typo={ITypo.P_16}>{user.contact?.last_name}</Typography> <div key={user.uid + "-" + officeUid} className={classes["user-line-desktop"]}>
<Typography typo={ITypo.P_16}>{user.contact?.first_name}</Typography>
<Typography typo={ITypo.P_16}>{user.contact?.email}</Typography>
<Typography typo={ITypo.P_16}>{user.contact?.phone_number}</Typography>
<Typography typo={ITypo.P_16}>{user.office_role ? user.office_role?.name : user.role?.name}</Typography>
</div>
<div key={user.uid} className={classes["user-line-mobile"]}>
<div className={classes["line"]}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK}>
Nom
</Typography>
<Typography typo={ITypo.P_16}>{user.contact?.last_name}</Typography> <Typography typo={ITypo.P_16}>{user.contact?.last_name}</Typography>
</div>
<div className={classes["line"]}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK}>
Prénom
</Typography>
<Typography typo={ITypo.P_16}>{user.contact?.first_name}</Typography> <Typography typo={ITypo.P_16}>{user.contact?.first_name}</Typography>
</div>
<div className={classes["line"]}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK}>
E-mail
</Typography>
<Typography typo={ITypo.P_16}>{user.contact?.email}</Typography> <Typography typo={ITypo.P_16}>{user.contact?.email}</Typography>
</div>
<div className={classes["line"]}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK}>
Téléphone
</Typography>
<Typography typo={ITypo.P_16}>{user.contact?.phone_number}</Typography> <Typography typo={ITypo.P_16}>{user.contact?.phone_number}</Typography>
<Typography typo={ITypo.P_16}>{user.office_role ? user.office_role?.name : "Utilisateur restreint"}</Typography>
</div> </div>
<div className={classes["line"]}> <div key={user.uid} className={classes["user-line-mobile"]}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK}> <div className={classes["line"]}>
Rôle <Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK}>
</Typography> Nom
<Typography typo={ITypo.P_16}>{user.office_role ? user.office_role?.name : user.role?.name}</Typography> </Typography>
<Typography typo={ITypo.P_16}>{user.contact?.last_name}</Typography>
</div>
<div className={classes["line"]}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK}>
Prénom
</Typography>
<Typography typo={ITypo.P_16}>{user.contact?.first_name}</Typography>
</div>
<div className={classes["line"]}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK}>
E-mail
</Typography>
<Typography typo={ITypo.P_16}>{user.contact?.email}</Typography>
</div>
<div className={classes["line"]}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK}>
Téléphone
</Typography>
<Typography typo={ITypo.P_16}>{user.contact?.phone_number}</Typography>
</div>
<div className={classes["line"]}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK}>
Rôle
</Typography>
<Typography typo={ITypo.P_16}>{user.office_role ? user.office_role?.name : user.role?.name}</Typography>
</div>
</div> </div>
</div> </>
</> ),
[officeUid],
); );
return ( return (
<DefaultOfficeDashboard mobileBackText={"Liste des utilisateurs"}> <DefaultOfficeDashboard mobileBackText={"Liste des utilisateurs"}>
<div className={classes["root"]}> <div className={classes["root"]}>
@ -134,22 +169,9 @@ export default function OfficeInformations(props: IProps) {
Rôle Rôle
</Typography> </Typography>
</div> </div>
{officeSelected?.users {adminUsers.map((user) => {
?.filter((user) => { return renderUser(user);
if (user.office_role && user.office_role.name === "admin") { })}
return true;
}
if (!user.office_role && user.role?.name === "admin") {
return true;
}
if (!user.office_role && user.role?.name === "super-admin") {
return true;
}
return false;
})
.map((user) => {
return renderUser(user);
})}
</div> </div>
</div> </div>
<div className={classes["users"]}> <div className={classes["users"]}>
@ -174,22 +196,9 @@ export default function OfficeInformations(props: IProps) {
Rôle Rôle
</Typography> </Typography>
</div> </div>
{officeSelected?.users {collaboratorUsers.map((user) => {
?.filter((user) => { return renderUser(user);
if (user.office_role && user.office_role.name === "admin") { })}
return false;
}
if (!user.office_role && user.role?.name === "admin") {
return false;
}
if (!user.office_role && user.role?.name === "super-admin") {
return false;
}
return true;
})
.map((user) => {
return renderUser(user);
})}
</div> </div>
</div> </div>
</div> </div>

View File

@ -285,7 +285,10 @@ export default function UserInformations(props: IProps) {
<Typography typo={ITypo.P_SB_18}>Attribuer un titre</Typography> <Typography typo={ITypo.P_SB_18}>Attribuer un titre</Typography>
</div> </div>
<div className={classes["second-line"]}> <div className={classes["second-line"]}>
<Switch label="Admin de son office" checked={isAdminChecked} onChange={handleAdminChanged} /> {!isSuperAdminChecked && (
<Switch label="Admin de son office" checked={isAdminChecked} onChange={handleAdminChanged} />
)}
<Switch <Switch
label="Super-admin LeCoffre.io" label="Super-admin LeCoffre.io"
checked={isSuperAdminChecked} checked={isSuperAdminChecked}