2025-04-15 09:23:10 +02:00

192 lines
6.0 KiB
TypeScript

import DocumentsNotary from "@Front/Api/LeCoffreApi/Customer/DocumentsNotary/DocumentsNotary";
import FilesNotary from "@Front/Api/LeCoffreApi/Customer/FilesNotary/Files";
import Button, { EButtonSize, EButtonstyletype, EButtonVariant } from "@Front/Components/DesignSystem/Button";
import IconButton from "@Front/Components/DesignSystem/IconButton";
import Table from "@Front/Components/DesignSystem/Table";
import { IHead, IRowProps } from "@Front/Components/DesignSystem/Table/MuiTable";
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
import BackArrow from "@Front/Components/Elements/BackArrow";
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
import Module from "@Front/Config/Module";
import JwtService, { ICustomerJwtPayload } from "@Front/Services/JwtService/JwtService";
import { ArrowDownTrayIcon, EyeIcon } from "@heroicons/react/24/outline";
import { saveAs } from "file-saver";
import JSZip from "jszip";
import { useRouter } from "next/router";
import React, { useCallback, useEffect, useState } from "react";
import classes from "./classes.module.scss";
import Link from "next/link";
import Folders from "@Front/Api/LeCoffreApi/Customer/Folders/Folders";
import Customer from "le-coffre-resources/dist/Customer";
import { DocumentNotary } from "le-coffre-resources/dist/Notary";
const header: readonly IHead[] = [
{
key: "name",
title: "Nom",
},
{
key: "sentAt",
title: "Envoyé le",
},
{
key: "actions",
title: "Action",
},
];
export default function ReceivedDocuments() {
const router = useRouter();
let { folderUid } = router.query;
const [documentsNotary, setDocumentsNotary] = useState<DocumentNotary[]>([]);
const [customer, setCustomer] = useState<Customer | null>(null);
const fetchFolderAndCustomer = 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,
notes: {
include: {
customer: true,
},
},
stakeholders: {
include: {
contact: true,
office_role: true,
},
},
deed: {
include: {
deed_type: true,
},
},
},
});
const customer = folder?.customers?.find((customer) => customer.contact?.email === jwt?.email);
if (!customer) throw new Error("Customer not found");
setCustomer(customer);
return { folder, customer };
}, [folderUid]);
useEffect(() => {
fetchFolderAndCustomer();
const customerUid = customer?.uid;
if (!folderUid || !customerUid) return;
DocumentsNotary.getInstance()
.get({ where: { folder: { uid: folderUid }, customer: { uid: customerUid } }, include: { files: true } })
.then((documentsNotary) => setDocumentsNotary(documentsNotary));
}, [folderUid, customer, fetchFolderAndCustomer]);
const onDownload = useCallback((doc: DocumentNotary) => {
const file = doc.files?.[0];
if (!file || !file?.uid || !doc.uid) return;
return FilesNotary.getInstance()
.download(file.uid, doc.uid)
.then((blob) => {
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = file.file_name ?? "file";
a.click();
URL.revokeObjectURL(url);
})
.catch((e) => console.warn(e));
}, []);
const onDownloadAll = useCallback(async () => {
if (documentsNotary.length === 0) return;
const zip = new JSZip();
const folder = zip.folder("documents") || zip;
const downloadPromises = documentsNotary.map(async (doc) => {
const file = doc.files?.[0];
if (file && file.uid && doc.uid) {
const blob = await FilesNotary.getInstance().download(file.uid, doc.uid);
folder.file(file.file_name ?? "file", blob);
}
});
await Promise.all(downloadPromises);
zip.generateAsync({ type: "blob" })
.then((blob: any) => {
saveAs(blob, "documents.zip");
})
.catch((error: any) => {
console.error("Error generating ZIP file: ", error);
});
}, [documentsNotary]);
return (
<DefaultTemplate title={"Documents reçus"} isPadding={false}>
<div className={classes["root"]}>
<BackArrow
text="Retour aux dossiers"
url={Module.getInstance()
.get()
.modules.pages.ClientDashboard.props.path.replace("[folderUid]", folderUid as string)}
/>
<Typography typo={ETypo.TITLE_H1} color={ETypoColor.TEXT_PRIMARY}>
Un document vous a é envoyé
</Typography>
<Table className={classes["table"]} header={header} rows={buildRows(documentsNotary, folderUid!, onDownload)} />
<Button
variant={EButtonVariant.PRIMARY}
size={EButtonSize.LG}
styletype={EButtonstyletype.CONTAINED}
leftIcon={<ArrowDownTrayIcon />}
onClick={onDownloadAll}>
Tout télécharger
</Button>
</div>
</DefaultTemplate>
);
}
function buildRows(
documentsNotary: DocumentNotary[],
folderUid: string | string[],
onDownloadFileNotary: (doc: DocumentNotary) => void,
): IRowProps[] {
console.log(documentsNotary);
console.log(folderUid);
return documentsNotary.map((documentNotary) => ({
key: documentNotary.uid ?? "",
name: formatName(documentNotary.files?.[0]?.file_name?.split(".")?.[0] ?? "") || "_",
sentAt: new Date(documentNotary.created_at!).toLocaleDateString(),
// actions: <IconButton onClick={() => onDownloadFileNotary(documentNotary)} icon={<ArrowDownTrayIcon />} />,
actions: {
sx: { width: 76 },
content: (
<div className={classes["actions"]}>
<Link
href={Module.getInstance()
.get()
.modules.pages.ClientDashboard.pages.ViewDocuments.props.path.replace("[folderUid]", folderUid as string)
.replace("[documentUid]", documentNotary.uid ?? "")}>
<IconButton icon={<EyeIcon />} />
</Link>
<IconButton onClick={() => onDownloadFileNotary(documentNotary)} icon={<ArrowDownTrayIcon />} />
</div>
),
},
}));
}
function formatName(text: string): string {
return text.replace(/[^a-zA-Z0-9 ]/g, "");
}