diff --git a/.vscode/custom.code-snippets b/.vscode/custom.code-snippets index 0a5a06ae..1999e949 100644 --- a/.vscode/custom.code-snippets +++ b/.vscode/custom.code-snippets @@ -6,4 +6,10 @@ ], "description": "media queries" }, + "Default div": { + "prefix": "$2" + ] + } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 520b5590..9ac54186 100644 --- a/package-lock.json +++ b/package-lock.json @@ -371,9 +371,9 @@ "integrity": "sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==" }, "node_modules/@floating-ui/dom": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.4.4.tgz", - "integrity": "sha512-21hhDEPOiWkGp0Ys4Wi6Neriah7HweToKra626CIK712B5m9qkdz54OP9gVldUg+URnBTpv/j/bi/skmGdstXQ==", + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.4.5.tgz", + "integrity": "sha512-96KnRWkRnuBSSFbj0sFGwwOUd8EkiecINVl0O9wiZlZ64EkpyAOG3Xc2vKKNJmru0Z7RqWNymA+6b8OZqjgyyw==", "dependencies": { "@floating-ui/core": "^1.3.1" } @@ -409,9 +409,9 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, "node_modules/@mui/base": { - "version": "5.0.0-beta.6", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.6.tgz", - "integrity": "sha512-jcHy6HwOX7KzRhRtL8nvIvUlxvLx2Fl6NMRCyUSQSvMTyfou9kndekz0H4HJaXvG1Y4WEifk23RYedOlrD1kEQ==", + "version": "5.0.0-beta.7", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.7.tgz", + "integrity": "sha512-Pjbwm6gjiS96kOMF7E5fjEJsenc0tZBesrLQ4rrdi3eT/c/yhSWnPbCUkHSz8bnS0l3/VQ8bA+oERSGSV2PK6A==", "dependencies": { "@babel/runtime": "^7.22.5", "@emotion/is-prop-valid": "^1.2.1", @@ -441,23 +441,23 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.13.7", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.7.tgz", - "integrity": "sha512-/suIo4WoeL/OyO3KUsFVpdOmKiSAr6NpWXmQ4WLSxwKrTiha1FJxM6vwAki5W/5kR9WnVLw5E8JC4oHHsutT8w==", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.0.tgz", + "integrity": "sha512-SYBOVCatVDUf/lbrLGah09bHhX5WfUXg7kSskfLILr6SvKRni0NLp0aonxQ0SMALVVK3Qwa6cW4CdWuwS0gC1w==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" } }, "node_modules/@mui/material": { - "version": "5.13.7", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.7.tgz", - "integrity": "sha512-+n453jDDm88zZM3b5YK29nZ7gXY+s+rryH9ovDbhmfSkOlFtp+KSqbXy5cTaC/UlDqDM7sYYJGq8BmJov3v9Tg==", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.0.tgz", + "integrity": "sha512-HP7CP71NhMkui2HUIEKl2/JfuHMuoarSUWAKlNw6s17bl/Num9rN61EM6uUzc2A2zHjj/00A66GnvDnmixEJEw==", "dependencies": { "@babel/runtime": "^7.22.5", - "@mui/base": "5.0.0-beta.6", - "@mui/core-downloads-tracker": "^5.13.7", - "@mui/system": "^5.13.7", + "@mui/base": "5.0.0-beta.7", + "@mui/core-downloads-tracker": "^5.14.0", + "@mui/system": "^5.14.0", "@mui/types": "^7.2.4", "@mui/utils": "^5.13.7", "@types/react-transition-group": "^4.4.6", @@ -551,9 +551,9 @@ } }, "node_modules/@mui/system": { - "version": "5.13.7", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.13.7.tgz", - "integrity": "sha512-7R2KdI6vr8KtnauEfg9e9xQmPk6Gg/1vGNiALYyhSI+cYztxN6WmlSqGX4bjWn/Sygp1TUE1jhFEgs7MWruhkQ==", + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.0.tgz", + "integrity": "sha512-0HZGkX8miJbiNw+rjlZ9l0Cfkz1bSqfSHQH0EH9J+nx0aAm5cBleg9piOlLdCNIWGgecCqsw4x62erGrGjjcJg==", "dependencies": { "@babel/runtime": "^7.22.5", "@mui/private-theming": "^5.13.7", @@ -970,13 +970,13 @@ "integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==" }, "node_modules/@typescript-eslint/parser": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz", - "integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dependencies": { - "@typescript-eslint/scope-manager": "5.61.0", - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/typescript-estree": "5.61.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" }, "engines": { @@ -996,12 +996,12 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz", - "integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dependencies": { - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/visitor-keys": "5.61.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1012,9 +1012,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz", - "integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -1024,12 +1024,12 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz", - "integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dependencies": { - "@typescript-eslint/types": "5.61.0", - "@typescript-eslint/visitor-keys": "5.61.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1050,11 +1050,11 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.61.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz", - "integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dependencies": { - "@typescript-eslint/types": "5.61.0", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1230,6 +1230,25 @@ "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": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", @@ -1267,6 +1286,11 @@ "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": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", @@ -1420,9 +1444,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001514", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001514.tgz", - "integrity": "sha512-ENcIpYBmwAAOm/V2cXgM7rZUrKKaqisZl4ZAI520FIkqGXUxJjmaIssbRW5HVVR5tyV6ygTLIm15aU8LUmQSaQ==", + "version": "1.0.30001516", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz", + "integrity": "sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g==", "funding": [ { "type": "opencollective", @@ -1839,17 +1863,18 @@ } }, "node_modules/es-abstract": { - "version": "1.21.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz", - "integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", + "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", "dependencies": { "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.1", "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.0", + "get-intrinsic": "^1.2.1", "get-symbol-description": "^1.0.0", "globalthis": "^1.0.3", "gopd": "^1.0.1", @@ -1869,14 +1894,18 @@ "object-inspect": "^1.12.3", "object-keys": "^1.1.1", "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", "string.prototype.trim": "^1.2.7", "string.prototype.trimend": "^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", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" + "which-typed-array": "^1.1.10" }, "engines": { "node": ">= 0.4" @@ -2158,9 +2187,9 @@ } }, "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "bin": { "semver": "bin/semver.js" } @@ -2195,9 +2224,9 @@ } }, "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "bin": { "semver": "bin/semver.js" } @@ -2269,17 +2298,17 @@ } }, "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "bin": { "semver": "bin/semver.js" } }, "node_modules/eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz", + "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -2303,9 +2332,9 @@ } }, "node_modules/espree": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", - "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -2391,6 +2420,11 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "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": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz", @@ -2856,9 +2890,9 @@ } }, "node_modules/immutable": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", - "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==" + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.1.tgz", + "integrity": "sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==" }, "node_modules/import-fresh": { "version": "3.3.0", @@ -3216,6 +3250,11 @@ "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": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -3917,6 +3956,32 @@ "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": { "version": "1.2.1", "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": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -4041,9 +4111,9 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/react-select": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.3.tgz", - "integrity": "sha512-z8i3NCuFFWL3w27xq92rBkVI2onT0jzIIPe480HlBjXJ3b5o6Q+Clp4ydyeKrj9DZZ3lrjawwLC5NGl0FSvUDg==", + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-5.7.4.tgz", + "integrity": "sha512-NhuE56X+p9QDFh4BgeygHFIvJJszO1i1KSkg/JPcIJrbovyRtI+GuOEa4XzFCEpZRAEoEI8u/cAHK+jG/PgUzQ==", "dependencies": { "@babel/runtime": "^7.12.0", "@emotion/cache": "^11.4.0", @@ -4298,6 +4368,23 @@ "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": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4369,18 +4456,18 @@ } }, "node_modules/sharp": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.1.tgz", - "integrity": "sha512-kQTFtj7ldpUqSe8kDxoGLZc1rnMFU0AO2pqbX6pLy3b7Oj8ivJIdoKNwxHVQG2HN6XpHPJqCSM2nsma2gOXvOg==", + "version": "0.32.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.3.tgz", + "integrity": "sha512-i1gFPiNqyqxC4ouVvCKj5G8WfPIMeeSxpKcMrjic6NY4e8zktW7bIdqHPc3FCG+pNKU/XCEabKA57hhvZi8UmQ==", "hasInstallScript": true, "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.1", "node-addon-api": "^6.1.0", "prebuild-install": "^7.1.1", - "semver": "^7.5.0", + "semver": "^7.5.4", "simple-get": "^4.0.1", - "tar-fs": "^2.1.1", + "tar-fs": "^3.0.4", "tunnel-agent": "^0.6.0" }, "engines": { @@ -4507,6 +4594,15 @@ "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": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -4689,29 +4785,23 @@ } }, "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==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", "dependencies": { - "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", - "tar-stream": "^2.1.4" + "tar-stream": "^3.1.5" } }, "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==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", "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" + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, "node_modules/text-table": { @@ -4817,6 +4907,54 @@ "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": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", @@ -4928,9 +5066,9 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.10.tgz", + "integrity": "sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA==", "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", diff --git a/src/front/Api/LeCoffreApi/Admin/BaseAdmin.ts b/src/front/Api/LeCoffreApi/Admin/BaseAdmin.ts new file mode 100644 index 00000000..fbcffb4d --- /dev/null +++ b/src/front/Api/LeCoffreApi/Admin/BaseAdmin.ts @@ -0,0 +1,5 @@ +import BaseApiService from "@Front/Api/BaseApiService"; + +export default abstract class BaseAdmin extends BaseApiService { + protected readonly namespaceUrl = this.getBaseUrl().concat("/admin"); +} diff --git a/src/front/Api/LeCoffreApi/Admin/DeedTypes/DeedTypes.ts b/src/front/Api/LeCoffreApi/Admin/DeedTypes/DeedTypes.ts new file mode 100644 index 00000000..a9254f9d --- /dev/null +++ b/src/front/Api/LeCoffreApi/Admin/DeedTypes/DeedTypes.ts @@ -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 { + 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(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async getByUid(uid: string, q?: any): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + if (q) Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value))); + try { + return await this.getRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Api/LeCoffreApi/Admin/Deeds/Deeds.ts b/src/front/Api/LeCoffreApi/Admin/Deeds/Deeds.ts new file mode 100644 index 00000000..1c0ddef8 --- /dev/null +++ b/src/front/Api/LeCoffreApi/Admin/Deeds/Deeds.ts @@ -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 { + 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(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async getByUid(uid: string, q?: any): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + if (q) Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value))); + try { + return await this.getRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Api/LeCoffreApi/Admin/DocumentTypes/DocumentTypes.ts b/src/front/Api/LeCoffreApi/Admin/DocumentTypes/DocumentTypes.ts new file mode 100644 index 00000000..b5237f87 --- /dev/null +++ b/src/front/Api/LeCoffreApi/Admin/DocumentTypes/DocumentTypes.ts @@ -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 { + 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(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + /** + * @description : Create a Document + */ + public async post(body: IPostDocumentTypesParams): Promise { + const url = new URL(this.baseURl); + try { + return await this.postRequest(url, body as any); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async getByUid(uid: string, q?: any): Promise { + 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(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async put(uid: string, body: IPutDocumentTypesParams): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + try { + return await this.putRequest(url, body); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Api/LeCoffreApi/Admin/Documents/Documents.ts b/src/front/Api/LeCoffreApi/Admin/Documents/Documents.ts new file mode 100644 index 00000000..e3f2159e --- /dev/null +++ b/src/front/Api/LeCoffreApi/Admin/Documents/Documents.ts @@ -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 { + 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(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + /** + * @description : Create a Document + */ + public async post(body: any): Promise { + const url = new URL(this.baseURl); + try { + return await this.postRequest(url, body); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async getByUid(uid: string, q?: any): Promise { + 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(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async put(uid: string, body: IPutDocumentsParams): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + try { + return await this.putRequest(url, body); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async delete(uid: string): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + try { + return await this.deleteRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles.ts b/src/front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles.ts new file mode 100644 index 00000000..913ba088 --- /dev/null +++ b/src/front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles.ts @@ -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 { + const url = new URL(this.baseURl); + if (q) { + const query = { q }; + Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value))); + } + try { + return await this.getRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async getByUid(uid: string, q?: any): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + if (q) Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value))); + try { + return await this.getRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async put(uid: string, body: IPutRoleParams): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + try { + return await this.putRequest(url, body); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Api/LeCoffreApi/Admin/Rules/Rules.ts b/src/front/Api/LeCoffreApi/Admin/Rules/Rules.ts new file mode 100644 index 00000000..f8d79d90 --- /dev/null +++ b/src/front/Api/LeCoffreApi/Admin/Rules/Rules.ts @@ -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 { + 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(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async getByUid(uid: string, q?: any): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + if (q) Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value))); + try { + return await this.getRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Components/DesignSystem/BlockList/classes.module.scss b/src/front/Components/DesignSystem/BlockList/classes.module.scss new file mode 100644 index 00000000..2e542b94 --- /dev/null +++ b/src/front/Components/DesignSystem/BlockList/classes.module.scss @@ -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; + } + } +} diff --git a/src/front/Components/DesignSystem/BlockList/index.tsx b/src/front/Components/DesignSystem/BlockList/index.tsx new file mode 100644 index 00000000..5f00c739 --- /dev/null +++ b/src/front/Components/DesignSystem/BlockList/index.tsx @@ -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) => { + onSelectedBlock && onSelectedBlock(blocks.find((block) => block.id === e.currentTarget.id)!); + }, + [blocks, onSelectedBlock], + ); + return ( +
+ {blocks.map((block) => { + return ( +
+
+
+ {block.name} +
+ chevron +
+
+ ); + })} +
+ ); +} diff --git a/src/front/Components/DesignSystem/CheckBox/index.tsx b/src/front/Components/DesignSystem/CheckBox/index.tsx index 36d5d001..4935ca95 100644 --- a/src/front/Components/DesignSystem/CheckBox/index.tsx +++ b/src/front/Components/DesignSystem/CheckBox/index.tsx @@ -9,13 +9,29 @@ type IProps = { name?: string; option: IOption; toolTip?: string; + onChange?: (e: React.ChangeEvent) => void; + checked: boolean; }; -export default class CheckBox extends React.Component { +type IState = { + checked: boolean; +}; + +export default class CheckBox extends React.Component { static defaultProps = { 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 { return ( @@ -24,6 +40,8 @@ export default class CheckBox extends React.Component { type="checkbox" name={this.props.name ?? (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.toolTip && } @@ -31,4 +49,20 @@ export default class CheckBox extends React.Component { ); } + + public override componentDidUpdate(prevProps: Readonly): void { + if (prevProps.checked !== this.props.checked) { + this.setState({ + checked: this.props.checked, + }); + } + } + + private onChange(e: React.ChangeEvent) { + this.setState({ + checked: !this.state.checked, + }); + + this.props.onChange && this.props.onChange(e); + } } diff --git a/src/front/Components/DesignSystem/FolderListContainer/index.tsx b/src/front/Components/DesignSystem/FolderListContainer/index.tsx index 2063cba5..2302050b 100644 --- a/src/front/Components/DesignSystem/FolderListContainer/index.tsx +++ b/src/front/Components/DesignSystem/FolderListContainer/index.tsx @@ -4,9 +4,11 @@ import Link from "next/link"; import React from "react"; import Button from "../Button"; -import FolderList from "../FolderList"; import SearchBar from "../SearchBar"; 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 = { folders: IDashBoardFolder[]; @@ -14,17 +16,26 @@ type IProps = { onSelectedFolder?: (folder: IDashBoardFolder) => void; onCloseLeftSide?: () => void; }; + +type IPropsClass = IProps & { + router: NextRouter; +}; + type IState = { filteredFolders: IDashBoardFolder[]; }; -export default class FolderListContainer extends React.Component { - public constructor(props: IProps) { +class FolderListContainerClass extends React.Component { + private redirectPath: string = this.props.isArchived + ? Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.pages.FolderInformation.props.path + : Module.getInstance().get().modules.pages.Folder.pages.FolderInformation.props.path; + public constructor(props: IPropsClass) { super(props); this.state = { filteredFolders: this.props.folders, }; this.filterFolders = this.filterFolders.bind(this); + this.onSelectedFolder = this.onSelectedFolder.bind(this); } public override render(): JSX.Element { @@ -33,15 +44,10 @@ export default class FolderListContainer extends React.Component
- +
- +
{!this.props.isArchived && ( @@ -55,8 +61,62 @@ export default class FolderListContainer extends React.Component ); } - private filterFolders(folders: IDashBoardFolder[]): IDashBoardFolder[] { - this.setState({ filteredFolders: folders }); - return folders; + private getBlocks(): IBlock[] { + const pendingFolders = this.props.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 ; +} diff --git a/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx b/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx index 2c6cd1d5..857c731c 100644 --- a/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx +++ b/src/front/Components/DesignSystem/Header/BurgerMenu/BurgerModal/index.tsx @@ -32,6 +32,11 @@ export default class BurgerModal extends React.Component { text="Dossiers archivés" routesActive={[Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path]} /> +
diff --git a/src/front/Components/DesignSystem/Header/Navigation/index.tsx b/src/front/Components/DesignSystem/Header/Navigation/index.tsx index 16025e88..3145fec9 100644 --- a/src/front/Components/DesignSystem/Header/Navigation/index.tsx +++ b/src/front/Components/DesignSystem/Header/Navigation/index.tsx @@ -24,6 +24,11 @@ export default class Navigation extends React.Component { path={Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path} routesActive={[Module.getInstance().get().modules.pages.Folder.pages.FolderArchived.props.path]} /> +
); } diff --git a/src/front/Components/DesignSystem/SearchBar/index.tsx b/src/front/Components/DesignSystem/SearchBar/index.tsx index 40590a95..cf1bf6c8 100644 --- a/src/front/Components/DesignSystem/SearchBar/index.tsx +++ b/src/front/Components/DesignSystem/SearchBar/index.tsx @@ -1,5 +1,4 @@ import LoopIcon from "@Assets/Icons/loop.svg"; -import { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard"; import Image from "next/image"; import React from "react"; @@ -7,10 +6,10 @@ import Typography, { ITypo } from "../Typography"; import classes from "./classes.module.scss"; type IProps = { - folders: IDashBoardFolder[]; - onChange?: (folders: IDashBoardFolder[]) => IDashBoardFolder[]; + onChange?: (input: string) => void; placeholder?: string; }; + type IState = { hasValue: boolean; }; @@ -46,30 +45,10 @@ export default class SearchBar extends React.Component { const hasValue = event.target.value.length > 0; this.doesInputHaveValue(hasValue); if (!this.props.onChange) return; - this.props.onChange(this.filterFolders(event)!); + this.props.onChange(event.target.value); } private doesInputHaveValue(hasValue: boolean) { this.setState({ hasValue }); } - - private filterFolders(event: React.ChangeEvent) { - 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; - } } diff --git a/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/CollaboratorListContainer/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/CollaboratorListContainer/classes.module.scss new file mode 100644 index 00000000..300d46f2 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/CollaboratorListContainer/classes.module.scss @@ -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); + } +} diff --git a/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/CollaboratorListContainer/index.tsx b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/CollaboratorListContainer/index.tsx new file mode 100644 index 00000000..3b93c202 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/CollaboratorListContainer/index.tsx @@ -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(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 ( +
+
+
+ +
+
+ { + return { + name: user.contact?.first_name + " " + user.contact?.last_name, + id: user.uid!, + selected: user.uid === collaboratorUid, + }; + })} + onSelectedBlock={onSelectedBlock} + /> +
+
+
+ ); +} diff --git a/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/classes.module.scss new file mode 100644 index 00000000..a5ba79a3 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/classes.module.scss @@ -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; + } + } + } + } +} diff --git a/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/index.tsx b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/index.tsx new file mode 100644 index 00000000..1c2067f5 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/index.tsx @@ -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 { + private onWindowResize = () => {}; + public static defaultProps: Partial = { + 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 ( +
+
+
+ {this.state.isLeftSideOpen &&
} +
+ {this.state.collaborators && ( + + )} +
+
+ open side menu +
+ +
+ {this.props.hasBackArrow && ( +
+ +
+ )} + {this.props.mobileBackText && ( +
+ +
+ )} + {this.props.children} +
+
+ +
+ ); + } + + 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 }); + } +} diff --git a/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/classes.module.scss new file mode 100644 index 00000000..300d46f2 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/classes.module.scss @@ -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); + } +} diff --git a/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/index.tsx b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/index.tsx new file mode 100644 index 00000000..c239d2d7 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/index.tsx @@ -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(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 ( +
+
+
+ +
+
+ { + return { + name: deed.name, + id: deed.uid!, + selected: deedTypeUid === deed.uid, + }; + })} + onSelectedBlock={onSelectedBlock} + /> +
+
+
+ + + +
+
+ ); +} diff --git a/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/classes.module.scss new file mode 100644 index 00000000..a5ba79a3 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/classes.module.scss @@ -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; + } + } + } + } +} diff --git a/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/index.tsx b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/index.tsx new file mode 100644 index 00000000..da41c677 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/index.tsx @@ -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 { + private onWindowResize = () => {}; + public static defaultProps: Partial = { + 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 ( +
+
+
+ {this.state.isLeftSideOpen &&
} +
+ {this.state.deedTypes && ( + + )} +
+
+ open side menu +
+ +
+ {this.props.hasBackArrow && ( +
+ +
+ )} + {this.props.mobileBackText && ( +
+ +
+ )} + {this.props.children} +
+
+ +
+ ); + } + + 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 }); + } +} diff --git a/src/front/Components/LayoutTemplates/DefaultRoleDashboard/RoleListContainer/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/RoleListContainer/classes.module.scss new file mode 100644 index 00000000..300d46f2 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/RoleListContainer/classes.module.scss @@ -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); + } +} diff --git a/src/front/Components/LayoutTemplates/DefaultRoleDashboard/RoleListContainer/index.tsx b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/RoleListContainer/index.tsx new file mode 100644 index 00000000..c08475a5 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/RoleListContainer/index.tsx @@ -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(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 ( +
+
+
+ +
+
+ { + return { + name: role.name, + id: role.uid!, + selected: false, + }; + })} + onSelectedBlock={onSelectedBlock} + /> +
+
+
+ ); +} diff --git a/src/front/Components/LayoutTemplates/DefaultRoleDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/classes.module.scss new file mode 100644 index 00000000..a5ba79a3 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/classes.module.scss @@ -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; + } + } + } + } +} diff --git a/src/front/Components/LayoutTemplates/DefaultRoleDashboard/index.tsx b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/index.tsx new file mode 100644 index 00000000..3ee9f0ff --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/index.tsx @@ -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 { + private onWindowResize = () => {}; + public static defaultProps: Partial = { + 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 ( +
+
+
+ {this.state.isLeftSideOpen &&
} +
+ {this.state.roles && } +
+
+ open side menu +
+ +
+ {this.props.hasBackArrow && ( +
+ +
+ )} + {this.props.mobileBackText && ( +
+ +
+ )} + {this.props.children} +
+
+ +
+ ); + } + + 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 }); + } +} diff --git a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/classes.module.scss b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/classes.module.scss new file mode 100644 index 00000000..d04c1ba8 --- /dev/null +++ b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/classes.module.scss @@ -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; + } + } +} diff --git a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx new file mode 100644 index 00000000..fc8b58f5 --- /dev/null +++ b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx @@ -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(null); + const [availableRoles, setAvailableRoles] = useState([]); + + 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 ( + +
+
+ {userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name} +
+
+
+ + Nom + + {userSelected?.contact?.first_name} +
+
+ + Prénom + + {userSelected?.contact?.last_name} +
+
+ + Numéro de téléphone + + {userSelected?.contact?.phone_number} +
+
+ + Email + + {userSelected?.contact?.email} +
+
+ +
+
+ Modifier le rôle +
+ + + +
+
+
+ +
+
+ +
+
+
+
+ ); +} diff --git a/src/front/Components/Layouts/Collaborators/classes.module.scss b/src/front/Components/Layouts/Collaborators/classes.module.scss new file mode 100644 index 00000000..a425a01a --- /dev/null +++ b/src/front/Components/Layouts/Collaborators/classes.module.scss @@ -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; + } + } +} diff --git a/src/front/Components/Layouts/Collaborators/index.tsx b/src/front/Components/Layouts/Collaborators/index.tsx new file mode 100644 index 00000000..90e43453 --- /dev/null +++ b/src/front/Components/Layouts/Collaborators/index.tsx @@ -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 { + public override render(): JSX.Element { + return ( + +
+
+ Informations du collaboraeur +
+ + Sélectionnez un collaborateur + +
+
+
+
+ ); + } +} diff --git a/src/front/Components/Layouts/DeedTypes/DeedTypesCreate/classes.module.scss b/src/front/Components/Layouts/DeedTypes/DeedTypesCreate/classes.module.scss new file mode 100644 index 00000000..848ef4bc --- /dev/null +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesCreate/classes.module.scss @@ -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; + } + } +} diff --git a/src/front/Components/Layouts/DeedTypes/DeedTypesCreate/index.tsx b/src/front/Components/Layouts/DeedTypes/DeedTypesCreate/index.tsx new file mode 100644 index 00000000..274b4205 --- /dev/null +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesCreate/index.tsx @@ -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 | null, values: { [key: string]: string }) => {}, []); + + return ( + +
+
+ Créer un type d'acte +
+
+ + +
+ + +
+ +
+
+ ); +} diff --git a/src/front/Components/Layouts/DeedTypes/DeedTypesEdit/classes.module.scss b/src/front/Components/Layouts/DeedTypes/DeedTypesEdit/classes.module.scss new file mode 100644 index 00000000..848ef4bc --- /dev/null +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesEdit/classes.module.scss @@ -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; + } + } +} diff --git a/src/front/Components/Layouts/DeedTypes/DeedTypesEdit/index.tsx b/src/front/Components/Layouts/DeedTypes/DeedTypesEdit/index.tsx new file mode 100644 index 00000000..7b05fc31 --- /dev/null +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesEdit/index.tsx @@ -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(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 | null, values: { [key: string]: string }) => {}, []); + + return ( + +
+
+ Modifier les informations de l'acte +
+
+ + +
+ + +
+ +
+
+ ); +} diff --git a/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/classes.module.scss b/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/classes.module.scss new file mode 100644 index 00000000..72fe71da --- /dev/null +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/classes.module.scss @@ -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; + } +} diff --git a/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/index.tsx b/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/index.tsx new file mode 100644 index 00000000..85d05fc5 --- /dev/null +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/index.tsx @@ -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(null); + const [availableDocuments, setAvailableDocuments] = useState([]); + const [selectedDocuments, setSelectedDocuments] = useState([]); + + 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 | null, values: { [key: string]: string }) => {}, []); + + const onDocumentChangeHandler = useCallback((values: MultiValue) => { + setSelectedDocuments(values as IOption[]); + }, []); + + const formattedOptions: IOption[] = availableDocuments.map((document) => { + return { + label: document.name, + value: document.uid, + }; + }); + + return ( + +
+
+ Paramétrage des listes de pièces + +
+
+ {deedTypeSelected?.name} +
+
+
+
+ + Nom du type d'acte + + {deedTypeSelected?.name} +
+
+ + Description + + {deedTypeSelected?.description} +
+
+
+ + éditer le type d'acte + +
+
+
+
+
+ Documents paramétrés +
+
+ +
+
+ +
+
+
+
+ +
+
+
+ ); +} diff --git a/src/front/Components/Layouts/DeedTypes/classes.module.scss b/src/front/Components/Layouts/DeedTypes/classes.module.scss new file mode 100644 index 00000000..4eca97a6 --- /dev/null +++ b/src/front/Components/Layouts/DeedTypes/classes.module.scss @@ -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; + } + } +} diff --git a/src/front/Components/Layouts/DeedTypes/index.tsx b/src/front/Components/Layouts/DeedTypes/index.tsx new file mode 100644 index 00000000..e169d5c4 --- /dev/null +++ b/src/front/Components/Layouts/DeedTypes/index.tsx @@ -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 { + public override render(): JSX.Element { + return ( + +
+
+ Paramétrage des listes de pièces +
+ + Sélectionnez une liste de pièces + +
+
+
+
+ ); + } +} diff --git a/src/front/Components/Layouts/Folder/CreateFolder/index.tsx b/src/front/Components/Layouts/Folder/CreateFolder/index.tsx index d3cfd7b7..4f30884c 100644 --- a/src/front/Components/Layouts/Folder/CreateFolder/index.tsx +++ b/src/front/Components/Layouts/Folder/CreateFolder/index.tsx @@ -234,8 +234,7 @@ class CreateFolderClass extends BasePage { [key: string]: any; }, ) { - const officeId = (JwtService.getInstance().decodeJwt())?.office_Id; - console.log('form initializdd'); + const officeId = JwtService.getInstance().decodeJwt()?.office_Id; const selectedDeedTypeUid: DeedType | undefined = this.state.deedTypes.find( (deedType) => deedType.uid === this.state.formValues.act_typ?.value, ); @@ -261,28 +260,24 @@ class CreateFolderClass extends BasePage { uid: officeId, }), customers: [], - stakeholders + stakeholders, }); - console.log('form'); - try { await officeFolderForm.validateOrReject?.({ groups: ["createFolder"], forbidUnknownValues: false }); } catch (validationErrors) { this.setState({ validationError: validationErrors as ValidationError[], }); - console.log('validation errros'); return; } try { const newOfficeFolder = await Folders.getInstance().post(officeFolderForm); - console.log('new office folder: ',newOfficeFolder) if (!newOfficeFolder) return; this.props.router.push(`/folders/${newOfficeFolder.uid}`); } catch (backError: any) { - if(!Array.isArray(backError)) return; + if (!Array.isArray(backError)) return; this.setState({ validationError: backError as ValidationError[], }); diff --git a/src/front/Components/Layouts/Login/index.tsx b/src/front/Components/Layouts/Login/index.tsx index 9dfdfd8c..52742c7e 100644 --- a/src/front/Components/Layouts/Login/index.tsx +++ b/src/front/Components/Layouts/Login/index.tsx @@ -35,7 +35,7 @@ export default class LoginClass extends BasePage { // const variables = FrontendVariables.getInstance(); // const baseFronturl = variables.BACK_API_PROTOCOL + variables.FRONT_APP_HOST; - await UserStore.instance.connect("SbRKyM8BJI"); + await UserStore.instance.connect("symWAJRxuu"); // await JwtService.getInstance().checkJwt(); // window.location.assign("http://localhost:3000" + "/folders"); diff --git a/src/front/Components/Layouts/Roles/RolesInformations/classes.module.scss b/src/front/Components/Layouts/Roles/RolesInformations/classes.module.scss new file mode 100644 index 00000000..2eb0753b --- /dev/null +++ b/src/front/Components/Layouts/Roles/RolesInformations/classes.module.scss @@ -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; + } + } +} diff --git a/src/front/Components/Layouts/Roles/RolesInformations/index.tsx b/src/front/Components/Layouts/Roles/RolesInformations/index.tsx new file mode 100644 index 00000000..7d8bca16 --- /dev/null +++ b/src/front/Components/Layouts/Roles/RolesInformations/index.tsx @@ -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(null); + const [rulesCheckboxes, setRulesCheckboxes] = useState([]); + const [selectAll, setSelectAll] = useState(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) => { + 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 | null, values: { [key: string]: string }) => { + if (!roleSelected || !roleSelected.uid) return; + const rules = rulesCheckboxes.filter((rule) => rule.checked)?.map((rule) => Rule.hydrate(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 ( + +
+
+ Gestion des rôles +
+
+ {roleSelected?.name} +
+
+
+ Modifier les droits +
+
+ +
+
+
+ {rulesCheckboxes.map((rule) => ( +
+ +
+ ))} +
+
+ +
+
+
+
+
+ ); +} diff --git a/src/front/Components/Layouts/Roles/classes.module.scss b/src/front/Components/Layouts/Roles/classes.module.scss new file mode 100644 index 00000000..4eca97a6 --- /dev/null +++ b/src/front/Components/Layouts/Roles/classes.module.scss @@ -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; + } + } +} diff --git a/src/front/Components/Layouts/Roles/index.tsx b/src/front/Components/Layouts/Roles/index.tsx new file mode 100644 index 00000000..333601eb --- /dev/null +++ b/src/front/Components/Layouts/Roles/index.tsx @@ -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 { + public override render(): JSX.Element { + return ( + +
+
+ Gestion des rôles +
+ + Sélectionnez un rôle + +
+
+
+
+ ); + } +} diff --git a/src/front/Config/Module/development.json b/src/front/Config/Module/development.json index 740f6ee9..e2a56d46 100644 --- a/src/front/Config/Module/development.json +++ b/src/front/Config/Module/development.json @@ -119,6 +119,68 @@ "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": { "enabled": true, "props": { diff --git a/src/front/Config/Module/preprod.json b/src/front/Config/Module/preprod.json index 740f6ee9..e2a56d46 100644 --- a/src/front/Config/Module/preprod.json +++ b/src/front/Config/Module/preprod.json @@ -119,6 +119,68 @@ "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": { "enabled": true, "props": { diff --git a/src/front/Config/Module/production.json b/src/front/Config/Module/production.json index 740f6ee9..e2a56d46 100644 --- a/src/front/Config/Module/production.json +++ b/src/front/Config/Module/production.json @@ -119,6 +119,68 @@ "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": { "enabled": true, "props": { diff --git a/src/front/Config/Module/staging.json b/src/front/Config/Module/staging.json index 740f6ee9..e2a56d46 100644 --- a/src/front/Config/Module/staging.json +++ b/src/front/Config/Module/staging.json @@ -119,6 +119,68 @@ "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": { "enabled": true, "props": { diff --git a/src/pages/collaborators/[collaboratorUid]/index.tsx b/src/pages/collaborators/[collaboratorUid]/index.tsx new file mode 100644 index 00000000..ec6a1b3d --- /dev/null +++ b/src/pages/collaborators/[collaboratorUid]/index.tsx @@ -0,0 +1,5 @@ +import CollaboratorInformations from "@Front/Components/Layouts/Collaborators/CollaboratorInformations"; + +export default function Route() { + return ; +} diff --git a/src/pages/collaborators/index.tsx b/src/pages/collaborators/index.tsx new file mode 100644 index 00000000..300413ce --- /dev/null +++ b/src/pages/collaborators/index.tsx @@ -0,0 +1,5 @@ +import Collaborators from "@Front/Components/Layouts/Collaborators"; + +export default function Route() { + return ; +} diff --git a/src/pages/deed-types/[deedTypeUid]/edit/index.tsx b/src/pages/deed-types/[deedTypeUid]/edit/index.tsx new file mode 100644 index 00000000..587de6f9 --- /dev/null +++ b/src/pages/deed-types/[deedTypeUid]/edit/index.tsx @@ -0,0 +1,5 @@ +import DeedTypesEdit from "@Front/Components/Layouts/DeedTypes/DeedTypesEdit"; + +export default function Route() { + return ; +} diff --git a/src/pages/deed-types/[deedTypeUid]/index.tsx b/src/pages/deed-types/[deedTypeUid]/index.tsx new file mode 100644 index 00000000..011399e3 --- /dev/null +++ b/src/pages/deed-types/[deedTypeUid]/index.tsx @@ -0,0 +1,5 @@ +import DeedTypesInformations from "@Front/Components/Layouts/DeedTypes/DeedTypesInformations"; + +export default function Route() { + return ; +} diff --git a/src/pages/deed-types/create/index.tsx b/src/pages/deed-types/create/index.tsx new file mode 100644 index 00000000..d78a060c --- /dev/null +++ b/src/pages/deed-types/create/index.tsx @@ -0,0 +1,5 @@ +import DeedTypesCreate from "@Front/Components/Layouts/DeedTypes/DeedTypesCreate"; + +export default function Route() { + return ; +} diff --git a/src/pages/deed-types/index.tsx b/src/pages/deed-types/index.tsx new file mode 100644 index 00000000..71922bce --- /dev/null +++ b/src/pages/deed-types/index.tsx @@ -0,0 +1,5 @@ +import DeedTypes from "@Front/Components/Layouts/DeedTypes"; + +export default function Route() { + return ; +} diff --git a/src/pages/roles/[roleUid]/index.tsx b/src/pages/roles/[roleUid]/index.tsx new file mode 100644 index 00000000..9dd7e651 --- /dev/null +++ b/src/pages/roles/[roleUid]/index.tsx @@ -0,0 +1,5 @@ +import RolesInformations from "@Front/Components/Layouts/Roles/RolesInformations"; + +export default function Route() { + return ; +} diff --git a/src/pages/roles/index.tsx b/src/pages/roles/index.tsx new file mode 100644 index 00000000..99d5bdcb --- /dev/null +++ b/src/pages/roles/index.tsx @@ -0,0 +1,5 @@ +import Roles from "@Front/Components/Layouts/Roles"; + +export default function Route() { + return ; +}