2023-05-02 10:01:04 +02:00

197 lines
5.4 KiB
TypeScript

import DepositDocumentIcon from "@Assets/Icons/deposit-document.svg";
import PlusIcon from "@Assets/Icons/plus.svg";
import CrossIcon from "@Assets/Icons/cross.svg";
import DocumentCheckIcon from "@Assets/Icons/document-check.svg";
import Image from "next/image";
import React from "react";
import Button, { EButtonVariant } from "../Button";
import Tooltip from "../ToolTip";
import Typography, { ITypo, ITypoColor } from "../Typography";
import classes from "./classes.module.scss";
import { File as FileCustomer } from "le-coffre-resources/dist/Customer";
type IProps = {
title: string;
dateAsked: Date;
defaultFiles?: FileCustomer[];
onChange?: (files: File[]) => void;
};
type IFile = {
index: number;
file: File;
};
type IState = {
files: IFile[];
isDragOver: boolean;
};
export default class DepositDocument extends React.Component<IProps, IState> {
private inputRef = React.createRef<HTMLInputElement>();
private index = 0;
public constructor(props: IProps) {
super(props);
this.state = {
files: [],
isDragOver: false,
};
this.addDocument = this.addDocument.bind(this);
this.onFileChange = this.onFileChange.bind(this);
this.removeFile = this.removeFile.bind(this);
this.onDragOver = this.onDragOver.bind(this);
this.onDragDrop = this.onDragDrop.bind(this);
this.onDragLeave = this.onDragLeave.bind(this);
}
public override render(): JSX.Element {
return (
<div
className={classes["root"]}
onDragOver={this.onDragOver}
onDrop={this.onDragDrop}
onDragLeave={this.onDragLeave}
data-drag-over={this.state.isDragOver.toString()}>
<input type="file" ref={this.inputRef} hidden onChange={this.onFileChange} />
<div className={classes["top-container"]}>
<div className={classes["left"]}>
<Image src={DepositDocumentIcon} alt="Deposit document" />
</div>
<div className={classes["separator"]} />
<div className={classes["right"]}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.BLACK} className={classes["title"]}>
{this.props.title} <Tooltip text={"Blabla"} />
</Typography>
<Typography typo={ITypo.CAPTION_14} color={ITypoColor.GREY}>
Demandé par le notaire le {this.formatDate(this.props.dateAsked)}
</Typography>
</div>
</div>
{this.state.files.length > 0 && (
<div className={classes["documents-container"]}>
{this.state.files.map((file) => {
const fileObj = file.file;
return (
<div className={classes["file-container"]} key={fileObj.name + file.index}>
<div className={classes["left-part"]}>
<Image src={DocumentCheckIcon} alt="Document check" />
<Typography typo={ITypo.P_16} color={ITypoColor.GREY}>
{this.shortName(fileObj.name)}
</Typography>
</div>
<Image
src={CrossIcon}
alt="Cross icon"
className={classes["cross"]}
onClick={this.removeFile}
data-file={file.index}
/>
</div>
);
})}
</div>
)}
<div className={classes["bottom-container"]}>
<Button variant={EButtonVariant.LINE} className={classes["add-button"]} onClick={this.addDocument}>
<Typography typo={ITypo.P_SB_16} color={ITypoColor.PINK_FLASH} className={classes["add-document"]}>
Ajouter un document <Image src={PlusIcon} alt="Plus icon" />
</Typography>
</Button>
</div>
</div>
);
}
public override componentDidMount(): void {
if (this.props.defaultFiles) {
this.setState({
files: this.props.defaultFiles.map((file) => ({
index: this.index++,
file: new File([""], file.file_path, {}),
})),
});
}
}
private shortName(name: string): string {
const maxLength = 20;
if (name.length > maxLength) {
return name.substring(0, maxLength / 2) + "..." + name.substring(name.length - maxLength / 2, name.length);
}
return name;
}
private onDragOver(event: React.DragEvent<HTMLDivElement>) {
if (!this.state.isDragOver) {
this.setState({
isDragOver: true,
});
}
event.preventDefault();
}
private onDragLeave(event: React.DragEvent<HTMLDivElement>) {
this.setState({
isDragOver: false,
});
event.preventDefault();
}
private async onDragDrop(event: React.DragEvent<HTMLDivElement>) {
event.preventDefault();
this.setState({
isDragOver: false,
});
const file = event.dataTransfer.files[0];
if (file) this.addFile(file);
}
private 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));
}
private removeFile(e: any) {
const image = e.target as HTMLElement;
const indexToRemove = image.getAttribute("data-file");
if (!indexToRemove) 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));
}
private async onFileChange() {
if (!this.inputRef.current) return;
const files = this.inputRef.current.files;
if (!files) return;
const file = files[0];
if (file) this.addFile(file);
}
private addDocument() {
if (!this.inputRef.current) return;
this.inputRef.current.click();
}
private formatDate(date: Date) {
return date.toLocaleDateString("fr-FR");
}
}