Merge branch 'staging' into preprod
This commit is contained in:
commit
02a9d4585e
@ -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
|
|
159
package-lock.json
generated
159
package-lock.json
generated
@ -22,7 +22,7 @@
|
|||||||
"eslint-config-next": "13.2.4",
|
"eslint-config-next": "13.2.4",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"jwt-decode": "^3.1.2",
|
"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",
|
"next": "13.2.4",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^2.8.7",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
@ -1436,9 +1436,9 @@
|
|||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"node_modules/bare-fs": {
|
"node_modules/bare-fs": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.1.5.tgz",
|
||||||
"integrity": "sha512-Oa7F0QJV7We0mtKq7Tk246uiBrl7vun64cPEsJOEwv2vHjnVL9yO7aH3643aSrd4rXfVe7yhJ9LHZywQQAXKFQ==",
|
"integrity": "sha512-5t0nlecX+N2uJqdxe9d18A98cp2u9BETelbjKpiVgQqzzmVNFYWEAjQHqS+2Khgto1vcwhik9cXucaj5ve2WWA==",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bare-events": "^2.0.0",
|
"bare-events": "^2.0.0",
|
||||||
@ -1448,9 +1448,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/bare-os": {
|
"node_modules/bare-os": {
|
||||||
"version": "2.1.2",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.2.0.tgz",
|
||||||
"integrity": "sha512-slQjOn78Q8itnzomNAamiKo5MDpEpV3JnoNZ93lyynaFh6paWcU+5c0GVcZ7EYIJC2unN2JGdF1qupdscYl0Yg==",
|
"integrity": "sha512-hD0rOPfYWOMpVirTACt4/nK8mC55La12K5fY1ij8HAdfQakD62M+H4o4tpfKzVGLgRDTuk3vjA4GqGXXCeFbag==",
|
||||||
"optional": true
|
"optional": true
|
||||||
},
|
},
|
||||||
"node_modules/bare-path": {
|
"node_modules/bare-path": {
|
||||||
@ -1543,14 +1543,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/call-bind": {
|
"node_modules/call-bind": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||||
"integrity": "sha512-Mj50FLHtlsoVfRfnHaZvyrooHcrlceNZdL/QBvJJVd9Ta55qCQK0gs4ss2oZDeV9zFCs6ewzYgVE5yfVmfFpVg==",
|
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"es-define-property": "^1.0.0",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
"function-bind": "^1.1.2",
|
"function-bind": "^1.1.2",
|
||||||
"get-intrinsic": "^1.2.3",
|
"get-intrinsic": "^1.2.4",
|
||||||
"set-function-length": "^1.2.0"
|
"set-function-length": "^1.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
@ -1568,9 +1569,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001587",
|
"version": "1.0.30001588",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001587.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz",
|
||||||
"integrity": "sha512-HMFNotUmLXn71BQxg8cijvqxnIAofforZOwGsxyXJ0qugTdspUF4sPSJ2vhgprHCB996tIDzEq1ubumPDV8ULA==",
|
"integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@ -1827,17 +1828,19 @@
|
|||||||
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
|
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
|
||||||
},
|
},
|
||||||
"node_modules/define-data-property": {
|
"node_modules/define-data-property": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||||
"integrity": "sha512-SRtsSqsDbgpJBbW3pABMCOt6rQyeM8s8RiyeSN8jYG8sYmt/kGJejbydttUsnDs1tadr19tvhT4ShwMyoqAm4g==",
|
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"es-define-property": "^1.0.0",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
"get-intrinsic": "^1.2.2",
|
"gopd": "^1.0.1"
|
||||||
"gopd": "^1.0.1",
|
|
||||||
"has-property-descriptors": "^1.0.1"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/define-properties": {
|
"node_modules/define-properties": {
|
||||||
@ -1912,9 +1915,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dotenv": {
|
"node_modules/dotenv": {
|
||||||
"version": "16.4.2",
|
"version": "16.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.4.tgz",
|
||||||
"integrity": "sha512-rZSSFxke7d9nYQ5NeMIwp5PP+f8wXgKNljpOb7KtH6SKW1cEqcXAz9VSJYVLKe7Jhup/gUYOkaeSVyK8GJ+nBg==",
|
"integrity": "sha512-XvPXc8XAQThSjAbY6cQ/9PcBXmFoWuw1sQ3b8HqUCR6ziGXjkTi//kB9SWa2UwqlgdAIuRqAa/9hVljzPehbYg==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
},
|
},
|
||||||
@ -1956,49 +1959,51 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/es-abstract": {
|
"node_modules/es-abstract": {
|
||||||
"version": "1.22.3",
|
"version": "1.22.4",
|
||||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz",
|
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.4.tgz",
|
||||||
"integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==",
|
"integrity": "sha512-vZYJlk2u6qHYxBOTjAeg7qUxHdNfih64Uu2J8QqWgXZ2cri0ZpJAkzDUK/q593+mvKwlxyaxr6F1Q+3LKoQRgg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"array-buffer-byte-length": "^1.0.0",
|
"array-buffer-byte-length": "^1.0.1",
|
||||||
"arraybuffer.prototype.slice": "^1.0.2",
|
"arraybuffer.prototype.slice": "^1.0.3",
|
||||||
"available-typed-arrays": "^1.0.5",
|
"available-typed-arrays": "^1.0.6",
|
||||||
"call-bind": "^1.0.5",
|
"call-bind": "^1.0.7",
|
||||||
"es-set-tostringtag": "^2.0.1",
|
"es-define-property": "^1.0.0",
|
||||||
|
"es-errors": "^1.3.0",
|
||||||
|
"es-set-tostringtag": "^2.0.2",
|
||||||
"es-to-primitive": "^1.2.1",
|
"es-to-primitive": "^1.2.1",
|
||||||
"function.prototype.name": "^1.1.6",
|
"function.prototype.name": "^1.1.6",
|
||||||
"get-intrinsic": "^1.2.2",
|
"get-intrinsic": "^1.2.4",
|
||||||
"get-symbol-description": "^1.0.0",
|
"get-symbol-description": "^1.0.2",
|
||||||
"globalthis": "^1.0.3",
|
"globalthis": "^1.0.3",
|
||||||
"gopd": "^1.0.1",
|
"gopd": "^1.0.1",
|
||||||
"has-property-descriptors": "^1.0.0",
|
"has-property-descriptors": "^1.0.2",
|
||||||
"has-proto": "^1.0.1",
|
"has-proto": "^1.0.1",
|
||||||
"has-symbols": "^1.0.3",
|
"has-symbols": "^1.0.3",
|
||||||
"hasown": "^2.0.0",
|
"hasown": "^2.0.1",
|
||||||
"internal-slot": "^1.0.5",
|
"internal-slot": "^1.0.7",
|
||||||
"is-array-buffer": "^3.0.2",
|
"is-array-buffer": "^3.0.4",
|
||||||
"is-callable": "^1.2.7",
|
"is-callable": "^1.2.7",
|
||||||
"is-negative-zero": "^2.0.2",
|
"is-negative-zero": "^2.0.2",
|
||||||
"is-regex": "^1.1.4",
|
"is-regex": "^1.1.4",
|
||||||
"is-shared-array-buffer": "^1.0.2",
|
"is-shared-array-buffer": "^1.0.2",
|
||||||
"is-string": "^1.0.7",
|
"is-string": "^1.0.7",
|
||||||
"is-typed-array": "^1.1.12",
|
"is-typed-array": "^1.1.13",
|
||||||
"is-weakref": "^1.0.2",
|
"is-weakref": "^1.0.2",
|
||||||
"object-inspect": "^1.13.1",
|
"object-inspect": "^1.13.1",
|
||||||
"object-keys": "^1.1.1",
|
"object-keys": "^1.1.1",
|
||||||
"object.assign": "^4.1.4",
|
"object.assign": "^4.1.5",
|
||||||
"regexp.prototype.flags": "^1.5.1",
|
"regexp.prototype.flags": "^1.5.2",
|
||||||
"safe-array-concat": "^1.0.1",
|
"safe-array-concat": "^1.1.0",
|
||||||
"safe-regex-test": "^1.0.0",
|
"safe-regex-test": "^1.0.3",
|
||||||
"string.prototype.trim": "^1.2.8",
|
"string.prototype.trim": "^1.2.8",
|
||||||
"string.prototype.trimend": "^1.0.7",
|
"string.prototype.trimend": "^1.0.7",
|
||||||
"string.prototype.trimstart": "^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-length": "^1.0.0",
|
||||||
"typed-array-byte-offset": "^1.0.0",
|
"typed-array-byte-offset": "^1.0.0",
|
||||||
"typed-array-length": "^1.0.4",
|
"typed-array-length": "^1.0.4",
|
||||||
"unbox-primitive": "^1.0.2",
|
"unbox-primitive": "^1.0.2",
|
||||||
"which-typed-array": "^1.1.13"
|
"which-typed-array": "^1.1.14"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"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",
|
"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=="
|
"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": {
|
"node_modules/es-errors": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||||
@ -2021,20 +2037,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/es-iterator-helpers": {
|
"node_modules/es-iterator-helpers": {
|
||||||
"version": "1.0.16",
|
"version": "1.0.17",
|
||||||
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.16.tgz",
|
"resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.17.tgz",
|
||||||
"integrity": "sha512-CREG2A9Vq7bpDRnldhFcMKuKArvkZtsH6Y0DHOHVg49qhf+LD8uEdUM3OkOAICv0EziGtDEnQtqY2/mfBILpFw==",
|
"integrity": "sha512-lh7BsUqelv4KUbR5a/ZTaGGIMLCjPGPqJ6q+Oq24YP0RdyptX1uzm4vvaqzk7Zx3bpl/76YLTTDj9L7uYQ92oQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"asynciterator.prototype": "^1.0.0",
|
"asynciterator.prototype": "^1.0.0",
|
||||||
"call-bind": "^1.0.6",
|
"call-bind": "^1.0.7",
|
||||||
"define-properties": "^1.2.1",
|
"define-properties": "^1.2.1",
|
||||||
"es-abstract": "^1.22.3",
|
"es-abstract": "^1.22.4",
|
||||||
"es-errors": "^1.3.0",
|
"es-errors": "^1.3.0",
|
||||||
"es-set-tostringtag": "^2.0.2",
|
"es-set-tostringtag": "^2.0.2",
|
||||||
"function-bind": "^1.1.2",
|
"function-bind": "^1.1.2",
|
||||||
"get-intrinsic": "^1.2.4",
|
"get-intrinsic": "^1.2.4",
|
||||||
"globalthis": "^1.0.3",
|
"globalthis": "^1.0.3",
|
||||||
"has-property-descriptors": "^1.0.1",
|
"has-property-descriptors": "^1.0.2",
|
||||||
"has-proto": "^1.0.1",
|
"has-proto": "^1.0.1",
|
||||||
"has-symbols": "^1.0.3",
|
"has-symbols": "^1.0.3",
|
||||||
"internal-slot": "^1.0.7",
|
"internal-slot": "^1.0.7",
|
||||||
@ -2856,11 +2872,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/has-property-descriptors": {
|
"node_modules/has-property-descriptors": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||||
"integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==",
|
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"get-intrinsic": "^1.2.2"
|
"es-define-property": "^1.0.0"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
@ -3442,7 +3458,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/le-coffre-resources": {
|
"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",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
@ -3463,9 +3479,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/libphonenumber-js": {
|
"node_modules/libphonenumber-js": {
|
||||||
"version": "1.10.55",
|
"version": "1.10.56",
|
||||||
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.55.tgz",
|
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.56.tgz",
|
||||||
"integrity": "sha512-MrTg2JFLscgmTY6/oT9vopYETlgUls/FU6OaeeamGwk4LFxjIgOUML/ZSZICgR0LPYXaonVJo40lzMvaaTJlQA=="
|
"integrity": "sha512-d0GdKshNnyfl5gM7kZ9rXjGiAbxT/zCXp0k+EAzh8H4zrb2R7GXtMCrULrX7UQxtfx6CLy/vz/lomvW79FAFdA=="
|
||||||
},
|
},
|
||||||
"node_modules/lines-and-columns": {
|
"node_modules/lines-and-columns": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.4",
|
||||||
@ -4404,9 +4420,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
"version": "1.70.0",
|
"version": "1.71.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz",
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.71.0.tgz",
|
||||||
"integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==",
|
"integrity": "sha512-HKKIKf49Vkxlrav3F/w6qRuPcmImGVbIXJ2I3Kg0VMA+3Bav+8yE9G5XmP5lMj6nl4OlqbPftGAscNaNu28b8w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": ">=3.0.0 <4.0.0",
|
"chokidar": ">=3.0.0 <4.0.0",
|
||||||
"immutable": "^4.0.0",
|
"immutable": "^4.0.0",
|
||||||
@ -4609,9 +4625,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/streamx": {
|
"node_modules/streamx": {
|
||||||
"version": "2.15.8",
|
"version": "2.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.8.tgz",
|
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.16.0.tgz",
|
||||||
"integrity": "sha512-6pwMeMY/SuISiRsuS8TeIrAzyFbG5gGPHFQsYjUr/pbBadaL1PCWmzKw+CHZSwainfvcF6Si6cVLq4XTEwswFQ==",
|
"integrity": "sha512-a7Fi0PoUeusrUcMS4+HxivnZqYsw2MFEP841TIyLxTcEIucHcJsk+0ARcq3tGq1xDn+xK7sKHetvfMzI1/CzMA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fast-fifo": "^1.1.0",
|
"fast-fifo": "^1.1.0",
|
||||||
"queue-tick": "^1.0.1"
|
"queue-tick": "^1.0.1"
|
||||||
@ -4922,15 +4938,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typed-array-byte-offset": {
|
"node_modules/typed-array-byte-offset": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.1.tgz",
|
||||||
"integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
|
"integrity": "sha512-tcqKMrTRXjqvHN9S3553NPCaGL0VPgFI92lXszmrE8DMhiDPLBYLlvo8Uu4WZAAX/aGqp/T1sbA4ph8EWjDF9Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"available-typed-arrays": "^1.0.5",
|
"available-typed-arrays": "^1.0.6",
|
||||||
"call-bind": "^1.0.2",
|
"call-bind": "^1.0.7",
|
||||||
"for-each": "^0.3.3",
|
"for-each": "^0.3.3",
|
||||||
|
"gopd": "^1.0.1",
|
||||||
"has-proto": "^1.0.1",
|
"has-proto": "^1.0.1",
|
||||||
"is-typed-array": "^1.1.10"
|
"is-typed-array": "^1.1.13"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
"eslint-config-next": "13.2.4",
|
"eslint-config-next": "13.2.4",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"jwt-decode": "^3.1.2",
|
"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",
|
"next": "13.2.4",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^2.8.7",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
53
src/common/Api/LeCoffreApi/Notary/Offices/Offices.ts
Normal file
53
src/common/Api/LeCoffreApi/Notary/Offices/Offices.ts
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,10 @@ export enum ContentType {
|
|||||||
FORM_DATA = "multipart/form-data;",
|
FORM_DATA = "multipart/form-data;",
|
||||||
PNG = "image/png",
|
PNG = "image/png",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type IRef = {
|
||||||
|
response?: Response;
|
||||||
|
};
|
||||||
export default abstract class BaseApiService {
|
export default abstract class BaseApiService {
|
||||||
private static baseUrl: string;
|
private static baseUrl: string;
|
||||||
protected readonly variables = FrontendVariables.getInstance();
|
protected readonly variables = FrontendVariables.getInstance();
|
||||||
@ -39,13 +43,13 @@ export default abstract class BaseApiService {
|
|||||||
return JSON.stringify(body);
|
return JSON.stringify(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async getRequest<T>(url: URL, token?: string, contentType?: ContentType, filename?: string) {
|
protected async getRequest<T>(url: URL, token?: string, contentType?: ContentType, ref?: IRef, fileName?: string) {
|
||||||
const request = async () =>
|
const request = async () =>
|
||||||
await fetch(url, {
|
await fetch(url, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: this.buildHeaders(contentType ?? ContentType.JSON),
|
headers: this.buildHeaders(contentType ?? ContentType.JSON),
|
||||||
});
|
});
|
||||||
return this.sendRequest<T>(request, filename);
|
return this.sendRequest<T>(request, ref, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async postRequest<T>(url: URL, body: { [key: string]: unknown } = {}, token?: string) {
|
protected async postRequest<T>(url: URL, body: { [key: string]: unknown } = {}, token?: string) {
|
||||||
@ -114,18 +118,18 @@ export default abstract class BaseApiService {
|
|||||||
return this.sendRequest<T>(request);
|
return this.sendRequest<T>(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async sendRequest<T>(request: () => Promise<Response>, filename?: string): Promise<T> {
|
private async sendRequest<T>(request: () => Promise<Response>, ref?: IRef, fileName?: string): Promise<T> {
|
||||||
const response = await request();
|
const response = await request();
|
||||||
return this.processResponse<T>(response, request, filename);
|
|
||||||
|
return this.processResponse<T>(response, request, ref, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async processResponse<T>(response: Response, request: () => Promise<Response>, filename?: string): Promise<T> {
|
protected async processResponse<T>(response: Response, request: () => Promise<Response>, ref?: IRef, fileName?: string): Promise<T> {
|
||||||
let responseContent: T;
|
let responseContent: T;
|
||||||
|
ref && (ref["response"] = response);
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
// Check the Content-Type header to determine the response type
|
// Check the Content-Type header to determine the response type
|
||||||
const contentType = response.headers.get("Content-Type");
|
const contentType = response.headers.get("Content-Type");
|
||||||
|
|
||||||
if (contentType && !contentType.includes("application/json")) {
|
if (contentType && !contentType.includes("application/json")) {
|
||||||
responseContent = (await response.blob()) as T;
|
responseContent = (await response.blob()) as T;
|
||||||
} else {
|
} else {
|
||||||
|
@ -17,4 +17,5 @@ export enum AppRuleNames {
|
|||||||
deedTypes = "deed-types",
|
deedTypes = "deed-types",
|
||||||
offices = "offices",
|
offices = "offices",
|
||||||
documents = "documents",
|
documents = "documents",
|
||||||
|
rib = "rib",
|
||||||
}
|
}
|
||||||
|
36
src/front/Api/LeCoffreApi/Customer/OfficeRib/OfficeRib.ts
Normal file
36
src/front/Api/LeCoffreApi/Customer/OfficeRib/OfficeRib.ts
Normal file
@ -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<any>(url);
|
||||||
|
} catch (err) {
|
||||||
|
this.onError(err);
|
||||||
|
return Promise.reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,7 +15,7 @@ export type IPutDocumentTypesParams = {};
|
|||||||
|
|
||||||
export interface IPostDocumentTypesParams {
|
export interface IPostDocumentTypesParams {
|
||||||
name: string;
|
name: string;
|
||||||
public_description: string;
|
public_description?: string | null;
|
||||||
private_description: string | null;
|
private_description: string | null;
|
||||||
office?: {
|
office?: {
|
||||||
uid?: string;
|
uid?: string;
|
||||||
|
@ -60,7 +60,7 @@ export default class OfficeFolderAnchors extends BaseNotary {
|
|||||||
public async download(uid: string): Promise<any> {
|
public async download(uid: string): Promise<any> {
|
||||||
const url = new URL(this.baseUrl.concat(`/download/${uid}`));
|
const url = new URL(this.baseUrl.concat(`/download/${uid}`));
|
||||||
try {
|
try {
|
||||||
return await this.getRequest<any>(url, undefined, ContentType.PDF, `${uid}.pdf`);
|
return await this.getRequest<any>(url, undefined, ContentType.PDF, undefined, `${uid}.pdf`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.onError(err);
|
this.onError(err);
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
|
68
src/front/Api/LeCoffreApi/Notary/OfficeRib/OfficeRib.ts
Normal file
68
src/front/Api/LeCoffreApi/Notary/OfficeRib/OfficeRib.ts
Normal file
@ -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<any>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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_type?.public_description !== "" &&
|
this.props.document.document_type?.public_description !== "" &&
|
||||||
this.props.document.document_status !== EDocumentStatus.VALIDATED && (
|
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 && (
|
{this.props.document.document_status === EDocumentStatus.VALIDATED && (
|
||||||
<Image src={GreenCheckIcon} alt="Document check" />
|
<Image src={GreenCheckIcon} alt="Document check" />
|
||||||
|
108
src/front/Components/DesignSystem/DepositRib/classes.module.scss
Normal file
108
src/front/Components/DesignSystem/DepositRib/classes.module.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
179
src/front/Components/DesignSystem/DepositRib/index.tsx
Normal file
179
src/front/Components/DesignSystem/DepositRib/index.tsx
Normal file
@ -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<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) 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<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>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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<IPropsClass, IState> {
|
||||||
|
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 (
|
||||||
|
<div className={classes["root"]}>
|
||||||
|
<div className={classes["header"]}>
|
||||||
|
<div className={classes["searchbar"]}>
|
||||||
|
<SearchBar onChange={this.filterFolders} placeholder="Chercher un dossier" />
|
||||||
|
</div>
|
||||||
|
<div className={classes["folderlist-container"]}>
|
||||||
|
<BlockList blocks={this.state.blocks} onSelectedBlock={this.onSelectedFolder} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{!this.props.isArchived && (
|
||||||
|
<div>
|
||||||
|
<Rules
|
||||||
|
mode={RulesMode.NECESSARY}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
action: AppRuleActions.create,
|
||||||
|
name: AppRuleNames.officeFolders,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<Link href={navigatePath}>
|
||||||
|
<Button fullwidth={true}>Créer un dossier</Button>
|
||||||
|
</Link>
|
||||||
|
</Rules>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override componentDidUpdate(prevProps: Readonly<IPropsClass>, prevState: Readonly<IState>, 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 <FolderArchivedListContainerClass {...props} router={router} selectedFolder={folderUid as string} />;
|
||||||
|
}
|
@ -122,6 +122,20 @@ export default class BurgerModal extends React.Component<IProps, IState> {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</Rules>
|
</Rules>
|
||||||
|
<Rules
|
||||||
|
mode={RulesMode.NECESSARY}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
action: AppRuleActions.update,
|
||||||
|
name: AppRuleNames.rib,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<NavigationLink
|
||||||
|
path={Module.getInstance().get().modules.pages.OfficesRib.props.path}
|
||||||
|
text="Gestion du RIB"
|
||||||
|
routesActive={[Module.getInstance().get().modules.pages.OfficesRib.props.path]}
|
||||||
|
/>
|
||||||
|
</Rules>
|
||||||
<NavigationLink path={Module.getInstance().get().modules.pages.MyAccount.props.path} text="Mon compte" />
|
<NavigationLink path={Module.getInstance().get().modules.pages.MyAccount.props.path} text="Mon compte" />
|
||||||
<NavigationLink target="_blank" path="/CGU_LeCoffre_io.pdf" text="CGU" />
|
<NavigationLink target="_blank" path="/CGU_LeCoffre_io.pdf" text="CGU" />
|
||||||
<div className={classes["separator"]} />
|
<div className={classes["separator"]} />
|
||||||
|
@ -96,6 +96,20 @@ export default class ProfileModal extends React.Component<IProps, IState> {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</Rules>
|
</Rules>
|
||||||
|
<Rules
|
||||||
|
mode={RulesMode.NECESSARY}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
action: AppRuleActions.update,
|
||||||
|
name: AppRuleNames.rib,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<NavigationLink
|
||||||
|
path={Module.getInstance().get().modules.pages.OfficesRib.props.path}
|
||||||
|
text="Gestion du RIB"
|
||||||
|
routesActive={[Module.getInstance().get().modules.pages.OfficesRib.props.path]}
|
||||||
|
/>
|
||||||
|
</Rules>
|
||||||
<NavigationLink target="_blank" path="/CGU_LeCoffre_io.pdf" text="CGU" />
|
<NavigationLink target="_blank" path="/CGU_LeCoffre_io.pdf" text="CGU" />
|
||||||
<div className={classes["separator"]} />
|
<div className={classes["separator"]} />
|
||||||
<LogOutButton />
|
<LogOutButton />
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.folderlist-container {
|
.folderlist-container {
|
||||||
max-height: calc(100vh - 215px);
|
max-height: calc(100vh - 290px);
|
||||||
height: calc(100vh - 215px);
|
height: calc(100vh - 290px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
border-right: 1px solid var(--grey-medium);
|
border-right: 1px solid var(--grey-medium);
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.folderlist-container {
|
.folderlist-container {
|
||||||
max-height: calc(100vh - 215px);
|
max-height: calc(100vh - 290px);
|
||||||
height: calc(100vh - 215px);
|
height: calc(100vh - 290px);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
border-right: 1px solid var(--grey-medium);
|
border-right: 1px solid var(--grey-medium);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import ChevronIcon from "@Assets/Icons/chevron.svg";
|
|||||||
import Folders, { IGetFoldersParams } from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
|
import Folders, { IGetFoldersParams } from "@Front/Api/LeCoffreApi/Notary/Folders/Folders";
|
||||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||||
import FolderListContainer from "@Front/Components/DesignSystem/FolderListContainer";
|
import FolderListContainer from "@Front/Components/DesignSystem/FolderListContainer";
|
||||||
|
import FolderArchivedListContainer from "@Front/Components/DesignSystem/FolderArchivedListContainer";
|
||||||
import Header from "@Front/Components/DesignSystem/Header";
|
import Header from "@Front/Components/DesignSystem/Header";
|
||||||
import Version from "@Front/Components/DesignSystem/Version";
|
import Version from "@Front/Components/DesignSystem/Version";
|
||||||
import BackArrow from "@Front/Components/Elements/BackArrow";
|
import BackArrow from "@Front/Components/Elements/BackArrow";
|
||||||
@ -54,12 +55,20 @@ export default class DefaultNotaryDashboard extends React.Component<IProps, ISta
|
|||||||
<div className={classes["content"]}>
|
<div className={classes["content"]}>
|
||||||
{this.state.isLeftSideOpen && <div className={classes["overlay"]} onClick={this.onCloseLeftSide} />}
|
{this.state.isLeftSideOpen && <div className={classes["overlay"]} onClick={this.onCloseLeftSide} />}
|
||||||
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
|
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
|
||||||
{this.state.folders && (
|
{this.props.isArchived && this.state.folders && (
|
||||||
|
<FolderArchivedListContainer
|
||||||
|
folders={this.state.folders}
|
||||||
|
onSelectedFolder={this.props.onSelectedFolder}
|
||||||
|
onCloseLeftSide={this.onCloseLeftSide}
|
||||||
|
isArchived={true}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!this.props.isArchived && this.state.folders && (
|
||||||
<FolderListContainer
|
<FolderListContainer
|
||||||
folders={this.state.folders}
|
folders={this.state.folders}
|
||||||
onSelectedFolder={this.props.onSelectedFolder}
|
onSelectedFolder={this.props.onSelectedFolder}
|
||||||
onCloseLeftSide={this.onCloseLeftSide}
|
onCloseLeftSide={this.onCloseLeftSide}
|
||||||
isArchived={this.props.isArchived!}
|
isArchived={false}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 64px;
|
padding: 64px;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
@media (max-width: $screen-m) {
|
@media (max-width: $screen-m) {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
@ -12,6 +12,7 @@ import { useRouter } from "next/router";
|
|||||||
import JwtService, { ICustomerJwtPayload } from "@Front/Services/JwtService/JwtService";
|
import JwtService, { ICustomerJwtPayload } from "@Front/Services/JwtService/JwtService";
|
||||||
import DepositOtherDocument from "@Front/Components/DesignSystem/DepositOtherDocument";
|
import DepositOtherDocument from "@Front/Components/DesignSystem/DepositOtherDocument";
|
||||||
import Folders from "@Front/Api/LeCoffreApi/Customer/Folders/Folders";
|
import Folders from "@Front/Api/LeCoffreApi/Customer/Folders/Folders";
|
||||||
|
import OfficeRib from "@Front/Api/LeCoffreApi/Customer/OfficeRib/OfficeRib";
|
||||||
|
|
||||||
type IProps = {};
|
type IProps = {};
|
||||||
|
|
||||||
@ -71,6 +72,20 @@ export default function ClientDashboard(props: IProps) {
|
|||||||
setIsAddDocumentModalVisible(true);
|
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(() => {
|
useEffect(() => {
|
||||||
getDocuments();
|
getDocuments();
|
||||||
}, [folderUid, getDocuments]);
|
}, [folderUid, getDocuments]);
|
||||||
@ -80,9 +95,11 @@ export default function ClientDashboard(props: IProps) {
|
|||||||
<div className={classes["header"]}>
|
<div className={classes["header"]}>
|
||||||
<div className={classes["text-container"]}>
|
<div className={classes["text-container"]}>
|
||||||
{/* TODO Get name from userStore */}
|
{/* TODO Get name from userStore */}
|
||||||
|
<div className={classes["title-container"]}>
|
||||||
<Typography typo={ITypo.H1} className={classes["title"]}>
|
<Typography typo={ITypo.H1} className={classes["title"]}>
|
||||||
Bonjour {customer?.contact?.first_name.concat(" ", customer?.contact?.last_name)}
|
Bonjour {customer?.contact?.first_name.concat(" ", customer?.contact?.last_name)}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Typography typo={ITypo.P_SB_18} className={classes["folder-number"]} color={ITypoColor.GREY}>
|
<Typography typo={ITypo.P_SB_18} className={classes["folder-number"]} color={ITypoColor.GREY}>
|
||||||
Dossier {folder?.folder_number} - {folder?.name}
|
Dossier {folder?.folder_number} - {folder?.name}
|
||||||
@ -103,6 +120,10 @@ export default function ClientDashboard(props: IProps) {
|
|||||||
transmis à votre notaire.
|
transmis à votre notaire.
|
||||||
</Typography>
|
</Typography>
|
||||||
</div>
|
</div>
|
||||||
|
{folder?.office?.rib_name && (
|
||||||
|
//Div to avoid the button to be on the same line as the text
|
||||||
|
<Button onClick={downloadFile}>Télécharger le RIB</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}, [customer, folder?.folder_number, folder?.name, folder?.office?.name]);
|
}, [customer, folder?.folder_number, folder?.name, folder?.office?.name]);
|
||||||
|
@ -14,7 +14,6 @@ import { ValidationError } from "class-validator";
|
|||||||
|
|
||||||
import classes from "./classes.module.scss";
|
import classes from "./classes.module.scss";
|
||||||
|
|
||||||
|
|
||||||
export default function DeedTypesEdit() {
|
export default function DeedTypesEdit() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
let { deedTypeUid } = router.query;
|
let { deedTypeUid } = router.query;
|
||||||
@ -107,8 +106,18 @@ export default function DeedTypesEdit() {
|
|||||||
<Typography typo={ITypo.H1Bis}>Modifier les informations de l'acte</Typography>
|
<Typography typo={ITypo.H1Bis}>Modifier les informations de l'acte</Typography>
|
||||||
</div>
|
</div>
|
||||||
<Form onSubmit={onSubmitHandler} className={classes["form-container"]} onFieldChange={onFieldChange}>
|
<Form onSubmit={onSubmitHandler} className={classes["form-container"]} onFieldChange={onFieldChange}>
|
||||||
<TextField name="name" placeholder="Nom de l'acte" defaultValue={deedTypeSelected?.name} validationError={validationError.find((error) => error.property === 'name')}/>
|
<TextField
|
||||||
<TextAreaField name="description" placeholder="Description" defaultValue={deedTypeSelected?.description} validationError={validationError.find((error) => error.property === 'description')} />
|
name="name"
|
||||||
|
placeholder="Nom de l'acte"
|
||||||
|
defaultValue={deedTypeSelected?.name}
|
||||||
|
validationError={validationError.find((error) => error.property === "name")}
|
||||||
|
/>
|
||||||
|
<TextAreaField
|
||||||
|
name="description"
|
||||||
|
placeholder="Description"
|
||||||
|
defaultValue={deedTypeSelected?.description || ""}
|
||||||
|
validationError={validationError.find((error) => error.property === "description")}
|
||||||
|
/>
|
||||||
<div className={classes["buttons-container"]}>
|
<div className={classes["buttons-container"]}>
|
||||||
<Button variant={EButtonVariant.GHOST} onClick={onCancel}>
|
<Button variant={EButtonVariant.GHOST} onClick={onCancel}>
|
||||||
Annuler
|
Annuler
|
||||||
|
@ -18,7 +18,7 @@ export default function DocumentTypesEdit() {
|
|||||||
let { documentTypeUid } = router.query;
|
let { documentTypeUid } = router.query;
|
||||||
|
|
||||||
const [documentTypeSelected, setDocumentTypeSelected] = useState<DocumentType | null>(null);
|
const [documentTypeSelected, setDocumentTypeSelected] = useState<DocumentType | null>(null);
|
||||||
const [validationError, setValidationError] = useState<ValidationError[]>([])
|
const [validationError, setValidationError] = useState<ValidationError[]>([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getDocumentType() {
|
async function getDocumentType() {
|
||||||
@ -73,7 +73,12 @@ export default function DocumentTypesEdit() {
|
|||||||
<Typography typo={ITypo.H1Bis}>Paramétrage des documents</Typography>
|
<Typography typo={ITypo.H1Bis}>Paramétrage des documents</Typography>
|
||||||
</div>
|
</div>
|
||||||
<Form onSubmit={onSubmitHandler} className={classes["form-container"]}>
|
<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
|
<TextAreaField
|
||||||
name="private_description"
|
name="private_description"
|
||||||
placeholder="Description visible par les collaborateurs de l'office"
|
placeholder="Description visible par les collaborateurs de l'office"
|
||||||
@ -83,7 +88,7 @@ export default function DocumentTypesEdit() {
|
|||||||
<TextAreaField
|
<TextAreaField
|
||||||
name="public_description"
|
name="public_description"
|
||||||
placeholder="Description visible par les clients de l'office"
|
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")}
|
validationError={validationError.find((error) => error.property === "public_description")}
|
||||||
/>
|
/>
|
||||||
<div className={classes["buttons-container"]}>
|
<div className={classes["buttons-container"]}>
|
||||||
|
@ -195,6 +195,7 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
|
|||||||
private async getFilePreview(): Promise<void> {
|
private async getFilePreview(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const fileBlob: Blob = await Files.getInstance().download(this.state.selectedFile?.uid as string);
|
const fileBlob: Blob = await Files.getInstance().download(this.state.selectedFile?.uid as string);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
fileBlob,
|
fileBlob,
|
||||||
});
|
});
|
||||||
@ -281,7 +282,9 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
|
|||||||
this.props.router.push(
|
this.props.router.push(
|
||||||
Module.getInstance()
|
Module.getInstance()
|
||||||
.get()
|
.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) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
@ -297,7 +300,9 @@ class ViewDocumentsClass extends BasePage<IPropsClass, IState> {
|
|||||||
this.props.router.push(
|
this.props.router.push(
|
||||||
Module.getInstance()
|
Module.getInstance()
|
||||||
.get()
|
.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) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
72
src/front/Components/Layouts/Rib/classes.module.scss
Normal file
72
src/front/Components/Layouts/Rib/classes.module.scss
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
166
src/front/Components/Layouts/Rib/index.tsx
Normal file
166
src/front/Components/Layouts/Rib/index.tsx
Normal file
@ -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<File[]>([]);
|
||||||
|
const router = useRouter();
|
||||||
|
let { officeUid } = router.query;
|
||||||
|
const [fileBlob, setFileBlob] = useState<Blob>();
|
||||||
|
const [fileName, setFileName] = useState<string>("");
|
||||||
|
const [key, setKey] = useState<string>("");
|
||||||
|
const [isRibModalOpen, setIsRibModalOpen] = useState<boolean>(false);
|
||||||
|
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState<boolean>(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 (
|
||||||
|
<DefaultTemplate title={"RIB"}>
|
||||||
|
<div className={classes["root"]}>
|
||||||
|
<Typography typo={ITypo.H1} color={ITypoColor.BLACK} className={classes["title"]}>
|
||||||
|
RIB de l'office
|
||||||
|
</Typography>
|
||||||
|
|
||||||
|
{!fileBlob && (
|
||||||
|
<div className={classes["document-container"]}>
|
||||||
|
<div>
|
||||||
|
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
|
||||||
|
Aucun RIB n'a été déposé pour cet office
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!fileBlob && (
|
||||||
|
<div className={classes["footer"]}>
|
||||||
|
<div className={classes["buttons-container"]}>
|
||||||
|
<Button onClick={openRibModal}>Déposer un RIB</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{fileBlob && (
|
||||||
|
<div className={classes["document-container"]}>
|
||||||
|
<div className={classes["file-container"]}>
|
||||||
|
{fileBlob && <FilePreview href={fileBlob ? URL.createObjectURL(fileBlob) : ""} fileName={fileName} />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{fileBlob && (
|
||||||
|
<div className={classes["footer"]}>
|
||||||
|
<div className={classes["buttons-container"]}>
|
||||||
|
<Button onClick={openDeleteModal} 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>
|
||||||
|
|
||||||
|
<Confirm
|
||||||
|
isOpen={isDeleteModalOpen}
|
||||||
|
onAccept={onDeleteModalAccepted}
|
||||||
|
onClose={onCloseDeleteModal}
|
||||||
|
closeBtn
|
||||||
|
cancelText={"Annuler"}
|
||||||
|
confirmText={"Supprimer"}>
|
||||||
|
<Typography typo={ITypo.H1} color={ITypoColor.BLACK} className={classes["title"]}>
|
||||||
|
Supprimer le RIB
|
||||||
|
</Typography>
|
||||||
|
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
|
||||||
|
Voulez-vous vraiment supprimer le RIB de votre office ?
|
||||||
|
</Typography>
|
||||||
|
</Confirm>
|
||||||
|
</div>
|
||||||
|
</DefaultTemplate>
|
||||||
|
);
|
||||||
|
}
|
@ -47,9 +47,17 @@ export default function RolesInformations(props: IProps) {
|
|||||||
|
|
||||||
const rules = await Rules.getInstance().get({
|
const rules = await Rules.getInstance().get({
|
||||||
where: {
|
where: {
|
||||||
|
OR: [
|
||||||
|
{
|
||||||
namespace: "notary",
|
namespace: "notary",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
namespace: "collaborator",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!role) return;
|
if (!role) return;
|
||||||
setRoleSelected(role);
|
setRoleSelected(role);
|
||||||
if (!role.rules) return;
|
if (!role.rules) return;
|
||||||
|
@ -257,6 +257,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"OfficesRib": {
|
||||||
|
"enabled": true,
|
||||||
|
"props": {
|
||||||
|
"path": "/offices/rib",
|
||||||
|
"labelKey": "officeRib"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"props": {
|
"props": {
|
||||||
|
@ -257,6 +257,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"OfficesRib": {
|
||||||
|
"enabled": true,
|
||||||
|
"props": {
|
||||||
|
"path": "/offices/rib",
|
||||||
|
"labelKey": "officeRib"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"props": {
|
"props": {
|
||||||
|
@ -257,6 +257,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"OfficesRib": {
|
||||||
|
"enabled": true,
|
||||||
|
"props": {
|
||||||
|
"path": "/offices/rib",
|
||||||
|
"labelKey": "officeRib"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"props": {
|
"props": {
|
||||||
|
@ -257,6 +257,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"OfficesRib": {
|
||||||
|
"enabled": true,
|
||||||
|
"props": {
|
||||||
|
"path": "/offices/rib",
|
||||||
|
"labelKey": "officeRib"
|
||||||
|
}
|
||||||
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"props": {
|
"props": {
|
||||||
|
18
src/pages/offices/rib/index.tsx
Normal file
18
src/pages/offices/rib/index.tsx
Normal file
@ -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 (
|
||||||
|
<Rules
|
||||||
|
mode={RulesMode.NECESSARY}
|
||||||
|
rules={[
|
||||||
|
{
|
||||||
|
action: AppRuleActions.update,
|
||||||
|
name: AppRuleNames.rib,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<Rib />
|
||||||
|
</Rules>
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user