diff --git a/.ssh/id_rsa.pub b/.ssh/id_rsa.pub deleted file mode 100644 index e1327d66..00000000 --- a/.ssh/id_rsa.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDOfOFPvQNw5XguFuX1YNvED8ulP+tIA/5xw7LHcA0gRj3hwILCAEAjuDs+d13zCsnEb0yd+laT3PU9iRIKa28Tynu+sTjGDyfx8MX/HjJtbEzyd6jLn87uTvw/6lzg2y5ZDEa6PEqrPIv0KEhuq6HuU8qAA0nBpsTIAUTK3XR8qm3I6J9Rs1JyBjvIP5UeICApvoLmgHuz6mKdvoQ8qKDWamsL4pSc4Hr7HlQ8ITNhnyS8XMgQInU/I2TzT/I4Dxx5IeFUQ5KOfJJNgK1d+PByLSWUrn+eRXki8m1hjMiwGIehVAriFW1C309SEHxLHjQKUPXHSv4kH7zqjO+p3kY5gwp/lvsBRSnihj8s1lADsJlMqjnSLeIQ+sY2CNkmXXI8ABkzhuJKTGTl+8pzGGhIHzeU7e7lpSn3gLn4p217kIppHNAr6dZH9UaYbgnwVonwr5cLbatRPFyI1NfXKDyZtSYlGQxLQUt9KDrNvVTZzaTt3YwM/YCsRIADAagKosM= gisele-smartchain@MacBook-Pro-6.local diff --git a/package-lock.json b/package-lock.json index c41f42fc..6bff1c1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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.119", "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" @@ -1568,9 +1569,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001587", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz", - "integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==", + "version": "1.0.30001588", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", + "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", "funding": [ { "type": "opencollective", @@ -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#de8a3be3ddad5e2b583f52f9830e7a10b0fc2e4c", "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", @@ -4609,9 +4625,9 @@ } }, "node_modules/streamx": { - "version": "2.15.8", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.8.tgz", - "integrity": "sha512-6pwMeMY/SuISiRsuS8TeIrAzyFbG5gGPHFQsYjUr/pbBadaL1PCWmzKw+CHZSwainfvcF6Si6cVLq4XTEwswFQ==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.0.tgz", + "integrity": "sha512-a7Fi0PoUeusrUcMS4+HxivnZqYsw2MFEP841TIyLxTcEIucHcJsk+0ARcq3tGq1xDn+xK7sKHetvfMzI1/CzMA==", "dependencies": { "fast-fifo": "^1.1.0", "queue-tick": "^1.0.1" @@ -4922,15 +4938,16 @@ } }, "node_modules/typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.1.tgz", + "integrity": "sha512-tcqKMrTRXjqvHN9S3553NPCaGL0VPgFI92lXszmrE8DMhiDPLBYLlvo8Uu4WZAAX/aGqp/T1sbA4ph8EWjDF9Q==", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.6", + "call-bind": "^1.0.7", "for-each": "^0.3.3", + "gopd": "^1.0.1", "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "is-typed-array": "^1.1.13" }, "engines": { "node": ">= 0.4" diff --git a/package.json b/package.json index eeb5e5f3..f95223f1 100644 --- a/package.json +++ b/package.json @@ -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.119", "next": "13.2.4", "prettier": "^2.8.7", "react": "18.2.0", diff --git a/src/common/Api/LeCoffreApi/Notary/Offices/Offices.ts b/src/common/Api/LeCoffreApi/Notary/Offices/Offices.ts new file mode 100644 index 00000000..ef825aba --- /dev/null +++ b/src/common/Api/LeCoffreApi/Notary/Offices/Offices.ts @@ -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 { + 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(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + /** + * @description : Get a folder by uid + */ + public async getByUid(uid: string, q?: any): Promise { + 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(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Api/BaseApiService.ts b/src/front/Api/BaseApiService.ts index 198141b2..40de30f5 100644 --- a/src/front/Api/BaseApiService.ts +++ b/src/front/Api/BaseApiService.ts @@ -7,6 +7,10 @@ export enum ContentType { FORM_DATA = "multipart/form-data;", PNG = "image/png", } + +export type IRef = { + response?: Response; +}; export default abstract class BaseApiService { private static baseUrl: string; protected readonly variables = FrontendVariables.getInstance(); @@ -39,13 +43,13 @@ export default abstract class BaseApiService { return JSON.stringify(body); } - protected async getRequest(url: URL, token?: string, contentType?: ContentType, filename?: string) { + protected async getRequest(url: URL, token?: string, contentType?: ContentType, ref?: IRef, fileName?: string) { const request = async () => await fetch(url, { method: "GET", headers: this.buildHeaders(contentType ?? ContentType.JSON), }); - return this.sendRequest(request, filename); + return this.sendRequest(request, ref, fileName); } protected async postRequest(url: URL, body: { [key: string]: unknown } = {}, token?: string) { @@ -114,18 +118,18 @@ export default abstract class BaseApiService { return this.sendRequest(request); } - private async sendRequest(request: () => Promise, filename?: string): Promise { + private async sendRequest(request: () => Promise, ref?: IRef, fileName?: string): Promise { const response = await request(); - return this.processResponse(response, request, filename); + + return this.processResponse(response, request, ref, fileName); } - protected async processResponse(response: Response, request: () => Promise, filename?: string): Promise { + protected async processResponse(response: Response, request: () => Promise, ref?: IRef, fileName?: string): Promise { let responseContent: T; - + ref && (ref["response"] = response); 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/json")) { responseContent = (await response.blob()) as T; } else { diff --git a/src/front/Api/Entities/rule.ts b/src/front/Api/Entities/rule.ts index ac4a0282..764f4720 100644 --- a/src/front/Api/Entities/rule.ts +++ b/src/front/Api/Entities/rule.ts @@ -17,4 +17,5 @@ export enum AppRuleNames { deedTypes = "deed-types", offices = "offices", documents = "documents", + rib = "rib", } diff --git a/src/front/Api/LeCoffreApi/Customer/OfficeRib/OfficeRib.ts b/src/front/Api/LeCoffreApi/Customer/OfficeRib/OfficeRib.ts new file mode 100644 index 00000000..23faeb0e --- /dev/null +++ b/src/front/Api/LeCoffreApi/Customer/OfficeRib/OfficeRib.ts @@ -0,0 +1,36 @@ +import BaseNotary from "../BaseCustomer"; + +// 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 OfficeRib extends BaseNotary { + private static instance: OfficeRib; + private readonly baseURl = this.namespaceUrl.concat("/office"); + + private constructor() { + super(); + } + + public static getInstance() { + return (this.instance ??= new this()); + } + + public async getRibStream(uid: string) { + const url = new URL(this.baseURl.concat(`/${uid}/rib`)); + try { + return await this.getRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Api/LeCoffreApi/Notary/DocumentTypes/DocumentTypes.ts b/src/front/Api/LeCoffreApi/Notary/DocumentTypes/DocumentTypes.ts index f73255e3..6fc75302 100644 --- a/src/front/Api/LeCoffreApi/Notary/DocumentTypes/DocumentTypes.ts +++ b/src/front/Api/LeCoffreApi/Notary/DocumentTypes/DocumentTypes.ts @@ -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; diff --git a/src/front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors.ts b/src/front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors.ts index 52735f61..11cbd40b 100644 --- a/src/front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors.ts +++ b/src/front/Api/LeCoffreApi/Notary/OfficeFolderAnchors/OfficeFolderAnchors.ts @@ -60,7 +60,7 @@ export default class OfficeFolderAnchors extends BaseNotary { 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`); + return await this.getRequest(url, undefined, ContentType.PDF, undefined, `${uid}.pdf`); } catch (err) { this.onError(err); return Promise.reject(err); diff --git a/src/front/Api/LeCoffreApi/Notary/OfficeRib/OfficeRib.ts b/src/front/Api/LeCoffreApi/Notary/OfficeRib/OfficeRib.ts new file mode 100644 index 00000000..9b9432eb --- /dev/null +++ b/src/front/Api/LeCoffreApi/Notary/OfficeRib/OfficeRib.ts @@ -0,0 +1,68 @@ +import { IRef } from "@Front/Api/BaseApiService"; +import BaseNotary from "../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 OfficeRib extends BaseNotary { + private static instance: OfficeRib; + private readonly baseURl = this.namespaceUrl.concat("/office/rib"); + + private constructor() { + super(); + } + + public static getInstance() { + return (this.instance ??= new this()); + } + + public async getRibStream() { + const url = new URL(this.baseURl); + try { + const ref: IRef = {}; + const blob = await this.getRequest(url, undefined, undefined, ref); + const contentDisposition = ref.response?.headers.get("Content-Disposition"); + const r = /attachment; filename="(.*)"/gim; + const fileName = r.exec(contentDisposition ?? "")?.[1] ?? ""; + return { blob, fileName }; + } 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() { + const url = new URL(this.baseURl); + try { + return await this.deleteRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Components/DesignSystem/DepositDocument/index.tsx b/src/front/Components/DesignSystem/DepositDocument/index.tsx index b7cf8644..be8b8184 100644 --- a/src/front/Components/DesignSystem/DepositDocument/index.tsx +++ b/src/front/Components/DesignSystem/DepositDocument/index.tsx @@ -133,7 +133,7 @@ export default class DepositDocument extends React.Component { {this.props.document.document_type?.public_description !== " " && this.props.document.document_type?.public_description !== "" && this.props.document.document_status !== EDocumentStatus.VALIDATED && ( - + )} {this.props.document.document_status === EDocumentStatus.VALIDATED && ( Document check diff --git a/src/front/Components/DesignSystem/DepositRib/classes.module.scss b/src/front/Components/DesignSystem/DepositRib/classes.module.scss new file mode 100644 index 00000000..9bba001b --- /dev/null +++ b/src/front/Components/DesignSystem/DepositRib/classes.module.scss @@ -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; + } +} \ No newline at end of file diff --git a/src/front/Components/DesignSystem/DepositRib/index.tsx b/src/front/Components/DesignSystem/DepositRib/index.tsx new file mode 100644 index 00000000..4c27cb15 --- /dev/null +++ b/src/front/Components/DesignSystem/DepositRib/index.tsx @@ -0,0 +1,179 @@ +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 { + fileInput: HTMLInputElement | null = null; + constructor(props: IProps) { + super(props); + this.state = { + documents: [], + errorMessage: "", + }; + } + + handleDrop = (e: React.DragEvent) => { + e.preventDefault(); + const file = e.dataTransfer.files[0]; + this.handleFile(file!); + }; + + handleFile = (file: File) => { + if (!file) return; + if (file.type === "application/pdf" || file.type === "image/jpeg" || file.type === "image/png") { + this.setState({ + documents: [file], + errorMessage: "", + }); + this.props.onChange([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) => { + 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 ( +
+
e.preventDefault()} onDrop={(e) => this.handleDrop(e)}> + (this.fileInput = input)} + /> + +
+
+ Deposit document +
+
+ +
+ +
Déposer un RIB
+
+ + Sélectionnez des documents .jpg, .pdf ou .png + +
+
+ +
+ {this.state.documents.map((file) => { + return ( +
+
+ Document check + + {this.shortName(file.name)} + +
+ Cross icon this.handleRemove()} + /> +
+ ); + })} +
+ +
+ +
+ + {/* + */} +
+ {this.state.errorMessage &&
{this.state.errorMessage}
} +
+ ); + } +} diff --git a/src/front/Components/DesignSystem/FolderArchivedListContainer/classes.module.scss b/src/front/Components/DesignSystem/FolderArchivedListContainer/classes.module.scss new file mode 100644 index 00000000..98e9d101 --- /dev/null +++ b/src/front/Components/DesignSystem/FolderArchivedListContainer/classes.module.scss @@ -0,0 +1,23 @@ +@import "@Themes/constants.scss"; + +.root { + width: calc(100vh - 83px); + display: flex; + flex-direction: column; + justify-content: space-between; + + .header { + flex: 1; + } + + .searchbar { + padding: 40px 24px 24px 24px; + } + + .folderlist-container { + max-height: calc(100vh - 215px); + height: calc(100vh - 215px); + overflow: auto; + border-right: 1px solid var(--grey-medium); + } +} diff --git a/src/front/Components/DesignSystem/FolderArchivedListContainer/index.tsx b/src/front/Components/DesignSystem/FolderArchivedListContainer/index.tsx new file mode 100644 index 00000000..19797c52 --- /dev/null +++ b/src/front/Components/DesignSystem/FolderArchivedListContainer/index.tsx @@ -0,0 +1,150 @@ +import Module from "@Front/Config/Module"; +import { OfficeFolder } from "le-coffre-resources/dist/Notary"; +import { EDocumentStatus } from "le-coffre-resources/dist/Notary/Document"; +import Link from "next/link"; +import { NextRouter, useRouter } from "next/router"; +import React from "react"; + +import BlockList, { IBlock } from "../BlockList"; +import Button from "../Button"; +import SearchBar from "../SearchBar"; +import classes from "./classes.module.scss"; +import Rules, { RulesMode } from "@Front/Components/Elements/Rules"; +import { AppRuleActions, AppRuleNames } from "@Front/Api/Entities/rule"; + +type IProps = { + folders: OfficeFolder[]; + isArchived: boolean; + onSelectedFolder?: (folder: OfficeFolder) => void; + onCloseLeftSide?: () => void; +}; + +type IPropsClass = IProps & { + router: NextRouter; + selectedFolder: string; +}; + +type IState = { + filteredFolders: OfficeFolder[]; + blocks: IBlock[]; +}; + +class FolderArchivedListContainerClass extends React.Component { + private redirectPath: string = this.props.isArchived + ? Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.pages.FolderInformation.props.path + : Module.getInstance().get().modules.pages.Folder.pages.FolderInformation.props.path; + public constructor(props: IPropsClass) { + super(props); + this.state = { + filteredFolders: this.props.folders, + blocks: this.getBlocks(this.props.folders), + }; + this.filterFolders = this.filterFolders.bind(this); + this.onSelectedFolder = this.onSelectedFolder.bind(this); + } + + public override render(): JSX.Element { + const navigatePath = Module.getInstance().get().modules.pages.Folder.pages.CreateFolder.props.path; + return ( +
+
+
+ +
+
+ +
+
+ {!this.props.isArchived && ( +
+ + + + + +
+ )} +
+ ); + } + + public override componentDidUpdate(prevProps: Readonly, prevState: Readonly, snapshot?: any): void { + if (prevProps.selectedFolder !== this.props.selectedFolder) { + this.setState({ filteredFolders: this.props.folders, blocks: this.getBlocks(this.props.folders) }); + } + } + private getBlocks(folders: OfficeFolder[]): IBlock[] { + const pendingFolders = folders + .filter((folder) => { + const pendingDocuments = (folder.documents ?? []).filter( + (document) => document.document_status === EDocumentStatus.DEPOSITED, + ); + return pendingDocuments.length >= 1; + }) + .sort((folder1, folder2) => { + return folder1.created_at! > folder2.created_at! ? -1 : 1; + }); + + const otherFolders = folders + .filter((folder) => { + const pendingDocuments = (folder.documents ?? []).filter( + (document) => document.document_status === EDocumentStatus.DEPOSITED, + ); + return pendingDocuments.length === 0; + }) + .sort((folder1, folder2) => { + return folder1.created_at! > folder2.created_at! ? -1 : 1; + }); + + return [...pendingFolders, ...otherFolders].map((folder) => { + return { + id: folder.uid!, + name: folder.folder_number! + " - " + folder.name!, + selected: this.props.selectedFolder === folder.uid, + hasFlag: folder.documents?.some((document) => document.document_status === EDocumentStatus.DEPOSITED), + }; + }); + } + + private onSelectedFolder(block: IBlock) { + const folder = this.props.folders.find((folder) => folder.uid === block.id); + if (!folder) return; + this.props.onSelectedFolder && this.props.onSelectedFolder(folder); + const path = this.redirectPath.replace("[folderUid]", folder.uid ?? ""); + this.props.router.push(path); + } + + private filterFolders(value: string): void { + const filteredFolders: OfficeFolder[] = this.props.folders.filter((folder) => { + const name = folder.name.toLowerCase(); + const number = folder.folder_number.toLowerCase(); + value = value.toLowerCase(); + if (folder.customers) { + const customerNames = folder.customers + .map((customer) => { + return `${customer.contact?.first_name.toLowerCase()} ${customer.contact?.last_name.toLowerCase()}`; + }) + .join(", "); + + return name.includes(value) || number.includes(value) || customerNames.includes(value); + } + + return name.includes(value) || number.includes(value); + }); + + this.setState({ filteredFolders, blocks: this.getBlocks(filteredFolders) }); + } +} + +export default function FolderListContainer(props: IProps) { + const router = useRouter(); + const { folderUid } = router.query; + return ; +} diff --git a/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx b/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx index a67c9523..b498cc7e 100644 --- a/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx +++ b/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx @@ -122,6 +122,20 @@ export default class BurgerModal extends React.Component { ]} /> + + +
diff --git a/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx b/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx index 8d34492d..a3a45e61 100644 --- a/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx +++ b/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx @@ -96,6 +96,20 @@ export default class ProfileModal extends React.Component { ]} /> + + +
diff --git a/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/classes.module.scss index e2840502..0bd02d2a 100644 --- a/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/classes.module.scss +++ b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/classes.module.scss @@ -17,8 +17,8 @@ } .folderlist-container { - max-height: calc(100vh - 215px); - height: calc(100vh - 215px); + max-height: calc(100vh - 290px); + height: calc(100vh - 290px); overflow: auto; border-right: 1px solid var(--grey-medium); } diff --git a/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/classes.module.scss index a172d64d..b8bae18e 100644 --- a/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/classes.module.scss +++ b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/classes.module.scss @@ -15,8 +15,8 @@ } .folderlist-container { - max-height: calc(100vh - 215px); - height: calc(100vh - 215px); + max-height: calc(100vh - 290px); + height: calc(100vh - 290px); overflow: auto; border-right: 1px solid var(--grey-medium); } diff --git a/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/index.tsx b/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/index.tsx index 37148adb..4fd445e3 100644 --- a/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/index.tsx +++ b/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/index.tsx @@ -2,6 +2,7 @@ import ChevronIcon from "@Assets/Icons/chevron.svg"; import Folders, { IGetFoldersParams } from "@Front/Api/LeCoffreApi/Notary/Folders/Folders"; import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; import FolderListContainer from "@Front/Components/DesignSystem/FolderListContainer"; +import FolderArchivedListContainer from "@Front/Components/DesignSystem/FolderArchivedListContainer"; import Header from "@Front/Components/DesignSystem/Header"; import Version from "@Front/Components/DesignSystem/Version"; import BackArrow from "@Front/Components/Elements/BackArrow"; @@ -54,12 +55,20 @@ export default class DefaultNotaryDashboard extends React.Component {this.state.isLeftSideOpen &&
}
- {this.state.folders && ( + {this.props.isArchived && this.state.folders && ( + + )} + {!this.props.isArchived && this.state.folders && ( )}
diff --git a/src/front/Components/Layouts/ClientDashboard/classes.module.scss b/src/front/Components/Layouts/ClientDashboard/classes.module.scss index 669d9522..97e56410 100644 --- a/src/front/Components/Layouts/ClientDashboard/classes.module.scss +++ b/src/front/Components/Layouts/ClientDashboard/classes.module.scss @@ -4,6 +4,7 @@ .header { display: flex; padding: 64px; + justify-content: space-between; @media (max-width: $screen-m) { flex-wrap: wrap; diff --git a/src/front/Components/Layouts/ClientDashboard/index.tsx b/src/front/Components/Layouts/ClientDashboard/index.tsx index e4383649..f4f3cc25 100644 --- a/src/front/Components/Layouts/ClientDashboard/index.tsx +++ b/src/front/Components/Layouts/ClientDashboard/index.tsx @@ -12,6 +12,7 @@ import { useRouter } from "next/router"; import JwtService, { ICustomerJwtPayload } from "@Front/Services/JwtService/JwtService"; import DepositOtherDocument from "@Front/Components/DesignSystem/DepositOtherDocument"; import Folders from "@Front/Api/LeCoffreApi/Customer/Folders/Folders"; +import OfficeRib from "@Front/Api/LeCoffreApi/Customer/OfficeRib/OfficeRib"; type IProps = {}; @@ -71,6 +72,20 @@ export default function ClientDashboard(props: IProps) { setIsAddDocumentModalVisible(true); }, []); + async function downloadFile() { + if (!folder?.office?.uid) return; + const blob = await OfficeRib.getInstance().getRibStream(folder.office.uid); + const ribUrl = URL.createObjectURL(blob); + + if (!ribUrl) return; + const a = document.createElement("a"); + a.style.display = "none"; + a.href = ribUrl; + a.download = ""; + document.body.appendChild(a); + a.click(); + } + useEffect(() => { getDocuments(); }, [folderUid, getDocuments]); @@ -80,9 +95,11 @@ export default function ClientDashboard(props: IProps) {
{/* TODO Get name from userStore */} - - Bonjour {customer?.contact?.first_name.concat(" ", customer?.contact?.last_name)} - +
+ + Bonjour {customer?.contact?.first_name.concat(" ", customer?.contact?.last_name)} + +
Dossier {folder?.folder_number} - {folder?.name} @@ -103,6 +120,10 @@ export default function ClientDashboard(props: IProps) { transmis à votre notaire.
+ {folder?.office?.rib_name && ( + //Div to avoid the button to be on the same line as the text + + )}
); }, [customer, folder?.folder_number, folder?.name, folder?.office?.name]); diff --git a/src/front/Components/Layouts/DeedTypes/DeedTypesEdit/index.tsx b/src/front/Components/Layouts/DeedTypes/DeedTypesEdit/index.tsx index ab21dabd..97df2dc7 100644 --- a/src/front/Components/Layouts/DeedTypes/DeedTypesEdit/index.tsx +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesEdit/index.tsx @@ -14,7 +14,6 @@ import { ValidationError } from "class-validator"; import classes from "./classes.module.scss"; - export default function DeedTypesEdit() { const router = useRouter(); let { deedTypeUid } = router.query; @@ -53,7 +52,7 @@ export default function DeedTypesEdit() { try { await deedType.validateOrReject?.({ groups: ["updateDeedType"], forbidUnknownValues: true }); } catch (validationErrors: Array | any) { - if(!Array.isArray(validationErrors)) return; + if (!Array.isArray(validationErrors)) return; setValidationError(validationErrors as ValidationError[]); return; } @@ -72,7 +71,7 @@ export default function DeedTypesEdit() { .modules.pages.DeedTypes.pages.DeedTypesInformations.props.path.replace("[uid]", deedTypeUid as string), ); } catch (validationErrors) { - if(!Array.isArray(validationErrors)) return; + if (!Array.isArray(validationErrors)) return; setValidationError(validationErrors as ValidationError[]); return; } @@ -107,8 +106,18 @@ export default function DeedTypesEdit() { Modifier les informations de l'acte
- error.property === 'name')}/> - error.property === 'description')} /> + error.property === "name")} + /> + error.property === "description")} + />
- error.property === "name")} /> + error.property === "name")} + /> error.property === "public_description")} />
diff --git a/src/front/Components/Layouts/Folder/ViewDocuments/index.tsx b/src/front/Components/Layouts/Folder/ViewDocuments/index.tsx index f1a209d1..b49f3482 100644 --- a/src/front/Components/Layouts/Folder/ViewDocuments/index.tsx +++ b/src/front/Components/Layouts/Folder/ViewDocuments/index.tsx @@ -195,6 +195,7 @@ class ViewDocumentsClass extends BasePage { private async getFilePreview(): Promise { try { const fileBlob: Blob = await Files.getInstance().download(this.state.selectedFile?.uid as string); + this.setState({ fileBlob, }); @@ -281,7 +282,9 @@ class ViewDocumentsClass extends BasePage { this.props.router.push( Module.getInstance() .get() - .modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid) + '?customerUid=' + this.state.document?.depositor?.uid, + .modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid) + + "?customerUid=" + + this.state.document?.depositor?.uid, ); } catch (e) { console.error(e); @@ -297,7 +300,9 @@ class ViewDocumentsClass extends BasePage { this.props.router.push( Module.getInstance() .get() - .modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid) + '?customerUid=' + this.state.document?.depositor?.uid, + .modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid) + + "?customerUid=" + + this.state.document?.depositor?.uid, ); } catch (e) { console.error(e); diff --git a/src/front/Components/Layouts/Rib/classes.module.scss b/src/front/Components/Layouts/Rib/classes.module.scss new file mode 100644 index 00000000..7e980200 --- /dev/null +++ b/src/front/Components/Layouts/Rib/classes.module.scss @@ -0,0 +1,72 @@ +@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; + + .arrow-container { + cursor: pointer; + + &[data-disabled="true"] { + opacity: 0.3; + cursor: not-allowed; + } + } + + .file-container { + max-width: 1000px; + min-height: 600px; + margin: auto; + flex: 1; + } + + .button-deposit { + align-items: center; + } + } + + .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; + } + } + } +} diff --git a/src/front/Components/Layouts/Rib/index.tsx b/src/front/Components/Layouts/Rib/index.tsx new file mode 100644 index 00000000..df6fdaeb --- /dev/null +++ b/src/front/Components/Layouts/Rib/index.tsx @@ -0,0 +1,166 @@ +import React, { useCallback, useEffect, 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 OfficeRib from "@Front/Api/LeCoffreApi/Notary/OfficeRib/OfficeRib"; +import DepositRib from "@Front/Components/DesignSystem/DepositRib"; +import Confirm from "@Front/Components/DesignSystem/Modal/Confirm"; + +export default function Rib() { + const [documentList, setDocumentList] = useState([]); + const router = useRouter(); + let { officeUid } = router.query; + const [fileBlob, setFileBlob] = useState(); + const [fileName, setFileName] = useState(""); + const [key, setKey] = useState(""); + const [isRibModalOpen, setIsRibModalOpen] = useState(false); + const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); + + //Put fetch data in a useCallback + + const fetchData = useCallback(async () => { + try { + const blob = await OfficeRib.getInstance().getRibStream(); + + setFileBlob(blob.blob); + setKey(key); + setFileName(blob.fileName); + } catch (error) { + setFileBlob(undefined); + setFileName(""); + setKey(""); + } + }, [officeUid]); + + useEffect(() => { + fetchData(); + }, [officeUid]); + + function downloadFile() { + if (!fileBlob) return; + const url = window.URL.createObjectURL(fileBlob); + const a = document.createElement("a"); + a.style.display = "none"; + a.href = url; + 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 OfficeRib.getInstance().post(formData); + + onCloseRibModal(); + fetchData(); + } + + function openRibModal(): void { + setIsRibModalOpen(true); + } + + function onCloseRibModal(): void { + setDocumentList([]); + setIsRibModalOpen(false); + } + + async function onDeleteModalAccepted() { + await OfficeRib.getInstance().delete(); + + onCloseDeleteModal(); + fetchData(); + } + + function openDeleteModal(): void { + setIsDeleteModalOpen(true); + } + + function onCloseDeleteModal(): void { + setIsDeleteModalOpen(false); + } + + const onDocumentChange = (documentList: File[]) => { + setDocumentList(documentList); + }; + + return ( + +
+ + RIB de l'office + + + {!fileBlob && ( +
+
+ + Aucun RIB n'a été déposé pour cet office + +
+
+ )} + + {!fileBlob && ( +
+
+ +
+
+ )} + + {fileBlob && ( +
+
+ {fileBlob && } +
+
+ )} + {fileBlob && ( +
+
+ + + +
+
+ )} + + + + + + + + Supprimer le RIB + + + Voulez-vous vraiment supprimer le RIB de votre office ? + + +
+
+ ); +} diff --git a/src/front/Components/Layouts/Roles/RolesInformations/index.tsx b/src/front/Components/Layouts/Roles/RolesInformations/index.tsx index 88f55e1e..04ebe346 100644 --- a/src/front/Components/Layouts/Roles/RolesInformations/index.tsx +++ b/src/front/Components/Layouts/Roles/RolesInformations/index.tsx @@ -47,9 +47,17 @@ export default function RolesInformations(props: IProps) { const rules = await Rules.getInstance().get({ where: { - namespace: "notary", + OR: [ + { + namespace: "notary", + }, + { + namespace: "collaborator", + }, + ], }, }); + if (!role) return; setRoleSelected(role); if (!role.rules) return; diff --git a/src/front/Config/Module/development.json b/src/front/Config/Module/development.json index b2464999..ad7eef2a 100644 --- a/src/front/Config/Module/development.json +++ b/src/front/Config/Module/development.json @@ -257,6 +257,13 @@ } } }, + "OfficesRib": { + "enabled": true, + "props": { + "path": "/offices/rib", + "labelKey": "officeRib" + } + }, "404": { "enabled": true, "props": { diff --git a/src/front/Config/Module/preprod.json b/src/front/Config/Module/preprod.json index b2464999..ad7eef2a 100644 --- a/src/front/Config/Module/preprod.json +++ b/src/front/Config/Module/preprod.json @@ -257,6 +257,13 @@ } } }, + "OfficesRib": { + "enabled": true, + "props": { + "path": "/offices/rib", + "labelKey": "officeRib" + } + }, "404": { "enabled": true, "props": { diff --git a/src/front/Config/Module/production.json b/src/front/Config/Module/production.json index b2464999..ad7eef2a 100644 --- a/src/front/Config/Module/production.json +++ b/src/front/Config/Module/production.json @@ -257,6 +257,13 @@ } } }, + "OfficesRib": { + "enabled": true, + "props": { + "path": "/offices/rib", + "labelKey": "officeRib" + } + }, "404": { "enabled": true, "props": { diff --git a/src/front/Config/Module/staging.json b/src/front/Config/Module/staging.json index b2464999..ad7eef2a 100644 --- a/src/front/Config/Module/staging.json +++ b/src/front/Config/Module/staging.json @@ -257,6 +257,13 @@ } } }, + "OfficesRib": { + "enabled": true, + "props": { + "path": "/offices/rib", + "labelKey": "officeRib" + } + }, "404": { "enabled": true, "props": { diff --git a/src/pages/offices/rib/index.tsx b/src/pages/offices/rib/index.tsx new file mode 100644 index 00000000..eeef1931 --- /dev/null +++ b/src/pages/offices/rib/index.tsx @@ -0,0 +1,18 @@ +import { AppRuleActions, AppRuleNames } from "@Front/Api/Entities/rule"; +import Rules, { RulesMode } from "@Front/Components/Elements/Rules"; +import Rib from "@Front/Components/Layouts/Rib"; + +export default function Route() { + return ( + + + + ); +}