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/next.config.js b/next.config.js index 6a80175b..b1ed70a2 100644 --- a/next.config.js +++ b/next.config.js @@ -13,16 +13,16 @@ const nextConfig = { NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT: process.env.NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT, NEXT_PUBLIC_IDNOT_CLIENT_ID: process.env.NEXT_PUBLIC_IDNOT_CLIENT_ID, }, - webpack: config => { - config.node = { - fs: 'empty', - child_process: 'empty', - net: 'empty', - dns: 'empty', - tls: 'empty', - }; - return config; - }, + // webpack: config => { + // config.node = { + // fs: 'empty', + // child_process: 'empty', + // net: 'empty', + // dns: 'empty', + // tls: 'empty', + // }; + // return config; + // }, }; module.exports = nextConfig; diff --git a/package-lock.json b/package-lock.json index f10b3e4e..4632a1db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,60 +21,70 @@ "eslint": "8.36.0", "eslint-config-next": "13.2.4", "form-data": "^4.0.0", - "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.47", + "jwt-decode": "^3.1.2", + "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.58", "next": "13.2.4", "prettier": "^2.8.7", "react": "18.2.0", "react-dom": "18.2.0", "react-select": "^5.7.2", "sass": "^1.59.2", + "sharp": "^0.32.1", "typescript": "4.9.5" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/@babel/code-frame": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz", - "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", + "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", "dependencies": { - "@babel/types": "^7.21.4" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.21.5.tgz", - "integrity": "sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-validator-identifier": "^7.22.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -147,9 +157,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", - "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz", + "integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==", "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -158,12 +168,12 @@ } }, "node_modules/@babel/types": { - "version": "7.21.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.5.tgz", - "integrity": "sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz", + "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==", "dependencies": { - "@babel/helper-string-parser": "^7.21.5", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.5", "to-fast-properties": "^2.0.0" }, "engines": { @@ -219,9 +229,9 @@ "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==" }, "node_modules/@emotion/react": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.0.tgz", - "integrity": "sha512-ZSK3ZJsNkwfjT3JpDAWJZlrGD81Z3ytNDsxw1LKq1o+xkmO5pnWfr6gmCC8gHEFf3nSSX/09YrG67jybNPxSUw==", + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.11.1.tgz", + "integrity": "sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==", "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.11.0", @@ -318,21 +328,21 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz", - "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.1.tgz", + "integrity": "sha512-O7x6dMstWLn2ktjcoiNLDkAGG2EjveHL+Vvc+n0fXumkJYAcSqcVYKtwDU+hDZ0uDUsnUagSYaZrOLAYE8un1A==", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -356,22 +366,22 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.6.tgz", - "integrity": "sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.3.1.tgz", + "integrity": "sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g==" }, "node_modules/@floating-ui/dom": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.7.tgz", - "integrity": "sha512-DyqylONj1ZaBnzj+uBnVfzdjjCkFCL2aA9ESHLyUOGSqb03RpbLMImP1ekIQXYs4KLk9jAjJfZAU8hXfWSahEg==", + "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.2.6" + "@floating-ui/core": "^1.3.1" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", @@ -399,15 +409,15 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" }, "node_modules/@mui/base": { - "version": "5.0.0-beta.0", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.0.tgz", - "integrity": "sha512-ap+juKvt8R8n3cBqd/pGtZydQ4v2I/hgJKnvJRGjpSh3RvsvnDHO4rXov8MHQlH6VqpOekwgilFLGxMZjNTucA==", + "version": "5.0.0-beta.8", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.8.tgz", + "integrity": "sha512-b4vVjMZx5KzzEMf4arXKoeV5ZegAMOoPwoy1vfUBwhvXc2QtaaAyBp50U7OA2L06Leubc1A+lEp3eqwZoFn87g==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@emotion/is-prop-valid": "^1.2.0", + "@babel/runtime": "^7.22.6", + "@emotion/is-prop-valid": "^1.2.1", "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.3", - "@popperjs/core": "^2.11.7", + "@mui/utils": "^5.14.1", + "@popperjs/core": "^2.11.8", "clsx": "^1.2.1", "prop-types": "^15.8.1", "react-is": "^18.2.0" @@ -431,25 +441,25 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.0.tgz", - "integrity": "sha512-5nXz2k8Rv2ZjtQY6kXirJVyn2+ODaQuAJmXSJtLDUQDKWp3PFUj6j3bILqR0JGOs9R5ejgwz3crLKsl6GwjwkQ==", + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.1.tgz", + "integrity": "sha512-mIa1WmDmNr1LoupV1Rbxt9bTFKMbIn10RHG1bnZ/FJCkAYpuU/D4n+R+ttiycgcZNngU++zyh/OQeJblzbQPzg==", "funding": { "type": "opencollective", "url": "https://opencollective.com/mui" } }, "node_modules/@mui/material": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.0.tgz", - "integrity": "sha512-ckS+9tCpAzpdJdaTF+btF0b6mF9wbXg/EVKtnoAWYi0UKXoXBAVvEUMNpLGA5xdpCdf+A6fPbVUEHs9TsfU+Yw==", + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.14.1.tgz", + "integrity": "sha512-WtsgYuageTunLfxH3Ri+o1RuQTFImtRHxMcVNyD0Hhd2/znjW6KODNz0XfjvLRnNCAynBxZNiflcoIBW40h9PQ==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/base": "5.0.0-beta.0", - "@mui/core-downloads-tracker": "^5.13.0", - "@mui/system": "^5.12.3", + "@babel/runtime": "^7.22.6", + "@mui/base": "5.0.0-beta.8", + "@mui/core-downloads-tracker": "^5.14.1", + "@mui/system": "^5.14.1", "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.3", + "@mui/utils": "^5.14.1", "@types/react-transition-group": "^4.4.6", "clsx": "^1.2.1", "csstype": "^3.1.2", @@ -484,12 +494,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.12.3", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.12.3.tgz", - "integrity": "sha512-o1e7Z1Bp27n4x2iUHhegV4/Jp6H3T6iBKHJdLivS5GbwsuAE/5l4SnZ+7+K+e5u9TuhwcAKZLkjvqzkDe8zqfA==", + "version": "5.13.7", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.7.tgz", + "integrity": "sha512-qbSr+udcij5F9dKhGX7fEdx2drXchq7htLNr2Qg2Ma+WJ6q0ERlEqGSBiPiVDJkptcjeVL4DGmcf1wl5+vD4EA==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/utils": "^5.12.3", + "@babel/runtime": "^7.22.5", + "@mui/utils": "^5.13.7", "prop-types": "^15.8.1" }, "engines": { @@ -510,12 +520,12 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.12.3", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.12.3.tgz", - "integrity": "sha512-AhZtiRyT8Bjr7fufxE/mLS+QJ3LxwX1kghIcM2B2dvJzSSg9rnIuXDXM959QfUVIM3C8U4x3mgVoPFMQJvc4/g==", + "version": "5.13.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz", + "integrity": "sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==", "dependencies": { "@babel/runtime": "^7.21.0", - "@emotion/cache": "^11.10.8", + "@emotion/cache": "^11.11.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" }, @@ -541,15 +551,15 @@ } }, "node_modules/@mui/system": { - "version": "5.12.3", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.12.3.tgz", - "integrity": "sha512-JB/6sypHqeJCqwldWeQ1MKkijH829EcZAKKizxbU2MJdxGG5KSwZvTBa5D9qiJUA1hJFYYupjiuy9ZdJt6rV6w==", + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.14.1.tgz", + "integrity": "sha512-u+xlsU34Jdkgx1CxmBnIC4Y08uPdVX5iEd3S/1dggDFtOGp+Lj8xmKRJAQ8PJOOJLOh8pDwaZx4AwXikL4l1QA==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/private-theming": "^5.12.3", - "@mui/styled-engine": "^5.12.3", + "@babel/runtime": "^7.22.6", + "@mui/private-theming": "^5.13.7", + "@mui/styled-engine": "^5.13.2", "@mui/types": "^7.2.4", - "@mui/utils": "^5.12.3", + "@mui/utils": "^5.14.1", "clsx": "^1.2.1", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -593,13 +603,13 @@ } }, "node_modules/@mui/utils": { - "version": "5.12.3", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.12.3.tgz", - "integrity": "sha512-D/Z4Ub3MRl7HiUccid7sQYclTr24TqUAQFFlxHQF8FR177BrCTQ0JJZom7EqYjZCdXhwnSkOj2ph685MSKNtIA==", + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.1.tgz", + "integrity": "sha512-39KHKK2JeqRmuUcLDLwM+c2XfVC136C5/yUyQXmO2PVbOb2Bol4KxtkssEqCbTwg87PSCG3f1Tb0keRsK7cVGw==", "dependencies": { - "@babel/runtime": "^7.21.0", + "@babel/runtime": "^7.22.6", "@types/prop-types": "^15.7.5", - "@types/react-is": "^16.7.1 || ^17.0.0", + "@types/react-is": "^18.2.1", "prop-types": "^15.8.1", "react-is": "^18.2.0" }, @@ -855,16 +865,16 @@ } }, "node_modules/@pkgr/utils": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.0.tgz", - "integrity": "sha512-2OCURAmRtdlL8iUDTypMrrxfwe8frXTeXaxGsVOaYtc/wrUyk8Z/0OBetM7cdlsy7ZFWlMX72VogKeh+A4Xcjw==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", + "integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==", "dependencies": { "cross-spawn": "^7.0.3", - "fast-glob": "^3.2.12", + "fast-glob": "^3.3.0", "is-glob": "^4.0.3", "open": "^9.1.0", "picocolors": "^1.0.0", - "tslib": "^2.5.0" + "tslib": "^2.6.0" }, "engines": { "node": "^12.20.0 || ^14.18.0 || >=16.0.0" @@ -874,18 +884,18 @@ } }, "node_modules/@popperjs/core": { - "version": "2.11.7", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.7.tgz", - "integrity": "sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==", + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "funding": { "type": "opencollective", "url": "https://opencollective.com/popperjs" } }, "node_modules/@rushstack/eslint-patch": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.2.0.tgz", - "integrity": "sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz", + "integrity": "sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==" }, "node_modules/@swc/helpers": { "version": "0.4.14", @@ -934,21 +944,11 @@ } }, "node_modules/@types/react-is": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.4.tgz", - "integrity": "sha512-FLzd0K9pnaEvKz4D1vYxK9JmgQPiGk1lu23o1kqGsLeT0iPbRSF7b76+S5T9fD8aRa0B8bY7I/3DebEj+1ysBA==", + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.1.tgz", + "integrity": "sha512-wyUkmaaSZEzFZivD8F2ftSyAfk6L+DfFliVj/mYdOXbVjRcS87fQJLTnhk6dRZPuJjI+9g6RZJO4PNCngUrmyw==", "dependencies": { - "@types/react": "^17" - } - }, - "node_modules/@types/react-is/node_modules/@types/react": { - "version": "17.0.59", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.59.tgz", - "integrity": "sha512-gSON5zWYIGyoBcycCE75E9+r6dCC2dHdsrVkOEiIYNU5+Q28HcBAuqvDuxHcCbMfHBHdeT5Tva/AFn3rnMKE4g==", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" + "@types/react": "*" } }, "node_modules/@types/react-transition-group": { @@ -970,13 +970,13 @@ "integrity": "sha512-aqayTNmeWrZcvnG2MG9eGYI6b7S5fl+yKgPs6bAjOTwPS316R5SxBGKvtSExfyoJU7pIeHJfsHI0Ji41RVMkvQ==" }, "node_modules/@typescript-eslint/parser": { - "version": "5.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.5.tgz", - "integrity": "sha512-NJXQC4MRnF9N9yWqQE2/KLRSOLvrrlZb48NGVfBa+RuPMN6B7ZcK5jZOvhuygv4D64fRKnZI4L4p8+M+rfeQuw==", + "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.59.5", - "@typescript-eslint/types": "5.59.5", - "@typescript-eslint/typescript-estree": "5.59.5", + "@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.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.5.tgz", - "integrity": "sha512-jVecWwnkX6ZgutF+DovbBJirZcAxgxC0EOHYt/niMROf8p4PwxxG32Qdhj/iIQQIuOflLjNkxoXyArkcIP7C3A==", + "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.59.5", - "@typescript-eslint/visitor-keys": "5.59.5" + "@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.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.5.tgz", - "integrity": "sha512-xkfRPHbqSH4Ggx4eHRIO/eGL8XL4Ysb4woL8c87YuAo8Md7AUjyWKa9YMwTL519SyDPrfEgKdewjkxNCVeJW7w==", + "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.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.5.tgz", - "integrity": "sha512-+XXdLN2CZLZcD/mO7mQtJMvCkzRfmODbeSKuMY/yXbGkzvA9rJyDY5qDYNoiz2kP/dmyAxXquL2BvLQLJFPQIg==", + "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.59.5", - "@typescript-eslint/visitor-keys": "5.59.5", + "@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.59.5", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.5.tgz", - "integrity": "sha512-qL+Oz+dbeBRTeyJTIy0eniD3uvqU7x+y1QceBismZ41hd4aBSRh8UAw4pZP0+XzLuPZmx4raNMq/I+59W2lXKA==", + "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.59.5", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1066,9 +1066,9 @@ } }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "bin": { "acorn": "bin/acorn" }, @@ -1139,11 +1139,11 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/aria-query": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", - "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dependencies": { - "deep-equal": "^2.0.5" + "dequal": "^2.0.3" } }, "node_modules/array-buffer-byte-length": { @@ -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", @@ -1252,21 +1271,26 @@ } }, "node_modules/axe-core": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.0.tgz", - "integrity": "sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz", + "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==", "engines": { "node": ">=4" } }, "node_modules/axobject-query": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz", - "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", + "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", "dependencies": { - "deep-equal": "^2.0.5" + "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", @@ -1286,6 +1310,25 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/big-integer": { "version": "1.6.51", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", @@ -1302,6 +1345,16 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/bplist-parser": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", @@ -1333,6 +1386,29 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/bundle-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", @@ -1368,9 +1444,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001486", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001486.tgz", - "integrity": "sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg==", + "version": "1.0.30001517", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz", + "integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==", "funding": [ { "type": "opencollective", @@ -1438,6 +1514,11 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "node_modules/class-transformer": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", @@ -1471,6 +1552,18 @@ "node": ">=6" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1487,6 +1580,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1576,32 +1678,26 @@ } } }, - "node_modules/deep-equal": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz", - "integrity": "sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ==", + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.0", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.9" + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" } }, "node_modules/deep-is": { @@ -1675,6 +1771,22 @@ "node": ">=0.4.0" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "engines": { + "node": ">=8" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1707,11 +1819,14 @@ } }, "node_modules/dotenv": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", - "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==", + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", + "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", "engines": { "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, "node_modules/emoji-regex": { @@ -1719,10 +1834,18 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enhanced-resolve": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.0.tgz", - "integrity": "sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==", + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -1740,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", @@ -1770,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" @@ -1786,25 +1914,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/es-set-tostringtag": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", @@ -1978,13 +2087,13 @@ } }, "node_modules/eslint-import-resolver-typescript/node_modules/globby": { - "version": "13.1.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz", - "integrity": "sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g==", + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", "dependencies": { "dir-glob": "^3.0.1", - "fast-glob": "^3.2.11", - "ignore": "^5.2.0", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", "merge2": "^1.4.1", "slash": "^4.0.0" }, @@ -2078,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" } @@ -2115,17 +2224,17 @@ } }, "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" } }, "node_modules/eslint-plugin-react": { - "version": "7.32.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz", - "integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==", + "version": "7.33.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.0.tgz", + "integrity": "sha512-qewL/8P34WkY8jAqdQxsiL82pDUeT7nhs8IsuXgfgnsEloKCT4miAV9N9kGtx7/KM9NH/NCGUE7Edt9iGxLXFw==", "dependencies": { "array-includes": "^3.1.6", "array.prototype.flatmap": "^1.3.1", @@ -2140,7 +2249,7 @@ "object.values": "^1.1.6", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.4", - "semver": "^6.3.0", + "semver": "^6.3.1", "string.prototype.matchall": "^4.0.8" }, "engines": { @@ -2189,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" @@ -2223,11 +2332,11 @@ } }, "node_modules/espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "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.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" }, @@ -2298,15 +2407,28 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "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.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2427,6 +2549,11 @@ "node": ">= 6" } }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2476,12 +2603,13 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", + "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3" }, "funding": { @@ -2515,13 +2643,21 @@ } }, "node_modules/get-tsconfig": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.5.0.tgz", - "integrity": "sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.2.tgz", + "integrity": "sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, "funding": { "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "node_modules/glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -2726,6 +2862,25 @@ "node": ">=14.18.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -2735,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", @@ -2776,6 +2931,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "node_modules/internal-slot": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", @@ -2789,21 +2949,6 @@ "node": ">= 0.4" } }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -2871,9 +3016,9 @@ } }, "node_modules/is-core-module": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", - "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", "dependencies": { "has": "^1.0.3" }, @@ -2945,14 +3090,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz", - "integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -3009,14 +3146,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-set": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz", - "integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-shared-array-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", @@ -3068,15 +3197,11 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.11" }, "engines": { "node": ">= 0.4" @@ -3085,14 +3210,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -3104,18 +3221,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-weakset": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz", - "integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -3152,9 +3257,9 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/js-sdsl": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz", - "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.2.tgz", + "integrity": "sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==", "funding": { "type": "opencollective", "url": "https://opencollective.com/js-sdsl" @@ -3203,17 +3308,24 @@ } }, "node_modules/jsx-ast-utils": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", - "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.4.tgz", + "integrity": "sha512-fX2TVdCViod6HwKEtSWGHs57oFhVfCMwieb9PuRDgjDPh5XeqJiHFFFJCHxU5cnTc3Bu/GRL+kPiFmw8XWOfKw==", "dependencies": { - "array-includes": "^3.1.5", - "object.assign": "^4.1.3" + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" }, "engines": { "node": ">=4.0" } }, + "node_modules/jwt-decode": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", + "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" + }, "node_modules/language-subtag-registry": { "version": "0.3.22", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz", @@ -3228,7 +3340,7 @@ } }, "node_modules/le-coffre-resources": { - "resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#467b34a484adbd6dfa3fd6082bb7677f6178da51", + "resolved": "git+ssh://git@github.com/smart-chain-fr/leCoffre-resources.git#5c506e8b49401240b8decee77f9b7e34694f490a", "license": "MIT", "dependencies": { "class-transformer": "^0.5.1", @@ -3249,9 +3361,9 @@ } }, "node_modules/libphonenumber-js": { - "version": "1.10.30", - "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.30.tgz", - "integrity": "sha512-PLGc+xfrQrkya/YK2/5X+bPpxRmyJBHM+xxz9krUdSgk4Vs2ZwxX5/Ow0lv3r9PDlDtNWb4u+it8MY5rZ0IyGw==" + "version": "1.10.37", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.10.37.tgz", + "integrity": "sha512-Z10PCaOCiAxbUxLyR31DNeeNugSVP6iv/m7UrSKS5JHziEMApJtgku4e9Q69pzzSC9LnQiM09sqsGf2ticZnMw==" }, "node_modules/lines-and-columns": { "version": "1.2.4", @@ -3359,6 +3471,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3378,6 +3501,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -3400,6 +3528,11 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3460,6 +3593,22 @@ } } }, + "node_modules/node-abi": { + "version": "3.45.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.45.0.tgz", + "integrity": "sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -3509,21 +3658,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -3646,16 +3780,16 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -3793,6 +3927,57 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "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", @@ -3830,6 +4015,15 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -3857,6 +4051,33 @@ } ] }, + "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", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -3886,9 +4107,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", @@ -3920,6 +4141,19 @@ "react-dom": ">=16.6.0" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -3981,6 +4215,14 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -4122,6 +4364,42 @@ "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", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -4136,9 +4414,9 @@ } }, "node_modules/sass": { - "version": "1.62.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz", - "integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==", + "version": "1.64.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.64.1.tgz", + "integrity": "sha512-16rRACSOFEE8VN7SCgBu1MpYCyN7urj9At898tyzdXFhC+a+yOX5dXwAR7L8/IdPJ1NB8OYoXmD55DM30B2kEQ==", "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -4160,9 +4438,9 @@ } }, "node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -4173,6 +4451,28 @@ "node": ">=10" } }, + "node_modules/sharp": { + "version": "0.32.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.4.tgz", + "integrity": "sha512-exUnZewqVZC6UXqXuQ8fyJJv0M968feBi04jb9GcUHrWtkRoAKnbJt8IfwT4NJs7FskArbJ14JAFGVuooszoGg==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4210,6 +4510,62 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -4234,15 +4590,21 @@ "node": ">=0.10.0" } }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", + "node_modules/streamx": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.0.tgz", + "integrity": "sha512-HcxY6ncGjjklGs1xsP1aR71INYcsXFJet5CU1CHqihQ2J5nOsbd4OjgjHO42w/4QNv9gZb3BueV+Vxok5pLEXg==", "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" + "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", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" } }, "node_modules/string.prototype.matchall": { @@ -4418,6 +4780,26 @@ "node": ">=6" } }, + "node_modules/tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "dependencies": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "node_modules/tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -4465,9 +4847,9 @@ } }, "node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==" + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", + "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==" }, "node_modules/tsutils": { "version": "3.21.0", @@ -4488,6 +4870,17 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -4510,6 +4903,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", @@ -4578,6 +5019,11 @@ } } }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "node_modules/validator": { "version": "13.9.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", @@ -4615,31 +5061,16 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", - "dependencies": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "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.11", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", + "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", "dependencies": { "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "has-tostringtag": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -4648,14 +5079,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index e53efd8f..44aac912 100644 --- a/package.json +++ b/package.json @@ -23,13 +23,15 @@ "eslint": "8.36.0", "eslint-config-next": "13.2.4", "form-data": "^4.0.0", - "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.52", + "jwt-decode": "^3.1.2", + "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.58", "next": "13.2.4", "prettier": "^2.8.7", "react": "18.2.0", "react-dom": "18.2.0", "react-select": "^5.7.2", "sass": "^1.59.2", + "sharp": "^0.32.1", "typescript": "4.9.5" } } diff --git a/src/front/Api/Auth/IdNot/User.ts b/src/front/Api/Auth/IdNot/User.ts new file mode 100644 index 00000000..7e1643fc --- /dev/null +++ b/src/front/Api/Auth/IdNot/User.ts @@ -0,0 +1,38 @@ +import BaseApiService from "@Front/Api/BaseApiService"; + +export default class User extends BaseApiService { + private static instance: User; + private readonly baseURl = this.getBaseUrl().concat("/idnot/user"); + + private constructor() { + super(); + } + + public static getInstance() { + if (!this.instance) { + return new User(); + } else { + return this.instance; + } + } + + public async login(uid: string) { + const url = new URL(this.baseURl.concat("/login/").concat(uid)); + try { + return await this.postRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + public async refreshToken(refreshToken: string): Promise<{ accessToken: string }> { + const url = new URL(this.baseURl.concat("/refresh-token")); + try { + return await this.postRequest(url, {}, refreshToken); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Api/BaseApiService.ts b/src/front/Api/BaseApiService.ts index 166621bc..003a902d 100644 --- a/src/front/Api/BaseApiService.ts +++ b/src/front/Api/BaseApiService.ts @@ -1,4 +1,5 @@ import { FrontendVariables } from "@Front/Config/VariablesFront"; +import CookieService from "@Front/Services/CookieService/CookieService"; export enum ContentType { JSON = "application/json", @@ -21,11 +22,14 @@ export default abstract class BaseApiService { } protected buildHeaders(contentType: ContentType) { + const token = CookieService.getInstance().getCookie("leCoffreAccessToken"); + const headers = new Headers(); if (contentType === ContentType.JSON) { headers.set("Content-Type", contentType); } + headers.set("Authorization", `Bearer ${token}`); return headers; } @@ -33,7 +37,7 @@ export default abstract class BaseApiService { return JSON.stringify(body); } - protected async getRequest(url: URL) { + protected async getRequest(url: URL, token?: string) { const request = async () => await fetch(url, { method: "GET", @@ -42,7 +46,7 @@ export default abstract class BaseApiService { return this.sendRequest(request); } - protected async postRequest(url: URL, body: { [key: string]: unknown } = {}) { + protected async postRequest(url: URL, body: { [key: string]: unknown } = {}, token?: string) { return this.sendRequest( async () => await fetch(url, { @@ -64,7 +68,7 @@ export default abstract class BaseApiService { ); } - protected async putRequest(url: URL, body: { [key: string]: unknown } = {}) { + protected async putRequest(url: URL, body: { [key: string]: unknown } = {}, token?: string) { const request = async () => await fetch(url, { method: "PUT", @@ -86,7 +90,7 @@ export default abstract class BaseApiService { return this.sendRequest(request); } - protected async deleteRequest(url: URL, body: { [key: string]: unknown } = {}) { + protected async deleteRequest(url: URL, body: { [key: string]: unknown } = {}, token?: string) { const request = async () => await fetch(url, { method: "DELETE", @@ -97,7 +101,7 @@ export default abstract class BaseApiService { return this.sendRequest(request); } - protected async putFormDataRequest(url: URL, body: FormData) { + protected async putFormDataRequest(url: URL, body: FormData, token?: string) { const request = async () => await fetch(url, { method: "PUT", 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..05003ce4 --- /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: DocumentType): 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..fe541fa2 --- /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/Api/LeCoffreApi/Admin/Users/Users.ts b/src/front/Api/LeCoffreApi/Admin/Users/Users.ts new file mode 100644 index 00000000..6e50f59a --- /dev/null +++ b/src/front/Api/LeCoffreApi/Admin/Users/Users.ts @@ -0,0 +1,91 @@ +import User from "le-coffre-resources/dist/SuperAdmin"; +import BaseAdmin from "../BaseAdmin"; + +// TODO Type get query params -> Where + inclue + orderby +export interface IGetUsersparams { + where?: {}; + include?: {}; + select?: {}; +} + +// TODO Type getbyuid query params + +export type IPutUsersParams = { + uid?: User["uid"]; + idNot?: User["idNot"]; + contact?: User["contact"]; + office_membership?: User["office_membership"]; + documents?: User["documents"]; +}; + +export default class Users extends BaseAdmin { + private static instance: Users; + private readonly baseURl = this.namespaceUrl.concat("/users"); + + private constructor() { + super(); + } + + public static getInstance() { + if (!this.instance) { + return new this(); + } else { + return this.instance; + } + } + + /** + * @description : Get all Users + */ + public async get(q: IGetUsersparams): 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); + } + } + + /** + * @description : Get a folder by uid + */ + public async getByUid(uid: string, q?: any): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + if (q) Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value))); + try { + return await this.getRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + /** + * @description : Create a User + */ + // public async post(body: IPostDeedsParams): Promise { + // const url = new URL(this.baseURl); + // try { + // return await this.postRequest(url, body); + // } catch (err) { + // this.onError(err); + // return Promise.reject(err); + // } + // } + + /** + * @description : Update the folder description + */ + public async put(uid: string, body: IPutUsersParams): 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/SuperAdmin/DeedTypes/DeedTypes.ts b/src/front/Api/LeCoffreApi/SuperAdmin/DeedTypes/DeedTypes.ts index 548a95ff..9ce2dc89 100644 --- a/src/front/Api/LeCoffreApi/SuperAdmin/DeedTypes/DeedTypes.ts +++ b/src/front/Api/LeCoffreApi/SuperAdmin/DeedTypes/DeedTypes.ts @@ -15,7 +15,7 @@ export type IPutDeedTypesParams = { deed?: DeedType["deed"]; office?: DeedType["office"]; archived_at?: DeedType["archived_at"]; - deed_type_has_document_types?: DeedType["deed_type_has_document_types"]; + document_types?: DeedType["document_types"]; }; export default class DeedTypes extends BaseSuperAdmin { @@ -37,9 +37,11 @@ export default class DeedTypes extends BaseSuperAdmin { /** * @description : Get all DeedTypes */ - public async get(q: IGetDeedTypesParams): Promise { + public async get(q?: IGetDeedTypesParams): Promise { const url = new URL(this.baseURl); - Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value))); + if(q){ + Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value))); + } try { return await this.getRequest(url); } catch (err) { diff --git a/src/front/Api/LeCoffreApi/SuperAdmin/Deeds/Deeds.ts b/src/front/Api/LeCoffreApi/SuperAdmin/Deeds/Deeds.ts index 3953781f..a3360412 100644 --- a/src/front/Api/LeCoffreApi/SuperAdmin/Deeds/Deeds.ts +++ b/src/front/Api/LeCoffreApi/SuperAdmin/Deeds/Deeds.ts @@ -15,7 +15,7 @@ export type IPutDeedsParams = { description?: OfficeFolder["description"]; archived_description?: OfficeFolder["archived_description"]; status?: OfficeFolder["status"]; - deed_has_document_types?: Deed["deed_has_document_types"]; + document_types?: Deed["document_types"]; }; export default class Deeds extends BaseSuperAdmin { diff --git a/src/front/Api/LeCoffreApi/SuperAdmin/DocumentTypes/DocumentTypes.ts b/src/front/Api/LeCoffreApi/SuperAdmin/DocumentTypes/DocumentTypes.ts index 1e8a09af..f151377e 100644 --- a/src/front/Api/LeCoffreApi/SuperAdmin/DocumentTypes/DocumentTypes.ts +++ b/src/front/Api/LeCoffreApi/SuperAdmin/DocumentTypes/DocumentTypes.ts @@ -37,10 +37,12 @@ export default class DocumentTypes extends BaseSuperAdmin { } } - public async get(q: IGetDocumentTypesparams): Promise { + 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))); + if (q) { + 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) { diff --git a/src/front/Api/LeCoffreApi/SuperAdmin/Files/Files.ts b/src/front/Api/LeCoffreApi/SuperAdmin/Files/Files.ts index fdad59f3..c3fe5580 100644 --- a/src/front/Api/LeCoffreApi/SuperAdmin/Files/Files.ts +++ b/src/front/Api/LeCoffreApi/SuperAdmin/Files/Files.ts @@ -1,5 +1,4 @@ import { File } from "le-coffre-resources/dist/SuperAdmin"; - import BaseSuperAdmin from "../BaseSuperAdmin"; // TODO Type get query params -> Where + inclue + orderby diff --git a/src/front/Api/LeCoffreApi/SuperAdmin/Folders/Folders.ts b/src/front/Api/LeCoffreApi/SuperAdmin/Folders/Folders.ts index b749519e..844095aa 100644 --- a/src/front/Api/LeCoffreApi/SuperAdmin/Folders/Folders.ts +++ b/src/front/Api/LeCoffreApi/SuperAdmin/Folders/Folders.ts @@ -88,7 +88,7 @@ export default class Folders extends BaseSuperAdmin { public async delete(uid: string): Promise { const url = new URL(this.baseURl.concat(`/${uid}`)); const targetedFolder = await this.getByUid(uid); - if (targetedFolder.office_folder_has_customers) return Promise.reject(`The folder ${uid} contains customers`); + if (targetedFolder.customers) return Promise.reject(`The folder ${uid} contains customers`); try { return await this.deleteRequest(url); } catch (err) { diff --git a/src/front/Api/LeCoffreApi/SuperAdmin/Offices/Offices.ts b/src/front/Api/LeCoffreApi/SuperAdmin/Offices/Offices.ts new file mode 100644 index 00000000..595a62eb --- /dev/null +++ b/src/front/Api/LeCoffreApi/SuperAdmin/Offices/Offices.ts @@ -0,0 +1,53 @@ +import { Office } from "le-coffre-resources/dist/SuperAdmin"; +import BaseSuperAdmin from "../BaseSuperAdmin"; + +export interface IGetOfficesparams { + where?: {}; + include?: {}; + select?: {}; +} + +export default class Offices extends BaseSuperAdmin { + private static instance: Offices; + private readonly baseURl = this.namespaceUrl.concat("/offices"); + + private constructor() { + super(); + } + + public static getInstance() { + if (!this.instance) { + return new this(); + } else { + return this.instance; + } + } + + public async get(q?: IGetOfficesparams): Promise { + const url = new URL(this.baseURl); + if (q) { + const query = { q }; + Object.entries(query).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value))); + } + try { + return await this.getRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } + + /** + * @description : Get a folder by uid + */ + public async getByUid(uid: string, q?: any): Promise { + const url = new URL(this.baseURl.concat(`/${uid}`)); + if (q) Object.entries(q).forEach(([key, value]) => url.searchParams.set(key, JSON.stringify(value))); + try { + return await this.getRequest(url); + } catch (err) { + this.onError(err); + return Promise.reject(err); + } + } +} diff --git a/src/front/Api/LeCoffreApi/SuperAdmin/Users/Users.ts b/src/front/Api/LeCoffreApi/SuperAdmin/Users/Users.ts index 17432643..319a01fd 100644 --- a/src/front/Api/LeCoffreApi/SuperAdmin/Users/Users.ts +++ b/src/front/Api/LeCoffreApi/SuperAdmin/Users/Users.ts @@ -15,7 +15,6 @@ export type IPutUsersParams = { idNot?: User["idNot"]; contact?: User["contact"]; office_membership?: User["office_membership"]; - office_folder_has_stakeholders?: User["office_folder_has_stakeholders"]; documents?: User["documents"]; }; diff --git a/src/front/Assets/images/warning.png b/src/front/Assets/images/warning.png new file mode 100644 index 00000000..ca122226 Binary files /dev/null and b/src/front/Assets/images/warning.png differ 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/Form/BaseField.tsx b/src/front/Components/DesignSystem/Form/BaseField.tsx index 43898868..05afdf38 100644 --- a/src/front/Components/DesignSystem/Form/BaseField.tsx +++ b/src/front/Components/DesignSystem/Form/BaseField.tsx @@ -55,6 +55,12 @@ export default abstract class BaseField

{ errors: this.props.errors ?? null, }); } + + if (this.props.selectedOption !== prevProps.selectedOption) { + this.setState({ + selectedOption: this.props.selectedOption ?? null, + }); + } } static getDerivedStateFromProps(props: IProps, state: IState) { 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/Header/Profile/ProfileModal/index.tsx b/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx index ba824a61..6612a016 100644 --- a/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx +++ b/src/front/Components/DesignSystem/Header/Profile/ProfileModal/index.tsx @@ -1,8 +1,9 @@ -import React from "react"; -import classes from "./classes.module.scss"; -import NavigationLink from "../../NavigationLink"; import LogOutButton from "@Front/Components/DesignSystem/LogOutButton"; import Module from "@Front/Config/Module"; +import React from "react"; + +import NavigationLink from "../../NavigationLink"; +import classes from "./classes.module.scss"; type IProps = { isOpen: boolean; @@ -19,6 +20,34 @@ export default class ProfileModal extends React.Component {
+ + + + +
diff --git a/src/front/Components/DesignSystem/SearchBar/index.tsx b/src/front/Components/DesignSystem/SearchBar/index.tsx index 3a680722..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.office_folder_has_customers) { - const customerNames = folder.office_folder_has_customers - .map((customer) => { - return `${customer.customer.contact?.first_name.toLowerCase()} ${customer.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..0ce3a812 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultCollaboratorDashboard/index.tsx @@ -0,0 +1,121 @@ +import ChevronIcon from "@Assets/Icons/chevron.svg"; +import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/Admin/Users/Users"; +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 JwtService from "@Front/Services/JwtService/JwtService"; +import WindowStore from "@Front/Stores/WindowStore"; +import classNames from "classnames"; +import User from "le-coffre-resources/dist/Notary"; +import Image from "next/image"; +import React, { ReactNode } from "react"; + +import classes from "./classes.module.scss"; +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 jwt = JwtService.getInstance().decodeJwt(); + if (!jwt) return; + const query: IGetUsersparams = { + where: { office_uid: jwt!.office_Id }, + 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..f5b589bb --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultDeedTypeDashboard/DeedTypeListContainer/classes.module.scss @@ -0,0 +1,22 @@ +@import "@Themes/constants.scss"; + +.root { + width: calc(100vh - 83px); + display: flex; + flex-direction: column; + justify-content: space-between; + + .header { + flex: 1; + } + + .searchbar { + padding: 40px 24px 24px 24px; + } + + .folderlist-container { + max-height: calc(100vh - 290px); + overflow: auto; + 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/DefaultDocumentTypesDashboard/DocumentTypeListContainer/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/classes.module.scss new file mode 100644 index 00000000..15e841c8 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/classes.module.scss @@ -0,0 +1,29 @@ +@import "@Themes/constants.scss"; + +.root { + display: flex; + flex-direction: column; + justify-content: space-between; + + position: relative; + .header { + flex: 1; + } + + .searchbar { + padding: 40px 24px 24px 24px; + } + + .folderlist-container { + max-height: calc(100vh - 290px); + overflow: auto; + border-right: 1px solid var(--grey-medium); + } + + .create-container { + position: absolute; + bottom: 0; + left: 0; + right: 0; + } +} diff --git a/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/index.tsx b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/index.tsx new file mode 100644 index 00000000..97a2e073 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/DocumentTypeListContainer/index.tsx @@ -0,0 +1,69 @@ +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 { DocumentType } from "le-coffre-resources/dist/SuperAdmin"; +import Link from "next/link"; +import { useRouter } from "next/router"; +import React, { useCallback, useState } from "react"; + +import classes from "./classes.module.scss"; + +type IProps = { + documentTypes: DocumentType[]; + onSelectedDocumentType?: (documentType: DocumentType) => void; + onCloseLeftSide?: () => void; +}; + +export default function DocumentTypeListContainer(props: IProps) { + const [filteredDocumentTypes, setFilteredDocumentTypes] = useState(props.documentTypes); + const router = useRouter(); + + const { documentTypeUid } = router.query; + const filterDocumentTypes = useCallback( + (input: string) => { + const filteredDocumentTypes = props.documentTypes.filter((documentType) => { + return documentType.name.toLowerCase().includes(input.toLowerCase()); + }); + setFilteredDocumentTypes(filteredDocumentTypes); + }, + [props.documentTypes], + ); + + const onSelectedBlock = useCallback( + (block: IBlock) => { + props.onCloseLeftSide && props.onCloseLeftSide(); + console.log("Block selected :", block); + const redirectPath = Module.getInstance().get().modules.pages.DocumentTypes.pages.Edit.props.path; + router.push(redirectPath.replace("[uid]", block.id)); + }, + [props, router], + ); + + return ( +
+
+
+ +
+
+ { + return { + name: documentType.name, + id: documentType.uid!, + selected: documentType.uid === documentTypeUid, + }; + })} + onSelectedBlock={onSelectedBlock} + /> +
+
+
+ + + +
+
+ ); +} diff --git a/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/classes.module.scss new file mode 100644 index 00000000..a5ba79a3 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/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/DefaultDocumentTypesDashboard/index.tsx b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/index.tsx new file mode 100644 index 00000000..7616bf7a --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultDocumentTypesDashboard/index.tsx @@ -0,0 +1,121 @@ +import ChevronIcon from "@Assets/Icons/chevron.svg"; +import DocumentTypes from "@Front/Api/LeCoffreApi/SuperAdmin/DocumentTypes/DocumentTypes"; +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 JwtService from "@Front/Services/JwtService/JwtService"; +import WindowStore from "@Front/Stores/WindowStore"; +import classNames from "classnames"; +import { DocumentType } from "le-coffre-resources/dist/Notary"; +import Image from "next/image"; +import React, { ReactNode } from "react"; + +import classes from "./classes.module.scss"; +import DocumentTypeListContainer from "./DocumentTypeListContainer"; + +type IProps = { + title: string; + children?: ReactNode; + onSelectedDocumentType: (documentType: DocumentType) => void; + hasBackArrow: boolean; + backArrowUrl?: string; + mobileBackText?: string; +}; +type IState = { + documentTypes: DocumentType[] | null; + isLeftSideOpen: boolean; + leftSideCanBeClosed: boolean; +}; + +export default class DefaultDocumentTypesDashboard extends React.Component { + private onWindowResize = () => {}; + public static defaultProps: Partial = { + hasBackArrow: false, + }; + + public constructor(props: IProps) { + super(props); + this.state = { + documentTypes: 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.documentTypes && ( + + )} +
+
+ 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 jwt = JwtService.getInstance().decodeJwt(); + if (!jwt) return; + const documentTypes = await DocumentTypes.getInstance().get({ + where: { + office_uid: jwt.office_Id, + }, + }); + this.setState({ documentTypes }); + } + + 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/DefaultNotaryDashboard/index.tsx b/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/index.tsx index bad6838a..bacb0a23 100644 --- a/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/index.tsx +++ b/src/front/Components/LayoutTemplates/DefaultNotaryDashboard/index.tsx @@ -1,4 +1,3 @@ - import ChevronIcon from "@Assets/Icons/chevron.svg"; import Folders, { IGetFoldersParams } from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders"; import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; @@ -9,12 +8,11 @@ import BackArrow from "@Front/Components/Elements/BackArrow"; import WindowStore from "@Front/Stores/WindowStore"; import classNames from "classnames"; import { OfficeFolder } from "le-coffre-resources/dist/Customer"; +import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus"; import Image from "next/image"; import React, { ReactNode } from "react"; import classes from "./classes.module.scss"; -import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus"; - type IProps = { title: string; @@ -39,7 +37,7 @@ export type IDashBoardFolder = { description: OfficeFolder["description"]; deed?: OfficeFolder["deed"]; created_at: OfficeFolder["created_at"]; - office_folder_has_customers?: OfficeFolder["office_folder_has_customers"]; + customers?: OfficeFolder["customers"]; archived_description: OfficeFolder["archived_description"]; status: OfficeFolder["status"]; }; @@ -118,18 +116,14 @@ export default class DefaultNotaryDashboard extends React.Component void; + onCloseLeftSide?: () => void; +}; + +export default function OfficeListContainer(props: IProps) { + const [filteredOffices, setFilteredOffices] = useState(props.offices); + const router = useRouter(); + + const { officeUid } = router.query; + const filterOffices = useCallback( + (input: string) => { + const filteredOffices = props.offices.filter((office) => { + return ( + office.name.toLowerCase().includes(input.toLowerCase()) || office.crpcen?.toLowerCase().includes(input.toLowerCase()) + ); + }); + setFilteredOffices(filteredOffices); + }, + [props.offices], + ); + + const onSelectedBlock = useCallback( + (block: IBlock) => { + props.onCloseLeftSide && props.onCloseLeftSide(); + const redirectPath = Module.getInstance().get().modules.pages.Offices.pages.OfficesInformations.props.path; + router.push(redirectPath.replace("[uid]", block.id)); + }, + [props, router], + ); + + return ( +
+
+
+ +
+
+ { + return { + name: office.crpcen + " - " + office.name, + id: office.uid!, + selected: office.uid === officeUid, + }; + })} + onSelectedBlock={onSelectedBlock} + /> +
+
+
+ ); +} diff --git a/src/front/Components/LayoutTemplates/DefaultOfficeDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultOfficeDashboard/classes.module.scss new file mode 100644 index 00000000..a5ba79a3 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultOfficeDashboard/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/DefaultOfficeDashboard/index.tsx b/src/front/Components/LayoutTemplates/DefaultOfficeDashboard/index.tsx new file mode 100644 index 00000000..37bb5770 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultOfficeDashboard/index.tsx @@ -0,0 +1,112 @@ +import ChevronIcon from "@Assets/Icons/chevron.svg"; +import Offices from "@Front/Api/LeCoffreApi/SuperAdmin/Offices/Offices"; +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 { Office } from "le-coffre-resources/dist/Notary"; +import Image from "next/image"; +import React, { ReactNode } from "react"; + +import classes from "./classes.module.scss"; +import OfficeListContainer from "./OfficeListContainer"; + +type IProps = { + title: string; + children?: ReactNode; + onSelectedOffice: (office: Office) => void; + hasBackArrow: boolean; + backArrowUrl?: string; + mobileBackText?: string; +}; +type IState = { + offices: Office[] | null; + isLeftSideOpen: boolean; + leftSideCanBeClosed: boolean; +}; + +export default class DefaultOfficeDashboard extends React.Component { + private onWindowResize = () => {}; + public static defaultProps: Partial = { + hasBackArrow: false, + }; + + public constructor(props: IProps) { + super(props); + this.state = { + offices: 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.offices && } +
+
+ 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 offices = await Offices.getInstance().get(); + this.setState({ offices }); + } + + 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..ffb79fef --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultRoleDashboard/RoleListContainer/index.tsx @@ -0,0 +1,62 @@ +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 [filteredRoles, setFilteredRoles] = useState(props.roles); + const router = useRouter(); + + const { roleUid } = router.query; + + const filterRoles = useCallback( + (input: string) => { + const filteredRoles = props.roles.filter((role) => { + return role.name?.toLowerCase().includes(input.toLowerCase()); + }); + setFilteredRoles(filteredRoles); + }, + [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: role.uid === roleUid, + }; + })} + 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/LayoutTemplates/DefaultUserDashboard/UserListContainer/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultUserDashboard/UserListContainer/classes.module.scss new file mode 100644 index 00000000..300d46f2 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultUserDashboard/UserListContainer/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/DefaultUserDashboard/UserListContainer/index.tsx b/src/front/Components/LayoutTemplates/DefaultUserDashboard/UserListContainer/index.tsx new file mode 100644 index 00000000..8128b38d --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultUserDashboard/UserListContainer/index.tsx @@ -0,0 +1,64 @@ +import BlockList, { IBlock } from "@Front/Components/DesignSystem/BlockList"; +import SearchBar from "@Front/Components/DesignSystem/SearchBar"; +import Module from "@Front/Config/Module"; +import User from "le-coffre-resources/dist/Notary"; +import { useRouter } from "next/router"; +import React, { useCallback, useState } from "react"; + +import classes from "./classes.module.scss"; + +type IProps = { + users: User[]; + onSelectedUser?: (user: User) => void; + onCloseLeftSide?: () => void; +}; + +export default function UserListContainer(props: IProps) { + const [filteredUsers, setFilteredUsers] = useState(props.users); + const router = useRouter(); + + const { userUid } = router.query; + const filterUsers = useCallback( + (input: string) => { + const filteredUsers = props.users.filter((user) => { + return ( + user.contact?.first_name?.toLowerCase().includes(input.toLowerCase()) || + user.contact?.last_name?.toLowerCase().includes(input.toLowerCase()) + ); + }); + setFilteredUsers(filteredUsers); + }, + [props.users], + ); + + const onSelectedBlock = useCallback( + (block: IBlock) => { + props.onCloseLeftSide && props.onCloseLeftSide(); + const redirectPath = Module.getInstance().get().modules.pages.Users.pages.UsersInformations.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 === userUid, + }; + })} + onSelectedBlock={onSelectedBlock} + /> +
+
+
+ ); +} diff --git a/src/front/Components/LayoutTemplates/DefaultUserDashboard/classes.module.scss b/src/front/Components/LayoutTemplates/DefaultUserDashboard/classes.module.scss new file mode 100644 index 00000000..a5ba79a3 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultUserDashboard/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/DefaultUserDashboard/index.tsx b/src/front/Components/LayoutTemplates/DefaultUserDashboard/index.tsx new file mode 100644 index 00000000..c65a6560 --- /dev/null +++ b/src/front/Components/LayoutTemplates/DefaultUserDashboard/index.tsx @@ -0,0 +1,115 @@ +import ChevronIcon from "@Assets/Icons/chevron.svg"; +import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users"; +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 User from "le-coffre-resources/dist/Notary"; +import Image from "next/image"; +import React, { ReactNode } from "react"; + +import classes from "./classes.module.scss"; +import UserListContainer from "./UserListContainer"; + +type IProps = { + title: string; + children?: ReactNode; + onSelectedUser: (user: User) => void; + hasBackArrow: boolean; + backArrowUrl?: string; + mobileBackText?: string; +}; +type IState = { + users: User[] | null; + isLeftSideOpen: boolean; + leftSideCanBeClosed: boolean; +}; + +export default class DefaultUserDashboard extends React.Component { + private onWindowResize = () => {}; + public static defaultProps: Partial = { + hasBackArrow: false, + }; + + public constructor(props: IProps) { + super(props); + this.state = { + users: 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.users && } +
+
+ 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 = { + include: { contact: true }, + }; + + const users = await Users.getInstance().get(query); + this.setState({ users }); + } + 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/ClientDashboard/index.tsx b/src/front/Components/Layouts/ClientDashboard/index.tsx index dd25c1ec..0df97dce 100644 --- a/src/front/Components/Layouts/ClientDashboard/index.tsx +++ b/src/front/Components/Layouts/ClientDashboard/index.tsx @@ -10,7 +10,6 @@ import React from "react"; import classes from "./classes.module.scss"; import Customers from "@Front/Api/LeCoffreApi/SuperAdmin/Customers/Customers"; import Customer, { Document } from "le-coffre-resources/dist/Customer"; -import { document } from "./../../../Components/Layouts/DesignSystem/dummyData"; type IProps = { targetedCustormer: string; // MOCK @@ -69,7 +68,7 @@ export default class ClientDashboard extends Base { Glissez / Déposez votre document dans la zone prévue à cet effet ou cliquez sur la zone puis sélectionnez le document correspondant. - + {/* */}
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..e0ee6c70 --- /dev/null +++ b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx @@ -0,0 +1,118 @@ +import ChevronIcon from "@Assets/Icons/chevron.svg"; +import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles"; +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 Module from "@Front/Config/Module"; +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"; + +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, + 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..ea85a5d1 --- /dev/null +++ b/src/front/Components/Layouts/DeedTypes/DeedTypesInformations/index.tsx @@ -0,0 +1,129 @@ +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 Module from "@Front/Config/Module"; +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"; + +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/DesignSystem/classes.module.scss b/src/front/Components/Layouts/DesignSystem/classes.module.scss deleted file mode 100644 index 61db99b4..00000000 --- a/src/front/Components/Layouts/DesignSystem/classes.module.scss +++ /dev/null @@ -1,18 +0,0 @@ -.root { - margin-left: 35px; - margin-right: 35px; - .section { - margin-bottom: 32px; - } - .sub-section { - margin-bottom: 24px; - } - - .inline-flex { - display: inline-flex; - } - - .folder-conatainer { - width: 389px; - } -} diff --git a/src/front/Components/Layouts/DesignSystem/dummyData.ts b/src/front/Components/Layouts/DesignSystem/dummyData.ts deleted file mode 100644 index 85af3021..00000000 --- a/src/front/Components/Layouts/DesignSystem/dummyData.ts +++ /dev/null @@ -1,347 +0,0 @@ -import { ECustomerStatus } from "le-coffre-resources/dist/Customer/Customer"; -import { EDocumentStatus } from "le-coffre-resources/dist/Customer/Document"; -import EFolderStatus from "le-coffre-resources/dist/Customer/EFolderStatus"; -import { - Address, - Contact, - Customer, - Deed, - DeedType, - Document, - DocumentType, - File, - Office, - OfficeFolder, - OfficeFolderHasCustomer, -} from "le-coffre-resources/dist/Notary"; - -export const address: Address = { - uid: "a&2azedzaa3", - address: "123", - city: "France", - zip_code: 78140, - created_at: new Date(), - updated_at: new Date(), -}; - -export const office: Office = { - uid: "111zdazaefez213", - idNot: "12EE12", - name: "Office 1", - crpcen: "AZezdz", - address: address, - created_at: new Date(), - updated_at: new Date(), - office_status: "ACTIVATED", -}; -export const deedType: DeedType = { - uid: "123azefezgzeg312", - name: "Acte mariage", - description: "dzsdaf", - archived_at: new Date(), - office: office, - created_at: new Date(), - updated_at: new Date(), -}; - -export const deed: Deed = { - uid: "zegefzeferg", - deed_type: deedType, - created_at: new Date(), - updated_at: new Date(), -}; - -export const contact: Contact = { - uid: "contact_1_uid", - first_name: "John", - last_name: "Doe", - email: "johnDoe@gmail.com", - address: address, - created_at: new Date(), - updated_at: new Date(), - cell_phone_number: "0132249865", - phone_number: "0132249865", - civility: "MALE", -}; - -export const contact2: Contact = { - uid: "contact_2_uid", - first_name: "Customer2", - last_name: "Doe", - email: "johnDoe@gmail.com", - address: address, - created_at: new Date(), - updated_at: new Date(), - cell_phone_number: "0132249865", - phone_number: "0132249865", - civility: "MALE", -}; - -export const docType: DocumentType = { - name: "Votre document", - uid: "fezezfazegezrgrezg", - created_at: new Date(), - updated_at: new Date(), - public_description: "", - private_description: "", - archived_at: new Date(), - office: office, -}; - -export const identityDocType: DocumentType = { - name: "Carte d'identité", - uid: "fezezfazegezrgrezg", - created_at: new Date(), - updated_at: new Date(), - public_description: "Carte d'identité public description", - private_description: "Carte d'identité private description", - archived_at: new Date(), - office: office, -}; - -export const customer: Customer = { - uid: "erhtgerfzeare", - contact: contact, - created_at: new Date(), - updated_at: new Date(), - status: ECustomerStatus.VALIDATED, -}; - -export const customer2_mock: Customer = { - uid: "yregrgetergrt", - contact: contact2, - created_at: new Date(), - updated_at: new Date(), - status: ECustomerStatus.VALIDATED, -}; - -export const folder: OfficeFolder = { - uid: "mkovrijvrezviev", - folder_number: "12331", - name: "Mon dossier", - status: EFolderStatus.ARCHIVED, - deed: deed, - office: office, - created_at: new Date(), - updated_at: new Date(), - description: "Description", - archived_description: "Archived description", -}; - -export const document: Document = { - uid: "fzeafergreztyzgrf", - depositor: customer2_mock, - document_status: "ASKED", - folder: folder, - document_type: docType, - updated_at: new Date(), - created_at: new Date(), -}; - -export const fileMock: File = { - uid: "super_file_uid_1", - created_at: new Date(), - updated_at: new Date(), - document: document, - file_name: "file_1", - file_path: - "https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/Qmf_Yb_Eh_X9st_F_Srq_Ve_Bj_Yb_Aj56xv_AV_Nj6_Wjypo_B4r5ubce_U_ae3303e7ab.pdf", - archived_at: null, - mimetype: "image/png", - size: 0, -}; - -export const fileMock2: File = { - uid: "super_file_uid_2", - created_at: new Date(), - updated_at: new Date(), - document: document, - file_name: "file_2", - file_path: - "https://minteed-prod-euwest3-s3.s3.eu-west-3.amazonaws.com/Qm_Wq_En1_DCA_8yt_RX_Qx_QFA_9_Fm_ZKZH_Qqb_VH_1_Q_Mnv_G_Jtt1_FS_Xp_2a35a36e19", - archived_at: null, - mimetype: "image/png", - size: 0, -}; - -export const identityFile: File = { - uid: "identity_file_uid", - created_at: new Date(), - updated_at: new Date(), - document: document, - file_name: "file_3", - file_path: "https://minteed-stg-euwest3-s3.s3.eu-west-3.amazonaws.com/cni_fake_c7259d4923.png", - archived_at: null, - mimetype: "image/png", - size: 0, -}; - -export const documentIdentity: Document = { - uid: "ethrthbkjtrbporjbh", - depositor: customer2_mock, - document_status: EDocumentStatus.DEPOSITED, - folder: folder, - document_type: identityDocType, - updated_at: new Date(), - created_at: new Date(), - files: [identityFile], -}; - -export const documentPending: Document = { - uid: "fzefeazdagrtetrury", - depositor: customer2_mock, - document_status: EDocumentStatus.DEPOSITED, - folder: folder, - document_type: docType, - updated_at: new Date(), - created_at: new Date(), - files: [fileMock, fileMock2], -}; - -export const documentDeposited: Document = { - uid: "uè§u§htfgrthytrgr", - depositor: customer2_mock, - document_status: "VALIDATED", - folder: folder, - document_type: docType, - updated_at: new Date(), - created_at: new Date(), - files: [fileMock], -}; - -export const customer2: Customer = { - uid: "yregrgetergrt", - contact: contact2, - created_at: new Date(), - updated_at: new Date(), - status: ECustomerStatus.VALIDATED, - documents: [document, documentPending, documentDeposited, documentIdentity], -}; - -export const folderWithPendingDocument: OfficeFolder = { - uid: "ferzferzfezeefzdd", - folder_number: "00001", - name: "Mon dossier", - status: EFolderStatus.LIVE, - deed: deed, - office: office, - created_at: new Date(), - updated_at: new Date(), - description: "Description", - archived_description: "Archived description", - documents: [], -}; -export const folderWithPendingDocument1: OfficeFolder = { - uid: "gtrtyutyhretgytu", - folder_number: "00002", - name: "Mon dossier", - status: EFolderStatus.LIVE, - deed: deed, - office: office, - created_at: new Date(), - updated_at: new Date(), - description: "Description", - archived_description: "Archived description", - documents: [documentDeposited], -}; -export const folderWithPendingDocument2: OfficeFolder = { - uid: "adzefzefsfrefzrtgtr", - folder_number: "00003", - name: "Mon dossier", - status: EFolderStatus.LIVE, - deed: deed, - office: office, - created_at: new Date(), - updated_at: new Date(), - description: "Description", - archived_description: "Archived description", - documents: [document], -}; - -export const officeFolderHasCustomer1: OfficeFolderHasCustomer = { - uid: "ferzfergrzeyerezrz", - customer: customer, - office_folder: folderWithPendingDocument, - created_at: new Date(), - updated_at: new Date(), -}; - -export const officeFolderHasCustomer2: OfficeFolderHasCustomer = { - uid: "tezrfzdfgrggeerry", - customer: customer2, - office_folder: folderWithPendingDocument, - created_at: new Date(), - updated_at: new Date(), -}; - -export const folderWithPendingDocument3: OfficeFolder = { - uid: "mkovrijvrezviev", - folder_number: "00014", - name: "Mon dossier", - status: EFolderStatus.LIVE, - deed: deed, - office: office, - created_at: new Date(), - updated_at: new Date(), - description: "Description", - archived_description: "Archived description", - documents: [document, documentDeposited, documentPending, documentIdentity], - office_folder_has_customers: [officeFolderHasCustomer1, officeFolderHasCustomer2], -}; - -export const document8: Document = { - uid: "eztreggrgbyunjukhg", - depositor: customer, - document_status: "ASKED", - folder: folderWithPendingDocument, - document_type: docType, - updated_at: new Date(), - created_at: new Date(), -}; - -export const folderWithPendingDocumentArchived1: OfficeFolder = { - uid: "gtrtyutyhrdazafad&éfytu", - folder_number: "00007", - name: "Mon dossier", - status: EFolderStatus.ARCHIVED, - deed: deed, - office: office, - created_at: new Date(), - updated_at: new Date(), - description: "Description", - archived_description: "Archived description", - documents: [documentDeposited], - office_folder_has_customers: [officeFolderHasCustomer1, officeFolderHasCustomer2], -}; -export const folderWithPendingDocumentArchived2: OfficeFolder = { - uid: "adzefdazdaazzrtgtr", - folder_number: "00008", - name: "Mon dossier", - status: EFolderStatus.ARCHIVED, - deed: deed, - office: office, - created_at: new Date(), - updated_at: new Date(), - description: "Description", - archived_description: "Archived description", - documents: [document], -}; - -export const document2: Document = { - uid: "mejfihruehfoire", - depositor: customer, - document_status: "ASKED", - folder: folderWithPendingDocument3, - document_type: docType, - updated_at: new Date(), - created_at: new Date(), -}; - -export const folders: OfficeFolder[] = [ - folderWithPendingDocument, - folderWithPendingDocument1, - folderWithPendingDocument2, - folderWithPendingDocument3, -]; - -export const foldersArchived: OfficeFolder[] = [folderWithPendingDocumentArchived1, folderWithPendingDocumentArchived2]; diff --git a/src/front/Components/Layouts/DesignSystem/index.tsx b/src/front/Components/Layouts/DesignSystem/index.tsx deleted file mode 100644 index 20a6108e..00000000 --- a/src/front/Components/Layouts/DesignSystem/index.tsx +++ /dev/null @@ -1,319 +0,0 @@ -import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; -import CheckBox from "@Front/Components/DesignSystem/CheckBox"; -import DocumentNotary from "@Front/Components/DesignSystem/Document/DocumentNotary"; -import FilePreview from "@Front/Components/DesignSystem/FilePreview"; -import FolderContainer from "@Front/Components/DesignSystem/FolderContainer"; -import FolderList from "@Front/Components/DesignSystem/FolderListContainer"; -import HeaderLink from "@Front/Components/DesignSystem/Header/HeaderLink"; -import Confirm from "@Front/Components/DesignSystem/Modal/Confirm"; -import MultiSelect from "@Front/Components/DesignSystem/MultiSelect"; -import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar"; -import RadioBox from "@Front/Components/DesignSystem/RadioBox"; -import SearchBar from "@Front/Components/DesignSystem/SearchBar"; -import ToolTip from "@Front/Components/DesignSystem/ToolTip"; -import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; -import UserFolder from "@Front/Components/DesignSystem/UserFolder"; -import BasePage from "@Front/Components/Layouts/Base"; -import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate"; -import Toasts, { IToast } from "@Front/Stores/Toasts"; - -import classes from "./classes.module.scss"; -import { customer2, document, documentDeposited, documentPending, folder, folders, folderWithPendingDocument } from "./dummyData"; -import { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard"; -import SelectField, { IOption } from "@Front/Components/DesignSystem/Form/SelectField"; -import TextField from "@Front/Components/DesignSystem/Form/TextField"; -import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField"; - -type IState = { - isModalDisplayed: boolean; - selectedOption?: IOption; -}; -type IProps = {}; - -export default class DesignSystem extends BasePage { - constructor(props: IProps) { - super(props); - this.state = { - isModalDisplayed: false, - }; - this.openModal = this.openModal.bind(this); - this.closeModal = this.closeModal.bind(this); - this.onSelectedOption = this.onSelectedOption.bind(this); - } - - public override render(): JSX.Element { - const selectOptions: IOption[] = [ - { value: "1", label: "Divorce" }, - { value: "2", label: "Succession" }, - { value: "3", label: "Vente immobilière" }, - ]; - return ( - -
-
-
- Website design System -
-
- - This page allows to gather all the design system of the site. A Design System is a library of components, - visuals and principles with reusable code. This evolving kit offers a UX and UI repository for designers and - developers of digital products and services. The construction of a design system offers many advantages. - This solution facilitates the work of the teams and reduces the "design debt" and the "technical debt". The - result is a coherent ecosystem and therefore a better experience for users and customers. - -
-
-
-
- Button components -
- - - -
- -
-
- Toaster component -
- -
-
-
- Modal components -
- - - - Lorem ipsum dolor sit amet consectetur. Aliquam nunc lobortis lacus vulputate sagittis sed tempor eget feugiat. - Elementum malesuada at sit elit. - -
- -
-
- HeaderLink components -
-
- - -
-
-
-
- CheckBox component -
- - -
-
-
- RadioBox component -
- - Radio Box 1 - - - Radio Box 2 - -
-
-
- Tool tip component -
- -
-
-
- Input component -
-
- -
-
- -
-
- -
-
- -
-
- Progress bar component -
-
- -
-
- -
-
- -
-
- -
-
- Folder container component -
-
- Folder with no document to validate -
- -
-
-
- Folder with document waiting for being validate -
- -
-
-
- -
-
- Select component -
-
-
- -
-
-
- -
-
- Notary Documents -
-
- Documents ASKED -
- -
-
-
- Documents Depoited -
- -
-
-
- Documents VALIDATED - -
- -
-
-
- -
-
- Notary Documents -
-
- { - return; - }} - /> -
-
- -
-
- MultiSelect -
-
- -
-
- -
-
- Document SearchBar -
-
- -
-
- -
-
- Folder List -
-
- -
-
- -
-
- Preview Image/Pdf -
-
-
- -
- -
-
-
-
- ); - } - private openModal() { - this.setState({ - isModalDisplayed: true, - }); - } - private closeModal() { - this.setState({ - isModalDisplayed: false, - }); - } - private spawnToast() { - const toast: IToast = { - title: "Un collaborateur veut rejoindre votre office", - text: "12:00 - 1 fev 2023", - }; - Toasts.getInstance().open(toast); - } - - private onSelectedOption(option: IOption) { - this.setState({ - selectedOption: option, - }); - } -} diff --git a/src/front/Components/Layouts/DocumentTypes/DocumentTypesCreate/classes.module.scss b/src/front/Components/Layouts/DocumentTypes/DocumentTypesCreate/classes.module.scss new file mode 100644 index 00000000..848ef4bc --- /dev/null +++ b/src/front/Components/Layouts/DocumentTypes/DocumentTypesCreate/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/DocumentTypes/DocumentTypesCreate/index.tsx b/src/front/Components/Layouts/DocumentTypes/DocumentTypesCreate/index.tsx new file mode 100644 index 00000000..2793df38 --- /dev/null +++ b/src/front/Components/Layouts/DocumentTypes/DocumentTypesCreate/index.tsx @@ -0,0 +1,78 @@ +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 TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField"; +import TextField from "@Front/Components/DesignSystem/Form/TextField"; +import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; +import DefaultDocumentTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDocumentTypesDashboard"; +import Module from "@Front/Config/Module"; +import JwtService from "@Front/Services/JwtService/JwtService"; +import { validateOrReject, ValidationError } from "class-validator"; +import { DocumentType, Office } from "le-coffre-resources/dist/Admin"; +import { useRouter } from "next/router"; +import { useCallback, useState } from "react"; + +import classes from "./classes.module.scss"; + +type IProps = {}; +export default function DocumentTypesCreate(props: IProps) { + const [validationError, setValidationError] = useState([]); + + const router = useRouter(); + const onSubmitHandler = useCallback( + async (e: React.FormEvent | null, values: { [key: string]: string }) => { + try { + const jwt = JwtService.getInstance().decodeJwt(); + if (!jwt) return; + const documentToCreate = DocumentType.hydrate({ + ...values, + office: Office.hydrate({ + uid: jwt.office_Id, + }), + }); + await validateOrReject(documentToCreate, { groups: ["createDocumentType"] }); + const documentTypeCreated = await DocumentTypes.getInstance().post(documentToCreate); + + router.push( + Module.getInstance().get().modules.pages.DocumentTypes.pages.Edit.props.path.replace("[uid]", documentTypeCreated.uid!), + ); + } catch (e) { + if (e instanceof Array) { + setValidationError(e); + } + } + }, + [router], + ); + + return ( + +
+
+ Créer un nouveau document +
+
+ error.property === "name")} + /> + error.property === "private_description")} + /> + error.property === "public_description")} + /> +
+ + +
+ +
+
+ ); +} diff --git a/src/front/Components/Layouts/DocumentTypes/DocumentTypesEdit/classes.module.scss b/src/front/Components/Layouts/DocumentTypes/DocumentTypesEdit/classes.module.scss new file mode 100644 index 00000000..848ef4bc --- /dev/null +++ b/src/front/Components/Layouts/DocumentTypes/DocumentTypesEdit/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/DocumentTypes/DocumentTypesEdit/index.tsx b/src/front/Components/Layouts/DocumentTypes/DocumentTypesEdit/index.tsx new file mode 100644 index 00000000..439dbbf3 --- /dev/null +++ b/src/front/Components/Layouts/DocumentTypes/DocumentTypesEdit/index.tsx @@ -0,0 +1,76 @@ +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 TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField"; +import TextField from "@Front/Components/DesignSystem/Form/TextField"; +import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; +import DefaultDocumentTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDocumentTypesDashboard"; +import { validateOrReject } from "class-validator"; +import { DocumentType } from "le-coffre-resources/dist/Admin"; +import { useRouter } from "next/router"; +import { useCallback, useEffect, useState } from "react"; + +import classes from "./classes.module.scss"; + +export default function DocumentTypesEdit() { + const router = useRouter(); + let { documentTypeUid } = router.query; + + const [documentTypeSelected, setDocumentTypeSelected] = useState(null); + + useEffect(() => { + async function getDocumentType() { + if (!documentTypeUid) return; + const documentType = await DocumentTypes.getInstance().getByUid(documentTypeUid as string, { + _count: true, + }); + setDocumentTypeSelected(documentType); + } + + getDocumentType(); + }, [documentTypeUid]); + + const onSubmitHandler = useCallback( + async (e: React.FormEvent | null, values: { [key: string]: string }) => { + try { + const documentToUpdate = DocumentType.hydrate({ + ...values, + uid: documentTypeUid as string, + }); + await validateOrReject(documentToUpdate, { groups: ["updateDocumentType"] }); + const documentTypeUpdated = await DocumentTypes.getInstance().put(documentTypeUid as string, documentToUpdate); + console.log(documentTypeUpdated); + } catch (e) { + console.log(e); + } + }, + [documentTypeUid], + ); + + return ( + +
+
+ Paramétrage des documents +
+
+ + + +
+ + +
+ +
+
+ ); +} diff --git a/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/classes.module.scss b/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/classes.module.scss new file mode 100644 index 00000000..72fe71da --- /dev/null +++ b/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/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/DocumentTypes/DocumentTypesInformations/index.tsx b/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/index.tsx new file mode 100644 index 00000000..8a000e92 --- /dev/null +++ b/src/front/Components/Layouts/DocumentTypes/DocumentTypesInformations/index.tsx @@ -0,0 +1,90 @@ +import ChevronIcon from "@Assets/Icons/chevron.svg"; +import PenICon from "@Assets/Icons/pen.svg"; +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 Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography"; +import DefaultDocumentTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDocumentTypesDashboard"; +import Module from "@Front/Config/Module"; +import classNames from "classnames"; +import { 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 classes from "./classes.module.scss"; + +type IProps = {}; +export default function DocumentTypesInformations(props: IProps) { + const router = useRouter(); + let { documentTypeUid } = router.query; + + const [documentTypeSelected, setDocumentTypeSelected] = useState(null); + + useEffect(() => { + async function getDocumentType() { + if (!documentTypeUid) return; + const documentType = await DocumentTypes.getInstance().getByUid(documentTypeUid as string); + setDocumentTypeSelected(documentType); + } + + getDocumentType(); + }, [documentTypeUid]); + + const onSubmitHandler = useCallback(async (e: React.FormEvent | null, values: { [key: string]: string }) => {}, []); + + return ( + +
+
+ Paramétrage des listes de pièces + +
+
+ {documentTypeSelected?.name} +
+
+
+
+ + Nom du type d'acte + + {documentTypeSelected?.name} +
+
+ + Description + +
+
+
+ + éditer le type d'acte + +
+
+
+
+
+ Documents paramétrés +
+
+ +
+
+
+
+ +
+
+
+ ); +} diff --git a/src/front/Components/Layouts/DocumentTypes/classes.module.scss b/src/front/Components/Layouts/DocumentTypes/classes.module.scss new file mode 100644 index 00000000..4eca97a6 --- /dev/null +++ b/src/front/Components/Layouts/DocumentTypes/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/DocumentTypes/index.tsx b/src/front/Components/Layouts/DocumentTypes/index.tsx new file mode 100644 index 00000000..99b018b4 --- /dev/null +++ b/src/front/Components/Layouts/DocumentTypes/index.tsx @@ -0,0 +1,26 @@ +import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography"; +import DefaultDocumentTypesDashboard from "@Front/Components/LayoutTemplates/DefaultDocumentTypesDashboard"; + +import BasePage from "../Base"; +import classes from "./classes.module.scss"; + +type IProps = {}; +type IState = {}; +export default class DocumentTypes extends BasePage { + public override render(): JSX.Element { + return ( + +
+
+ Paramétrage des documents +
+ + Sélectionnez un document + +
+
+
+
+ ); + } +} diff --git a/src/front/Components/Layouts/Folder/AddClientToFolder/index.tsx b/src/front/Components/Layouts/Folder/AddClientToFolder/index.tsx index 69e613cf..87fd41de 100644 --- a/src/front/Components/Layouts/Folder/AddClientToFolder/index.tsx +++ b/src/front/Components/Layouts/Folder/AddClientToFolder/index.tsx @@ -2,21 +2,21 @@ import Customers from "@Front/Api/LeCoffreApi/SuperAdmin/Customers/Customers"; import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders"; 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 RadioBox from "@Front/Components/DesignSystem/RadioBox"; import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; import BackArrow from "@Front/Components/Elements/BackArrow"; import DefaultNotaryDashboard from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard"; import Module from "@Front/Config/Module"; +import { TextField } from "@mui/material"; import { ECivility } from "le-coffre-resources/dist/Customer/Contact"; -import { Customer, OfficeFolder, OfficeFolderHasCustomer } from "le-coffre-resources/dist/Notary"; +import { Customer, OfficeFolder } from "le-coffre-resources/dist/Notary"; import Link from "next/link"; import { NextRouter, useRouter } from "next/router"; import BasePage from "../../Base"; import classes from "./classes.module.scss"; -import { IOption } from "@Front/Components/DesignSystem/Form/SelectField"; -import { TextField } from "@mui/material"; enum ESelectedOption { EXISTING_CUSTOMER = "existing_customer", @@ -108,10 +108,7 @@ class AddClientToFolderClass extends BasePage { - +
@@ -150,13 +147,9 @@ class AddClientToFolderClass extends BasePage { private async getFolderPreSelectedCustomers(folderUid: string): Promise { const query = { q: { - office_folder_has_customers: { + customers: { include: { - customer: { - include: { - contact: true, - }, - }, + contact: true, }, }, }, @@ -164,10 +157,10 @@ class AddClientToFolderClass extends BasePage { let preExistingCustomers: IOption[] = []; try { const folder = await Folders.getInstance().getByUid(folderUid, query); - preExistingCustomers = folder.office_folder_has_customers!.map((folderHasCustomer) => { + preExistingCustomers = folder.customers!.map((customer) => { return { - label: folderHasCustomer.customer.contact?.first_name + " " + folderHasCustomer.customer.contact?.last_name, - value: folderHasCustomer.customer.uid, + label: customer.contact?.first_name + " " + customer.contact?.last_name, + value: customer.uid, }; }); } catch (error) { @@ -209,24 +202,26 @@ class AddClientToFolderClass extends BasePage { values["civility"] = ECivility.MALE; // TODO: should maybe be deleted later or added to the form const allCustomersToLink = this.state.selectedCustomers.concat(this.state.existingCustomers); - let customersToLink: Partial[] = allCustomersToLink.map((customer) => { + let customersToLink: Partial[] = allCustomersToLink.map((customer) => { return { customer: { uid: customer.value }, }; - }) as Partial[]; + }) as Partial[]; if (this.state.selectedOption === "new_customer") { const customer: Customer = await Customers.getInstance().post({ contact: values, }); if (!customer.uid) return; - customersToLink?.push({ customer: { uid: customer.uid } } as Partial); + customersToLink?.push({ customer: { uid: customer.uid } } as Partial); } if (customersToLink) { - const body = OfficeFolder.hydrate({ office_folder_has_customers: customersToLink.map((customer) => { - return OfficeFolderHasCustomer.hydrate(customer); - }) }); + const body = OfficeFolder.hydrate({ + customers: customersToLink.map((customer) => { + return Customer.hydrate(customer); + }), + }); await Folders.getInstance().put(this.props.selectedFolderUid, body); this.props.router.push(`/folders/${this.props.selectedFolderUid}`); diff --git a/src/front/Components/Layouts/Folder/AskDocuments/index.tsx b/src/front/Components/Layouts/Folder/AskDocuments/index.tsx index d360b6f5..eedec845 100644 --- a/src/front/Components/Layouts/Folder/AskDocuments/index.tsx +++ b/src/front/Components/Layouts/Folder/AskDocuments/index.tsx @@ -169,8 +169,8 @@ class AskDocumentsClass extends BasePage { .map((document) => { return document.document_type!.uid!; }); - const documentTypes = folder.deed!.deed_has_document_types!.filter((documentType) => { - if (userDocumentTypesUids.includes(documentType.document_type!.uid!)) return false; + const documentTypes = folder.deed!.document_types!.filter((documentType) => { + if (userDocumentTypesUids.includes(documentType!.uid!)) return false; return true; }); @@ -182,9 +182,9 @@ class AskDocumentsClass extends BasePage { }) .map((documentType) => { return { - label: documentType.document_type!.name!, - value: documentType.document_type!.uid!, - description: documentType.document_type!.private_description!, + label: documentType!.name!, + value: documentType!.uid!, + description: documentType!.private_description!, }; }); @@ -209,13 +209,11 @@ class AskDocumentsClass extends BasePage { public_description: this.state.visibleDescription, }); - const oldDocumentsType = this.state.folder?.deed?.deed_has_document_types!; + const oldDocumentsType = this.state.folder?.deed?.document_types!; await Deeds.getInstance().put(this.state.folder?.deed?.uid!, { - deed_has_document_types: [ + document_types: [ ...oldDocumentsType, - { - document_type: documentType, - }, + documentType, ], }); diff --git a/src/front/Components/Layouts/Folder/CreateFolder/index.tsx b/src/front/Components/Layouts/Folder/CreateFolder/index.tsx index bbae4b7b..4f30884c 100644 --- a/src/front/Components/Layouts/Folder/CreateFolder/index.tsx +++ b/src/front/Components/Layouts/Folder/CreateFolder/index.tsx @@ -13,7 +13,7 @@ import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Ty import BackArrow from "@Front/Components/Elements/BackArrow"; import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage"; import { ValidationError } from "class-validator"; -import { Deed, DeedType, Office, OfficeFolder, OfficeFolderHasStakeholder } from "le-coffre-resources/dist/Notary"; +import { Deed, DeedType, Office, OfficeFolder } from "le-coffre-resources/dist/Notary"; import User from "le-coffre-resources/dist/Notary"; import { NextRouter, useRouter } from "next/router"; import React from "react"; @@ -21,6 +21,7 @@ import { ActionMeta, MultiValue } from "react-select"; import BasePage from "../../Base"; import classes from "./classes.module.scss"; +import JwtService from "@Front/Services/JwtService/JwtService"; type IFormValues = { folder_number: string; @@ -150,7 +151,7 @@ class CreateFolderClass extends BasePage { } public override async componentDidMount() { - const deedTypes = await DeedTypes.getInstance().get({ q: {} }); + const deedTypes = await DeedTypes.getInstance().get(); // TODO SETUP userStore and get the user's office membership -> Replace IwJ70M471c by the user's office membership uid const usersMock = await Users.getInstance().get({ include: { office_membership: true } }); @@ -233,23 +234,19 @@ class CreateFolderClass extends BasePage { [key: string]: any; }, ) { + const officeId = JwtService.getInstance().decodeJwt()?.office_Id; const selectedDeedTypeUid: DeedType | undefined = this.state.deedTypes.find( (deedType) => deedType.uid === this.state.formValues.act_typ?.value, ); - /** - * MOCK DATA - */ - const usersMock = await Users.getInstance().get({ include: { office_membership: true } }); - const userMock = usersMock[0]; - - let stakeholders = this.getStakeholders(); - let testUsers = stakeholders.map((stakeholder) => ({ - user_stakeholder: { - uid: stakeholder.user_stakeholder.uid, - }, - })); - + let stakeholders = this.state.collaborators; + if (this.state.folder_access === "select_collaborators") { + stakeholders = this.state.collaborators.filter((collaborator) => { + return this.state.formValues.collaborators?.some((selectedCollaborator) => { + return selectedCollaborator.value === collaborator.uid; + }); + }); + } const officeFolderForm = OfficeFolder.hydrate({ folder_number: values["folder_number"], name: values["name"], @@ -260,15 +257,10 @@ class CreateFolderClass extends BasePage { }), }), office: Office.hydrate({ - uid: userMock?.office_membership?.uid, - }), - office_folder_has_stakeholder: testUsers.map((user) => { - return OfficeFolderHasStakeholder.hydrate({ - user_stakeholder: User.hydrate({ - uid: user.user_stakeholder.uid, - }), - }); + uid: officeId, }), + customers: [], + stakeholders, }); try { @@ -285,6 +277,7 @@ class CreateFolderClass extends BasePage { if (!newOfficeFolder) return; this.props.router.push(`/folders/${newOfficeFolder.uid}`); } catch (backError: any) { + if (!Array.isArray(backError)) return; this.setState({ validationError: backError as ValidationError[], }); @@ -313,25 +306,6 @@ class CreateFolderClass extends BasePage { folder_access: e.target.value, }); } - - private getStakeholders() { - let collaborators: User[] = this.state.collaborators; - - let office_folder_has_stakeholders = collaborators.map((collaborator) => { - return OfficeFolderHasStakeholder.hydrate({ - user_stakeholder: collaborator, - }); - }); - - if (this.state.folder_access === "select_collaborators") { - office_folder_has_stakeholders = office_folder_has_stakeholders.filter((collaborator) => { - return this.state.formValues.collaborators?.some((selectedCollaborator) => { - return selectedCollaborator.value === collaborator.user_stakeholder.uid; - }); - }); - } - return office_folder_has_stakeholders; - } } export default function CreateFolder(props: IProps): JSX.Element { diff --git a/src/front/Components/Layouts/Folder/FolderInformation/ClientSection/index.tsx b/src/front/Components/Layouts/Folder/FolderInformation/ClientSection/index.tsx index e95817f0..aa5f46b0 100644 --- a/src/front/Components/Layouts/Folder/FolderInformation/ClientSection/index.tsx +++ b/src/front/Components/Layouts/Folder/FolderInformation/ClientSection/index.tsx @@ -60,14 +60,14 @@ export default class ClientSection extends React.Component { } private renderCustomerFolders() { - const output = this.props.folder.office_folder_has_customers?.map((folderHasCustomer) => { - if (!folderHasCustomer.customer) return null; + const output = this.props.folder.customers?.map((customer) => { + if (!customer) return null; return ( ); @@ -83,7 +83,7 @@ export default class ClientSection extends React.Component { } private doesFolderHaveCustomer(): boolean { - if (!this.props.folder?.office_folder_has_customers) return false; - return this.props.folder?.office_folder_has_customers!.length > 0; + if (!this.props.folder?.customers) return false; + return this.props.folder?.customers!.length > 0; } } diff --git a/src/front/Components/Layouts/Folder/FolderInformation/index.tsx b/src/front/Components/Layouts/Folder/FolderInformation/index.tsx index cd91f829..4f335c3b 100644 --- a/src/front/Components/Layouts/Folder/FolderInformation/index.tsx +++ b/src/front/Components/Layouts/Folder/FolderInformation/index.tsx @@ -2,6 +2,7 @@ import ChevronIcon from "@Assets/Icons/chevron.svg"; import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders"; import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; import FolderBoxInformation, { EFolderBoxInformationType } from "@Front/Components/DesignSystem/FolderBoxInformation"; +import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField"; import Confirm from "@Front/Components/DesignSystem/Modal/Confirm"; import QuantityProgressBar from "@Front/Components/DesignSystem/QuantityProgressBar"; import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography"; @@ -16,7 +17,6 @@ import { ChangeEvent } from "react"; import BasePage from "../../Base"; import classes from "./classes.module.scss"; import ClientSection from "./ClientSection"; -import TextAreaField from "@Front/Components/DesignSystem/Form/TextareaField"; type IProps = {}; @@ -155,8 +155,8 @@ class FolderInformationClass extends BasePage { } private doesFolderHaveCustomer(): boolean { - if (!this.state.selectedFolder?.office_folder_has_customers) return false; - return this.state.selectedFolder?.office_folder_has_customers!.length > 0; + if (!this.state.selectedFolder?.customers) return false; + return this.state.selectedFolder?.customers!.length > 0; } private onSelectedFolder(folder: IDashBoardFolder): void { @@ -189,18 +189,14 @@ class FolderInformationClass extends BasePage { q: { deed: { include: { deed_type: true } }, office: true, - office_folder_has_customers: { + customers: { include: { - customer: { + contact: true, + documents: { include: { - contact: true, - documents: { - include: { - folder: true, - document_type: true, - files: true, - }, - }, + folder: true, + document_type: true, + files: true, }, }, }, diff --git a/src/front/Components/Layouts/Folder/UpdateFolderCollaborators/index.tsx b/src/front/Components/Layouts/Folder/UpdateFolderCollaborators/index.tsx index 25ce20ba..02f600ba 100644 --- a/src/front/Components/Layouts/Folder/UpdateFolderCollaborators/index.tsx +++ b/src/front/Components/Layouts/Folder/UpdateFolderCollaborators/index.tsx @@ -1,20 +1,20 @@ +import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders"; +import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users"; 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 RadioBox from "@Front/Components/DesignSystem/RadioBox"; import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; import BackArrow from "@Front/Components/Elements/BackArrow"; import DefaultNotaryDashboard, { IDashBoardFolder } from "@Front/Components/LayoutTemplates/DefaultNotaryDashboard"; -import BasePage from "../../Base"; -import classes from "./classes.module.scss"; +import Module from "@Front/Config/Module"; +import User from "le-coffre-resources/dist/Notary"; import Link from "next/link"; import { NextRouter, useRouter } from "next/router"; -import RadioBox from "@Front/Components/DesignSystem/RadioBox"; -import MultiSelect from "@Front/Components/DesignSystem/MultiSelect"; -import Module from "@Front/Config/Module"; -import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users"; -import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders"; -import { OfficeFolderHasStakeholder } from "le-coffre-resources/dist/Customer"; -import { IOption } from "@Front/Components/DesignSystem/Form/SelectField"; -import User from "le-coffre-resources/dist/Notary"; + +import BasePage from "../../Base"; +import classes from "./classes.module.scss"; type IPropsClass = { selectedFolderUid: string; @@ -104,13 +104,9 @@ class UpdateFolderCollaboratorsClass extends BasePage { const query = { q: { office: true, - office_folder_has_stakeholder: { + stakeholders: { include: { - user_stakeholder: { - include: { - contact: true, - }, - }, + contact: true, }, }, }, @@ -119,10 +115,10 @@ class UpdateFolderCollaboratorsClass extends BasePage { let folder = null; try { folder = await Folders.getInstance().getByUid(folderUid, query); - const preSelectedCollaborators: IOption[] = folder.office_folder_has_stakeholder!.map((collaborator) => { + const preSelectedCollaborators: IOption[] = folder.stakeholders!.map((collaborator) => { return { - label: collaborator.user_stakeholder.contact?.first_name + " " + collaborator.user_stakeholder.contact?.last_name, - value: collaborator.user_stakeholder.uid, + label: collaborator.contact?.first_name + " " + collaborator.contact?.last_name, + value: collaborator.uid, }; }); this.setState({ selectedCollaborators: preSelectedCollaborators }); @@ -173,17 +169,13 @@ class UpdateFolderCollaboratorsClass extends BasePage { private async onFormSubmit(e: React.FormEvent | null, values: { [key: string]: string }) { try { - let collaboratorsUid: OfficeFolderHasStakeholder[]; + let collaboratorsUid: User[] = this.state.availableCollaborators; if (this.state.selectedOption === ERadioBoxValue.SELECTION) { - collaboratorsUid = this.state.selectedCollaborators.map( - (collaborator) => ({ user_stakeholder: { uid: collaborator.value } } as OfficeFolderHasStakeholder), - ); - } else { - collaboratorsUid = this.state.availableCollaborators.map( - (collaborator) => ({ user_stakeholder: { uid: collaborator.uid } } as OfficeFolderHasStakeholder), + collaboratorsUid = this.state.selectedCollaborators.map((collaborator) => + User.hydrate({ uid: collaborator.value as string }), ); } - await Folders.getInstance().put(this.props.selectedFolderUid, { office_folder_has_stakeholder: collaboratorsUid }); + await Folders.getInstance().put(this.props.selectedFolderUid, { stakeholders: collaboratorsUid }); this.props.router.push( Module.getInstance() .get() diff --git a/src/front/Components/Layouts/Folder/UpdateFolderMetadata/index.tsx b/src/front/Components/Layouts/Folder/UpdateFolderMetadata/index.tsx index 3f480fe7..f1e2ca9a 100644 --- a/src/front/Components/Layouts/Folder/UpdateFolderMetadata/index.tsx +++ b/src/front/Components/Layouts/Folder/UpdateFolderMetadata/index.tsx @@ -12,6 +12,7 @@ import { NextRouter, useRouter } from "next/router"; import BasePage from "../../Base"; import classes from "./classes.module.scss"; +import { Deed, OfficeFolder } from "le-coffre-resources/dist/Notary"; type IProps = {}; @@ -88,7 +89,14 @@ class UpdateFolderMetadataClass extends BasePage { }, ) { try { - await Folders.getInstance().put(this.props.folderUid, values); + const newValues = OfficeFolder.hydrate({ + ...values, + deed: Deed.hydrate({ + uid: values["deed"], + }) + }); + + await Folders.getInstance().put(this.props.folderUid, newValues); const url = Module.getInstance() .get() .modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid); @@ -103,7 +111,7 @@ class UpdateFolderMetadataClass extends BasePage { q: { deed: { include: { deed_type: true } }, office: true, - office_folder_has_customers: { include: { customer: { include: { contact: true } } } }, + customers: { include: { contact: true } }, }, }; const folder = await Folders.getInstance().getByUid(this.props.folderUid, query); diff --git a/src/front/Components/Layouts/FolderArchived/FolderInformation/ClientSection/index.tsx b/src/front/Components/Layouts/FolderArchived/FolderInformation/ClientSection/index.tsx index 84eafba9..33143af1 100644 --- a/src/front/Components/Layouts/FolderArchived/FolderInformation/ClientSection/index.tsx +++ b/src/front/Components/Layouts/FolderArchived/FolderInformation/ClientSection/index.tsx @@ -40,14 +40,14 @@ export default class ClientSection extends React.Component { } private renderCustomerFolders() { - const output = this.props.folder.office_folder_has_customers?.map((folderHasCustomer) => { - if (!folderHasCustomer.customer) return null; + const output = this.props.folder.customers?.map((customer) => { + if (!customer) return null; return ( ); @@ -62,7 +62,7 @@ export default class ClientSection extends React.Component { } private doesFolderHaveCustomer(): boolean { - if (!this.props.folder?.office_folder_has_customers) return false; - return this.props.folder?.office_folder_has_customers!.length > 0; + if (!this.props.folder?.customers) return false; + return this.props.folder?.customers!.length > 0; } } diff --git a/src/front/Components/Layouts/FolderArchived/FolderInformation/index.tsx b/src/front/Components/Layouts/FolderArchived/FolderInformation/index.tsx index 99609888..e681b9da 100644 --- a/src/front/Components/Layouts/FolderArchived/FolderInformation/index.tsx +++ b/src/front/Components/Layouts/FolderArchived/FolderInformation/index.tsx @@ -108,7 +108,7 @@ class FolderInformationClass extends BasePage { } private doesFolderHaveCustomer(): boolean { - return this.state.selectedFolder?.office_folder_has_customers !== undefined; + return this.state.selectedFolder?.customers !== undefined; } private onSelectedFolder(folder: IDashBoardFolder): void { @@ -140,7 +140,7 @@ class FolderInformationClass extends BasePage { q: { deed: { include: { deed_type: "true" } }, office: "true", - office_folder_has_customers: { include: { customer: { include: { contact: true } } } }, + customers: { include: { contact: true } }, }, }; const folder = await Folders.getInstance().getByUid(this.props.selectedFolderUid, query); diff --git a/src/front/Components/Layouts/Login/index.tsx b/src/front/Components/Layouts/Login/index.tsx index d404a76e..59da4eb7 100644 --- a/src/front/Components/Layouts/Login/index.tsx +++ b/src/front/Components/Layouts/Login/index.tsx @@ -1,13 +1,15 @@ +import CoffreIcon from "@Assets/Icons/coffre.svg"; +// import { FrontendVariables } from "@Front/Config/VariablesFront"; +import idNoteLogo from "@Assets/Icons/id-note-logo.svg"; import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button"; import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; +import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage"; +import UserStore from "@Front/Stores/UserStore"; +import Image from "next/image"; + import BasePage from "../Base"; import classes from "./classes.module.scss"; -import CoffreIcon from "@Assets/Icons/coffre.svg"; import LandingImage from "./landing-connect.jpeg"; -import Image from "next/image"; -import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage"; -import { FrontendVariables } from "@Front/Config/VariablesFront"; -import idNoteLogo from "@Assets/Icons/id-note-logo.svg"; export default class LoginClass extends BasePage { public override render(): JSX.Element { @@ -30,12 +32,17 @@ export default class LoginClass extends BasePage { ); } - private redirectUserOnConnection() { - const variables = FrontendVariables.getInstance(); - const baseFronturl = variables.BACK_API_PROTOCOL + variables.FRONT_APP_HOST; - const authorizeEndPoint = variables.IDNOT_AUTHORIZE_ENDPOINT; - const clientId = variables.IDNOT_CLIENT_ID; - const url = `${authorizeEndPoint}?client_id=${clientId}&redirect_uri=${baseFronturl}/authorized-client&scope=openid,profile,offline_access&response_type=code`; - window.location.assign(url); + private async redirectUserOnConnection() { + // const variables = FrontendVariables.getInstance(); + // const baseFronturl = variables.BACK_API_PROTOCOL + variables.FRONT_APP_HOST; + + await UserStore.instance.connect(process.env["NEXT_PUBLIC_ADMIN_ID"] as string); + // await JwtService.getInstance().checkJwt(); + // window.location.assign("http://localhost:3000" + "/folders"); + + // const authorizeEndPoint = variables.IDNOT_AUTHORIZE_ENDPOINT; + // const clientId = variables.IDNOT_CLIENT_ID; + // const url = `${authorizeEndPoint}?client_id=${clientId}&redirect_uri=${baseFronturl}/authorized-client&scope=openid,profile,offline_access&response_type=code`; + // window.location.assign(url); } } diff --git a/src/front/Components/Layouts/Offices/OfficeInformations/classes.module.scss b/src/front/Components/Layouts/Offices/OfficeInformations/classes.module.scss new file mode 100644 index 00000000..403eb7ec --- /dev/null +++ b/src/front/Components/Layouts/Offices/OfficeInformations/classes.module.scss @@ -0,0 +1,114 @@ +@import "@Themes/constants.scss"; + +.root { + .header { + display: flex; + justify-content: space-between; + align-items: center; + + @media (max-width: $screen-s) { + flex-direction: column; + align-items: flex-start; + gap: 16px; + } + + .header-right { + display: flex; + align-items: center; + gap: 16px; + + .round { + width: 16px; + height: 16px; + background-color: var(--green-flash); + border-radius: 100px; + } + } + } + + .office-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); + } + + .office-infos-row { + display: flex; + flex-direction: column; + gap: 12px; + } + } + + .office-users { + .users { + .title { + margin-top: 32px; + } + + .users-container { + margin-top: 32px; + text-align: center; + + display: flex; + flex-direction: column; + gap: 24px; + + @media (max-width: $screen-l) { + text-align: left; + display: grid; + grid-template-columns: repeat(2, 1fr); + } + + @media (max-width: $screen-s) { + grid-template-columns: repeat(1, 1fr); + } + + .first-line, + .user-line-desktop { + display: grid; + grid-template-columns: repeat(5, 1fr); + padding: 24px; + background-color: var(--purple-soft); + + @media (max-width: $screen-l) { + display: none; + } + } + + .user-line-desktop { + background-color: var(--grey-soft); + } + + .user-line-desktop { + &:nth-child(odd) { + background-color: var(--grey-medium); + } + } + + .user-line-mobile { + display: none; + + @media (max-width: $screen-l) { + display: flex; + flex-direction: column; + gap: 24px; + background-color: var(--grey-soft); + padding: 24px 16px; + } + } + } + } + } +} diff --git a/src/front/Components/Layouts/Offices/OfficeInformations/index.tsx b/src/front/Components/Layouts/Offices/OfficeInformations/index.tsx new file mode 100644 index 00000000..9c55a60e --- /dev/null +++ b/src/front/Components/Layouts/Offices/OfficeInformations/index.tsx @@ -0,0 +1,193 @@ +import Offices from "@Front/Api/LeCoffreApi/SuperAdmin/Offices/Offices"; +import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Typography"; +import DefaultOfficeDashboard from "@Front/Components/LayoutTemplates/DefaultOfficeDashboard"; +import User, { Office } from "le-coffre-resources/dist/SuperAdmin"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; + +import classes from "./classes.module.scss"; + +type IProps = {}; +export default function OfficeInformations(props: IProps) { + const router = useRouter(); + let { officeUid } = router.query; + + const [officeSelected, setOfficeSelected] = useState(null); + + useEffect(() => { + async function getOffice() { + if (!officeUid) return; + const office = await Offices.getInstance().getByUid(officeUid as string, { + q: { + address: true, + users: { + include: { + role: true, + office_role: true, + contact: true, + }, + }, + }, + }); + if (!office) return; + setOfficeSelected(office); + } + + getOffice(); + }, [officeUid]); + + const renderUser = (user: User) => ( + <> +
+ {user.contact?.last_name} + {user.contact?.first_name} + {user.contact?.email} + {user.contact?.phone_number} + {user.office_role ? user.office_role?.name : user.role?.name} +
+
+
+ + Nom + + {user.contact?.last_name} +
+
+ + Prénom + + {user.contact?.first_name} +
+
+ + E-mail pro + + {user.contact?.email} +
+
+ + Numéro de téléphone + + {user.contact?.phone_number} +
+
+ + Rôle + + {user.office_role ? user.office_role?.name : user.role?.name} +
+
+ + ); + return ( + +
+
+ Office {officeSelected?.crpcen + " - " + officeSelected?.name} +
+
+ Office active +
+
+
+
+ + CRPCEN + + {officeSelected?.crpcen} +
+
+ + Dénomination + + {officeSelected?.name} +
+
+ + Addresse + + + {officeSelected?.address?.address} - {officeSelected?.address?.city} {officeSelected?.address?.zip_code} + +
+
+
+
+
+ Administrateurs +
+
+
+ + Nom + + + Prénom + + + E-mail pro + + + Numéro de téléphone + + + Rôle + +
+ {officeSelected?.users + ?.filter((user) => { + if (user.office_role && user.office_role.name === "admin") { + return true; + } + if (!user.office_role && user.role?.name === "admin") { + return true; + } + return false; + }) + .map((user) => { + return renderUser(user); + })} +
+
+
+
+ Collaborateurs +
+
+
+ + Nom + + + Prénom + + + E-mail pro + + + Numéro de téléphone + + + Rôle + +
+ {officeSelected?.users + ?.filter((user) => { + if (user.office_role && user.office_role.name !== "admin") { + return true; + } + if (!user.office_role && user.role?.name !== "admin") { + return true; + } + return false; + }) + .map((user) => { + return renderUser(user); + })} +
+
+
+
+ + ); +} diff --git a/src/front/Components/Layouts/Offices/classes.module.scss b/src/front/Components/Layouts/Offices/classes.module.scss new file mode 100644 index 00000000..a425a01a --- /dev/null +++ b/src/front/Components/Layouts/Offices/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/Offices/index.tsx b/src/front/Components/Layouts/Offices/index.tsx new file mode 100644 index 00000000..67ba24fc --- /dev/null +++ b/src/front/Components/Layouts/Offices/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 DefaultOfficeDashboard from "@Front/Components/LayoutTemplates/DefaultOfficeDashboard"; + +type IProps = {}; +type IState = {}; +export default class Offices extends BasePage { + public override render(): JSX.Element { + return ( + +
+
+ Informations des offices +
+ + Sélectionnez une office + +
+
+
+
+ ); + } +} 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/Components/Layouts/Users/UserInformations/classes.module.scss b/src/front/Components/Layouts/Users/UserInformations/classes.module.scss new file mode 100644 index 00000000..2bac3ec5 --- /dev/null +++ b/src/front/Components/Layouts/Users/UserInformations/classes.module.scss @@ -0,0 +1,81 @@ +@import "@Themes/constants.scss"; + +.root { + .header { + display: flex; + align-items: flex-end; + gap: 24px; + + @media (max-width: $screen-s) { + flex-direction: column; + align-items: flex-start; + gap: 16px; + } + } + + .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; + + display: flex; + gap: 32px; + + @media (max-width: $screen-m) { + flex-direction: column; + } + + .part { + flex: 1; + .first-line { + display: flex; + justify-content: space-between; + } + .second-line { + margin-top: 32px; + display: flex; + gap: 16px; + flex-direction: column; + + .votes-block { + align-items: center; + display: flex; + gap: 16px; + background-color: var(--orange-soft); + border: 1px solid #e7e7e7; + border-radius: 5px; + padding: 16px; + } + } + } + .third-line { + margin-top: 32px; + } + } +} diff --git a/src/front/Components/Layouts/Users/UserInformations/index.tsx b/src/front/Components/Layouts/Users/UserInformations/index.tsx new file mode 100644 index 00000000..02a9b43b --- /dev/null +++ b/src/front/Components/Layouts/Users/UserInformations/index.tsx @@ -0,0 +1,141 @@ +import WarningIcon from "@Assets/images/warning.png"; +import OfficeRoles from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles"; +import Users from "@Front/Api/LeCoffreApi/SuperAdmin/Users/Users"; +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 DefaultUserDashboard from "@Front/Components/LayoutTemplates/DefaultUserDashboard"; +import User from "le-coffre-resources/dist/Notary"; +import Image from "next/image"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; + +import classes from "./classes.module.scss"; + +type IProps = {}; +export default function UserInformations(props: IProps) { + const router = useRouter(); + let { userUid } = router.query; + + const [userSelected, setUserSelected] = useState(null); + const [availableRoles, setAvailableRoles] = useState([]); + + useEffect(() => { + async function getUser() { + if (!userUid) return; + const user = await Users.getInstance().getByUid(userUid as string, { + q: { + contact: true, + office_role: true, + office_membership: true, + 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(); + }, [userUid]); + + return ( + +
+
+ {userSelected?.contact?.first_name + " " + userSelected?.contact?.last_name} + + Office {userSelected?.office_membership?.name.toLocaleUpperCase()} + +
+
+
+ + 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} +
+
+ +
+
+
+ Rôle au sein de son office +
+
+ +
+
+
+
+ Attribuer un titre +
+
+ + +
+
+ warning +
+
+
+ 1/3 +
+
+ + Vous avez voté pour attribuer le titre de Super Admin. Il manque 2 votes pour que le + collaborateur se voit attribuer le titre. + +
+
+
+
+
+
+
+
+ ); +} diff --git a/src/front/Components/Layouts/Users/classes.module.scss b/src/front/Components/Layouts/Users/classes.module.scss new file mode 100644 index 00000000..a425a01a --- /dev/null +++ b/src/front/Components/Layouts/Users/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/Users/index.tsx b/src/front/Components/Layouts/Users/index.tsx new file mode 100644 index 00000000..c686a669 --- /dev/null +++ b/src/front/Components/Layouts/Users/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 DefaultUserDashboard from "@Front/Components/LayoutTemplates/DefaultUserDashboard"; + +type IProps = {}; +type IState = {}; +export default class Users extends BasePage { + public override render(): JSX.Element { + return ( + +
+
+ Informations des utilisateurs +
+ + Sélectionnez un utilisateur + +
+
+
+
+ ); + } +} diff --git a/src/front/Config/Module/development.json b/src/front/Config/Module/development.json index 740f6ee9..3dde562b 100644 --- a/src/front/Config/Module/development.json +++ b/src/front/Config/Module/development.json @@ -119,6 +119,130 @@ "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" + } + } + } + }, + "Users": { + "enabled": true, + "props": { + "path": "/users", + "labelKey": "users" + }, + "pages": { + "UsersInformations": { + "enabled": true, + "props": { + "path": "/users/[uid]", + "labelKey": "users_informations" + } + } + } + }, + "Offices": { + "enabled": true, + "props": { + "path": "/offices", + "labelKey": "offices" + }, + "pages": { + "OfficesInformations": { + "enabled": true, + "props": { + "path": "/offices/[uid]", + "labelKey": "offices_informations" + } + } + } + }, + "DocumentTypes": { + "enabled": true, + "props": { + "path": "/document-types", + "labelKey": "documentTypes" + }, + "pages": { + "DocumentTypesInformations": { + "enabled": true, + "props": { + "path": "/document-types/[uid]", + "labelKey": "documentInformations" + } + }, + "Create": { + "enabled": true, + "props": { + "path": "/document-types/create", + "labelKey": "createDocumentType" + } + }, + "Edit": { + "enabled": true, + "props": { + "path": "/document-types/[uid]/edit", + "labelKey": "editDocumentType" + } + } + } + }, "404": { "enabled": true, "props": { diff --git a/src/front/Config/Module/preprod.json b/src/front/Config/Module/preprod.json index 740f6ee9..8540ba0d 100644 --- a/src/front/Config/Module/preprod.json +++ b/src/front/Config/Module/preprod.json @@ -119,6 +119,100 @@ "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" + } + } + } + }, + "Users": { + "enabled": true, + "props": { + "path": "/users", + "labelKey": "users" + }, + "pages": { + "UsersInformations": { + "enabled": true, + "props": { + "path": "/users/[uid]", + "labelKey": "users_informations" + } + } + } + }, + "Offices": { + "enabled": true, + "props": { + "path": "/offices", + "labelKey": "offices" + }, + "pages": { + "OfficesInformations": { + "enabled": true, + "props": { + "path": "/offices/[uid]", + "labelKey": "offices_informations" + } + } + } + }, "404": { "enabled": true, "props": { diff --git a/src/front/Config/Module/production.json b/src/front/Config/Module/production.json index 740f6ee9..8540ba0d 100644 --- a/src/front/Config/Module/production.json +++ b/src/front/Config/Module/production.json @@ -119,6 +119,100 @@ "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" + } + } + } + }, + "Users": { + "enabled": true, + "props": { + "path": "/users", + "labelKey": "users" + }, + "pages": { + "UsersInformations": { + "enabled": true, + "props": { + "path": "/users/[uid]", + "labelKey": "users_informations" + } + } + } + }, + "Offices": { + "enabled": true, + "props": { + "path": "/offices", + "labelKey": "offices" + }, + "pages": { + "OfficesInformations": { + "enabled": true, + "props": { + "path": "/offices/[uid]", + "labelKey": "offices_informations" + } + } + } + }, "404": { "enabled": true, "props": { diff --git a/src/front/Config/Module/staging.json b/src/front/Config/Module/staging.json index 740f6ee9..8540ba0d 100644 --- a/src/front/Config/Module/staging.json +++ b/src/front/Config/Module/staging.json @@ -119,6 +119,100 @@ "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" + } + } + } + }, + "Users": { + "enabled": true, + "props": { + "path": "/users", + "labelKey": "users" + }, + "pages": { + "UsersInformations": { + "enabled": true, + "props": { + "path": "/users/[uid]", + "labelKey": "users_informations" + } + } + } + }, + "Offices": { + "enabled": true, + "props": { + "path": "/offices", + "labelKey": "offices" + }, + "pages": { + "OfficesInformations": { + "enabled": true, + "props": { + "path": "/offices/[uid]", + "labelKey": "offices_informations" + } + } + } + }, "404": { "enabled": true, "props": { diff --git a/src/front/Config/VariablesFront.ts b/src/front/Config/VariablesFront.ts index b2d11b4f..76f85149 100644 --- a/src/front/Config/VariablesFront.ts +++ b/src/front/Config/VariablesFront.ts @@ -11,8 +11,6 @@ export class FrontendVariables { public FRONT_APP_HOST!: string; - public FRONT_APP_PORT!: string; - public IDNOT_AUTHORIZE_ENDPOINT!: string; public IDNOT_CLIENT_ID!: string; diff --git a/src/front/Services/CookieService/CookieService.ts b/src/front/Services/CookieService/CookieService.ts new file mode 100644 index 00000000..0f2f33cc --- /dev/null +++ b/src/front/Services/CookieService/CookieService.ts @@ -0,0 +1,44 @@ +export default class CookieService { + private static instance: CookieService; + private constructor() {} + + public static getInstance() { + return (this.instance ??= new this()); + } + + /** + * @description : set a cookie with a name and a value that expire in 7 days + * @throws {Error} If the name or the value is empty + */ + public setCookie(name: string, value: string) { + if (!name || !value) throw new Error("Cookie name or value is empty"); + const date = new Date(); + + // Set it expire in 7 days + date.setTime(date.getTime() + 7 * 24 * 60 * 60 * 1000); + + // Set it + document.cookie = name + "=" + value + "; expires=" + date.toUTCString() + "; path=/"; + } + + public getCookie(name: string) { + const value = "; " + document.cookie; + const parts = value.split("; " + name + "="); + + if (parts.length == 2) { + return parts.pop()!.split(";").shift(); + } + + return; + } + + public deleteCookie(name: string) { + const date = new Date(); + + // Set it expire in -1 days + date.setTime(date.getTime() + -1 * 24 * 60 * 60 * 1000); + + // Set it + document.cookie = name + "=; expires=" + date.toUTCString() + "; path=/"; + } +} diff --git a/src/front/Services/JwtService/JwtService.ts b/src/front/Services/JwtService/JwtService.ts new file mode 100644 index 00000000..66db5c7c --- /dev/null +++ b/src/front/Services/JwtService/JwtService.ts @@ -0,0 +1,56 @@ +import jwt_decode from "jwt-decode"; +import CookieService from "../CookieService/CookieService"; +import User from "@Front/Api/Auth/IdNot/User"; + +enum PROVIDER_OPENID { + idNot = "idNot", +} + +interface IUserJwtPayload { + userId: string; + openId: { + providerName: PROVIDER_OPENID; + userId: string | number; + }; + office_Id: string; + role: string; + rules: string[]; + exp: number; +} + +export default class JwtService { + private static instance: JwtService; + private constructor() {} + + public static getInstance() { + return (this.instance ??= new this()); + } + + public decodeJwt(): IUserJwtPayload | undefined { + const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken"); + if (!accessToken) return; + return jwt_decode(accessToken); + } + + /** + * @description : set a cookie with a name and a value that expire in 7 days + * @throws {Error} If the name or the value is empty + */ + public async checkJwt() { + const decodedToken = this.decodeJwt(); + if(!decodedToken) return; + + const now = Math.floor(Date.now() / 1000); + + if (decodedToken.exp < now) { + const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken"); + + if (!refreshToken) return; + const newAccessToken: { accessToken: string } = await User.getInstance().refreshToken(refreshToken); + + if (newAccessToken) { + CookieService.getInstance().setCookie("leCoffreAccessToken", newAccessToken.accessToken); + } + } + } +} diff --git a/src/front/Stores/UserStore.ts b/src/front/Stores/UserStore.ts new file mode 100644 index 00000000..c4bf3a1a --- /dev/null +++ b/src/front/Stores/UserStore.ts @@ -0,0 +1,57 @@ +"use client"; + +import User from "@Front/Api/Auth/IdNot/User"; +import CookieService from "@Front/Services/CookieService/CookieService"; +import EventEmitter from "@Front/Services/EventEmitter"; + +export default class UserStore { + public static readonly instance = new this(); + protected readonly event = new EventEmitter(); + public accessToken: string | null = null; + public refreshToken: string | null = null; + + private constructor() {} + + public isConnected(): boolean { + return !!this.accessToken; + } + + public async connect(idnotUid: string) { + try { + //call connection function + const user: any = await User.getInstance().login(idnotUid); + + //Save tokens in cookies + CookieService.getInstance().setCookie("leCoffreAccessToken", user.accessToken); + CookieService.getInstance().setCookie("leCoffreRefreshToken", user.refreshToken); + + this.event.emit("connection", this.accessToken); + } catch (error) { + console.error(error); + return false; + } + return true; + } + + public async disconnect() { + try { + //Remove tokens from cookies + CookieService.getInstance().deleteCookie("leCoffreAccessToken"); + CookieService.getInstance().deleteCookie("leCoffreRefreshToken"); + + this.event.emit("disconnection", this.accessToken); + } catch (error) { + console.error(error); + } + } + + public onDisconnect(callback: (userAddress: string) => void): () => void { + this.event.on("disconnection", callback); + return () => this.event.off("disconnection", callback); + } + + public onConnect(callback: (userAddress: string) => void): () => void { + this.event.on("connection", callback); + return () => this.event.off("connection", callback); + } +} diff --git a/src/front/Themes/constants.scss b/src/front/Themes/constants.scss index dea3df9f..647f82b3 100644 --- a/src/front/Themes/constants.scss +++ b/src/front/Themes/constants.scss @@ -1,5 +1,5 @@ // $screen-xl: 2559px; -$screen-l: 1440px; +$screen-l: 1439px; $screen-ls: 1280px; $screen-m: 1023px; $screen-s: 767px; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index c45d2226..40cfb752 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -17,7 +17,6 @@ type AppPropsWithLayout = AppProps & { backApiRootUrl: string; backApiVersion: string; frontAppHost: string; - frontAppPort: string; idNotAuthorizeEndpoint: string; idNotClientId: string; fcAuthorizeEndpoint: string; @@ -32,7 +31,6 @@ const MyApp = (({ backApiRootUrl, backApiVersion, frontAppHost, - frontAppPort, idNotAuthorizeEndpoint, idNotClientId, fcAuthorizeEndpoint, @@ -46,7 +44,6 @@ const MyApp = (({ instance.BACK_API_ROOT_URL = backApiRootUrl ?? "/api"; instance.BACK_API_VERSION = backApiVersion ?? "/v1"; instance.FRONT_APP_HOST = frontAppHost ?? "app.stg.lecoffre.smart-chain.fr"; - instance.FRONT_APP_PORT = frontAppPort ?? "3000"; instance.IDNOT_AUTHORIZE_ENDPOINT = idNotAuthorizeEndpoint ?? "https://qual-connexion.idnot.fr/IdPOAuth2/authorize/idnot_idp_v1"; instance.IDNOT_CLIENT_ID = idNotClientId ?? "4501646203F3EF67"; instance.FC_AUTHORIZE_ENDPOINT= fcAuthorizeEndpoint ?? "https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize"; 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/design-system.tsx b/src/pages/design-system.tsx deleted file mode 100644 index d3835570..00000000 --- a/src/pages/design-system.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import DesignSystem from "@Front/Components/Layouts/DesignSystem"; - -export default function Route() { - return ; -} diff --git a/src/pages/document-types/[documentTypeUid]/edit/index.tsx b/src/pages/document-types/[documentTypeUid]/edit/index.tsx new file mode 100644 index 00000000..744ab0ef --- /dev/null +++ b/src/pages/document-types/[documentTypeUid]/edit/index.tsx @@ -0,0 +1,5 @@ +import DocumentTypesEdit from "@Front/Components/Layouts/DocumentTypes/DocumentTypesEdit"; + +export default function Route() { + return ; +} diff --git a/src/pages/document-types/[documentTypeUid]/index.tsx b/src/pages/document-types/[documentTypeUid]/index.tsx new file mode 100644 index 00000000..df5aca44 --- /dev/null +++ b/src/pages/document-types/[documentTypeUid]/index.tsx @@ -0,0 +1,5 @@ +import DocumentTypesInformations from "@Front/Components/Layouts/DocumentTypes/DocumentTypesInformations"; + +export default function Route() { + return ; +} diff --git a/src/pages/document-types/create/index.tsx b/src/pages/document-types/create/index.tsx new file mode 100644 index 00000000..cb5dc311 --- /dev/null +++ b/src/pages/document-types/create/index.tsx @@ -0,0 +1,5 @@ +import DocumentTypesCreate from "@Front/Components/Layouts/DocumentTypes/DocumentTypesCreate"; + +export default function Route() { + return ; +} diff --git a/src/pages/document-types/index.tsx b/src/pages/document-types/index.tsx new file mode 100644 index 00000000..95347545 --- /dev/null +++ b/src/pages/document-types/index.tsx @@ -0,0 +1,5 @@ +import DocumentTypes from "@Front/Components/Layouts/DocumentTypes"; + +export default function Route() { + return ; +} diff --git a/src/pages/offices/[officeUid]/index.tsx b/src/pages/offices/[officeUid]/index.tsx new file mode 100644 index 00000000..5fcacb34 --- /dev/null +++ b/src/pages/offices/[officeUid]/index.tsx @@ -0,0 +1,5 @@ +import OfficeInformations from "@Front/Components/Layouts/Offices/OfficeInformations"; + +export default function Route() { + return ; +} diff --git a/src/pages/offices/index.tsx b/src/pages/offices/index.tsx new file mode 100644 index 00000000..a65bfe0e --- /dev/null +++ b/src/pages/offices/index.tsx @@ -0,0 +1,5 @@ +import Offices from "@Front/Components/Layouts/Offices"; + +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 ; +} diff --git a/src/pages/users/[userUid]/index.tsx b/src/pages/users/[userUid]/index.tsx new file mode 100644 index 00000000..6886fefb --- /dev/null +++ b/src/pages/users/[userUid]/index.tsx @@ -0,0 +1,5 @@ +import UserInformations from "@Front/Components/Layouts/Users/UserInformations"; + +export default function Route() { + return ; +} diff --git a/src/pages/users/index.tsx b/src/pages/users/index.tsx new file mode 100644 index 00000000..579670dd --- /dev/null +++ b/src/pages/users/index.tsx @@ -0,0 +1,5 @@ +import Users from "@Front/Components/Layouts/Users"; + +export default function Route() { + return ; +}