diff --git a/src/front/Components/DesignSystem/Button/classes.module.scss b/src/front/Components/DesignSystem/Button/classes.module.scss index cc21022a..a1dc4704 100644 --- a/src/front/Components/DesignSystem/Button/classes.module.scss +++ b/src/front/Components/DesignSystem/Button/classes.module.scss @@ -15,6 +15,7 @@ white-space: nowrap; user-select: none; cursor: pointer; + font-family: var(--font-primary); svg { width: 18px; @@ -109,4 +110,4 @@ line-height: 22px; text-decoration-line: underline; } -} +} \ No newline at end of file diff --git a/src/front/Components/DesignSystem/DepositDocument/classes.module.scss b/src/front/Components/DesignSystem/DepositDocument/classes.module.scss index 3ef6b854..36f56325 100644 --- a/src/front/Components/DesignSystem/DepositDocument/classes.module.scss +++ b/src/front/Components/DesignSystem/DepositDocument/classes.module.scss @@ -1,12 +1,17 @@ .root { padding: 24px; - background-color: white; + background-color: var(--white); border: 1px dashed #e7e7e7; - - height: fit-content; - &[data-drag-over="true"] { - border: 1px dashed grey; - } + + height: fit-content; + + &[data-drag-over="true"] { + border: 1px dashed var(--grey); + } + + &.validated { + border: 1px dashed var(--green-flash); + } .top-container { display: flex; @@ -25,6 +30,12 @@ .right { margin-left: 18px; + .refused-button { + font-size: 14px; + color: var(--re-hover); + margin-left: 8px; + } + .title { display: flex; align-items: center; @@ -40,9 +51,9 @@ margin-top: 16px; .file-container { - display: flex; - align-items: center; - justify-content: space-between; + display: flex; + align-items: center; + justify-content: space-between; .left-part { display: flex; @@ -50,7 +61,7 @@ gap: 8px; } - .cross{ + .cross { cursor: pointer; } } @@ -58,6 +69,7 @@ .bottom-container { margin-top: 16px; + .add-button { .add-document { display: flex; @@ -66,4 +78,8 @@ } } } -} + + .text { + margin-bottom: 12px; + } +} \ No newline at end of file diff --git a/src/front/Components/DesignSystem/DepositDocument/index.tsx b/src/front/Components/DesignSystem/DepositDocument/index.tsx index 0f566b4b..60acbac0 100644 --- a/src/front/Components/DesignSystem/DepositDocument/index.tsx +++ b/src/front/Components/DesignSystem/DepositDocument/index.tsx @@ -9,8 +9,12 @@ import Button, { EButtonVariant } from "../Button"; import Tooltip from "../ToolTip"; import Typography, { ITypo, ITypoColor } from "../Typography"; import classes from "./classes.module.scss"; -import { Document, File as FileCustomer } from "le-coffre-resources/dist/Customer"; +import { Document, DocumentHistory, File as FileCustomer } from "le-coffre-resources/dist/Customer"; import Files from "@Front/Api/LeCoffreApi/SuperAdmin/Files/Files"; +import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document"; +import classNames from "classnames"; +import Confirm from "../Modal/Confirm"; +import InputField from "../Form/Elements/InputField"; type IProps = { title: string; @@ -23,12 +27,15 @@ type IProps = { type IFile = { index: number; file: File; + uid: string; }; type IState = { files: IFile[]; isDragOver: boolean; currentFiles?: FileCustomer[]; + refusedReason?: string; + isShowRefusedReasonModalVisible: boolean; }; export default class DepositDocument extends React.Component { @@ -42,6 +49,8 @@ export default class DepositDocument extends React.Component { files: [], isDragOver: false, currentFiles: this.props.defaultFiles, + refusedReason: "", + isShowRefusedReasonModalVisible: false, }; this.addDocument = this.addDocument.bind(this); @@ -50,12 +59,18 @@ export default class DepositDocument extends React.Component { this.onDragOver = this.onDragOver.bind(this); this.onDragDrop = this.onDragDrop.bind(this); this.onDragLeave = this.onDragLeave.bind(this); + this.onCloseModalShowRefusedReason = this.onCloseModalShowRefusedReason.bind(this); + this.onOpenModalShowRefusedReason = this.onOpenModalShowRefusedReason.bind(this); + this.showRefusedReason = this.showRefusedReason.bind(this); } public override render(): JSX.Element { return (
{
- {this.props.title} - - - Demandé par le notaire le {this.formatDate(this.props.dateAsked)} + {this.props.title}{" "} + {this.props.document.document_type?.public_description !== "" && ( + + )} + {this.props.document.document_status !== EDocumentStatus.VALIDATED && ( + + Sélectionnez des documents .jpg, .pdf ou .png + + )} + {this.props.document.document_history?.map((history) => ( +
{this.renderDocumentHistory(history)}
+ ))}
- {this.state.files.length > 0 && ( + {this.props.document.document_status !== EDocumentStatus.VALIDATED && this.state.files.length > 0 && (
{this.state.files.map((file) => { const fileObj = file.file; @@ -99,14 +122,31 @@ export default class DepositDocument extends React.Component { })}
)} - -
- +
+ )} + +
+ + Votre document a été refusé pour la raison suivante : - -
+ +
+ + ; ); } @@ -117,11 +157,63 @@ export default class DepositDocument extends React.Component { files: this.props.defaultFiles.map((file) => ({ index: this.index++, file: new File([""], file.file_path ?? "", {}), + uid: file.uid!, })), }); } } + private onCloseModalShowRefusedReason() { + this.setState({ + isShowRefusedReasonModalVisible: false, + }); + } + + private onOpenModalShowRefusedReason() { + this.setState({ + isShowRefusedReasonModalVisible: true, + }); + } + + private renderDocumentHistory(history: DocumentHistory): JSX.Element | null { + switch (history.document_status) { + case EDocumentStatus.ASKED: + return ( + + Demandé par votre notaire le {this.formatDate(history.created_at!)} + + ); + case EDocumentStatus.VALIDATED: + return ( + + Validé par votre notaire le {this.formatDate(history.created_at!)} + + ); + case EDocumentStatus.DEPOSITED: + return ( + + Déposé le {this.formatDate(history.created_at!)} + + ); + + case EDocumentStatus.REFUSED: + return ( + + Document non conforme + {history.refused_reason !== "" && ( + + )} + + ); + } + return null; + } + private shortName(name: string): string { const maxLength = 20; if (name.length > maxLength) { @@ -139,6 +231,13 @@ export default class DepositDocument extends React.Component { event.preventDefault(); } + private showRefusedReason(refusedReason: string) { + this.setState({ + refusedReason, + }); + this.onOpenModalShowRefusedReason(); + } + private onDragLeave(event: React.DragEvent) { this.setState({ isDragOver: false, @@ -156,18 +255,6 @@ export default class DepositDocument extends React.Component { } private async addFile(file: File) { - this.setState({ - files: [ - ...this.state.files, - { - index: this.index++, - file: file, - }, - ], - }); - - if (this.props.onChange) this.props.onChange(this.state.files.map((file) => file.file)); - const formData = new FormData(); formData.append("file", file, file.name); const query = JSON.stringify({ document: { uid: this.props.document.uid } }); @@ -175,25 +262,34 @@ export default class DepositDocument extends React.Component { const newFile = await Files.getInstance().post(formData); const files = this.state.currentFiles ? [...this.state.currentFiles, newFile] : [newFile]; + this.setState({ currentFiles: files, + files: [ + ...this.state.files, + { + index: this.index++, + file: file, + uid: newFile.uid!, + }, + ], }); + + if (this.props.onChange) this.props.onChange(this.state.files.map((file) => file.file)); } private async removeFile(e: any) { const image = e.target as HTMLElement; const indexToRemove = image.getAttribute("data-file"); if (!indexToRemove) return; - // const file = this.state.files.find((file) => file.index === parseInt(indexToRemove)); + const file = this.state.files.find((file) => file.index === parseInt(indexToRemove)); + if (!file) return; this.setState({ files: this.state.files.filter((file) => file.index !== parseInt(indexToRemove)), }); if (this.props.onChange) this.props.onChange(this.state.files.map((file) => file.file)); - // TODO Finir la suppression de fichier - // const deletedFileUid = this.props.document.files?.find((file) => file.file_path === newFile.file_path)?.uid; - // console.log({ deletedFileUid }); - // await Files.getInstance().delete(file?.uid); + await Files.getInstance().delete(file.uid); } private async onFileChange() { @@ -211,6 +307,7 @@ export default class DepositDocument extends React.Component { } private formatDate(date: Date) { - return date.toLocaleDateString("fr-FR"); + const dateToConvert = new Date(date); + return dateToConvert.toLocaleDateString("fr-FR"); } } diff --git a/src/front/Components/DesignSystem/Form/Elements/InputField/index.tsx b/src/front/Components/DesignSystem/Form/Elements/InputField/index.tsx index 61a55cdc..10d0cfea 100644 --- a/src/front/Components/DesignSystem/Form/Elements/InputField/index.tsx +++ b/src/front/Components/DesignSystem/Form/Elements/InputField/index.tsx @@ -14,9 +14,9 @@ export type IProps = IBaseFieldProps & { export default class InputField extends BaseField { static override defaultProps: Partial = { ...BaseField.defaultProps, - required: true - } - + required: true, + }; + public override render(): ReactNode { let pattern; @@ -51,9 +51,12 @@ export default class InputField extends BaseField { className={ this.props.className ? [classes["textarea"], classes[this.props.className]].join(" ") : classes["textarea"] } - value={value} - /> -
{this.props.fakeplaceholder} {!this.props.required && " (Facultatif)"}
+ value={value}> + {value.toString()} + +
+ {this.props.fakeplaceholder} {!this.props.required && " (Facultatif)"} +
); @@ -74,7 +77,9 @@ export default class InputField extends BaseField { } value={value} /> -
{this.props.fakeplaceholder} {!this.props.required && " (Facultatif)"}
+
+ {this.props.fakeplaceholder} {!this.props.required && " (Facultatif)"} +
); @@ -84,7 +89,7 @@ export default class InputField extends BaseField { public override componentDidMount() { this.setState({ value: this.props.defaultValue ?? "", - }) + }); } // We filter the props we'll pass to the primitive input as they're useless for it diff --git a/src/front/Components/DesignSystem/ToolTip/index.tsx b/src/front/Components/DesignSystem/ToolTip/index.tsx index dddea180..a843ef6a 100644 --- a/src/front/Components/DesignSystem/ToolTip/index.tsx +++ b/src/front/Components/DesignSystem/ToolTip/index.tsx @@ -19,13 +19,18 @@ type IState = { const LightTooltip = styled(({ className, ...props }: TooltipProps) => )( ({ theme }) => ({ [`& .${tooltipClasses.tooltip}`]: { - backgroundColor: "var(--turquoise-flash)", - color: "white", - //boxShadow: theme.shadows[1], - fontSize: 11, + backgroundColor: "var(--white)", + color: "var(--black)", + boxShadow: "0px 4px 24px 0px #00000026", + fontSize: 14, + fontWeight: 400, + lineHeight: "22px", + fontFamily: "var(--font-primary)", + padding: "16px", + borderRadius: "0px", }, [`& .${tooltipClasses.arrow}`]: { - color: "var(--turquoise-flash)", + color: "var(--white)", }, }), ); diff --git a/src/front/Components/Layouts/ClientDashboard/index.tsx b/src/front/Components/Layouts/ClientDashboard/index.tsx index d8a6d00e..360aa976 100644 --- a/src/front/Components/Layouts/ClientDashboard/index.tsx +++ b/src/front/Components/Layouts/ClientDashboard/index.tsx @@ -1,3 +1,4 @@ +import "reflect-metadata"; import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; import DepositDocument from "@Front/Components/DesignSystem/DepositDocument"; import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField"; @@ -112,6 +113,8 @@ export default class ClientDashboard extends Base { where: { depositor: mockUsers?.uid }, include: { files: true, + document_history: true, + document_type: true, }, }; const documents: Document[] = await Documents.getInstance().get(query);