Merge branch 'dev' of https://github.com/smart-chain-fr/leCoffre-front into dev
This commit is contained in:
commit
39dd0ea84d
6
src/front/Assets/Icons/deposit-document.svg
Normal file
6
src/front/Assets/Icons/deposit-document.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M17.5 2.5H7.5C6.83696 2.5 6.20107 2.76339 5.73223 3.23223C5.26339 3.70107 5 4.33696 5 5V25C5 25.663 5.26339 26.2989 5.73223 26.7678C6.20107 27.2366 6.83696 27.5 7.5 27.5H22.5C23.163 27.5 23.7989 27.2366 24.2678 26.7678C24.7366 26.2989 25 25.663 25 25V10L17.5 2.5Z" stroke="#320756" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M15 22.5V15" stroke="#C5B2D4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M11.25 18.75H18.75" stroke="#C5B2D4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M17.5 2.5V10H25" stroke="#320756" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 786 B |
4
src/front/Assets/Icons/document-check.svg
Normal file
4
src/front/Assets/Icons/document-check.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M32 16C32 24.8366 24.8366 32 16 32C7.16344 32 0 24.8366 0 16C0 7.16344 7.16344 0 16 0C24.8366 0 32 7.16344 32 16ZM4 16C4 22.6274 9.37258 28 16 28C22.6274 28 28 22.6274 28 16C28 9.37258 22.6274 4 16 4C9.37258 4 4 9.37258 4 16Z" fill="#3FA79E"/>
|
||||||
|
<path d="M22 12L13.75 20.5714L10 16.6753" stroke="#3FA79E" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 483 B |
@ -0,0 +1,69 @@
|
|||||||
|
.root {
|
||||||
|
padding: 24px;
|
||||||
|
background-color: white;
|
||||||
|
border: 1px dashed #e7e7e7;
|
||||||
|
|
||||||
|
height: fit-content;
|
||||||
|
&[data-drag-over="true"] {
|
||||||
|
border: 1px dashed grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.left {
|
||||||
|
margin-right: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.separator {
|
||||||
|
background-color: #939393;
|
||||||
|
width: 1px;
|
||||||
|
align-self: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
margin-left: 18px;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.documents-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 16px;
|
||||||
|
margin-top: 16px;
|
||||||
|
|
||||||
|
.file-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.left-part {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cross{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-container {
|
||||||
|
margin-top: 16px;
|
||||||
|
.add-button {
|
||||||
|
.add-document {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
196
src/front/Components/DesignSystem/DepositDocument/index.tsx
Normal file
196
src/front/Components/DesignSystem/DepositDocument/index.tsx
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
@ -27,12 +27,15 @@
|
|||||||
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
background: white;
|
||||||
|
opacity: 0.6;
|
||||||
~ .fake-placeholder {
|
~ .fake-placeholder {
|
||||||
|
color: rgba($grey, 0.6);
|
||||||
/**
|
/**
|
||||||
TODO
|
TODO
|
||||||
* 1. Add styles so the placeholder has the same color as the background when disabled
|
* 1. Add styles so the placeholder has the same color as the background when disabled
|
||||||
*/
|
*/
|
||||||
background: transparent;
|
// background: transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&:focus {
|
&:focus {
|
||||||
|
@ -130,6 +130,10 @@
|
|||||||
color: var(--purple-flash);
|
color: var(--purple-flash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.pink-flash {
|
||||||
|
color: var(--pink-flash);
|
||||||
|
}
|
||||||
|
|
||||||
&.green-flash {
|
&.green-flash {
|
||||||
color: var(--green-flash);
|
color: var(--green-flash);
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ export enum ITypoColor {
|
|||||||
GREY = "grey",
|
GREY = "grey",
|
||||||
BLACK = "black",
|
BLACK = "black",
|
||||||
PURPLE_FLASH = "purple-flash",
|
PURPLE_FLASH = "purple-flash",
|
||||||
|
PINK_FLASH = "pink-flash",
|
||||||
GREEN_FLASH = "green-flash",
|
GREEN_FLASH = "green-flash",
|
||||||
ORANGE_FLASH = "orange-flash",
|
ORANGE_FLASH = "orange-flash",
|
||||||
RED_FLASH = "red-flash",
|
RED_FLASH = "red-flash",
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
|
import DepositDocument from "@Front/Components/DesignSystem/DepositDocument";
|
||||||
|
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
||||||
|
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||||
import Base from "@Front/Components/Layouts/Base";
|
import Base from "@Front/Components/Layouts/Base";
|
||||||
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
|
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { documentDeposited } from "../DesignSystem/dummyData";
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
|
||||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
|
||||||
import InputField from "@Front/Components/DesignSystem/Form/Elements/InputField";
|
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
type IState = {
|
type IState = {
|
||||||
@ -30,19 +31,23 @@ export default class ClientDashboard extends Base<IProps, IState> {
|
|||||||
{this.renderHeader()}
|
{this.renderHeader()}
|
||||||
<div className={classes["sub-container"]}>
|
<div className={classes["sub-container"]}>
|
||||||
<div className={classes["content"]}>
|
<div className={classes["content"]}>
|
||||||
<div className={classes["component-to-replace"]}></div>
|
<DepositDocument
|
||||||
<div className={classes["component-to-replace"]}></div>
|
title={"Carte d'identité - recto-verso"}
|
||||||
<div className={classes["component-to-replace"]}></div>
|
dateAsked={new Date()}
|
||||||
<div className={classes["component-to-replace"]}></div>
|
defaultFiles={documentDeposited.files ?? []}
|
||||||
<div className={classes["component-to-replace"]}></div>
|
/>
|
||||||
<div className={classes["component-to-replace"]}></div>
|
<DepositDocument title={"Carte d'identité - recto-verso"} dateAsked={new Date()} />
|
||||||
|
<DepositDocument title={"Carte d'identité - recto-verso"} dateAsked={new Date()} />
|
||||||
|
<DepositDocument title={"Carte d'identité - recto-verso"} dateAsked={new Date()} />
|
||||||
|
<DepositDocument title={"Carte d'identité - recto-verso"} dateAsked={new Date()} />
|
||||||
|
<DepositDocument title={"Carte d'identité - recto-verso"} dateAsked={new Date()} />
|
||||||
</div>
|
</div>
|
||||||
<Typography typo={ITypo.H2}>Documents supplémentaires (facultatif)</Typography>
|
<Typography typo={ITypo.H2}>Documents supplémentaires (facultatif)</Typography>
|
||||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
||||||
Vous souhaitez envoyer d’autres documents à votre notaire ?
|
Vous souhaitez envoyer d'autres documents à votre notaire ?
|
||||||
</Typography>
|
</Typography>
|
||||||
<Button variant={EButtonVariant.GHOST} className={classes["button"]} onClick={this.onOpenModalAddDocument}>
|
<Button variant={EButtonVariant.GHOST} className={classes["button"]} onClick={this.onOpenModalAddDocument}>
|
||||||
Ajouter d’autres documents
|
Ajouter d'autres documents
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Confirm
|
<Confirm
|
||||||
@ -62,7 +67,7 @@ export default class ClientDashboard extends Base<IProps, IState> {
|
|||||||
Glissez / Déposez votre document dans la zone prévue à cet effet ou cliquez sur la zone puis sélectionnez le
|
Glissez / Déposez votre document dans la zone prévue à cet effet ou cliquez sur la zone puis sélectionnez le
|
||||||
document correspondant.
|
document correspondant.
|
||||||
</Typography>
|
</Typography>
|
||||||
<div className={classes["component-to-replace"]}></div>
|
<DepositDocument title={"Carte d'identité - recto-verso"} dateAsked={new Date()} />
|
||||||
</div>
|
</div>
|
||||||
</Confirm>
|
</Confirm>
|
||||||
</div>
|
</div>
|
||||||
@ -84,7 +89,7 @@ export default class ClientDashboard extends Base<IProps, IState> {
|
|||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
<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.
Veuillez
|
Votre notaire est dans l'attente de documents pour valider votre dossier. Voici la liste des documents.Veuillez
|
||||||
glisser / déposez chaque document dans la zone prévue à cet effet ou cliquez sur la zone puis sélectionnez le
|
glisser / déposez chaque document dans la zone prévue à cet effet ou cliquez sur la zone puis sélectionnez le
|
||||||
document correspondant. Si un des documents demandés ne vous concernent pas, veuillez contacter votre notaire à
|
document correspondant. Si un des documents demandés ne vous concernent pas, veuillez contacter votre notaire à
|
||||||
l’aide du bouton ci-dessus.
|
l’aide du bouton ci-dessus.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user