This commit is contained in:
Vins 2024-02-16 14:59:49 +01:00
parent c4da62a394
commit 5c5c13c620
12 changed files with 701 additions and 70 deletions

134
package-lock.json generated
View File

@ -22,7 +22,7 @@
"eslint-config-next": "13.2.4",
"form-data": "^4.0.0",
"jwt-decode": "^3.1.2",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.108",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.115",
"next": "13.2.4",
"prettier": "^2.8.7",
"react": "18.2.0",
@ -1436,9 +1436,9 @@
"optional": true
},
"node_modules/bare-fs": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.1.3.tgz",
"integrity": "sha512-Oa7F0QJV7We0mtKq7Tk246uiBrl7vun64cPEsJOEwv2vHjnVL9yO7aH3643aSrd4rXfVe7yhJ9LHZywQQAXKFQ==",
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.1.5.tgz",
"integrity": "sha512-5t0nlecX+N2uJqdxe9d18A98cp2u9BETelbjKpiVgQqzzmVNFYWEAjQHqS+2Khgto1vcwhik9cXucaj5ve2WWA==",
"optional": true,
"dependencies": {
"bare-events": "^2.0.0",
@ -1448,9 +1448,9 @@
}
},
"node_modules/bare-os": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.1.2.tgz",
"integrity": "sha512-slQjOn78Q8itnzomNAamiKo5MDpEpV3JnoNZ93lyynaFh6paWcU+5c0GVcZ7EYIJC2unN2JGdF1qupdscYl0Yg==",
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.2.0.tgz",
"integrity": "sha512-hD0rOPfYWOMpVirTACt4/nK8mC55La12K5fY1ij8HAdfQakD62M+H4o4tpfKzVGLgRDTuk3vjA4GqGXXCeFbag==",
"optional": true
},
"node_modules/bare-path": {
@ -1543,14 +1543,15 @@
}
},
"node_modules/call-bind": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz",
"integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==",
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.3",
"set-function-length": "^1.2.0"
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
@ -1827,17 +1828,19 @@
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
},
"node_modules/define-data-property": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz",
"integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==",
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dependencies": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.2",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.1"
"gopd": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/define-properties": {
@ -1912,9 +1915,9 @@
}
},
"node_modules/dotenv": {
"version": "16.4.2",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.2.tgz",
"integrity": "sha512-rZSSFxke7d9nYQ5NeMIwp5PP+f8wXgKNljpOb7KtH6SKW1cEqcXAz9VSJYVLKe7Jhup/gUYOkaeSVyK8GJ+nBg==",
"version": "16.4.4",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz",
"integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==",
"engines": {
"node": ">=12"
},
@ -1956,49 +1959,51 @@
}
},
"node_modules/es-abstract": {
"version": "1.22.3",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz",
"integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==",
"version": "1.22.4",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz",
"integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==",
"dependencies": {
"array-buffer-byte-length": "^1.0.0",
"arraybuffer.prototype.slice": "^1.0.2",
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.5",
"es-set-tostringtag": "^2.0.1",
"array-buffer-byte-length": "^1.0.1",
"arraybuffer.prototype.slice": "^1.0.3",
"available-typed-arrays": "^1.0.6",
"call-bind": "^1.0.7",
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"es-set-tostringtag": "^2.0.2",
"es-to-primitive": "^1.2.1",
"function.prototype.name": "^1.1.6",
"get-intrinsic": "^1.2.2",
"get-symbol-description": "^1.0.0",
"get-intrinsic": "^1.2.4",
"get-symbol-description": "^1.0.2",
"globalthis": "^1.0.3",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"has-property-descriptors": "^1.0.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0",
"internal-slot": "^1.0.5",
"is-array-buffer": "^3.0.2",
"hasown": "^2.0.1",
"internal-slot": "^1.0.7",
"is-array-buffer": "^3.0.4",
"is-callable": "^1.2.7",
"is-negative-zero": "^2.0.2",
"is-regex": "^1.1.4",
"is-shared-array-buffer": "^1.0.2",
"is-string": "^1.0.7",
"is-typed-array": "^1.1.12",
"is-typed-array": "^1.1.13",
"is-weakref": "^1.0.2",
"object-inspect": "^1.13.1",
"object-keys": "^1.1.1",
"object.assign": "^4.1.4",
"regexp.prototype.flags": "^1.5.1",
"safe-array-concat": "^1.0.1",
"safe-regex-test": "^1.0.0",
"object.assign": "^4.1.5",
"regexp.prototype.flags": "^1.5.2",
"safe-array-concat": "^1.1.0",
"safe-regex-test": "^1.0.3",
"string.prototype.trim": "^1.2.8",
"string.prototype.trimend": "^1.0.7",
"string.prototype.trimstart": "^1.0.7",
"typed-array-buffer": "^1.0.0",
"typed-array-buffer": "^1.0.1",
"typed-array-byte-length": "^1.0.0",
"typed-array-byte-offset": "^1.0.0",
"typed-array-length": "^1.0.4",
"unbox-primitive": "^1.0.2",
"which-typed-array": "^1.1.13"
"which-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
@ -2012,6 +2017,17 @@
"resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz",
"integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA=="
},
"node_modules/es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"dependencies": {
"get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
@ -2021,20 +2037,20 @@
}
},
"node_modules/es-iterator-helpers": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.16.tgz",
"integrity": "sha512-CREG2A9Vq7bpDRnldhFcMKuKArvkZtsH6Y0DHOHVg49qhf+LD8uEdUM3OkOAICv0EziGtDEnQtqY2/mfBILpFw==",
"version": "1.0.17",
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz",
"integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==",
"dependencies": {
"asynciterator.prototype": "^1.0.0",
"call-bind": "^1.0.6",
"call-bind": "^1.0.7",
"define-properties": "^1.2.1",
"es-abstract": "^1.22.3",
"es-abstract": "^1.22.4",
"es-errors": "^1.3.0",
"es-set-tostringtag": "^2.0.2",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"globalthis": "^1.0.3",
"has-property-descriptors": "^1.0.1",
"has-property-descriptors": "^1.0.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"internal-slot": "^1.0.7",
@ -2856,11 +2872,11 @@
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
"integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dependencies": {
"get-intrinsic": "^1.2.2"
"es-define-property": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@ -3442,7 +3458,7 @@
}
},
"node_modules/le-coffre-resources": {
"resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#9e5840c4634a50851ceb7b912737e15b0bbe1c49",
"resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#cc49eea2e6692637edda2335970deaa4221a9201",
"license": "MIT",
"dependencies": {
"class-transformer": "^0.5.1",
@ -3463,9 +3479,9 @@
}
},
"node_modules/libphonenumber-js": {
"version": "1.10.55",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.55.tgz",
"integrity": "sha512-MrTg2JFLscgmTY6/oT9vopYETlgUls/FU6OaeeamGwk4LFxjIgOUML/ZSZICgR0LPYXaonVJo40lzMvaaTJlQA=="
"version": "1.10.56",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.56.tgz",
"integrity": "sha512-d0GdKshNnyfl5gM7kZ9rXjGiAbxT/zCXp0k+EAzh8H4zrb2R7GXtMCrULrX7UQxtfx6CLy/vz/lomvW79FAFdA=="
},
"node_modules/lines-and-columns": {
"version": "1.2.4",
@ -4404,9 +4420,9 @@
}
},
"node_modules/sass": {
"version": "1.70.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz",
"integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==",
"version": "1.71.0",
"resolved": "https://registry.npmjs.org/sass/-/sass-1.71.0.tgz",
"integrity": "sha512-HKKIKf49Vkxlrav3F/w6qRuPcmImGVbIXJ2I3Kg0VMA+3Bav+8yE9G5XmP5lMj6nl4OlqbPftGAscNaNu28b8w==",
"dependencies": {
"chokidar": ">=3.0.0 <4.0.0",
"immutable": "^4.0.0",

View File

@ -24,7 +24,7 @@
"eslint-config-next": "13.2.4",
"form-data": "^4.0.0",
"jwt-decode": "^3.1.2",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.108",
"le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.115",
"next": "13.2.4",
"prettier": "^2.8.7",
"react": "18.2.0",

View File

@ -0,0 +1,53 @@
import { Office } from "le-coffre-resources/dist/SuperAdmin";
import BaseNotary from "../BaseNotary";
export interface IGetOfficesparams {
where?: {};
include?: {};
select?: {};
}
export default class Offices extends BaseNotary {
private static instance: Offices;
private readonly baseURl = this.namespaceUrl.concat("/offices");
private constructor() {
super();
}
public static getInstance() {
if (!this.instance) {
return new this();
} else {
return this.instance;
}
}
public async get(q?: IGetOfficesparams): Promise<Office[]> {
const url = new URL(this.baseURl);
if (q) {
const query = { q };
Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
}
try {
return await this.getRequest<Office[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
/**
* @description : Get a folder by uid
*/
public async getByUid(uid: string, q?: any): Promise<Office> {
const url = new URL(this.baseURl.concat(`/${uid}`));
if (q) Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
try {
return await this.getRequest<Office>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -0,0 +1,62 @@
import BaseNotary from "../../Notary/BaseNotary";
// TODO Type get query params -> Where + inclue + orderby
export interface IGetFilesparams {
where?: {};
include?: {};
}
// TODO Type getbyuid query params
export type IPutFilesParams = {};
export interface IPostFilesParams {}
export default class Bucket extends BaseNotary {
private static instance: Bucket;
private readonly baseURl = this.namespaceUrl.concat("/bucket");
private constructor() {
super();
}
public static getInstance() {
return (this.instance ??= new this());
}
public async getRibStream(uid: string) {
const url = new URL(this.baseURl.concat(`/${uid}`));
try {
return await this.getRequest<any>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
/**
* @description : Create a File
*/
public async post(body: any) {
const url = new URL(this.baseURl);
try {
return await this.postRequestFormData(url, body);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
/**
* @description : Delete a File
*/
public async delete(uid: string) {
const url = new URL(this.baseURl.concat(`/${uid}`));
try {
return await this.deleteRequest(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -15,7 +15,7 @@ export type IPutDocumentTypesParams = {};
export interface IPostDocumentTypesParams {
name: string;
public_description: string;
public_description?: string | null;
private_description: string | null;
office?: {
uid?: string;

View File

@ -133,7 +133,7 @@ export default class DepositDocument extends React.Component<IProps, IState> {
{this.props.document.document_type?.public_description !== " " &&
this.props.document.document_type?.public_description !== "" &&
this.props.document.document_status !== EDocumentStatus.VALIDATED && (
<Tooltip text={this.props.document.document_type?.public_description} />
<Tooltip text={this.props.document.document_type?.public_description || ""} />
)}
{this.props.document.document_status === EDocumentStatus.VALIDATED && (
<Image src={GreenCheckIcon} alt="Document check" />

View File

@ -0,0 +1,108 @@
.container {
.root {
padding: 24px;
background-color: var(--white);
border: 1px dashed #e7e7e7;
height: fit-content;
&[data-drag-over="true"] {
border: 1px dashed var(--grey);
}
&.validated {
border: 1px dashed var(--green-flash);
}
.top-container {
display: flex;
align-items: center;
.left {
margin-right: 28px;
}
.separator {
background-color: #939393;
width: 1px;
align-self: stretch;
}
.right {
margin-left: 18px;
.validated {
color: var(--green-flash);
}
.refused-button {
font-size: 14px;
color: var(--re-hover);
margin-left: 8px;
}
.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;
.loader {
width: 32px;
height: 32px;
}
}
.cross {
cursor: pointer;
}
}
}
.bottom-container {
margin-top: 16px;
.add-button {
.add-document {
display: flex;
align-items: center;
gap: 14px;
}
}
}
.text {
margin-bottom: 12px;
}
}
.modal-content {
display: flex;
flex-direction: column;
gap: 16px;
}
.error-message {
color: var(--red-flash);
margin-top: 8px;
}
}

View File

@ -0,0 +1,178 @@
import React from "react";
import classes from "./classes.module.scss";
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 Button, { EButtonVariant } from "../Button";
import Typography, { ITypo, ITypoColor } from "../Typography";
type IProps = {
onChange: (documentList: File[]) => void;
};
interface IState {
documents: File[];
errorMessage: string;
}
type fileAccepted = {
extension: string;
size: number;
};
const filesAccepted: { [key: string]: fileAccepted } = {
"application/pdf": {
extension: "pdf",
size: 41943040,
},
"image/jpeg": {
extension: "jpeg",
size: 41943040,
},
"image/png": {
extension: "png",
size: 41943040,
},
"image/jpg": {
extension: "jpg",
size: 41943040,
},
};
export default class DepositRib extends React.Component<IProps, IState> {
fileInput: HTMLInputElement | null = null;
constructor(props: IProps) {
super(props);
this.state = {
documents: [],
errorMessage: "",
};
}
handleDrop = (e: React.DragEvent<HTMLDivElement>) => {
e.preventDefault();
const file = e.dataTransfer.files[0];
this.handleFile(file!);
};
handleFile = (file: File) => {
if (file.type === "application/pdf" || file.type === "image/jpeg" || file.type === "image/png") {
this.setState((prevState) => ({
documents: [...prevState.documents, file],
errorMessage: "",
}));
this.props.onChange([...this.state.documents, file]);
} else {
this.setState({ errorMessage: "Only PDF, JPEG, and PNG files are allowed." });
}
};
handleRemove = () => {
const updatedDocuments = [...this.state.documents];
updatedDocuments.splice(0, 1);
this.setState({ documents: updatedDocuments });
this.props.onChange(updatedDocuments);
};
// handleValidate = async () => {
// // Send documents to the backend for validation
// if (this.state.documents.length === 0) return;
// const formData = new FormData();
// formData.append("file", this.state.documents[0]!, this.state.documents[0]!.name);
// const sentFile = await Bucket.getInstance().post(formData);
// console.log("Sent file:", sentFile);
// // Reset documents state
// this.setState({ documents: [] });
// };
// handleCancel = () => {
// console.log("Cancel:", this.state.documents);
// // Reset documents state
// this.setState({ documents: [] });
// };
handleAddFile = (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files && e.target.files[0];
if (file) {
this.handleFile(file);
}
};
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;
}
public override render(): JSX.Element {
return (
<div className={classes["container"]}>
<div className={classes["root"]} onDragOver={(e) => e.preventDefault()} onDrop={(e) => this.handleDrop(e)}>
<input
type="file"
accept={Object.keys(filesAccepted).join(",")}
onChange={this.handleAddFile}
style={{ display: "none" }}
ref={(input) => (this.fileInput = input)}
/>
<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"]}>
<div>Déposer un RIB</div>
</Typography>
<Typography color={ITypoColor.GREY} typo={ITypo.CAPTION_14}>
Sélectionnez des documents .jpg, .pdf ou .png
</Typography>
</div>
</div>
<div className={classes["documents-container"]}>
{this.state.documents.map((file) => {
return (
<div className={classes["file-container"]} key="0">
<div className={classes["left-part"]}>
<Image src={DocumentCheckIcon} alt="Document check" />
<Typography typo={ITypo.P_16} color={ITypoColor.GREY} title={file.name}>
{this.shortName(file.name)}
</Typography>
</div>
<Image
src={CrossIcon}
alt="Cross icon"
className={classes["cross"]}
onClick={() => this.handleRemove()}
/>
</div>
);
})}
</div>
<div className={classes["bottom-container"]}>
<Button variant={EButtonVariant.LINE} className={classes["add-button"]} onClick={() => this.fileInput!.click()}>
<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>
{/* <button onClick={this.handleValidate}>Enregistrer</button>
<button onClick={this.handleCancel}>Annuler</button> */}
</div>
{this.state.errorMessage && <div style={{ color: "red" }}>{this.state.errorMessage}</div>}
</div>
);
}
}

View File

@ -18,7 +18,7 @@ export default function DocumentTypesEdit() {
let { documentTypeUid } = router.query;
const [documentTypeSelected, setDocumentTypeSelected] = useState<DocumentType | null>(null);
const [validationError, setValidationError] = useState<ValidationError[]>([])
const [validationError, setValidationError] = useState<ValidationError[]>([]);
useEffect(() => {
async function getDocumentType() {
@ -43,7 +43,7 @@ export default function DocumentTypesEdit() {
await validateOrReject(documentToUpdate, { groups: ["updateDocumentType"] });
} catch (validationErrors: Array<ValidationError> | any) {
console.log(validationErrors);
if(!Array.isArray(validationErrors)) return;
if (!Array.isArray(validationErrors)) return;
setValidationError(validationErrors as ValidationError[]);
return;
}
@ -58,7 +58,7 @@ export default function DocumentTypesEdit() {
),
);
} catch (validationErrors: Array<ValidationError> | any) {
if(!Array.isArray(validationErrors)) return;
if (!Array.isArray(validationErrors)) return;
setValidationError(validationErrors as ValidationError[]);
return;
}
@ -73,7 +73,12 @@ export default function DocumentTypesEdit() {
<Typography typo={ITypo.H1Bis}>Paramétrage des documents</Typography>
</div>
<Form onSubmit={onSubmitHandler} className={classes["form-container"]}>
<TextField name="name" placeholder="Nom du document" defaultValue={documentTypeSelected?.name} validationError={validationError.find((error) => error.property === "name")} />
<TextField
name="name"
placeholder="Nom du document"
defaultValue={documentTypeSelected?.name}
validationError={validationError.find((error) => error.property === "name")}
/>
<TextAreaField
name="private_description"
placeholder="Description visible par les collaborateurs de l'office"
@ -83,7 +88,7 @@ export default function DocumentTypesEdit() {
<TextAreaField
name="public_description"
placeholder="Description visible par les clients de l'office"
defaultValue={documentTypeSelected?.public_description}
defaultValue={documentTypeSelected?.public_description ?? ""}
validationError={validationError.find((error) => error.property === "public_description")}
/>
<div className={classes["buttons-container"]}>

View File

@ -0,0 +1,68 @@
@import "@Themes/constants.scss";
.root {
.title {
margin-top: 24px;
}
.subtitle {
margin-top: 32px;
}
.document-container {
margin-top: 32px;
gap: 64px;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
.arrow-container {
cursor: pointer;
&[data-disabled="true"] {
opacity: 0.3;
cursor: not-allowed;
}
}
.file-container {
max-width: 1000px;
margin: auto;
flex: 1;
}
}
.footer {
width: fit-content;
margin: auto;
.ocr-container {
margin-top: 42px;
}
.buttons-container {
display: flex;
gap: 24px;
justify-content: center;
margin-top: 32px;
@media (max-width: $screen-s) {
flex-direction: column-reverse;
}
}
}
.refuse-document-container {
.refuse-text {
margin-bottom: 24px;
}
}
.validate-document-container {
.document-validating-container {
.validate-gif {
width: 100%;
height: 100%;
object-fit: contain;
}
}
}
}

View File

@ -0,0 +1,136 @@
import React, { useState } from "react";
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import classes from "./classes.module.scss";
import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate";
import FilePreview from "@Front/Components/DesignSystem/FilePreview";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import { useRouter } from "next/router";
import Bucket from "@Front/Api/LeCoffreApi/Notary/Bucket/Bucket";
import DepositRib from "@Front/Components/DesignSystem/DepositRib";
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
export default function Rib() {
const [documentList, setDocumentList] = useState<File[]>([]);
const router = useRouter();
let { officeUid } = router.query;
const [fileUrl, setFileUrl] = useState<string>("");
const [fileName, setFileName] = useState<string>("");
const [key, setKey] = useState<string>("");
const [isRibModalOpen, setIsRibModalOpen] = useState<boolean>(false);
const fetchData = async () => {
if (!officeUid) return;
const blob = await Bucket.getInstance().getRibStream(officeUid as string);
if (!blob) {
setFileUrl("");
setFileName("");
setKey("");
}
const ribUrl = URL.createObjectURL(blob);
setFileUrl(ribUrl);
setKey(key);
setFileName(key);
};
async function deleteFile() {
if (!officeUid) return;
await Bucket.getInstance().delete(officeUid as string);
setDocumentList([]);
fetchData();
}
function downloadFile() {
if (!fileUrl) return;
const a = document.createElement("a");
a.style.display = "none";
a.href = fileUrl;
a.download = key;
document.body.appendChild(a);
a.click();
}
async function onRibModalAccepted() {
// Send documents to the backend for validation
if (documentList.length === 0) return;
const formData = new FormData();
formData.append("file", documentList[0]!, documentList[0]!.name);
await Bucket.getInstance().post(formData);
setDocumentList([]);
setIsRibModalOpen(false);
fetchData();
}
function onCloseRibModal(): void {
setDocumentList([]);
setIsRibModalOpen(false);
}
function openRibModal(): void {
setIsRibModalOpen(true);
}
const onDocumentChange = (documentList: File[]) => {
setDocumentList(documentList);
};
return (
<DefaultTemplate title={"Rib"}>
<div className={classes["root"]}>
<Typography typo={ITypo.H1} color={ITypoColor.BLACK} className={classes["title"]}>
Rib de l'office
</Typography>
{!fileUrl && (
<div className={classes["document-container"]}>
<div className={classes["file-container"]}>
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
Aucun RIB n'a é déposé pour cet office
</Typography>
</div>
<div className={classes["footer"]}>
<div className={classes["buttons-container"]}>
<Button onClick={openRibModal}>Déposer un RIB</Button>
</div>
</div>
</div>
)}
{fileUrl && (
<div className={classes["document-container"]}>
<div className={classes["file-container"]}>{fileUrl && <FilePreview href={fileUrl} fileName={fileName} />}</div>
<div className={classes["footer"]}>
<Button onClick={deleteFile} variant={EButtonVariant.SECONDARY}>
Supprimer
</Button>
<Button onClick={openRibModal} variant={EButtonVariant.GHOST}>
Modifier
</Button>
<Button onClick={downloadFile}>Télécharger</Button>
</div>
</div>
)}
<Confirm
isOpen={isRibModalOpen}
onAccept={onRibModalAccepted}
onClose={onCloseRibModal}
closeBtn
cancelText={"Annuler"}
confirmText={"Enregistrer"}>
<DepositRib onChange={onDocumentChange} />
</Confirm>
{/* <div className={classes["footer"]}>
<DepositRib />
<Button variant={EButtonVariant.SECONDARY}>Supprimer</Button>
<Button variant={EButtonVariant.GHOST}>Modifier</Button>
<Button onClick={downloadFile}>Télécharger</Button>
</div> */}
</div>
</DefaultTemplate>
);
}

View File

@ -0,0 +1,5 @@
import Rib from "@Front/Components/Layouts/Rib";
export default function Route() {
return <Rib />;
}