diff --git a/package.json b/package.json index d56f6410..23f59498 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "react-select": "^5.7.2", "sass": "^1.59.2", "sharp": "^0.32.1", - "typescript": "4.9.5" - }, - "devDependencies": {} + "typescript": "4.9.5", + "uuidv4": "^6.2.13" + } } diff --git a/src/front/Api/BaseApiService.ts b/src/front/Api/BaseApiService.ts index cd6e75d7..dfa17f91 100644 --- a/src/front/Api/BaseApiService.ts +++ b/src/front/Api/BaseApiService.ts @@ -1,8 +1,10 @@ import { FrontendVariables } from "@Front/Config/VariablesFront"; import CookieService from "@Front/Services/CookieService/CookieService"; +import { uuid } from "uuidv4"; export enum ContentType { JSON = "application/json", + PDF = "application/pdf", FORM_DATA = "multipart/form-data;", } export default abstract class BaseApiService { @@ -26,7 +28,7 @@ export default abstract class BaseApiService { const headers = new Headers(); - if (contentType === ContentType.JSON) { + if (contentType === ContentType.JSON || contentType === ContentType.PDF) { headers.set("Content-Type", contentType); } headers.set("Authorization", `Bearer ${token}`); @@ -37,13 +39,13 @@ export default abstract class BaseApiService { return JSON.stringify(body); } - protected async getRequest(url: URL, token?: string) { + protected async getRequest(url: URL, token?: string, contentType?: ContentType, filename?: string) { const request = async () => await fetch(url, { method: "GET", - headers: this.buildHeaders(ContentType.JSON), + headers: this.buildHeaders(contentType ?? ContentType.JSON), }); - return this.sendRequest(request); + return this.sendRequest(request, filename); } protected async postRequest(url: URL, body: { [key: string]: unknown } = {}, token?: string) { @@ -112,25 +114,51 @@ export default abstract class BaseApiService { return this.sendRequest(request); } - private async sendRequest(request: () => Promise): Promise { + private async sendRequest(request: () => Promise, filename?: string): Promise { const response = await request(); - return this.processResponse(response, request); + return this.processResponse(response, request, filename); } - protected async processResponse(response: Response, request: () => Promise): Promise { - let responseJson: any | null; - try { - responseJson = await response.json(); - } catch (err: unknown) { - responseJson = null; - return Promise.reject(err); + protected async processResponse(response: Response, request: () => Promise, filename?: string): Promise { + let responseContent: T; + + if (response.ok) { + // Check the Content-Type header to determine the response type + const contentType = response.headers.get("Content-Type"); + + if (contentType && contentType.includes("application/octet-stream")) { + // Handle PDF response + const blob = await response.blob(); + const url = URL.createObjectURL(blob); + + const anchor = document.createElement("a"); + + anchor.href = url; + anchor.download = filename ?? `${uuid()}.pdf`; + anchor.click(); + + URL.revokeObjectURL(url); + + responseContent = {} as T; + } else { + // Handle JSON response + try { + responseContent = await response.json(); + } catch (err) { + return Promise.reject(err); + } + } + } else { + // Handle error response + try { + const responseJson = await response.json(); + return Promise.reject(responseJson); + } catch (err) { + return Promise.reject(err); + } } - if (!response.ok) { - return Promise.reject(responseJson); - } - - return responseJson as T; + return responseContent; } protected onError(error: unknown) { diff --git a/src/front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors.ts b/src/front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors.ts new file mode 100644 index 00000000..24cab51f --- /dev/null +++ b/src/front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors.ts @@ -0,0 +1,52 @@ +import { ContentType } from "@Front/Api/BaseApiService"; +import BaseNotary from "../BaseNotary"; + +import CookieService from "@Front/Services/CookieService/CookieService"; + +export default class OfficeFolderAnchors extends BaseNotary { + private static instance: OfficeFolderAnchors; + private readonly baseURl = this.namespaceUrl.concat("/anchors"); + + private constructor() { + super(); + } + + public static getInstance() { + if (!this.instance) { + return new this(); + } else { + return this.instance; + } + } + + public async get(uid: string): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + try { + return await this.getRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async post(uid: string): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + try { + return await this.postRequest(url, {}); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async download(uid: string): Promise { + const url = new URL(this.baseURl.concat(`/download/${uid}`)); + try { + return await this.getRequest(url, undefined, ContentType.PDF, `${uid}.pdf`); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + +} diff --git a/src/front/Components/Layouts/Folder/FolderInformation/index.tsx b/src/front/Components/Layouts/Folder/FolderInformation/index.tsx index 970061a1..b8f824e6 100644 --- a/src/front/Components/Layouts/Folder/FolderInformation/index.tsx +++ b/src/front/Components/Layouts/Folder/FolderInformation/index.tsx @@ -1,5 +1,6 @@ import ChevronIcon from "@Assets/Icons/chevron.svg"; import Folders from "@Front/Api/LeCoffreApi/Notary/Folders/Folders"; +import OfficeFolderAnchors from "@Front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors"; import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; import FolderBoxInformation, { EFolderBoxInformationType } from "@Front/Components/DesignSystem/FolderBoxInformation"; import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField"; @@ -112,6 +113,11 @@ class FolderInformationClass extends BasePage { Ancrer le dossier )} + {this.everyDocumentValidated() && ( + + )} {!this.doesFolderHaveCustomer() && ( @@ -235,6 +241,7 @@ class FolderInformationClass extends BasePage { try { const timeoutDelay = 9800; + await this.anchorFolder(); setTimeout(() => { this.setState({ isValidateModalVisible: false, @@ -246,6 +253,29 @@ class FolderInformationClass extends BasePage { hasValidateAnchoring: false, }); }, timeoutDelay + 1000); + } catch (e) { + this.setState({ + isValidateModalVisible: false, + hasValidateAnchoring: false, + }); + console.error(e); + } + } + + private async anchorFolder() { + if (!this.state.selectedFolder?.uid) return; + const anchor = await OfficeFolderAnchors.getInstance().post(this.state.selectedFolder.uid); + console.log(anchor); + } + + private async downloadAnchoringProof(uid?: string) { + if (!uid) return; + + const anchor = await OfficeFolderAnchors.getInstance().get(uid); + if (anchor.transactions[0].status !== "VERIFIED_ON_CHAIN") return; + + try { + await OfficeFolderAnchors.getInstance().download(uid); } catch (e) { console.error(e); }