Merge branch 'feature/ora-397-deed-type' into dev

This commit is contained in:
Maxime Lalo 2023-07-17 17:55:43 +02:00
commit ef2de855ca
58 changed files with 2927 additions and 142 deletions

View File

@ -6,4 +6,10 @@
], ],
"description": "media queries" "description": "media queries"
}, },
"Default div": {
"prefix": "<div",
"body": [
"<div className={classes[\"$1\"]}>$2</div>"
]
}
} }

328
package-lock.json generated
View File

@ -371,9 +371,9 @@
"integrity": "sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==" "integrity": "sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g=="
}, },
"node_modules/@floating-ui/dom": { "node_modules/@floating-ui/dom": {
"version": "1.4.4", "version": "1.4.5",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.4.4.tgz", "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.4.5.tgz",
"integrity": "sha512-21hhDEPOiWkGp0Ys4Wi6Neriah7HweToKra626CIK712B5m9qkdz54OP9gVldUg+URnBTpv/j/bi/skmGdstXQ==", "integrity": "sha512-96KnRWkRnuBSSFbj0sFGwwOUd8EkiecINVl0O9wiZlZ64EkpyAOG3Xc2vKKNJmru0Z7RqWNymA+6b8OZqjgyyw==",
"dependencies": { "dependencies": {
"@floating-ui/core": "^1.3.1" "@floating-ui/core": "^1.3.1"
} }
@ -409,9 +409,9 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
}, },
"node_modules/@mui/base": { "node_modules/@mui/base": {
"version": "5.0.0-beta.6", "version": "5.0.0-beta.7",
"resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.6.tgz", "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.7.tgz",
"integrity": "sha512-jcHy6HwOX7KzRhRtL8nvIvUlxvLx2Fl6NMRCyUSQSvMTyfou9kndekz0H4HJaXvG1Y4WEifk23RYedOlrD1kEQ==", "integrity": "sha512-Pjbwm6gjiS96kOMF7E5fjEJsenc0tZBesrLQ4rrdi3eT/c/yhSWnPbCUkHSz8bnS0l3/VQ8bA+oERSGSV2PK6A==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.22.5", "@babel/runtime": "^7.22.5",
"@emotion/is-prop-valid": "^1.2.1", "@emotion/is-prop-valid": "^1.2.1",
@ -441,23 +441,23 @@
} }
}, },
"node_modules/@mui/core-downloads-tracker": { "node_modules/@mui/core-downloads-tracker": {
"version": "5.13.7", "version": "5.14.0",
"resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.7.tgz", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.0.tgz",
"integrity": "sha512-/suIo4WoeL/OyO3KUsFVpdOmKiSAr6NpWXmQ4WLSxwKrTiha1FJxM6vwAki5W/5kR9WnVLw5E8JC4oHHsutT8w==", "integrity": "sha512-SYBOVCatVDUf/lbrLGah09bHhX5WfUXg7kSskfLILr6SvKRni0NLp0aonxQ0SMALVVK3Qwa6cW4CdWuwS0gC1w==",
"funding": { "funding": {
"type": "opencollective", "type": "opencollective",
"url": "https://opencollective.com/mui" "url": "https://opencollective.com/mui"
} }
}, },
"node_modules/@mui/material": { "node_modules/@mui/material": {
"version": "5.13.7", "version": "5.14.0",
"resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.7.tgz", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.0.tgz",
"integrity": "sha512-+n453jDDm88zZM3b5YK29nZ7gXY+s+rryH9ovDbhmfSkOlFtp+KSqbXy5cTaC/UlDqDM7sYYJGq8BmJov3v9Tg==", "integrity": "sha512-HP7CP71NhMkui2HUIEKl2/JfuHMuoarSUWAKlNw6s17bl/Num9rN61EM6uUzc2A2zHjj/00A66GnvDnmixEJEw==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.22.5", "@babel/runtime": "^7.22.5",
"@mui/base": "5.0.0-beta.6", "@mui/base": "5.0.0-beta.7",
"@mui/core-downloads-tracker": "^5.13.7", "@mui/core-downloads-tracker": "^5.14.0",
"@mui/system": "^5.13.7", "@mui/system": "^5.14.0",
"@mui/types": "^7.2.4", "@mui/types": "^7.2.4",
"@mui/utils": "^5.13.7", "@mui/utils": "^5.13.7",
"@types/react-transition-group": "^4.4.6", "@types/react-transition-group": "^4.4.6",
@ -551,9 +551,9 @@
} }
}, },
"node_modules/@mui/system": { "node_modules/@mui/system": {
"version": "5.13.7", "version": "5.14.0",
"resolved": "https://registry.npmjs.org/@mui/system/-/system-5.13.7.tgz", "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.0.tgz",
"integrity": "sha512-7R2KdI6vr8KtnauEfg9e9xQmPk6Gg/1vGNiALYyhSI+cYztxN6WmlSqGX4bjWn/Sygp1TUE1jhFEgs7MWruhkQ==", "integrity": "sha512-0HZGkX8miJbiNw+rjlZ9l0Cfkz1bSqfSHQH0EH9J+nx0aAm5cBleg9piOlLdCNIWGgecCqsw4x62erGrGjjcJg==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.22.5", "@babel/runtime": "^7.22.5",
"@mui/private-theming": "^5.13.7", "@mui/private-theming": "^5.13.7",
@ -970,13 +970,13 @@
"integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==" "integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ=="
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "5.61.0", "version": "5.62.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz",
"integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==", "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "5.61.0", "@typescript-eslint/scope-manager": "5.62.0",
"@typescript-eslint/types": "5.61.0", "@typescript-eslint/types": "5.62.0",
"@typescript-eslint/typescript-estree": "5.61.0", "@typescript-eslint/typescript-estree": "5.62.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -996,12 +996,12 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "5.61.0", "version": "5.62.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
"integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.61.0", "@typescript-eslint/types": "5.62.0",
"@typescript-eslint/visitor-keys": "5.61.0" "@typescript-eslint/visitor-keys": "5.62.0"
}, },
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -1012,9 +1012,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "5.61.0", "version": "5.62.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
"integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
"engines": { "engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}, },
@ -1024,12 +1024,12 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "5.61.0", "version": "5.62.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
"integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.61.0", "@typescript-eslint/types": "5.62.0",
"@typescript-eslint/visitor-keys": "5.61.0", "@typescript-eslint/visitor-keys": "5.62.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"globby": "^11.1.0", "globby": "^11.1.0",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -1050,11 +1050,11 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "5.61.0", "version": "5.62.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
"integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "5.61.0", "@typescript-eslint/types": "5.62.0",
"eslint-visitor-keys": "^3.3.0" "eslint-visitor-keys": "^3.3.0"
}, },
"engines": { "engines": {
@ -1230,6 +1230,25 @@
"get-intrinsic": "^1.1.3" "get-intrinsic": "^1.1.3"
} }
}, },
"node_modules/arraybuffer.prototype.slice": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz",
"integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==",
"dependencies": {
"array-buffer-byte-length": "^1.0.0",
"call-bind": "^1.0.2",
"define-properties": "^1.2.0",
"get-intrinsic": "^1.2.1",
"is-array-buffer": "^3.0.2",
"is-shared-array-buffer": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/ast-types-flow": { "node_modules/ast-types-flow": {
"version": "0.0.7", "version": "0.0.7",
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
@ -1267,6 +1286,11 @@
"dequal": "^2.0.3" "dequal": "^2.0.3"
} }
}, },
"node_modules/b4a": {
"version": "1.6.4",
"resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
"integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw=="
},
"node_modules/babel-plugin-macros": { "node_modules/babel-plugin-macros": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
@ -1420,9 +1444,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001514", "version": "1.0.30001516",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001514.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz",
"integrity": "sha512-ENcIpYBmwAAOm/V2cXgM7rZUrKKaqisZl4ZAI520FIkqGXUxJjmaIssbRW5HVVR5tyV6ygTLIm15aU8LUmQSaQ==", "integrity": "sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -1839,17 +1863,18 @@
} }
}, },
"node_modules/es-abstract": { "node_modules/es-abstract": {
"version": "1.21.2", "version": "1.22.1",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
"integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==",
"dependencies": { "dependencies": {
"array-buffer-byte-length": "^1.0.0", "array-buffer-byte-length": "^1.0.0",
"arraybuffer.prototype.slice": "^1.0.1",
"available-typed-arrays": "^1.0.5", "available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2", "call-bind": "^1.0.2",
"es-set-tostringtag": "^2.0.1", "es-set-tostringtag": "^2.0.1",
"es-to-primitive": "^1.2.1", "es-to-primitive": "^1.2.1",
"function.prototype.name": "^1.1.5", "function.prototype.name": "^1.1.5",
"get-intrinsic": "^1.2.0", "get-intrinsic": "^1.2.1",
"get-symbol-description": "^1.0.0", "get-symbol-description": "^1.0.0",
"globalthis": "^1.0.3", "globalthis": "^1.0.3",
"gopd": "^1.0.1", "gopd": "^1.0.1",
@ -1869,14 +1894,18 @@
"object-inspect": "^1.12.3", "object-inspect": "^1.12.3",
"object-keys": "^1.1.1", "object-keys": "^1.1.1",
"object.assign": "^4.1.4", "object.assign": "^4.1.4",
"regexp.prototype.flags": "^1.4.3", "regexp.prototype.flags": "^1.5.0",
"safe-array-concat": "^1.0.0",
"safe-regex-test": "^1.0.0", "safe-regex-test": "^1.0.0",
"string.prototype.trim": "^1.2.7", "string.prototype.trim": "^1.2.7",
"string.prototype.trimend": "^1.0.6", "string.prototype.trimend": "^1.0.6",
"string.prototype.trimstart": "^1.0.6", "string.prototype.trimstart": "^1.0.6",
"typed-array-buffer": "^1.0.0",
"typed-array-byte-length": "^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.9" "which-typed-array": "^1.1.10"
}, },
"engines": { "engines": {
"node": ">= 0.4" "node": ">= 0.4"
@ -2158,9 +2187,9 @@
} }
}, },
"node_modules/eslint-plugin-import/node_modules/semver": { "node_modules/eslint-plugin-import/node_modules/semver": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
@ -2195,9 +2224,9 @@
} }
}, },
"node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
@ -2269,17 +2298,17 @@
} }
}, },
"node_modules/eslint-plugin-react/node_modules/semver": { "node_modules/eslint-plugin-react/node_modules/semver": {
"version": "6.3.0", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
}, },
"node_modules/eslint-scope": { "node_modules/eslint-scope": {
"version": "7.2.0", "version": "7.2.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz",
"integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==",
"dependencies": { "dependencies": {
"esrecurse": "^4.3.0", "esrecurse": "^4.3.0",
"estraverse": "^5.2.0" "estraverse": "^5.2.0"
@ -2303,9 +2332,9 @@
} }
}, },
"node_modules/espree": { "node_modules/espree": {
"version": "9.6.0", "version": "9.6.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
"integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"dependencies": { "dependencies": {
"acorn": "^8.9.0", "acorn": "^8.9.0",
"acorn-jsx": "^5.3.2", "acorn-jsx": "^5.3.2",
@ -2391,6 +2420,11 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
}, },
"node_modules/fast-fifo": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.0.tgz",
"integrity": "sha512-IgfweLvEpwyA4WgiQe9Nx6VV2QkML2NkvZnk1oKnIzXgXdWxuhF7zw4DvLTPZJn6PIUneiAXPF24QmoEqHTjyw=="
},
"node_modules/fast-glob": { "node_modules/fast-glob": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz",
@ -2856,9 +2890,9 @@
} }
}, },
"node_modules/immutable": { "node_modules/immutable": {
"version": "4.3.0", "version": "4.3.1",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.1.tgz",
"integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==" "integrity": "sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A=="
}, },
"node_modules/import-fresh": { "node_modules/import-fresh": {
"version": "3.3.0", "version": "3.3.0",
@ -3216,6 +3250,11 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
},
"node_modules/isexe": { "node_modules/isexe": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -3917,6 +3956,32 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/prebuild-install/node_modules/tar-fs": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
"dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.1.4"
}
},
"node_modules/prebuild-install/node_modules/tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"dependencies": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
},
"engines": {
"node": ">=6"
}
},
"node_modules/prelude-ls": { "node_modules/prelude-ls": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@ -3990,6 +4055,11 @@
} }
] ]
}, },
"node_modules/queue-tick": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
"integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
},
"node_modules/rc": { "node_modules/rc": {
"version": "1.2.8", "version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@ -4041,9 +4111,9 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
}, },
"node_modules/react-select": { "node_modules/react-select": {
"version": "5.7.3", "version": "5.7.4",
"resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.3.tgz", "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.4.tgz",
"integrity": "sha512-z8i3NCuFFWL3w27xq92rBkVI2onT0jzIIPe480HlBjXJ3b5o6Q+Clp4ydyeKrj9DZZ3lrjawwLC5NGl0FSvUDg==", "integrity": "sha512-NhuE56X+p9QDFh4BgeygHFIvJJszO1i1KSkg/JPcIJrbovyRtI+GuOEa4XzFCEpZRAEoEI8u/cAHK+jG/PgUzQ==",
"dependencies": { "dependencies": {
"@babel/runtime": "^7.12.0", "@babel/runtime": "^7.12.0",
"@emotion/cache": "^11.4.0", "@emotion/cache": "^11.4.0",
@ -4298,6 +4368,23 @@
"queue-microtask": "^1.2.2" "queue-microtask": "^1.2.2"
} }
}, },
"node_modules/safe-array-concat": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz",
"integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==",
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.0",
"has-symbols": "^1.0.3",
"isarray": "^2.0.5"
},
"engines": {
"node": ">=0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/safe-buffer": { "node_modules/safe-buffer": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@ -4369,18 +4456,18 @@
} }
}, },
"node_modules/sharp": { "node_modules/sharp": {
"version": "0.32.1", "version": "0.32.3",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.1.tgz", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.3.tgz",
"integrity": "sha512-kQTFtj7ldpUqSe8kDxoGLZc1rnMFU0AO2pqbX6pLy3b7Oj8ivJIdoKNwxHVQG2HN6XpHPJqCSM2nsma2gOXvOg==", "integrity": "sha512-i1gFPiNqyqxC4ouVvCKj5G8WfPIMeeSxpKcMrjic6NY4e8zktW7bIdqHPc3FCG+pNKU/XCEabKA57hhvZi8UmQ==",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"color": "^4.2.3", "color": "^4.2.3",
"detect-libc": "^2.0.1", "detect-libc": "^2.0.1",
"node-addon-api": "^6.1.0", "node-addon-api": "^6.1.0",
"prebuild-install": "^7.1.1", "prebuild-install": "^7.1.1",
"semver": "^7.5.0", "semver": "^7.5.4",
"simple-get": "^4.0.1", "simple-get": "^4.0.1",
"tar-fs": "^2.1.1", "tar-fs": "^3.0.4",
"tunnel-agent": "^0.6.0" "tunnel-agent": "^0.6.0"
}, },
"engines": { "engines": {
@ -4507,6 +4594,15 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/streamx": {
"version": "2.15.0",
"resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.0.tgz",
"integrity": "sha512-HcxY6ncGjjklGs1xsP1aR71INYcsXFJet5CU1CHqihQ2J5nOsbd4OjgjHO42w/4QNv9gZb3BueV+Vxok5pLEXg==",
"dependencies": {
"fast-fifo": "^1.1.0",
"queue-tick": "^1.0.1"
}
},
"node_modules/string_decoder": { "node_modules/string_decoder": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@ -4689,29 +4785,23 @@
} }
}, },
"node_modules/tar-fs": { "node_modules/tar-fs": {
"version": "2.1.1", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz",
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==",
"dependencies": { "dependencies": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2", "mkdirp-classic": "^0.5.2",
"pump": "^3.0.0", "pump": "^3.0.0",
"tar-stream": "^2.1.4" "tar-stream": "^3.1.5"
} }
}, },
"node_modules/tar-stream": { "node_modules/tar-stream": {
"version": "2.2.0", "version": "3.1.6",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==",
"dependencies": { "dependencies": {
"bl": "^4.0.3", "b4a": "^1.6.4",
"end-of-stream": "^1.4.1", "fast-fifo": "^1.2.0",
"fs-constants": "^1.0.0", "streamx": "^2.15.0"
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
},
"engines": {
"node": ">=6"
} }
}, },
"node_modules/text-table": { "node_modules/text-table": {
@ -4817,6 +4907,54 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/typed-array-buffer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
"integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.1",
"is-typed-array": "^1.1.10"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-byte-length": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
"integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
"dependencies": {
"call-bind": "^1.0.2",
"for-each": "^0.3.3",
"has-proto": "^1.0.1",
"is-typed-array": "^1.1.10"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"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==",
"dependencies": {
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
"for-each": "^0.3.3",
"has-proto": "^1.0.1",
"is-typed-array": "^1.1.10"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typed-array-length": { "node_modules/typed-array-length": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
@ -4928,9 +5066,9 @@
} }
}, },
"node_modules/which-typed-array": { "node_modules/which-typed-array": {
"version": "1.1.9", "version": "1.1.10",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.10.tgz",
"integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", "integrity": "sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA==",
"dependencies": { "dependencies": {
"available-typed-arrays": "^1.0.5", "available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2", "call-bind": "^1.0.2",

View File

@ -0,0 +1,5 @@
import BaseApiService from "@Front/Api/BaseApiService";
export default abstract class BaseAdmin extends BaseApiService {
protected readonly namespaceUrl = this.getBaseUrl().concat("/admin");
}

View File

@ -0,0 +1,49 @@
import { DeedType } from "le-coffre-resources/dist/Admin";
import BaseAdmin from "../BaseAdmin";
export type IGetDeedTypesParams = {
where?: {};
include?: {};
select?: {};
};
export default class DeedTypes extends BaseAdmin {
private static instance: DeedTypes;
private readonly baseURl = this.namespaceUrl.concat("/deed-types");
private constructor() {
super();
}
public static getInstance() {
if (!this.instance) {
return new DeedTypes();
} else {
return this.instance;
}
}
public async get(q: IGetDeedTypesParams): Promise<DeedType[]> {
const url = new URL(this.baseURl);
const query = { q };
Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
try {
return await this.getRequest<DeedType[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getByUid(uid: string, q?: any): Promise<DeedType> {
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<DeedType>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -0,0 +1,49 @@
import { Deed } from "le-coffre-resources/dist/Admin";
import BaseAdmin from "../BaseAdmin";
export type IGetDeedsParams = {
where?: {};
include?: {};
select?: {};
};
export default class Deeds extends BaseAdmin {
private static instance: Deeds;
private readonly baseURl = this.namespaceUrl.concat("/deeds");
private constructor() {
super();
}
public static getInstance() {
if (!this.instance) {
return new Deeds();
} else {
return this.instance;
}
}
public async get(q: IGetDeedsParams): Promise<Deed[]> {
const url = new URL(this.baseURl);
const query = { q };
Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
try {
return await this.getRequest<Deed[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getByUid(uid: string, q?: any): Promise<Deed> {
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<Deed>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -0,0 +1,86 @@
import { DocumentType } from "le-coffre-resources/dist/SuperAdmin";
import BaseAdmin from "../BaseAdmin";
// TODO Type get query params -> Where + inclue + orderby
export interface IGetDocumentTypesparams {
where?: {};
include?: {};
}
// TODO Type getbyuid query params
export type IPutDocumentTypesParams = {};
export interface IPostDocumentTypesParams {
name: string;
public_description: string;
private_description: string;
office: {
uid: string;
};
}
export default class DocumentTypes extends BaseAdmin {
private static instance: DocumentTypes;
private readonly baseURl = this.namespaceUrl.concat("/document-types");
private constructor() {
super();
}
public static getInstance() {
if (!this.instance) {
return new this();
} else {
return this.instance;
}
}
public async get(q: IGetDocumentTypesparams): Promise<DocumentType[]> {
const url = new URL(this.baseURl);
const query = { q };
if (q) Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
try {
return await this.getRequest<DocumentType[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
/**
* @description : Create a Document
*/
public async post(body: IPostDocumentTypesParams): Promise<DocumentType> {
const url = new URL(this.baseURl);
try {
return await this.postRequest<DocumentType>(url, body as any);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getByUid(uid: string, q?: any): Promise<DocumentType> {
const url = new URL(this.baseURl.concat(`/${uid}`));
const query = { q };
if (q) Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
try {
return await this.getRequest<DocumentType>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async put(uid: string, body: IPutDocumentTypesParams): Promise<DocumentType> {
const url = new URL(this.baseURl.concat(`/${uid}`));
try {
return await this.putRequest<DocumentType>(url, body);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -0,0 +1,93 @@
import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document";
import { Document } from "le-coffre-resources/dist/SuperAdmin";
import BaseAdmin from "../BaseAdmin";
// TODO Type get query params -> Where + inclue + orderby
export interface IGetDocumentsparams {
where?: {};
include?: {};
}
// TODO Type getbyuid query params
export type IPutDocumentsParams = {
document_status?: EDocumentStatus;
refused_reason?: string;
};
export interface IPostDocumentsParams {}
export default class Documents extends BaseAdmin {
private static instance: Documents;
private readonly baseURl = this.namespaceUrl.concat("/documents");
private constructor() {
super();
}
public static getInstance() {
if (!this.instance) {
return new this();
} else {
return this.instance;
}
}
public async get(q: IGetDocumentsparams): Promise<Document[]> {
const url = new URL(this.baseURl);
const query = { q };
if (q) Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
try {
return await this.getRequest<Document[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
/**
* @description : Create a Document
*/
public async post(body: any): Promise<Document> {
const url = new URL(this.baseURl);
try {
return await this.postRequest<Document>(url, body);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getByUid(uid: string, q?: any): Promise<Document> {
const url = new URL(this.baseURl.concat(`/${uid}`));
const query = { q };
if (q) Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
try {
return await this.getRequest<Document>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async put(uid: string, body: IPutDocumentsParams): Promise<Document> {
const url = new URL(this.baseURl.concat(`/${uid}`));
try {
return await this.putRequest<Document>(url, body);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async delete(uid: string): Promise<Document> {
const url = new URL(this.baseURl.concat(`/${uid}`));
try {
return await this.deleteRequest<Document>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -0,0 +1,65 @@
import { OfficeRole } from "le-coffre-resources/dist/Admin";
import BaseAdmin from "../BaseAdmin";
export type IGetRolesParams = {
where?: {};
include?: {};
select?: {};
};
export type IPutRoleParams = {
rules: OfficeRole["rules"];
};
export default class OfficeRoles extends BaseAdmin {
private static instance: OfficeRoles;
private readonly baseURl = this.namespaceUrl.concat("/office-roles");
private constructor() {
super();
}
public static getInstance() {
if (!this.instance) {
return new OfficeRoles();
} else {
return this.instance;
}
}
public async get(q: IGetRolesParams): Promise<OfficeRole[]> {
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<OfficeRole[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getByUid(uid: string, q?: any): Promise<OfficeRole> {
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<OfficeRole>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async put(uid: string, body: IPutRoleParams): Promise<OfficeRole> {
const url = new URL(this.baseURl.concat(`/${uid}`));
try {
return await this.putRequest<OfficeRole>(url, body);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -0,0 +1,49 @@
import { Rule } from "le-coffre-resources/dist/Admin";
import BaseAdmin from "../BaseAdmin";
export type IGetRulesParams = {
where?: {};
include?: {};
select?: {};
};
export default class Rules extends BaseAdmin {
private static instance: Rules;
private readonly baseURl = this.namespaceUrl.concat("/rules");
private constructor() {
super();
}
public static getInstance() {
if (!this.instance) {
return new Rules();
} else {
return this.instance;
}
}
public async get(q: IGetRulesParams): Promise<Rule[]> {
const url = new URL(this.baseURl);
const query = { q };
Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value)));
try {
return await this.getRequest<Rule[]>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
public async getByUid(uid: string, q?: any): Promise<Rule> {
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<Rule>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
}

View File

@ -0,0 +1,29 @@
@import "@Themes/constants.scss";
.root {
display: inline-flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 24px;
border: 1px solid $grey-medium;
cursor: pointer;
&:hover {
background-color: $grey-medium;
}
&[data-selected="true"] {
background-color: $grey-medium;
}
.left-side {
display: inline-flex;
justify-content: space-between;
align-items: center;
.warning {
margin-left: 32px;
}
}
}

View File

@ -0,0 +1,40 @@
import React, { useCallback } from "react";
import classes from "./classes.module.scss";
import Typography, { ITypo } from "../Typography";
import ChevronIcon from "@Assets/Icons/chevron.svg";
import Image from "next/image";
export type IBlock = {
name: string;
id: string;
selected: boolean;
};
type IProps = {
blocks: IBlock[];
onSelectedBlock: (block: IBlock) => void;
};
export default function BlockList({ blocks, onSelectedBlock }: IProps) {
const selectBlock = useCallback(
(e: React.MouseEvent<HTMLDivElement>) => {
onSelectedBlock && onSelectedBlock(blocks.find((block) => block.id === e.currentTarget.id)!);
},
[blocks, onSelectedBlock],
);
return (
<div>
{blocks.map((block) => {
return (
<div onClick={selectBlock} key={block.id} id={block.id}>
<div className={classes["root"]} data-selected={block.selected.toString()}>
<div className={classes["left-side"]}>
<Typography typo={ITypo.P_16}>{block.name}</Typography>
</div>
<Image alt="chevron" src={ChevronIcon} />
</div>
</div>
);
})}
</div>
);
}

View File

@ -9,13 +9,29 @@ type IProps = {
name?: string; name?: string;
option: IOption; option: IOption;
toolTip?: string; toolTip?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
checked: boolean;
}; };
export default class CheckBox extends React.Component<IProps> { type IState = {
checked: boolean;
};
export default class CheckBox extends React.Component<IProps, IState> {
static defaultProps = { static defaultProps = {
toolTip: "", toolTip: "",
checked: false,
}; };
constructor(props: IProps) {
super(props);
this.state = {
checked: this.props.checked ?? false,
};
this.onChange = this.onChange.bind(this);
}
public override render(): JSX.Element { public override render(): JSX.Element {
return ( return (
<Typography typo={ITypo.P_ERR_16} color={ITypoColor.BLACK}> <Typography typo={ITypo.P_ERR_16} color={ITypoColor.BLACK}>
@ -24,6 +40,8 @@ export default class CheckBox extends React.Component<IProps> {
type="checkbox" type="checkbox"
name={this.props.name ?? (this.props.option.value as string)} name={this.props.name ?? (this.props.option.value as string)}
value={this.props.option.value as string} value={this.props.option.value as string}
onChange={this.onChange}
checked={this.state.checked}
/> />
{this.props.option.label} {this.props.option.label}
{this.props.toolTip && <Tooltip className={classes["tooltip"]} text={this.props.toolTip} />} {this.props.toolTip && <Tooltip className={classes["tooltip"]} text={this.props.toolTip} />}
@ -31,4 +49,20 @@ export default class CheckBox extends React.Component<IProps> {
</Typography> </Typography>
); );
} }
public override componentDidUpdate(prevProps: Readonly<IProps>): void {
if (prevProps.checked !== this.props.checked) {
this.setState({
checked: this.props.checked,
});
}
}
private onChange(e: React.ChangeEvent<HTMLInputElement>) {
this.setState({
checked: !this.state.checked,
});
this.props.onChange && this.props.onChange(e);
}
} }

View File

@ -4,9 +4,11 @@ import Link from "next/link";
import React from "react"; import React from "react";
import Button from "../Button"; import Button from "../Button";
import FolderList from "../FolderList";
import SearchBar from "../SearchBar"; import SearchBar from "../SearchBar";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import BlockList, { IBlock } from "../BlockList";
import { NextRouter, useRouter } from "next/router";
import { EDocumentStatus } from "le-coffre-resources/dist/SuperAdmin/Document";
type IProps = { type IProps = {
folders: IDashBoardFolder[]; folders: IDashBoardFolder[];
@ -14,17 +16,26 @@ type IProps = {
onSelectedFolder?: (folder: IDashBoardFolder) => void; onSelectedFolder?: (folder: IDashBoardFolder) => void;
onCloseLeftSide?: () => void; onCloseLeftSide?: () => void;
}; };
type IPropsClass = IProps & {
router: NextRouter;
};
type IState = { type IState = {
filteredFolders: IDashBoardFolder[]; filteredFolders: IDashBoardFolder[];
}; };
export default class FolderListContainer extends React.Component<IProps, IState> { class FolderListContainerClass extends React.Component<IPropsClass, IState> {
public constructor(props: IProps) { 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); super(props);
this.state = { this.state = {
filteredFolders: this.props.folders, filteredFolders: this.props.folders,
}; };
this.filterFolders = this.filterFolders.bind(this); this.filterFolders = this.filterFolders.bind(this);
this.onSelectedFolder = this.onSelectedFolder.bind(this);
} }
public override render(): JSX.Element { public override render(): JSX.Element {
@ -33,15 +44,10 @@ export default class FolderListContainer extends React.Component<IProps, IState>
<div className={classes["root"]}> <div className={classes["root"]}>
<div className={classes["header"]}> <div className={classes["header"]}>
<div className={classes["searchbar"]}> <div className={classes["searchbar"]}>
<SearchBar folders={this.props.folders} onChange={this.filterFolders} placeholder="Chercher un dossier" /> <SearchBar onChange={this.filterFolders} placeholder="Chercher un dossier" />
</div> </div>
<div className={classes["folderlist-container"]}> <div className={classes["folderlist-container"]}>
<FolderList <BlockList blocks={this.getBlocks()} onSelectedBlock={this.onSelectedFolder} />
folders={this.state.filteredFolders}
onSelectedFolder={this.props.onSelectedFolder && this.props.onSelectedFolder}
onCloseLeftSide={this.props.onCloseLeftSide}
isArchived={this.props.isArchived}
/>
</div> </div>
</div> </div>
{!this.props.isArchived && ( {!this.props.isArchived && (
@ -55,8 +61,62 @@ export default class FolderListContainer extends React.Component<IProps, IState>
); );
} }
private filterFolders(folders: IDashBoardFolder[]): IDashBoardFolder[] { private getBlocks(): IBlock[] {
this.setState({ filteredFolders: folders }); const pendingFolders = this.props.folders
return 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 = this.props.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: false };
});
}
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: IDashBoardFolder[] = this.props.folders.filter((folder) => {
const name = folder.name.toLowerCase();
const number = folder.folder_number.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 });
} }
} }
export default function FolderListContainer(props: IProps) {
const router = useRouter();
return <FolderListContainerClass {...props} router={router} />;
}

View File

@ -32,6 +32,11 @@ export default class BurgerModal extends React.Component<IProps, IState> {
text="Dossiers archivés" text="Dossiers archivés"
routesActive={[Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path]} routesActive={[Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path]}
/> />
<NavigationLink
path={Module.getInstance().get().modules.pages.Collaborators.props.path}
text="Collaborateurs"
routesActive={[Module.getInstance().get().modules.pages.Collaborators.props.path]}
/>
<div className={classes["separator"]} /> <div className={classes["separator"]} />
<LogOutButton /> <LogOutButton />
</div> </div>

View File

@ -24,6 +24,11 @@ export default class Navigation extends React.Component<IProps, IState> {
path={Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path} path={Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path}
routesActive={[Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path]} routesActive={[Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path]}
/> />
<HeaderLink
text={"Collaborateurs"}
path={Module.getInstance().get().modules.pages.Collaborators.props.path}
routesActive={[Module.getInstance().get().modules.pages.Collaborators.props.path]}
/>
</div> </div>
); );
} }

View File

@ -1,5 +1,4 @@
import LoopIcon from "@Assets/Icons/loop.svg"; import LoopIcon from "@Assets/Icons/loop.svg";
import { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard";
import Image from "next/image"; import Image from "next/image";
import React from "react"; import React from "react";
@ -7,10 +6,10 @@ import Typography, { ITypo } from "../Typography";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
type IProps = { type IProps = {
folders: IDashBoardFolder[]; onChange?: (input: string) => void;
onChange?: (folders: IDashBoardFolder[]) => IDashBoardFolder[];
placeholder?: string; placeholder?: string;
}; };
type IState = { type IState = {
hasValue: boolean; hasValue: boolean;
}; };
@ -46,30 +45,10 @@ export default class SearchBar extends React.Component<IProps, IState> {
const hasValue = event.target.value.length > 0; const hasValue = event.target.value.length > 0;
this.doesInputHaveValue(hasValue); this.doesInputHaveValue(hasValue);
if (!this.props.onChange) return; if (!this.props.onChange) return;
this.props.onChange(this.filterFolders(event)!); this.props.onChange(event.target.value);
} }
private doesInputHaveValue(hasValue: boolean) { private doesInputHaveValue(hasValue: boolean) {
this.setState({ hasValue }); this.setState({ hasValue });
} }
private filterFolders(event: React.ChangeEvent<HTMLInputElement>) {
const filteredFolders: IDashBoardFolder[] = this.props.folders.filter((folder) => {
const name = folder.name.toLowerCase();
const number = folder.folder_number.toLowerCase();
const value = event.target.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);
});
return filteredFolders;
}
} }

View File

@ -0,0 +1,21 @@
@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 {
height: 100%;
border-right: 1px solid var(--grey-medium);
}
}

View File

@ -0,0 +1,64 @@
import React, { useCallback, useState } from "react";
import classes from "./classes.module.scss";
import SearchBar from "@Front/Components/DesignSystem/SearchBar";
import User from "le-coffre-resources/dist/Notary";
import BlockList, { IBlock } from "@Front/Components/DesignSystem/BlockList";
import { useRouter } from "next/router";
import Module from "@Front/Config/Module";
type IProps = {
collaborators: User[];
onSelectedCollaborator?: (user: User) => void;
onCloseLeftSide?: () => void;
};
export default function CollaboratorListContainer(props: IProps) {
const [filteredUsers, setFilteredUsers] = useState<User[]>(props.collaborators);
const router = useRouter();
const { collaboratorUid } = router.query;
const filterUsers = useCallback(
(input: string) => {
const filteredUsers = props.collaborators.filter((user) => {
return (
user.contact?.first_name?.toLowerCase().includes(input.toLowerCase()) ||
user.contact?.last_name?.toLowerCase().includes(input.toLowerCase())
);
});
setFilteredUsers(filteredUsers);
},
[props.collaborators],
);
const onSelectedBlock = useCallback(
(block: IBlock) => {
props.onCloseLeftSide && props.onCloseLeftSide();
const redirectPath = Module.getInstance().get().modules.pages.Collaborators.pages.CollaboratorInformations.props.path;
router.push(redirectPath.replace("[uid]", block.id));
},
[props, router],
);
return (
<div className={classes["root"]}>
<div className={classes["header"]}>
<div className={classes["searchbar"]}>
<SearchBar onChange={filterUsers} placeholder="Chercher un collaborateur" />
</div>
<div className={classes["folderlist-container"]}>
<BlockList
blocks={filteredUsers.map((user) => {
return {
name: user.contact?.first_name + " " + user.contact?.last_name,
id: user.uid!,
selected: user.uid === collaboratorUid,
};
})}
onSelectedBlock={onSelectedBlock}
/>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,117 @@
@import "@Themes/constants.scss";
@keyframes growWidth {
0% {
width: 100%;
}
100% {
width: 200%;
}
}
.root {
.content {
display: flex;
overflow: hidden;
height: calc(100vh - 83px);
.overlay {
position: absolute;
width: 100%;
height: 100%;
background-color: var(--white);
opacity: 0.5;
z-index: 2;
transition: all 0.3s $custom-easing;
}
.left-side {
background-color: $white;
z-index: 3;
display: flex;
width: 389px;
min-width: 389px;
transition: all 0.3s $custom-easing;
overflow: hidden;
@media (max-width: ($screen-m - 1px)) {
width: 56px;
min-width: 56px;
transform: translateX(-389px);
&.opened {
transform: translateX(0px);
width: 389px;
min-width: 389px;
}
}
@media (max-width: $screen-s) {
width: 0px;
min-width: 0px;
&.opened {
width: 100vw;
min-width: 100vw;
}
}
}
.closable-left-side {
position: absolute;
background-color: $white;
z-index: 0;
display: flex;
justify-content: center;
min-width: 56px;
max-width: 56px;
height: calc(100vh - 83px);
border-right: 1px $grey-medium solid;
@media (min-width: $screen-m) {
display: none;
}
.chevron-icon {
margin-top: 21px;
transform: rotate(180deg);
cursor: pointer;
}
@media (max-width: $screen-s) {
display: none;
}
}
.right-side {
min-width: calc(100vw - 389px);
padding: 64px 48px;
overflow-y: auto;
@media (max-width: ($screen-m - 1px)) {
min-width: calc(100vw - 56px);
}
@media (max-width: $screen-s) {
padding: 40px 16px 64px 16px;
flex: 1;
min-width: unset;
}
.back-arrow-mobile {
display: none;
@media (max-width: $screen-s) {
display: block;
margin-bottom: 24px;
}
}
.back-arrow-desktop {
@media (max-width: $screen-s) {
display: none;
}
}
}
}
}

View File

@ -0,0 +1,118 @@
import ChevronIcon from "@Assets/Icons/chevron.svg";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Header from "@Front/Components/DesignSystem/Header";
import Version from "@Front/Components/DesignSystem/Version";
import BackArrow from "@Front/Components/Elements/BackArrow";
import WindowStore from "@Front/Stores/WindowStore";
import classNames from "classnames";
import Image from "next/image";
import React, { ReactNode } from "react";
import classes from "./classes.module.scss";
import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
import User from "le-coffre-resources/dist/Notary";
import CollaboratorListContainer from "./CollaboratorListContainer";
type IProps = {
title: string;
children?: ReactNode;
onSelectedUser: (user: User) => void;
hasBackArrow: boolean;
backArrowUrl?: string;
mobileBackText?: string;
};
type IState = {
collaborators: User[] | null;
isLeftSideOpen: boolean;
leftSideCanBeClosed: boolean;
};
export default class DefaultCollaboratorDashboard extends React.Component<IProps, IState> {
private onWindowResize = () => {};
public static defaultProps: Partial<IProps> = {
hasBackArrow: false,
};
public constructor(props: IProps) {
super(props);
this.state = {
collaborators: null,
isLeftSideOpen: false,
leftSideCanBeClosed: typeof window !== "undefined" ? window.innerWidth < 1024 : false,
};
this.onOpenLeftSide = this.onOpenLeftSide.bind(this);
this.onCloseLeftSide = this.onCloseLeftSide.bind(this);
}
public override render(): JSX.Element {
return (
<div className={classes["root"]}>
<Header isUserConnected={true} />
<div className={classes["content"]}>
{this.state.isLeftSideOpen && <div className={classes["overlay"]} onClick={this.onCloseLeftSide} />}
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
{this.state.collaborators && (
<CollaboratorListContainer collaborators={this.state.collaborators} onCloseLeftSide={this.onCloseLeftSide} />
)}
</div>
<div className={classNames(classes["closable-left-side"])}>
<Image alt="open side menu" src={ChevronIcon} className={classes["chevron-icon"]} onClick={this.onOpenLeftSide} />
</div>
<div className={classes["right-side"]}>
{this.props.hasBackArrow && (
<div className={classes["back-arrow-desktop"]}>
<BackArrow url={this.props.backArrowUrl ?? ""} />
</div>
)}
{this.props.mobileBackText && (
<div className={classes["back-arrow-mobile"]}>
<Button
icon={ChevronIcon}
iconposition={"left"}
iconstyle={{ transform: "rotate(180deg)", width: "22px", height: "22px" }}
variant={EButtonVariant.LINE}
onClick={this.onOpenLeftSide}>
{this.props.mobileBackText ?? "Retour"}
</Button>
</div>
)}
{this.props.children}
</div>
</div>
<Version />
</div>
);
}
public override async componentDidMount() {
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
const query: IGetUsersparams = {
where: { office_uid: "6981326f-8a0a-4437-b15c-4cd5c4d80f6e" },
include: { contact: true },
};
const collaborators = await Users.getInstance().get(query);
this.setState({ collaborators });
}
public override componentWillUnmount() {
this.onWindowResize();
}
private onOpenLeftSide() {
this.setState({ isLeftSideOpen: true });
}
private onCloseLeftSide() {
if (!this.state.leftSideCanBeClosed) return;
this.setState({ isLeftSideOpen: false });
}
private onResize(window: Window) {
if (window.innerWidth > 1023) {
if (!this.state.leftSideCanBeClosed) return;
this.setState({ leftSideCanBeClosed: false });
}
this.setState({ leftSideCanBeClosed: true });
}
}

View File

@ -0,0 +1,21 @@
@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 {
height: 100%;
border-right: 1px solid var(--grey-medium);
}
}

View File

@ -0,0 +1,69 @@
import DeedTypes from "@Front/Api/LeCoffreApi/Admin/DeedTypes/DeedTypes";
import BlockList, { IBlock } from "@Front/Components/DesignSystem/BlockList";
import Button from "@Front/Components/DesignSystem/Button";
import SearchBar from "@Front/Components/DesignSystem/SearchBar";
import Module from "@Front/Config/Module";
import { DeedType } from "le-coffre-resources/dist/Admin";
import Link from "next/link";
import { useRouter } from "next/router";
import React, { useCallback, useState } from "react";
import classes from "./classes.module.scss";
type IProps = {
deedTypes: DeedType[];
onSelectedDeed?: (deed: DeedTypes) => void;
onCloseLeftSide?: () => void;
};
export default function DeedListContainer(props: IProps) {
const [filteredUsers, setFilteredUsers] = useState<DeedType[]>(props.deedTypes);
const router = useRouter();
const { deedTypeUid } = router.query;
const filterDeeds = useCallback(
(input: string) => {
const filteredUsers = props.deedTypes.filter((deedType) => {
return deedType.name?.toLowerCase().includes(input.toLowerCase());
});
setFilteredUsers(filteredUsers);
},
[props.deedTypes],
);
const onSelectedBlock = useCallback(
(block: IBlock) => {
props.onCloseLeftSide && props.onCloseLeftSide();
const redirectPath = Module.getInstance().get().modules.pages.DeedTypes.pages.DeedTypesInformations.props.path;
router.push(redirectPath.replace("[uid]", block.id));
},
[props, router],
);
return (
<div className={classes["root"]}>
<div className={classes["header"]}>
<div className={classes["searchbar"]}>
<SearchBar onChange={filterDeeds} placeholder="Chercher un type d'acte" />
</div>
<div className={classes["folderlist-container"]}>
<BlockList
blocks={filteredUsers.map((deed) => {
return {
name: deed.name,
id: deed.uid!,
selected: deedTypeUid === deed.uid,
};
})}
onSelectedBlock={onSelectedBlock}
/>
</div>
</div>
<div>
<Link href={Module.getInstance().get().modules.pages.DeedTypes.pages.Create.props.path}>
<Button fullwidth={true}>Créer un type d'acte</Button>
</Link>
</div>
</div>
);
}

View File

@ -0,0 +1,117 @@
@import "@Themes/constants.scss";
@keyframes growWidth {
0% {
width: 100%;
}
100% {
width: 200%;
}
}
.root {
.content {
display: flex;
overflow: hidden;
height: calc(100vh - 83px);
.overlay {
position: absolute;
width: 100%;
height: 100%;
background-color: var(--white);
opacity: 0.5;
z-index: 2;
transition: all 0.3s $custom-easing;
}
.left-side {
background-color: $white;
z-index: 3;
display: flex;
width: 389px;
min-width: 389px;
transition: all 0.3s $custom-easing;
overflow: hidden;
@media (max-width: ($screen-m - 1px)) {
width: 56px;
min-width: 56px;
transform: translateX(-389px);
&.opened {
transform: translateX(0px);
width: 389px;
min-width: 389px;
}
}
@media (max-width: $screen-s) {
width: 0px;
min-width: 0px;
&.opened {
width: 100vw;
min-width: 100vw;
}
}
}
.closable-left-side {
position: absolute;
background-color: $white;
z-index: 0;
display: flex;
justify-content: center;
min-width: 56px;
max-width: 56px;
height: calc(100vh - 83px);
border-right: 1px $grey-medium solid;
@media (min-width: $screen-m) {
display: none;
}
.chevron-icon {
margin-top: 21px;
transform: rotate(180deg);
cursor: pointer;
}
@media (max-width: $screen-s) {
display: none;
}
}
.right-side {
min-width: calc(100vw - 389px);
padding: 64px 48px;
overflow-y: auto;
@media (max-width: ($screen-m - 1px)) {
min-width: calc(100vw - 56px);
}
@media (max-width: $screen-s) {
padding: 40px 16px 64px 16px;
flex: 1;
min-width: unset;
}
.back-arrow-mobile {
display: none;
@media (max-width: $screen-s) {
display: block;
margin-bottom: 24px;
}
}
.back-arrow-desktop {
@media (max-width: $screen-s) {
display: none;
}
}
}
}
}

View File

@ -0,0 +1,116 @@
import ChevronIcon from "@Assets/Icons/chevron.svg";
import DeedTypes, { IGetDeedTypesParams } from "@Front/Api/LeCoffreApi/Admin/DeedTypes/DeedTypes";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Header from "@Front/Components/DesignSystem/Header";
import Version from "@Front/Components/DesignSystem/Version";
import BackArrow from "@Front/Components/Elements/BackArrow";
import WindowStore from "@Front/Stores/WindowStore";
import classNames from "classnames";
import { Deed, DeedType } from "le-coffre-resources/dist/Admin";
import Image from "next/image";
import React, { ReactNode } from "react";
import classes from "./classes.module.scss";
import DeedListContainer from "./DeedTypeListContainer";
type IProps = {
title: string;
children?: ReactNode;
onSelectedDeed: (deed: Deed) => void;
hasBackArrow: boolean;
backArrowUrl?: string;
mobileBackText?: string;
};
type IState = {
deedTypes: DeedType[] | null;
isLeftSideOpen: boolean;
leftSideCanBeClosed: boolean;
};
export default class DefaultDeedTypesDashboard extends React.Component<IProps, IState> {
private onWindowResize = () => {};
public static defaultProps: Partial<IProps> = {
hasBackArrow: false,
};
public constructor(props: IProps) {
super(props);
this.state = {
deedTypes: null,
isLeftSideOpen: false,
leftSideCanBeClosed: typeof window !== "undefined" ? window.innerWidth < 1024 : false,
};
this.onOpenLeftSide = this.onOpenLeftSide.bind(this);
this.onCloseLeftSide = this.onCloseLeftSide.bind(this);
}
public override render(): JSX.Element {
return (
<div className={classes["root"]}>
<Header isUserConnected={true} />
<div className={classes["content"]}>
{this.state.isLeftSideOpen && <div className={classes["overlay"]} onClick={this.onCloseLeftSide} />}
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
{this.state.deedTypes && (
<DeedListContainer deedTypes={this.state.deedTypes} onCloseLeftSide={this.onCloseLeftSide} />
)}
</div>
<div className={classNames(classes["closable-left-side"])}>
<Image alt="open side menu" src={ChevronIcon} className={classes["chevron-icon"]} onClick={this.onOpenLeftSide} />
</div>
<div className={classes["right-side"]}>
{this.props.hasBackArrow && (
<div className={classes["back-arrow-desktop"]}>
<BackArrow url={this.props.backArrowUrl ?? ""} />
</div>
)}
{this.props.mobileBackText && (
<div className={classes["back-arrow-mobile"]}>
<Button
icon={ChevronIcon}
iconposition={"left"}
iconstyle={{ transform: "rotate(180deg)", width: "22px", height: "22px" }}
variant={EButtonVariant.LINE}
onClick={this.onOpenLeftSide}>
{this.props.mobileBackText ?? "Retour"}
</Button>
</div>
)}
{this.props.children}
</div>
</div>
<Version />
</div>
);
}
public override async componentDidMount() {
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
const query: IGetDeedTypesParams = {};
const deedTypes = await DeedTypes.getInstance().get(query);
this.setState({ deedTypes });
}
public override componentWillUnmount() {
this.onWindowResize();
}
private onOpenLeftSide() {
this.setState({ isLeftSideOpen: true });
}
private onCloseLeftSide() {
if (!this.state.leftSideCanBeClosed) return;
this.setState({ isLeftSideOpen: false });
}
private onResize(window: Window) {
if (window.innerWidth > 1023) {
if (!this.state.leftSideCanBeClosed) return;
this.setState({ leftSideCanBeClosed: false });
}
this.setState({ leftSideCanBeClosed: true });
}
}

View File

@ -0,0 +1,21 @@
@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 {
height: 100%;
border-right: 1px solid var(--grey-medium);
}
}

View File

@ -0,0 +1,60 @@
import BlockList, { IBlock } from "@Front/Components/DesignSystem/BlockList";
import SearchBar from "@Front/Components/DesignSystem/SearchBar";
import Module from "@Front/Config/Module";
import { OfficeRole } from "le-coffre-resources/dist/Admin";
import { useRouter } from "next/router";
import React, { useCallback, useState } from "react";
import classes from "./classes.module.scss";
type IProps = {
roles: OfficeRole[];
onSelectedRole?: (role: OfficeRole) => void;
onCloseLeftSide?: () => void;
};
export default function RoleListContainer(props: IProps) {
const [filteredUsers, setFilteredUsers] = useState<OfficeRole[]>(props.roles);
const router = useRouter();
const filterRoles = useCallback(
(input: string) => {
const filteredUsers = props.roles.filter((role) => {
return role.name?.toLowerCase().includes(input.toLowerCase());
});
setFilteredUsers(filteredUsers);
},
[props.roles],
);
const onSelectedBlock = useCallback(
(block: IBlock) => {
props.onCloseLeftSide && props.onCloseLeftSide();
const redirectPath = Module.getInstance().get().modules.pages.Roles.pages.RolesInformations.props.path;
router.push(redirectPath.replace("[uid]", block.id));
},
[props, router],
);
return (
<div className={classes["root"]}>
<div className={classes["header"]}>
<div className={classes["searchbar"]}>
<SearchBar onChange={filterRoles} placeholder="Chercher un rôle" />
</div>
<div className={classes["folderlist-container"]}>
<BlockList
blocks={filteredUsers.map((role) => {
return {
name: role.name,
id: role.uid!,
selected: false,
};
})}
onSelectedBlock={onSelectedBlock}
/>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,117 @@
@import "@Themes/constants.scss";
@keyframes growWidth {
0% {
width: 100%;
}
100% {
width: 200%;
}
}
.root {
.content {
display: flex;
overflow: hidden;
height: calc(100vh - 83px);
.overlay {
position: absolute;
width: 100%;
height: 100%;
background-color: var(--white);
opacity: 0.5;
z-index: 2;
transition: all 0.3s $custom-easing;
}
.left-side {
background-color: $white;
z-index: 3;
display: flex;
width: 389px;
min-width: 389px;
transition: all 0.3s $custom-easing;
overflow: hidden;
@media (max-width: ($screen-m - 1px)) {
width: 56px;
min-width: 56px;
transform: translateX(-389px);
&.opened {
transform: translateX(0px);
width: 389px;
min-width: 389px;
}
}
@media (max-width: $screen-s) {
width: 0px;
min-width: 0px;
&.opened {
width: 100vw;
min-width: 100vw;
}
}
}
.closable-left-side {
position: absolute;
background-color: $white;
z-index: 0;
display: flex;
justify-content: center;
min-width: 56px;
max-width: 56px;
height: calc(100vh - 83px);
border-right: 1px $grey-medium solid;
@media (min-width: $screen-m) {
display: none;
}
.chevron-icon {
margin-top: 21px;
transform: rotate(180deg);
cursor: pointer;
}
@media (max-width: $screen-s) {
display: none;
}
}
.right-side {
min-width: calc(100vw - 389px);
padding: 64px 48px;
overflow-y: auto;
@media (max-width: ($screen-m - 1px)) {
min-width: calc(100vw - 56px);
}
@media (max-width: $screen-s) {
padding: 40px 16px 64px 16px;
flex: 1;
min-width: unset;
}
.back-arrow-mobile {
display: none;
@media (max-width: $screen-s) {
display: block;
margin-bottom: 24px;
}
}
.back-arrow-desktop {
@media (max-width: $screen-s) {
display: none;
}
}
}
}
}

View File

@ -0,0 +1,118 @@
import ChevronIcon from "@Assets/Icons/chevron.svg";
import OfficeRoles, { IGetRolesParams } from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Header from "@Front/Components/DesignSystem/Header";
import Version from "@Front/Components/DesignSystem/Version";
import BackArrow from "@Front/Components/Elements/BackArrow";
import WindowStore from "@Front/Stores/WindowStore";
import classNames from "classnames";
import { OfficeRole } from "le-coffre-resources/dist/Admin";
import Image from "next/image";
import React, { ReactNode } from "react";
import classes from "./classes.module.scss";
import RoleListContainer from "./RoleListContainer";
type IProps = {
title: string;
children?: ReactNode;
onSelectedRole: (role: OfficeRole) => void;
hasBackArrow: boolean;
backArrowUrl?: string;
mobileBackText?: string;
};
type IState = {
roles: OfficeRole[] | null;
isLeftSideOpen: boolean;
leftSideCanBeClosed: boolean;
};
export default class DefaultRoleDashboard extends React.Component<IProps, IState> {
private onWindowResize = () => {};
public static defaultProps: Partial<IProps> = {
hasBackArrow: false,
};
public constructor(props: IProps) {
super(props);
this.state = {
roles: null,
isLeftSideOpen: false,
leftSideCanBeClosed: typeof window !== "undefined" ? window.innerWidth < 1024 : false,
};
this.onOpenLeftSide = this.onOpenLeftSide.bind(this);
this.onCloseLeftSide = this.onCloseLeftSide.bind(this);
}
public override render(): JSX.Element {
return (
<div className={classes["root"]}>
<Header isUserConnected={true} />
<div className={classes["content"]}>
{this.state.isLeftSideOpen && <div className={classes["overlay"]} onClick={this.onCloseLeftSide} />}
<div className={classNames(classes["left-side"], this.state.isLeftSideOpen && classes["opened"])}>
{this.state.roles && <RoleListContainer roles={this.state.roles} onCloseLeftSide={this.onCloseLeftSide} />}
</div>
<div className={classNames(classes["closable-left-side"])}>
<Image alt="open side menu" src={ChevronIcon} className={classes["chevron-icon"]} onClick={this.onOpenLeftSide} />
</div>
<div className={classes["right-side"]}>
{this.props.hasBackArrow && (
<div className={classes["back-arrow-desktop"]}>
<BackArrow url={this.props.backArrowUrl ?? ""} />
</div>
)}
{this.props.mobileBackText && (
<div className={classes["back-arrow-mobile"]}>
<Button
icon={ChevronIcon}
iconposition={"left"}
iconstyle={{ transform: "rotate(180deg)", width: "22px", height: "22px" }}
variant={EButtonVariant.LINE}
onClick={this.onOpenLeftSide}>
{this.props.mobileBackText ?? "Retour"}
</Button>
</div>
)}
{this.props.children}
</div>
</div>
<Version />
</div>
);
}
public override async componentDidMount() {
this.onWindowResize = WindowStore.getInstance().onResize((window) => this.onResize(window));
const query: IGetRolesParams = {
include: { rules: true },
};
const roles = await OfficeRoles.getInstance().get(query);
console.log(roles);
this.setState({ roles });
}
public override componentWillUnmount() {
this.onWindowResize();
}
private onOpenLeftSide() {
this.setState({ isLeftSideOpen: true });
}
private onCloseLeftSide() {
if (!this.state.leftSideCanBeClosed) return;
this.setState({ isLeftSideOpen: false });
}
private onResize(window: Window) {
if (window.innerWidth > 1023) {
if (!this.state.leftSideCanBeClosed) return;
this.setState({ leftSideCanBeClosed: false });
}
this.setState({ leftSideCanBeClosed: true });
}
}

View File

@ -0,0 +1,46 @@
@import "@Themes/constants.scss";
.root {
.user-infos {
background-color: var(--grey-soft);
display: flex;
justify-content: space-between;
padding: 24px;
margin-top: 32px;
@media (max-width: $screen-l) {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 32px;
}
@media (max-width: $screen-s) {
grid-template-columns: repeat(1, 1fr);
}
.user-infos-row {
display: flex;
flex-direction: column;
gap: 12px;
}
}
.role-container {
padding: 32px 16px;
border: 1px solid var(--grey);
margin-top: 32px;
.first-line {
display: flex;
justify-content: space-between;
}
.second-line {
margin-top: 32px;
}
.third-line {
margin-top: 32px;
}
}
}

View File

@ -0,0 +1,117 @@
import ChevronIcon from "@Assets/Icons/chevron.svg";
import Users from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
import SelectField, { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import DefaultCollaboratorDashboard from "@Front/Components/LayoutTemplates/DefaultCollaboratorDashboard";
import User from "le-coffre-resources/dist/Notary";
import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import classes from "./classes.module.scss";
import Module from "@Front/Config/Module";
import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
type IProps = {};
export default function CollaboratorInformations(props: IProps) {
const router = useRouter();
let { collaboratorUid } = router.query;
const [userSelected, setUserSelected] = useState<User | null>(null);
const [availableRoles, setAvailableRoles] = useState<IOption[]>([]);
useEffect(() => {
async function getUser() {
if (!collaboratorUid) return;
const user = await Users.getInstance().getByUid(collaboratorUid as string, {
q: {
contact: true,
office_role: true,
},
});
if (!user) return;
const roles = await OfficeRoles.getInstance().get();
if (!roles) return;
setAvailableRoles(roles.map((role) => ({ value: role.uid, label: role.name })));
setUserSelected(user);
}
getUser();
}, [collaboratorUid]);
return (
<DefaultCollaboratorDashboard mobileBackText={"Liste des collaborateurs"}>
<div className={classes["root"]}>
<div className={classes["folder-header"]}>
<Typography typo={ITypo.H1Bis}>{userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name}</Typography>
</div>
<div className={classes["user-infos"]}>
<div className={classes["user-infos-row"]}>
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
Nom
</Typography>
<Typography typo={ITypo.P_18}>{userSelected?.contact?.first_name}</Typography>
</div>
<div className={classes["user-infos-row"]}>
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
Prénom
</Typography>
<Typography typo={ITypo.P_18}>{userSelected?.contact?.last_name}</Typography>
</div>
<div className={classes["user-infos-row"]}>
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
Numéro de téléphone
</Typography>
<Typography typo={ITypo.P_18}>{userSelected?.contact?.phone_number}</Typography>
</div>
<div className={classes["user-infos-row"]}>
<Typography typo={ITypo.NAV_INPUT_16} color={ITypoColor.GREY}>
Email
</Typography>
<Typography typo={ITypo.P_18}>{userSelected?.contact?.email}</Typography>
</div>
</div>
<div className={classes["role-container"]}>
<div className={classes["first-line"]}>
<Typography typo={ITypo.P_SB_18}>Modifier le rôle</Typography>
<div className={classes["gestion-role"]}>
<Link href={Module.getInstance().get().modules.pages.Roles.props.path}>
<Button
icon={ChevronIcon}
iconposition={"right"}
iconstyle={{ width: "22px", height: "22px" }}
variant={EButtonVariant.LINE}>
Gestion des rôles
</Button>
</Link>
</div>
</div>
<div className={classes["second-line"]}>
<SelectField
placeholder="Rôle"
name="role"
options={availableRoles}
selectedOption={{
value: userSelected?.office_role?.uid,
label: userSelected?.office_role?.name!,
}}
/>
</div>
<div className={classes["third-line"]}>
<CheckBox
option={{
value: "1",
label: "Nommer administrateur de l'office",
}}
toolTip="blabla"
/>
</div>
</div>
</div>
</DefaultCollaboratorDashboard>
);
}

View File

@ -0,0 +1,72 @@
@import "@Themes/constants.scss";
.root {
display: flex;
align-items: center;
flex-direction: column;
min-height: 100%;
.no-folder-selected {
width: 100%;
.choose-a-folder {
margin-top: 96px;
text-align: center;
}
}
.folder-informations {
width: 100%;
min-height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
flex-grow: 1;
.folder-header {
width: 100%;
.header {
margin-bottom: 32px;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
}
}
.second-box {
margin-top: 24px;
margin-bottom: 32px;
}
.progress-bar {
margin-bottom: 32px;
}
.button-container {
width: 100%;
text-align: center;
:first-child {
margin-right: 12px;
}
> * {
margin: auto;
}
@media (max-width: $screen-m) {
:first-child {
margin-right: 0;
margin-bottom: 12px;
}
> * {
width: 100%;
}
}
}
.modal-title {
margin-bottom: 24px;
}
}
}

View File

@ -0,0 +1,26 @@
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import BasePage from "../Base";
import classes from "./classes.module.scss";
import DefaultCollaboratorDashboard from "@Front/Components/LayoutTemplates/DefaultCollaboratorDashboard";
type IProps = {};
type IState = {};
export default class Collaborators extends BasePage<IProps, IState> {
public override render(): JSX.Element {
return (
<DefaultCollaboratorDashboard title={"Dossier"} mobileBackText={"Liste des collaborateurs"}>
<div className={classes["root"]}>
<div className={classes["no-folder-selected"]}>
<Typography typo={ITypo.H1Bis}>Informations du collaboraeur</Typography>
<div className={classes["choose-a-folder"]}>
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
Sélectionnez un collaborateur
</Typography>
</div>
</div>
</div>
</DefaultCollaboratorDashboard>
);
}
}

View File

@ -0,0 +1,24 @@
@import "@Themes/constants.scss";
.root {
.header {
margin-top: 24px;
}
.form-container {
margin-top: 32px;
display: flex;
flex-direction: column;
gap: 32px;
}
.buttons-container {
display: flex;
gap: 32px;
@media (max-width: $screen-s) {
flex-direction: column-reverse;
gap: 16px;
}
}
}

View File

@ -0,0 +1,32 @@
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Form from "@Front/Components/DesignSystem/Form";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import DefaultDeedTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDeedTypeDashboard";
import { useCallback } from "react";
import classes from "./classes.module.scss";
import TextField from "@Front/Components/DesignSystem/Form/TextField";
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
type IProps = {};
export default function DeedTypesCreate(props: IProps) {
const onSubmitHandler = useCallback(async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {}, []);
return (
<DefaultDeedTypesDashboard mobileBackText={"Liste des types d'actes"} hasBackArrow title="Créer un type d'acte">
<div className={classes["root"]}>
<div className={classes["header"]}>
<Typography typo={ITypo.H1Bis}>Créer un type d'acte</Typography>
</div>
<Form onSubmit={onSubmitHandler} className={classes["form-container"]}>
<TextField name="name" placeholder="Nom de l'acte" />
<TextAreaField name="description" placeholder="Description" />
<div className={classes["buttons-container"]}>
<Button variant={EButtonVariant.GHOST}>Annuler</Button>
<Button type="submit">Créer le type d'acte</Button>
</div>
</Form>
</div>
</DefaultDeedTypesDashboard>
);
}

View File

@ -0,0 +1,24 @@
@import "@Themes/constants.scss";
.root {
.header {
margin-top: 24px;
}
.form-container {
margin-top: 32px;
display: flex;
flex-direction: column;
gap: 32px;
}
.buttons-container {
display: flex;
gap: 32px;
@media (max-width: $screen-s) {
flex-direction: column-reverse;
gap: 16px;
}
}
}

View File

@ -0,0 +1,53 @@
import DeedTypes from "@Front/Api/LeCoffreApi/Admin/DeedTypes/DeedTypes";
import Form from "@Front/Components/DesignSystem/Form";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import DefaultDeedTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDeedTypeDashboard";
import { DeedType } from "le-coffre-resources/dist/Admin";
import { useRouter } from "next/router";
import { useCallback, useEffect, useState } from "react";
import classes from "./classes.module.scss";
import TextField from "@Front/Components/DesignSystem/Form/TextField";
import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
export default function DeedTypesEdit() {
const router = useRouter();
let { deedTypeUid } = router.query;
const [deedTypeSelected, setDeedTypeSelected] = useState<DeedType | null>(null);
useEffect(() => {
async function getDeedType() {
if (!deedTypeUid) return;
const deedType = await DeedTypes.getInstance().getByUid(deedTypeUid as string, {
q: {
document_types: true,
},
});
setDeedTypeSelected(deedType);
}
getDeedType();
}, [deedTypeUid]);
const onSubmitHandler = useCallback(async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {}, []);
return (
<DefaultDeedTypesDashboard mobileBackText={"Liste des types d'actes"} hasBackArrow title="Modifier les informations d'un acte">
<div className={classes["root"]}>
<div className={classes["header"]}>
<Typography typo={ITypo.H1Bis}>Modifier les informations de l'acte</Typography>
</div>
<Form onSubmit={onSubmitHandler} className={classes["form-container"]}>
<TextField name="name" placeholder="Nom de l'acte" defaultValue={deedTypeSelected?.name} />
<TextAreaField name="description" placeholder="Description" defaultValue={deedTypeSelected?.description} />
<div className={classes["buttons-container"]}>
<Button variant={EButtonVariant.GHOST}>Annuler</Button>
<Button type="submit">Enregistrer</Button>
</div>
</Form>
</div>
</DefaultDeedTypesDashboard>
);
}

View File

@ -0,0 +1,91 @@
@import "@Themes/constants.scss";
.root {
.header {
display: flex;
justify-content: space-between;
align-items: flex-end;
@media (max-width: $screen-l) {
flex-direction: column;
align-items: flex-start;
gap: 24px;
}
}
.subtitle {
margin-top: 32px;
}
.deed-type-container {
margin-top: 32px;
display: flex;
gap: 100px;
justify-content: space-between;
padding: 24px;
background-color: var(--grey-soft);
@media (max-width: $screen-l) {
gap: 80px;
}
@media (max-width: $screen-m) {
flex-direction: column;
gap: 32px;
}
.infos {
display: flex;
gap: 100px;
flex: 1;
@media (max-width: $screen-l) {
flex-direction: column;
gap: 32px;
}
.box {
.box-title {
margin-bottom: 8px;
opacity: 0.4;
}
}
.middle-box {
flex: 1;
}
}
.pencil {
align-self: center;
@media (max-width: $screen-m) {
align-self: flex-start;
}
}
}
.documents-container {
margin-top: 32px;
padding: 32px 16px;
border: 1px solid var(--grey);
.container-title {
}
.documents {
margin-top: 32px;
}
.button-container {
margin-top: 32px;
}
}
.delete-container {
display: flex;
justify-content: center;
margin-top: 32px;
}
}

View File

@ -0,0 +1,127 @@
import ChevronIcon from "@Assets/Icons/chevron.svg";
import PenICon from "@Assets/Icons/pen.svg";
import DeedTypes from "@Front/Api/LeCoffreApi/Admin/DeedTypes/DeedTypes";
import DocumentTypes from "@Front/Api/LeCoffreApi/Admin/DocumentTypes/DocumentTypes";
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
import Form from "@Front/Components/DesignSystem/Form";
import { IOption } from "@Front/Components/DesignSystem/Form/SelectField";
import MultiSelect from "@Front/Components/DesignSystem/MultiSelect";
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import DefaultDeedTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDeedTypeDashboard";
import classNames from "classnames";
import { DeedType, DocumentType } from "le-coffre-resources/dist/Admin";
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";
import { useCallback, useEffect, useState } from "react";
import { MultiValue } from "react-select";
import classes from "./classes.module.scss";
import Module from "@Front/Config/Module";
type IProps = {};
export default function DeedTypesInformations(props: IProps) {
const router = useRouter();
let { deedTypeUid } = router.query;
const [deedTypeSelected, setDeedTypeSelected] = useState<DeedType | null>(null);
const [availableDocuments, setAvailableDocuments] = useState<DocumentType[]>([]);
const [selectedDocuments, setSelectedDocuments] = useState<IOption[]>([]);
useEffect(() => {
async function getDeedType() {
if (!deedTypeUid) return;
const deedType = await DeedTypes.getInstance().getByUid(deedTypeUid as string, {
q: {
document_types: true,
},
});
setDeedTypeSelected(deedType);
}
async function getDocuments() {
const documents = await DocumentTypes.getInstance().get({});
setAvailableDocuments(documents);
}
setSelectedDocuments([]);
getDocuments();
getDeedType();
}, [deedTypeUid]);
const onSubmitHandler = useCallback(async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {}, []);
const onDocumentChangeHandler = useCallback((values: MultiValue<IOption>) => {
setSelectedDocuments(values as IOption[]);
}, []);
const formattedOptions: IOption[] = availableDocuments.map((document) => {
return {
label: document.name,
value: document.uid,
};
});
return (
<DefaultDeedTypesDashboard mobileBackText={"Liste des types d'actes"}>
<div className={classes["root"]}>
<div className={classes["header"]}>
<Typography typo={ITypo.H1Bis}>Paramétrage des listes de pièces</Typography>
<Button variant={EButtonVariant.LINE}>
Modifier la liste des documents
<Image src={ChevronIcon} alt="Chevron" />
</Button>
</div>
<div className={classes["subtitle"]}>
<Typography typo={ITypo.H3}>{deedTypeSelected?.name}</Typography>
</div>
<div className={classes["deed-type-container"]}>
<div className={classes["infos"]}>
<div className={classes["box"]}>
<Typography typo={ITypo.NAV_INPUT_16} className={classes["box-title"]} color={ITypoColor.BLACK}>
Nom du type d'acte
</Typography>
<Typography typo={ITypo.P_18}>{deedTypeSelected?.name}</Typography>
</div>
<div className={classNames(classes["middle-box"], classes["box"])}>
<Typography typo={ITypo.NAV_INPUT_16} className={classes["box-title"]} color={ITypoColor.BLACK}>
Description
</Typography>
<Typography typo={ITypo.P_18}>{deedTypeSelected?.description}</Typography>
</div>
</div>
<div className={classes["pencil"]}>
<Link
href={Module.getInstance()
.get()
.modules.pages.DeedTypes.pages.Edit.props.path.replace("[uid]", deedTypeUid as string)}
className={classes["edit-icon-container"]}>
<Image src={PenICon} alt="éditer le type d'acte" />
</Link>
</div>
</div>
<div className={classes["documents-container"]}>
<Form onSubmit={onSubmitHandler}>
<div className={classes["container-title"]}>
<Typography typo={ITypo.P_SB_18}>Documents paramétrés</Typography>
</div>
<div className={classes["documents"]}>
<MultiSelect
options={formattedOptions}
placeholder="Type de document"
onChange={onDocumentChangeHandler}
defaultValue={selectedDocuments}
/>
</div>
<div className={classes["button-container"]}>
<Button type="submit">Enregistrer</Button>
</div>
</Form>
</div>
<div className={classes["delete-container"]}>
<Button variant={EButtonVariant.GHOST}>Supprimer</Button>
</div>
</div>
</DefaultDeedTypesDashboard>
);
}

View File

@ -0,0 +1,17 @@
@import "@Themes/constants.scss";
.root {
display: flex;
align-items: center;
flex-direction: column;
min-height: 100%;
.no-role-selected {
width: 100%;
.choose-a-role {
margin-top: 96px;
text-align: center;
}
}
}

View File

@ -0,0 +1,26 @@
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import DefaultDeedTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDeedTypeDashboard";
import BasePage from "../Base";
import classes from "./classes.module.scss";
type IProps = {};
type IState = {};
export default class DeedTypes extends BasePage<IProps, IState> {
public override render(): JSX.Element {
return (
<DefaultDeedTypesDashboard mobileBackText={"Liste des listes de pièces"}>
<div className={classes["root"]}>
<div className={classes["no-role-selected"]}>
<Typography typo={ITypo.H1Bis}>Paramétrage des listes de pièces</Typography>
<div className={classes["choose-a-role"]}>
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
Sélectionnez une liste de pièces
</Typography>
</div>
</div>
</div>
</DefaultDeedTypesDashboard>
);
}
}

View File

@ -234,8 +234,7 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
[key: string]: any; [key: string]: any;
}, },
) { ) {
const officeId = (JwtService.getInstance().decodeJwt())?.office_Id; const officeId = JwtService.getInstance().decodeJwt()?.office_Id;
console.log('form initializdd');
const selectedDeedTypeUid: DeedType | undefined = this.state.deedTypes.find( const selectedDeedTypeUid: DeedType | undefined = this.state.deedTypes.find(
(deedType) => deedType.uid === this.state.formValues.act_typ?.value, (deedType) => deedType.uid === this.state.formValues.act_typ?.value,
); );
@ -261,28 +260,24 @@ class CreateFolderClass extends BasePage<IPropsClass, IState> {
uid: officeId, uid: officeId,
}), }),
customers: [], customers: [],
stakeholders stakeholders,
}); });
console.log('form');
try { try {
await officeFolderForm.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: false }); await officeFolderForm.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: false });
} catch (validationErrors) { } catch (validationErrors) {
this.setState({ this.setState({
validationError: validationErrors as ValidationError[], validationError: validationErrors as ValidationError[],
}); });
console.log('validation errros');
return; return;
} }
try { try {
const newOfficeFolder = await Folders.getInstance().post(officeFolderForm); const newOfficeFolder = await Folders.getInstance().post(officeFolderForm);
console.log('new office folder: ',newOfficeFolder)
if (!newOfficeFolder) return; if (!newOfficeFolder) return;
this.props.router.push(`/folders/${newOfficeFolder.uid}`); this.props.router.push(`/folders/${newOfficeFolder.uid}`);
} catch (backError: any) { } catch (backError: any) {
if(!Array.isArray(backError)) return; if (!Array.isArray(backError)) return;
this.setState({ this.setState({
validationError: backError as ValidationError[], validationError: backError as ValidationError[],
}); });

View File

@ -35,7 +35,7 @@ export default class LoginClass extends BasePage {
// const variables = FrontendVariables.getInstance(); // const variables = FrontendVariables.getInstance();
// const baseFronturl = variables.BACK_API_PROTOCOL + variables.FRONT_APP_HOST; // const baseFronturl = variables.BACK_API_PROTOCOL + variables.FRONT_APP_HOST;
await UserStore.instance.connect("SbRKyM8BJI"); await UserStore.instance.connect("symWAJRxuu");
// await JwtService.getInstance().checkJwt(); // await JwtService.getInstance().checkJwt();
// window.location.assign("http://localhost:3000" + "/folders"); // window.location.assign("http://localhost:3000" + "/folders");

View File

@ -0,0 +1,31 @@
@import "@Themes/constants.scss";
.root {
.subtitle {
margin-top: 32px;
}
.rights-container {
margin-top: 32px;
padding: 32px 16px;
border: 1px solid gray;
.select-all-container {
margin-top: 32px;
}
.rights {
margin-top: 32px;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 32px;
@media (max-width: $screen-m) {
grid-template-columns: 1fr;
}
}
.save-container {
margin-top: 32px;
}
}
}

View File

@ -0,0 +1,122 @@
import Roles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
import Rules from "@Front/Api/LeCoffreApi/Admin/Rules/Rules";
import Button from "@Front/Components/DesignSystem/Button";
import CheckBox from "@Front/Components/DesignSystem/CheckBox";
import Form from "@Front/Components/DesignSystem/Form";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import DefaultRoleDashboard from "@Front/Components/LayoutTemplates/DefaultRoleDashboard";
import { Role, Rule } from "le-coffre-resources/dist/Admin";
import { useRouter } from "next/router";
import { useCallback, useEffect, useState } from "react";
import classes from "./classes.module.scss";
type IProps = {};
type RuleCheckbox = Rule & {
checked: boolean;
};
export default function RolesInformations(props: IProps) {
const router = useRouter();
let { roleUid } = router.query;
const [roleSelected, setRoleSelected] = useState<Role | null>(null);
const [rulesCheckboxes, setRulesCheckboxes] = useState<RuleCheckbox[]>([]);
const [selectAll, setSelectAll] = useState<boolean>(false);
useEffect(() => {
setSelectAll(false);
async function getUser() {
if (!roleUid) return;
const role = await Roles.getInstance().getByUid(roleUid as string, {
q: {
rules: true,
},
});
const rules = await Rules.getInstance().get({});
if (!role) return;
setRoleSelected(role);
if (!role.rules) return;
const rulesCheckboxes = rules
.map((rule) => {
if (role.rules?.find((r) => r.uid === rule.uid)) {
return { ...rule, checked: true };
}
return { ...rule, checked: false };
})
.sort((ruleA, ruleB) => (ruleA.name < ruleB.name ? 1 : -1))
.sort((rule) => (rule.checked ? -1 : 1));
const selectAll = rulesCheckboxes.every((rule) => rule.checked);
setSelectAll(selectAll);
setRulesCheckboxes(rulesCheckboxes);
}
getUser();
}, [roleUid]);
const handleSelectAllChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => {
setSelectAll(e.target.checked);
const checked = e.target.checked;
rulesCheckboxes.forEach((rule) => (rule.checked = checked));
setRulesCheckboxes([...rulesCheckboxes]);
},
[rulesCheckboxes],
);
const onSubmitHandler = useCallback(
async (e: React.FormEvent<HTMLFormElement> | null, values: { [key: string]: string }) => {
if (!roleSelected || !roleSelected.uid) return;
const rules = rulesCheckboxes.filter((rule) => rule.checked)?.map((rule) => Rule.hydrate<Rule>(rule));
const role = await Roles.getInstance().put(roleSelected.uid, {
rules,
});
if (!role) return;
setRoleSelected(role);
if (!role.rules) return;
setRulesCheckboxes(role.rules.map((rule) => ({ ...rule, checked: false })));
},
[roleSelected, rulesCheckboxes],
);
return (
<DefaultRoleDashboard mobileBackText={"Liste des rôles"}>
<div className={classes["root"]}>
<div className={classes["header"]}>
<Typography typo={ITypo.H1Bis}>Gestion des rôles</Typography>
</div>
<div className={classes["subtitle"]}>
<Typography typo={ITypo.H3}>{roleSelected?.name}</Typography>
</div>
<div className={classes["rights-container"]}>
<div className={classes["rights-header"]}>
<Typography typo={ITypo.P_SB_18}>Modifier les droits</Typography>
</div>
<div className={classes["select-all-container"]}>
<CheckBox
option={{
label: "Tout sélectionner",
value: "all",
}}
toolTip="Tout sélectionner"
onChange={handleSelectAllChange}
checked={selectAll}
/>
</div>
<Form onSubmit={onSubmitHandler}>
<div className={classes["rights"]}>
{rulesCheckboxes.map((rule) => (
<div className={classes["right"]} key={rule.uid}>
<CheckBox option={{ label: rule.name, value: rule.uid }} checked={rule.checked} />
</div>
))}
</div>
<div className={classes["save-container"]}>
<Button type="submit">Enregistrer</Button>
</div>
</Form>
</div>
</div>
</DefaultRoleDashboard>
);
}

View File

@ -0,0 +1,17 @@
@import "@Themes/constants.scss";
.root {
display: flex;
align-items: center;
flex-direction: column;
min-height: 100%;
.no-role-selected {
width: 100%;
.choose-a-role {
margin-top: 96px;
text-align: center;
}
}
}

View File

@ -0,0 +1,26 @@
import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography";
import DefaultRoleDashboard from "@Front/Components/LayoutTemplates/DefaultRoleDashboard";
import BasePage from "../Base";
import classes from "./classes.module.scss";
type IProps = {};
type IState = {};
export default class Collaborators extends BasePage<IProps, IState> {
public override render(): JSX.Element {
return (
<DefaultRoleDashboard mobileBackText={"Liste des rôles"}>
<div className={classes["root"]}>
<div className={classes["no-role-selected"]}>
<Typography typo={ITypo.H1Bis}>Gestion des rôles</Typography>
<div className={classes["choose-a-role"]}>
<Typography typo={ITypo.P_18} color={ITypoColor.GREY}>
Sélectionnez un rôle
</Typography>
</div>
</div>
</div>
</DefaultRoleDashboard>
);
}
}

View File

@ -119,6 +119,68 @@
"labelKey": "my_account" "labelKey": "my_account"
} }
}, },
"Collaborators": {
"enabled": true,
"props": {
"path": "/collaborators",
"labelKey": "collaborators"
},
"pages": {
"CollaboratorInformations": {
"enabled": true,
"props": {
"path": "/collaborators/[uid]",
"labelKey": "collaborator_informations"
}
}
}
},
"Roles": {
"enabled": true,
"props": {
"path": "/roles",
"labelKey": "roles"
},
"pages": {
"RolesInformations": {
"enabled": true,
"props": {
"path": "/roles/[uid]",
"labelKey": "roles_informations"
}
}
}
},
"DeedTypes": {
"enabled": true,
"props": {
"path": "/deed-types",
"labelKey": "deedTypes"
},
"pages": {
"DeedTypesInformations": {
"enabled": true,
"props": {
"path": "/deed-types/[uid]",
"labelKey": "deedTypesInformations"
}
},
"Create": {
"enabled": true,
"props": {
"path": "/deed-types/create",
"labelKey": "createDeedType"
}
},
"Edit": {
"enabled": true,
"props": {
"path": "/deed-types/[uid]/edit",
"labelKey": "editDeedType"
}
}
}
},
"404": { "404": {
"enabled": true, "enabled": true,
"props": { "props": {

View File

@ -119,6 +119,68 @@
"labelKey": "my_account" "labelKey": "my_account"
} }
}, },
"Collaborators": {
"enabled": true,
"props": {
"path": "/collaborators",
"labelKey": "collaborators"
},
"pages": {
"CollaboratorInformations": {
"enabled": true,
"props": {
"path": "/collaborators/[uid]",
"labelKey": "collaborator_informations"
}
}
}
},
"Roles": {
"enabled": true,
"props": {
"path": "/roles",
"labelKey": "roles"
},
"pages": {
"RolesInformations": {
"enabled": true,
"props": {
"path": "/roles/[uid]",
"labelKey": "roles_informations"
}
}
}
},
"DeedTypes": {
"enabled": true,
"props": {
"path": "/deed-types",
"labelKey": "deedTypes"
},
"pages": {
"DeedTypesInformations": {
"enabled": true,
"props": {
"path": "/deed-types/[uid]",
"labelKey": "deedTypesInformations"
}
},
"Create": {
"enabled": true,
"props": {
"path": "/deed-types/create",
"labelKey": "createDeedType"
}
},
"Edit": {
"enabled": true,
"props": {
"path": "/deed-types/[uid]/edit",
"labelKey": "editDeedType"
}
}
}
},
"404": { "404": {
"enabled": true, "enabled": true,
"props": { "props": {

View File

@ -119,6 +119,68 @@
"labelKey": "my_account" "labelKey": "my_account"
} }
}, },
"Collaborators": {
"enabled": true,
"props": {
"path": "/collaborators",
"labelKey": "collaborators"
},
"pages": {
"CollaboratorInformations": {
"enabled": true,
"props": {
"path": "/collaborators/[uid]",
"labelKey": "collaborator_informations"
}
}
}
},
"Roles": {
"enabled": true,
"props": {
"path": "/roles",
"labelKey": "roles"
},
"pages": {
"RolesInformations": {
"enabled": true,
"props": {
"path": "/roles/[uid]",
"labelKey": "roles_informations"
}
}
}
},
"DeedTypes": {
"enabled": true,
"props": {
"path": "/deed-types",
"labelKey": "deedTypes"
},
"pages": {
"DeedTypesInformations": {
"enabled": true,
"props": {
"path": "/deed-types/[uid]",
"labelKey": "deedTypesInformations"
}
},
"Create": {
"enabled": true,
"props": {
"path": "/deed-types/create",
"labelKey": "createDeedType"
}
},
"Edit": {
"enabled": true,
"props": {
"path": "/deed-types/[uid]/edit",
"labelKey": "editDeedType"
}
}
}
},
"404": { "404": {
"enabled": true, "enabled": true,
"props": { "props": {

View File

@ -119,6 +119,68 @@
"labelKey": "my_account" "labelKey": "my_account"
} }
}, },
"Collaborators": {
"enabled": true,
"props": {
"path": "/collaborators",
"labelKey": "collaborators"
},
"pages": {
"CollaboratorInformations": {
"enabled": true,
"props": {
"path": "/collaborators/[uid]",
"labelKey": "collaborator_informations"
}
}
}
},
"Roles": {
"enabled": true,
"props": {
"path": "/roles",
"labelKey": "roles"
},
"pages": {
"RolesInformations": {
"enabled": true,
"props": {
"path": "/roles/[uid]",
"labelKey": "roles_informations"
}
}
}
},
"DeedTypes": {
"enabled": true,
"props": {
"path": "/deed-types",
"labelKey": "deedTypes"
},
"pages": {
"DeedTypesInformations": {
"enabled": true,
"props": {
"path": "/deed-types/[uid]",
"labelKey": "deedTypesInformations"
}
},
"Create": {
"enabled": true,
"props": {
"path": "/deed-types/create",
"labelKey": "createDeedType"
}
},
"Edit": {
"enabled": true,
"props": {
"path": "/deed-types/[uid]/edit",
"labelKey": "editDeedType"
}
}
}
},
"404": { "404": {
"enabled": true, "enabled": true,
"props": { "props": {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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