118 lines
4.2 KiB
TypeScript

import DragAndDrop, { IDocumentFileWithUid } from "@Front/Components/DesignSystem/DragAndDrop";
import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Typography";
import { Document } from "le-coffre-resources/dist/Customer";
import { useCallback, useMemo, useState } from "react";
import classes from "./classes.module.scss";
import Files from "@Front/Api/LeCoffreApi/Customer/Files/Files";
import { ToasterService } from "@Front/Components/DesignSystem/Toaster";
import Confirm from "@Front/Components/DesignSystem/OldModal/Confirm";
type IProps = {
document: Document;
onChange: () => void;
};
export default function DepositDocumentComponent(props: IProps) {
const { document, onChange } = props;
const [isModalOpen, setIsModalOpen] = useState(false);
const [refused_reason, setRefusedReason] = useState<string | null>(null);
const defaultFiles: IDocumentFileWithUid[] = useMemo(() => {
const filesNotArchived = document.files?.filter((file) => !file.archived_at) ?? [];
return filesNotArchived.map((file) => ({
id: file.uid!,
file: new File([""], file.file_name!, { type: file.mimetype }),
uid: file.uid!,
}));
}, [document.files]);
const addFile = useCallback(
(file: File) => {
const formData = new FormData();
const safeFileName = file.name.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
formData.append("file", file, safeFileName);
const query = JSON.stringify({ document: { uid: document.uid } });
formData.append("q", query);
return Files.getInstance()
.post(formData)
.then(onChange)
.then(() => ToasterService.getInstance().success({ title: "Succès !", description: "Fichier uploadé avec succès!" }))
.catch((error) => ToasterService.getInstance().error({ title: "Erreur !", description: error.message }));
},
[document.uid, onChange],
);
const deleteFile = useCallback(
(filedUid: string) => {
return Files.getInstance()
.delete(filedUid)
.then(onChange)
.then(() => ToasterService.getInstance().success({ title: "Succès !", description: "Fichier supprimé avec succès!" }))
.catch((error) => ToasterService.getInstance().error({ title: "Erreur !", description: error.message }));
},
[onChange],
);
const onOpenModal = useCallback(async () => {
const refused_reason = document.document_history?.find((history) => history.document_status === "REFUSED")?.refused_reason;
if (!refused_reason) return;
setRefusedReason(refused_reason);
setIsModalOpen(true);
}, []);
const closeModal = useCallback(() => {
setIsModalOpen(false);
}, []);
return (
<div className={classes["root"]}>
<div className={classes["title"]}>
<Typography typo={ETypo.TEXT_MD_SEMIBOLD} color={ETypoColor.TEXT_PRIMARY}>
{document.document_type?.name ?? "_"}
</Typography>
<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
Demandé le: {document.created_at ? new Date(document.created_at).toLocaleDateString() : "_"}
</Typography>
{document.document_status === "REFUSED" && (
<div>
<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.TEXT_SECONDARY}>
Refusé le : {document.updated_at ? new Date(document.updated_at).toLocaleDateString() : "_"}
</Typography>
<Typography typo={ETypo.TEXT_MD_REGULAR} color={ETypoColor.ERROR_WEAK_CONTRAST} onClick={onOpenModal}>
Document non-conforme{" : "} <a className={classes["refused-link"]}>Voir le motif de refus</a>
</Typography>
</div>
)}
</div>
<Confirm
isOpen={isModalOpen}
showCancelButton={false}
onAccept={closeModal}
onClose={closeModal}
closeBtn
header={"Motif de refus"}
confirmText={"J'ai compris"}>
<div className={classes["modal-content"]}>
<Typography typo={ETypo.TEXT_MD_SEMIBOLD} className={classes["text"]}>
Votre document a é refusé pour la raison suivante :
</Typography>
<br />
<Typography typo={ETypo.TEXT_MD_REGULAR} className={classes["text"]}>
{refused_reason}
</Typography>
</div>
</Confirm>
<DragAndDrop
title={"Glisser-déposer ou"}
description={document.document_type?.public_description ?? undefined}
defaultFiles={defaultFiles}
onAddFile={addFile}
onDelete={deleteFile}
/>
</div>
);
}