2024-05-31 16:12:59 +02:00

207 lines
7.2 KiB
TypeScript

"use client";
import Documents, { IGetDocumentsparams } from "@Front/Api/LeCoffreApi/Customer/Documents/Documents";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import DepositDocument from "@Front/Components/DesignSystem/DepositDocument";
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
import Customer, { Document, DocumentType, OfficeFolder } from "le-coffre-resources/dist/Customer";
import React, { useCallback, useEffect, useState } from "react";
import classes from "./classes.module.scss";
import { useRouter } from "next/router";
import JwtService, { ICustomerJwtPayload } from "@Front/Services/JwtService/JwtService";
import DepositOtherDocument from "@Front/Components/DesignSystem/DepositOtherDocument";
import Folders from "@Front/Api/LeCoffreApi/Customer/Folders/Folders";
import OfficeRib from "@Front/Api/LeCoffreApi/Customer/OfficeRib/OfficeRib";
type IProps = {};
export default function ClientDashboard(props: IProps) {
const router = useRouter();
let { folderUid } = router.query;
const [documents, setDocuments] = useState<Document[] | null>(null);
const [customer, setCustomer] = useState<Customer | null>(null);
const [contact, setContact] = useState<Customer["contact"] | null>(null);
const [folder, setFolder] = useState<OfficeFolder | null>(null);
const [isAddDocumentModalVisible, setIsAddDocumentModalVisible] = useState<boolean>(false);
const getDocuments = useCallback(async () => {
let jwt: ICustomerJwtPayload | undefined;
if (typeof document !== "undefined") {
jwt = JwtService.getInstance().decodeCustomerJwt();
}
const folder = await Folders.getInstance().getByUid(folderUid as string, {
q: {
office: true,
customers: true,
stakeholders: {
include: {
contact: true,
office_role: true,
},
},
},
});
//Loop through the folder stakeholders, if there is at least one stakeholder that role is "Collaborateur" set contact to this stakeholders.contact, else, take the first stakeholders of the list
const contact = folder.stakeholders!.find((stakeholder) => stakeholder.office_role?.name === "Collaborateur")?.contact;
setContact(contact ?? folder.stakeholders![0]!.contact);
const actualCustomer = folder?.customers?.find((customer) => customer.contact?.email === jwt?.email);
if (!actualCustomer) throw new Error("Customer not found");
const query: IGetDocumentsparams = {
where: { depositor: { uid: actualCustomer.uid }, folder_uid: folderUid as string },
include: {
files: true,
document_history: true,
document_type: true,
depositor: true,
folder: {
include: {
customers: {
include: {
contact: true,
},
},
},
},
},
};
const documentList = await Documents.getInstance().get(query);
//const folder = await Folders.getInstance().getByUid(folderUid as string, { q: { office: true, customers: true } });
setFolder(folder);
setDocuments(documentList);
setCustomer(actualCustomer);
}, [folderUid]);
const onCloseModalAddDocument = useCallback(() => {
setIsAddDocumentModalVisible(false);
getDocuments();
}, [getDocuments]);
const onOpenModalAddDocument = useCallback(() => {
setIsAddDocumentModalVisible(true);
}, []);
const downloadFile = useCallback(async () => {
if (!folder?.office?.uid) return;
const blob = await OfficeRib.getInstance().getRibStream(folder.office.uid);
const ribUrl = URL.createObjectURL(blob);
if (!ribUrl) return;
const a = document.createElement("a");
a.style.display = "none";
a.href = ribUrl;
a.download = "";
document.body.appendChild(a);
a.click();
}, [folder]);
useEffect(() => {
getDocuments();
}, [folderUid, getDocuments]);
const renderHeader = useCallback(() => {
return (
<div className={classes["header"]}>
<div className={classes["text-container"]}>
{/* TODO Get name from userStore */}
<div className={classes["title-container"]}>
<Typography typo={ITypo.H1} className={classes["title"]}>
Bonjour {customer?.contact?.first_name.concat(" ", customer?.contact?.last_name)}
</Typography>
</div>
<Typography typo={ITypo.P_SB_18} className={classes["folder-number"]} color={ITypoColor.GREY}>
Dossier {folder?.folder_number} - {folder?.name}
</Typography>
<Typography typo={ITypo.P_SB_18} className={classes["office-name"]} color={ITypoColor.GREY}>
{folder?.office?.name}
</Typography>
<Typography typo={ITypo.H2} className={classes["subtitle"]}>
Documents à envoyer
</Typography>
<Typography typo={ITypo.P_16} className={classes["text"]}>
Votre notaire est dans l'attente de documents pour valider votre dossier. Voici la liste des documents.
<br /> Veuillez glisser / déposer chaque document dans la zone prévue à cet effet ou cliquez sur la zone puis
sélectionnez le document correspondant. <br /> En déposant un document, celui-ci est automatiquement enregistré et
transmis à votre notaire.
</Typography>
</div>
<div className={classes["contact"]}>
<Typography typo={ITypo.P_SB_18} className={classes["contact-text"]} color={ITypoColor.GREY}>
<p>
{contact?.first_name} {contact?.last_name}
</p>
<p>{contact?.phone_number ?? contact?.cell_phone_number}</p>
<p>{contact?.email}</p>
</Typography>
<div className="separator"></div>
{folder?.office?.rib_name && (
//Div to avoid the button to be on the same line as the text
<Button className={classes["contact-button"]} onClick={downloadFile}>
Télécharger le RIB de votre notaire
</Button>
)}
</div>
</div>
);
}, [
customer?.contact?.first_name,
customer?.contact?.last_name,
downloadFile,
folder?.folder_number,
folder?.name,
folder?.office?.name,
folder?.office?.rib_name,
]);
const renderBox = useCallback(() => {
return (
<DepositOtherDocument
folder_uid={folderUid!}
customer_uid={customer!.uid!}
open={isAddDocumentModalVisible}
onClose={onCloseModalAddDocument}
document={Document.hydrate<Document>({
document_type: DocumentType.hydrate<DocumentType>({
name: "Autres documents",
}),
})}
/>
);
}, [customer, folderUid, isAddDocumentModalVisible, onCloseModalAddDocument]);
return (
<DefaultTemplate title={"Mon compte"} isPadding={false} hasHeaderLinks={false}>
<div className={classes["root"]}>
{renderHeader()}
<div className={classes["sub-container"]}>
<div className={classes["content"]}>
{documents?.map((document) => (
<DepositDocument document={document} key={document.uid} defaultFiles={document.files ?? []} />
))}
</div>
<Typography typo={ITypo.H2}>Documents supplémentaires (facultatif)</Typography>
<Typography typo={ITypo.P_16} className={classes["text"]}>
Vous souhaitez envoyer d'autres documents à votre notaire ?
</Typography>
<Button variant={EButtonVariant.GHOST} className={classes["button"]} onClick={onOpenModalAddDocument}>
Ajouter d'autres documents
</Button>
</div>
</div>
{isAddDocumentModalVisible && renderBox()}
</DefaultTemplate>
);
}