diff --git a/.eslintrc.js b/.eslintrc.js
index b1a39d9..2295461 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,47 +1,47 @@
// eslint-disable-next-line no-undef
module.exports = {
- env: {
- browser: true,
- es2021: true
- },
- extends: [
- // 'standard',
- 'eslint:recommended',
- //'plugin:@eslint-community/eslint-comments/recommended',
- //'plugin:@typescript-eslint/recommended',
- //'plugin:import/recommended',
- //'plugin:import/typescript',
- //'plugin:promise/recommended',
- //'plugin:security/recommended-legacy',
- 'plugin:react/recommended',
- ],
- parserOptions: {
- ecmaVersion: 'latest',
- parser: '@typescript-eslint/parser',
- sourceType: 'module',
- },
- plugins: [
- //'@typescript-eslint',
- //'import',
- //'promise',
- //'security',
- //'no-catch-all',
- 'react',
- 'react-hooks',
- ],
- settings: {
- //'import/resolver': {
- // typescript: true,
- // node: true,
- //},
- 'react': {
- 'version': 'detect'
- }
- },
- rules: {
- 'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks
- 'react-hooks/exhaustive-deps': 'warn', // Checks effect dependencies
- 'react/react-in-jsx-scope': 'off' // Disable requirement for React import
+ env: {
+ browser: true,
+ es2021: true
+ },
+ extends: [
+ 'standard',
+ 'eslint:recommended',
+ // 'plugin:@eslint-community/eslint-comments/recommended',
+ // 'plugin:@typescript-eslint/recommended',
+ // 'plugin:import/recommended',
+ // 'plugin:import/typescript',
+ // 'plugin:promise/recommended',
+ // 'plugin:security/recommended-legacy',
+ 'plugin:react/recommended'
+ ],
+ parserOptions: {
+ ecmaVersion: 'latest',
+ parser: '@typescript-eslint/parser',
+ sourceType: 'module'
+ },
+ plugins: [
+ // '@typescript-eslint',
+ // 'import',
+ // 'promise',
+ // 'security',
+ // 'no-catch-all',
+ 'react',
+ 'react-hooks'
+ ],
+ settings: {
+ // 'import/resolver': {
+ // typescript: true,
+ // node: true,
+ // },
+ react: {
+ version: 'detect'
+ }
+ },
+ rules: {
+ 'react-hooks/rules-of-hooks': 'error', // Checks rules of Hooks
+ 'react-hooks/exhaustive-deps': 'warn', // Checks effect dependencies
+ 'react/react-in-jsx-scope': 'off' // Disable requirement for React import
// 'no-catch-all/no-catch-all': 'error',
// 'no-console': 'error',
// 'no-debugger': 'error',
@@ -135,78 +135,78 @@ module.exports = {
// 'promise/valid-params': 'warn',
// 'promise/prefer-await-to-callbacks': 'error',
// 'promise/no-multiple-resolved': 'error',
+ },
+ overrides: [
+ {
+ files: ['*.ts', '*.tsx'],
+ parser: '@typescript-eslint/parser'
+ // parserOptions: {
+ // tsconfigRootDir: __dirname,
+ // project: ['./tsconfig.json', '**/tsconfig.json'],
+ // ecmaVersion: 'latest',
+ // parser: '@typescript-eslint/parser',
+ // sourceType: 'module',
+ // },
+ // plugins: ['@typescript-eslint'],
+ // extends: [
+ // 'plugin:@typescript-eslint/recommended',
+ // 'plugin:@typescript-eslint/recommended-requiring-type-checking',
+ // 'plugin:@typescript-eslint/strict',
+ // ],
+ // rules: {
+ // // allow explicitly defined dangling promises
+ // '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
+ // 'no-void': ['error', { allowAsStatement: true }],
+ // },
+ // },
+ // {
+ // files: ['!*.json'],
+ // plugins: ['prettier'],
+ // extends: ['plugin:prettier/recommended'],
+ // rules: {
+ // 'prettier/prettier': 'error',
+ // },
},
- overrides: [
- {
- files: ['*.ts', '*.tsx'],
- parser: '@typescript-eslint/parser',
- // parserOptions: {
- // tsconfigRootDir: __dirname,
- // project: ['./tsconfig.json', '**/tsconfig.json'],
- // ecmaVersion: 'latest',
- // parser: '@typescript-eslint/parser',
- // sourceType: 'module',
- // },
- // plugins: ['@typescript-eslint'],
- // extends: [
- // 'plugin:@typescript-eslint/recommended',
- // 'plugin:@typescript-eslint/recommended-requiring-type-checking',
- // 'plugin:@typescript-eslint/strict',
- // ],
- // rules: {
- // // allow explicitly defined dangling promises
- // '@typescript-eslint/no-floating-promises': ['error', { ignoreVoid: true }],
- // 'no-void': ['error', { allowAsStatement: true }],
- // },
- // },
- // {
- // files: ['!*.json'],
- // plugins: ['prettier'],
- // extends: ['plugin:prettier/recommended'],
- // rules: {
- // 'prettier/prettier': 'error',
- // },
- },
- {
- files: ['*.json'],
- plugins: ['json'],
- extends: ['plugin:json/recommended-with-comments'],
- },
- // {
- // files: ['*.{test,spec}.[tj]s'],
- // plugins: ['vitest'],
- // extends: ['plugin:vitest/all'],
- // rules: {
- // 'vitest/prefer-lowercase-title': 'off',
- // 'vitest/no-hooks': 'off',
- // 'vitest/consistent-test-filename': 'off',
- // 'vitest/prefer-expect-assertions': [
- // 'off',
- // {
- // onlyFunctionsWithExpectInLoop: true,
- // onlyFunctionsWithExpectInCallback: true,
- // },
- // ],
- // 'vitest/prefer-strict-equal': 'off',
- // 'vitest/prefer-to-be-falsy': 'off',
- // 'vitest/prefer-to-be-truthy': 'off',
- // 'vitest/require-hook': [
- // 'error',
- // {
- // allowedFunctionCalls: [
- // 'mockClient.setRequestHandler',
- // 'setActivePinia',
- // 'provideApolloClient',
- // ],
- // },
- // ],
- // },
- // },
- {
- files: ['*.yaml', '*.yml'],
- parser: 'yaml-eslint-parser',
- plugins: ['yml'],
- extends: ['plugin:yml/prettier'],
- },
- ],
+ {
+ files: ['*.json'],
+ plugins: ['json'],
+ extends: ['plugin:json/recommended-with-comments']
+ },
+ // {
+ // files: ['*.{test,spec}.[tj]s'],
+ // plugins: ['vitest'],
+ // extends: ['plugin:vitest/all'],
+ // rules: {
+ // 'vitest/prefer-lowercase-title': 'off',
+ // 'vitest/no-hooks': 'off',
+ // 'vitest/consistent-test-filename': 'off',
+ // 'vitest/prefer-expect-assertions': [
+ // 'off',
+ // {
+ // onlyFunctionsWithExpectInLoop: true,
+ // onlyFunctionsWithExpectInCallback: true,
+ // },
+ // ],
+ // 'vitest/prefer-strict-equal': 'off',
+ // 'vitest/prefer-to-be-falsy': 'off',
+ // 'vitest/prefer-to-be-truthy': 'off',
+ // 'vitest/require-hook': [
+ // 'error',
+ // {
+ // allowedFunctionCalls: [
+ // 'mockClient.setRequestHandler',
+ // 'setActivePinia',
+ // 'provideApolloClient',
+ // ],
+ // },
+ // ],
+ // },
+ // },
+ {
+ files: ['*.yaml', '*.yml'],
+ parser: 'yaml-eslint-parser',
+ plugins: ['yml'],
+ extends: ['plugin:yml/prettier']
+ }
+ ]
}
diff --git a/package-lock.json b/package-lock.json
index a76f35e..c0efde4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -39,6 +39,7 @@
"autoprefixer": "^10.4.14",
"daisyui": "^4.6.1",
"eslint": "^8.24.0",
+ "eslint-config-standard": "^17.1.0",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-react": "^7.31.8",
"eslint-plugin-react-hooks": "^4.6.0",
@@ -67,6 +68,37 @@
"node": ">=0.10.0"
}
},
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
+ "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
"node_modules/@eslint/eslintrc": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz",
@@ -90,21 +122,6 @@
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "13.17.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
- "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
- "dev": true,
- "dependencies": {
- "type-fest": "^0.20.2"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/@heroicons/react": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.0.18.tgz",
@@ -263,6 +280,14 @@
"node": ">=14.0.0"
}
},
+ "node_modules/@rtsao/scc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
+ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/@tanstack/query-core": {
"version": "5.17.8",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.17.8.tgz",
@@ -337,6 +362,14 @@
"integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
"dev": true
},
+ "node_modules/@types/json5": {
+ "version": "0.0.29",
+ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
+ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
"node_modules/@types/leaflet": {
"version": "1.7.11",
"resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.7.11.tgz",
@@ -695,16 +728,35 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
+ "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.5",
+ "is-array-buffer": "^3.0.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/array-includes": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz",
- "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==",
+ "version": "3.1.8",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz",
+ "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.19.5",
- "get-intrinsic": "^1.1.1",
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.4",
"is-string": "^1.0.7"
},
"engines": {
@@ -723,15 +775,58 @@
"node": ">=8"
}
},
+ "node_modules/array.prototype.findlastindex": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz",
+ "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-shim-unscopables": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
+ "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "es-shim-unscopables": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/array.prototype.flatmap": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz",
- "integrity": "sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz",
+ "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
"es-shim-unscopables": "^1.0.0"
},
"engines": {
@@ -741,6 +836,29 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
+ "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.1",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.22.3",
+ "es-errors": "^1.2.1",
+ "get-intrinsic": "^1.2.3",
+ "is-array-buffer": "^3.0.4",
+ "is-shared-array-buffer": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -779,6 +897,22 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+ "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/axios": {
"version": "1.7.7",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
@@ -865,14 +999,60 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/builtin-modules": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
+ "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/builtins": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.1.0.tgz",
+ "integrity": "sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "semver": "^7.0.0"
+ }
+ },
+ "node_modules/builtins/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
+ "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -1305,6 +1485,60 @@
"url": "https://opencollective.com/daisyui"
}
},
+ "node_modules/data-view-buffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+ "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+ "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/data-view-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
+ "is-data-view": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/date-fns": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.3.1.tgz",
@@ -1356,12 +1590,32 @@
"node": ">=0.10.0"
}
},
- "node_modules/define-properties": {
+ "node_modules/define-data-property": {
"version": "1.1.4",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
- "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+ "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
+ "define-data-property": "^1.0.1",
"has-property-descriptors": "^1.0.0",
"object-keys": "^1.1.1"
},
@@ -1513,35 +1767,58 @@
}
},
"node_modules/es-abstract": {
- "version": "1.20.3",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.3.tgz",
- "integrity": "sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw==",
+ "version": "1.23.3",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
+ "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
+ "array-buffer-byte-length": "^1.0.1",
+ "arraybuffer.prototype.slice": "^1.0.3",
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "data-view-buffer": "^1.0.1",
+ "data-view-byte-length": "^1.0.1",
+ "data-view-byte-offset": "^1.0.0",
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0",
+ "es-set-tostringtag": "^2.0.3",
"es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
- "function.prototype.name": "^1.1.5",
- "get-intrinsic": "^1.1.3",
- "get-symbol-description": "^1.0.0",
- "has": "^1.0.3",
- "has-property-descriptors": "^1.0.0",
+ "function.prototype.name": "^1.1.6",
+ "get-intrinsic": "^1.2.4",
+ "get-symbol-description": "^1.0.2",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2",
+ "has-proto": "^1.0.3",
"has-symbols": "^1.0.3",
- "internal-slot": "^1.0.3",
- "is-callable": "^1.2.6",
- "is-negative-zero": "^2.0.2",
+ "hasown": "^2.0.2",
+ "internal-slot": "^1.0.7",
+ "is-array-buffer": "^3.0.4",
+ "is-callable": "^1.2.7",
+ "is-data-view": "^1.0.1",
+ "is-negative-zero": "^2.0.3",
"is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
+ "is-shared-array-buffer": "^1.0.3",
"is-string": "^1.0.7",
+ "is-typed-array": "^1.1.13",
"is-weakref": "^1.0.2",
- "object-inspect": "^1.12.2",
+ "object-inspect": "^1.13.1",
"object-keys": "^1.1.1",
- "object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.4.3",
- "safe-regex-test": "^1.0.0",
- "string.prototype.trimend": "^1.0.5",
- "string.prototype.trimstart": "^1.0.5",
- "unbox-primitive": "^1.0.2"
+ "object.assign": "^4.1.5",
+ "regexp.prototype.flags": "^1.5.2",
+ "safe-array-concat": "^1.1.2",
+ "safe-regex-test": "^1.0.3",
+ "string.prototype.trim": "^1.2.9",
+ "string.prototype.trimend": "^1.0.8",
+ "string.prototype.trimstart": "^1.0.8",
+ "typed-array-buffer": "^1.0.2",
+ "typed-array-byte-length": "^1.0.1",
+ "typed-array-byte-offset": "^1.0.2",
+ "typed-array-length": "^1.0.6",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.15"
},
"engines": {
"node": ">= 0.4"
@@ -1550,13 +1827,65 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/es-shim-unscopables": {
+ "node_modules/es-define-property": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
- "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+ "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has": "^1.0.3"
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
+ "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
+ "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-shim-unscopables": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
+ "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.0"
}
},
"node_modules/es-to-primitive": {
@@ -1681,6 +2010,173 @@
"node": ">=10"
}
},
+ "node_modules/eslint-config-standard": {
+ "version": "17.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz",
+ "integrity": "sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^8.0.1",
+ "eslint-plugin-import": "^2.25.2",
+ "eslint-plugin-n": "^15.0.0 || ^16.0.0 ",
+ "eslint-plugin-promise": "^6.0.0"
+ }
+ },
+ "node_modules/eslint-import-resolver-node": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
+ "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "debug": "^3.2.7",
+ "is-core-module": "^2.13.0",
+ "resolve": "^1.22.4"
+ }
+ },
+ "node_modules/eslint-import-resolver-node/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
+ "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "debug": "^3.2.7"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-es-x": {
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz",
+ "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/ota-meshi",
+ "https://opencollective.com/eslint"
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.1.2",
+ "@eslint-community/regexpp": "^4.11.0",
+ "eslint-compat-utils": "^0.5.1"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=8"
+ }
+ },
+ "node_modules/eslint-plugin-import": {
+ "version": "2.31.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz",
+ "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@rtsao/scc": "^1.1.0",
+ "array-includes": "^3.1.8",
+ "array.prototype.findlastindex": "^1.2.5",
+ "array.prototype.flat": "^1.3.2",
+ "array.prototype.flatmap": "^1.3.2",
+ "debug": "^3.2.7",
+ "doctrine": "^2.1.0",
+ "eslint-import-resolver-node": "^0.3.9",
+ "eslint-module-utils": "^2.12.0",
+ "hasown": "^2.0.2",
+ "is-core-module": "^2.15.1",
+ "is-glob": "^4.0.3",
+ "minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.8",
+ "object.groupby": "^1.0.3",
+ "object.values": "^1.2.0",
+ "semver": "^6.3.1",
+ "string.prototype.trimend": "^1.0.8",
+ "tsconfig-paths": "^3.15.0"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/eslint-plugin-json": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-3.1.0.tgz",
@@ -1695,6 +2191,67 @@
"node": ">=12.0"
}
},
+ "node_modules/eslint-plugin-n": {
+ "version": "16.6.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-16.6.2.tgz",
+ "integrity": "sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "builtins": "^5.0.1",
+ "eslint-plugin-es-x": "^7.5.0",
+ "get-tsconfig": "^4.7.0",
+ "globals": "^13.24.0",
+ "ignore": "^5.2.4",
+ "is-builtin-module": "^3.2.1",
+ "is-core-module": "^2.12.1",
+ "minimatch": "^3.1.2",
+ "resolve": "^1.22.2",
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mysticatea"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-n/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/eslint-plugin-promise": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz",
+ "integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0"
+ }
+ },
"node_modules/eslint-plugin-react": {
"version": "7.31.8",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.8.tgz",
@@ -1837,12 +2394,16 @@
}
},
"node_modules/eslint-visitor-keys": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
- "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
+ "license": "Apache-2.0",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint/node_modules/ansi-styles": {
@@ -1929,21 +2490,6 @@
"node": ">=10.13.0"
}
},
- "node_modules/eslint/node_modules/globals": {
- "version": "13.17.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
- "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
- "dev": true,
- "dependencies": {
- "type-fest": "^0.20.2"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/eslint/node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -2224,6 +2770,16 @@
}
}
},
+ "node_modules/for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
@@ -2283,20 +2839,25 @@
}
},
"node_modules/function-bind": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/function.prototype.name": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz",
- "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==",
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
+ "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.0",
- "functions-have-names": "^1.2.2"
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.22.1",
+ "functions-have-names": "^1.2.3"
},
"engines": {
"node": ">= 0.4"
@@ -2324,27 +2885,35 @@
}
},
"node_modules/get-intrinsic": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
- "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
+ "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "function-bind": "^1.1.1",
- "has": "^1.0.3",
- "has-symbols": "^1.0.3"
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "hasown": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-symbol-description": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
- "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
+ "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.1"
+ "call-bind": "^1.0.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4"
},
"engines": {
"node": ">= 0.4"
@@ -2353,6 +2922,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/get-tsconfig": {
+ "version": "4.8.1",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
+ "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -2384,6 +2967,39 @@
"node": ">= 6"
}
},
+ "node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globalthis": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+ "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/globby": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
@@ -2413,6 +3029,19 @@
"node": ">=8"
}
},
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/graceful-fs": {
"version": "4.2.10",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
@@ -2425,17 +3054,6 @@
"integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
"dev": true
},
- "node_modules/has": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
- "dependencies": {
- "function-bind": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
- },
"node_modules/has-bigints": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
@@ -2455,12 +3073,26 @@
}
},
"node_modules/has-property-descriptors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
- "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "get-intrinsic": "^1.1.1"
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+ "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -2479,12 +3111,13 @@
}
},
"node_modules/has-tostringtag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
- "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "has-symbols": "^1.0.2"
+ "has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
@@ -2493,6 +3126,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/hast-util-to-jsx-runtime": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz",
@@ -2559,10 +3204,11 @@
}
},
"node_modules/ignore": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
- "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 4"
}
@@ -2645,13 +3291,14 @@
"integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ=="
},
"node_modules/internal-slot": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
- "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
+ "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "get-intrinsic": "^1.1.0",
- "has": "^1.0.3",
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.0",
"side-channel": "^1.0.4"
},
"engines": {
@@ -2672,12 +3319,29 @@
"resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
"integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
"dependencies": {
- "is-alphabetical": "^2.0.0",
- "is-decimal": "^2.0.0"
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-array-buffer": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
+ "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-bigint": {
@@ -2719,6 +3383,23 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-builtin-module": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
+ "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "builtin-modules": "^3.3.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/is-callable": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
@@ -2732,11 +3413,31 @@
}
},
"node_modules/is-core-module": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
- "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
+ "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-view": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
+ "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
+ "dev": true,
+ "license": "MIT",
"dependencies": {
- "has": "^1.0.3"
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -2795,10 +3496,11 @@
}
},
"node_modules/is-negative-zero": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
- "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+ "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">= 0.4"
},
@@ -2845,6 +3547,7 @@
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
"integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"call-bind": "^1.0.2",
"has-tostringtag": "^1.0.0"
@@ -2857,12 +3560,16 @@
}
},
"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",
- "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2"
+ "call-bind": "^1.0.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -2898,6 +3605,22 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-typed-array": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
+ "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "which-typed-array": "^1.1.14"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "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",
@@ -2910,6 +3633,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -2959,6 +3689,20 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
+ "node_modules/json5": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "minimist": "^1.2.0"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ }
+ },
"node_modules/jsonc-parser": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
@@ -3783,6 +4527,17 @@
"node": "*"
}
},
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -3885,10 +4640,14 @@
}
},
"node_modules/object-inspect": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
- "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
+ "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
"dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -3903,13 +4662,14 @@
}
},
"node_modules/object.assign": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz",
- "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
+ "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
+ "call-bind": "^1.0.5",
+ "define-properties": "^1.2.1",
"has-symbols": "^1.0.3",
"object-keys": "^1.1.1"
},
@@ -3935,14 +4695,16 @@
}
},
"node_modules/object.fromentries": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz",
- "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
+ "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -3951,6 +4713,22 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/object.groupby": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
+ "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/object.hasown": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.1.tgz",
@@ -3965,14 +4743,15 @@
}
},
"node_modules/object.values": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz",
- "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
+ "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.1"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -4208,6 +4987,16 @@
"node": ">=8"
}
},
+ "node_modules/possible-typed-array-names": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+ "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -5064,14 +5853,16 @@
}
},
"node_modules/regexp.prototype.flags": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
- "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz",
+ "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "functions-have-names": "^1.2.2"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-errors": "^1.3.0",
+ "set-function-name": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -5138,11 +5929,12 @@
}
},
"node_modules/resolve": {
- "version": "1.22.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
- "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "license": "MIT",
"dependencies": {
- "is-core-module": "^2.9.0",
+ "is-core-module": "^2.13.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
@@ -5162,6 +5954,17 @@
"node": ">=8"
}
},
+ "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==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "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",
@@ -5338,6 +6141,25 @@
"queue-microtask": "^1.2.2"
}
},
+ "node_modules/safe-array-concat": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+ "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "get-intrinsic": "^1.2.4",
+ "has-symbols": "^1.0.3",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/safe-identifier": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz",
@@ -5345,15 +6167,19 @@
"dev": true
},
"node_modules/safe-regex-test": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
- "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
+ "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
+ "call-bind": "^1.0.6",
+ "es-errors": "^1.3.0",
"is-regex": "^1.1.4"
},
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -5375,6 +6201,40 @@
"semver": "bin/semver.js"
}
},
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-function-name": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+ "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "functions-have-names": "^1.2.3",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -5468,29 +6328,53 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
+ "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-abstract": "^1.23.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/string.prototype.trimend": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz",
- "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
+ "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.19.5"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/string.prototype.trimstart": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz",
- "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==",
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+ "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.1.4",
- "es-abstract": "^1.19.5"
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -5521,6 +6405,17 @@
"node": ">=8"
}
},
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -5761,6 +6656,20 @@
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
},
+ "node_modules/tsconfig-paths": {
+ "version": "3.15.0",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
+ "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/json5": "^0.0.29",
+ "json5": "^1.0.2",
+ "minimist": "^1.2.6",
+ "strip-bom": "^3.0.0"
+ }
+ },
"node_modules/tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
@@ -5878,6 +6787,83 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
+ "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+ "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
+ "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
+ "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-proto": "^1.0.3",
+ "is-typed-array": "^1.1.13",
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/typescript": {
"version": "4.7.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
@@ -6153,6 +7139,26 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/which-typed-array": {
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
+ "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.7",
+ "call-bind": "^1.0.7",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/word-wrap": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
diff --git a/package.json b/package.json
index cbab64a..5b585e0 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,7 @@
"autoprefixer": "^10.4.14",
"daisyui": "^4.6.1",
"eslint": "^8.24.0",
+ "eslint-config-standard": "^17.1.0",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-react": "^7.31.8",
"eslint-plugin-react-hooks": "^4.6.0",
diff --git a/postcss.config.js b/postcss.config.js
index 3bf778b..a3f5603 100644
--- a/postcss.config.js
+++ b/postcss.config.js
@@ -1,8 +1,7 @@
// eslint-disable-next-line no-undef
module.exports = {
- plugins: {
- tailwindcss: {},
- autoprefixer: {},
- }
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {}
}
-
\ No newline at end of file
+}
diff --git a/rollup.config.js b/rollup.config.js
index 30cd35a..e868bf4 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -2,21 +2,21 @@ import postcss from 'rollup-plugin-postcss'
import typescript from 'rollup-plugin-typescript2'
export default {
- input: 'src/index.tsx',
- output: [
- {
- dir: 'dist/',
- format: 'esm',
- exports: 'named',
- sourcemap: true,
- strict: false
- }
- ],
- plugins: [
- postcss({
- plugins: []
- }),
- typescript(),
- ],
- external: ['react', 'react-dom', 'leaflet', 'react-leaflet', 'react-toastify' , 'react-string-replace', 'react-toastify/dist/ReactToastify.css','tw-elements' ,'react-router-dom', 'react-leaflet-cluster', '@tanstack/react-query', 'tributejs', 'prop-types', 'leaflet/dist/leaflet.css', '@heroicons/react/20/solid']
- }
\ No newline at end of file
+ input: 'src/index.tsx',
+ output: [
+ {
+ dir: 'dist/',
+ format: 'esm',
+ exports: 'named',
+ sourcemap: true,
+ strict: false
+ }
+ ],
+ plugins: [
+ postcss({
+ plugins: []
+ }),
+ typescript()
+ ],
+ external: ['react', 'react-dom', 'leaflet', 'react-leaflet', 'react-toastify', 'react-string-replace', 'react-toastify/dist/ReactToastify.css', 'tw-elements', 'react-router-dom', 'react-leaflet-cluster', '@tanstack/react-query', 'tributejs', 'prop-types', 'leaflet/dist/leaflet.css', '@heroicons/react/20/solid']
+}
diff --git a/src/Components/AppShell/AppShell.tsx b/src/Components/AppShell/AppShell.tsx
index c388d92..be31706 100644
--- a/src/Components/AppShell/AppShell.tsx
+++ b/src/Components/AppShell/AppShell.tsx
@@ -2,11 +2,10 @@ import * as React from 'react'
import NavBar from './NavBar'
import { SetAssetsApi } from './SetAssetsApi'
import { AssetsApi } from '../../types'
-import { ContextWrapper } from './ContextWrapper';
+import { ContextWrapper } from './ContextWrapper'
-
-export function AppShell({ appName, children, assetsApi, userType }: { appName: string, children: React.ReactNode, assetsApi: AssetsApi, userType: string }) {
- return (
+export function AppShell ({ appName, children, assetsApi, userType }: { appName: string, children: React.ReactNode, assetsApi: AssetsApi, userType: string }) {
+ return (
@@ -16,5 +15,5 @@ export function AppShell({ appName, children, assetsApi, userType }: { appName:
- )
+ )
}
diff --git a/src/Components/AppShell/Content.tsx b/src/Components/AppShell/Content.tsx
index 3631f58..f462518 100644
--- a/src/Components/AppShell/Content.tsx
+++ b/src/Components/AppShell/Content.tsx
@@ -4,7 +4,7 @@ type ContentProps = {
children?: React.ReactNode;
}
-export function Content({children} : ContentProps) {
+export function Content ({ children } : ContentProps) {
return (
{children}
diff --git a/src/Components/AppShell/ContextWrapper.tsx b/src/Components/AppShell/ContextWrapper.tsx
index 0146822..ddb5469 100644
--- a/src/Components/AppShell/ContextWrapper.tsx
+++ b/src/Components/AppShell/ContextWrapper.tsx
@@ -10,24 +10,23 @@ import { PermissionsProvider } from '../Map/hooks/usePermissions'
import { SelectPositionProvider } from '../Map/hooks/useSelectPosition'
import { TagsProvider } from '../Map/hooks/useTags'
import { AssetsProvider } from './hooks/useAssets'
-import { useContext, createContext } from 'react';
-import { BrowserRouter as Router, useLocation } from 'react-router-dom';
-
+import { useContext, createContext } from 'react'
+import { BrowserRouter as Router, useLocation } from 'react-router-dom'
// Helper context to determine if the ContextWrapper is already present.
-const ContextCheckContext = createContext(false);
+const ContextCheckContext = createContext(false)
// eslint-disable-next-line react/prop-types
export const ContextWrapper = ({ children }) => {
- const isWrapped = useContext(ContextCheckContext);
+ const isWrapped = useContext(ContextCheckContext)
// Check if we are already inside a Router
- let location;
+ let location
try {
// eslint-disable-next-line react-hooks/rules-of-hooks
- location = useLocation();
+ location = useLocation()
} catch (e) {
- location = null;
+ location = null
}
// Case 1: Only the Router is missing, but ContextWrapper is already provided
@@ -36,7 +35,7 @@ export const ContextWrapper = ({ children }) => {
{children}
- );
+ )
}
// Case 2: Neither Router nor ContextWrapper is present
@@ -49,7 +48,7 @@ export const ContextWrapper = ({ children }) => {
- );
+ )
}
// Case 3: Only ContextWrapper is missing
@@ -58,16 +57,16 @@ export const ContextWrapper = ({ children }) => {
{children}
- );
+ )
}
// Case 4: Both Router and ContextWrapper are already present
- return children;
-};
+ return children
+}
// eslint-disable-next-line react/prop-types
export const Wrappers = ({ children }) => {
- const queryClient = new QueryClient();
+ const queryClient = new QueryClient()
return (
@@ -103,5 +102,5 @@ export const Wrappers = ({ children }) => {
- );
-};
\ No newline at end of file
+ )
+}
diff --git a/src/Components/AppShell/NavBar.tsx b/src/Components/AppShell/NavBar.tsx
index e09be0c..d276e3f 100644
--- a/src/Components/AppShell/NavBar.tsx
+++ b/src/Components/AppShell/NavBar.tsx
@@ -1,72 +1,64 @@
-import { useAuth } from "../Auth"
-import { Link, useLocation } from "react-router-dom";
-import { toast } from "react-toastify";
+import { useAuth } from '../Auth'
+import { Link, useLocation } from 'react-router-dom'
+import { toast } from 'react-toastify'
import QuestionMarkIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon'
-import { useEffect, useRef, useState } from "react";
-import { useItems } from "../Map/hooks/useItems";
-import { Item } from "../../types";
+import { useEffect, useRef, useState } from 'react'
+import { useItems } from '../Map/hooks/useItems'
+import { Item } from '../../types'
+export default function NavBar ({ appName, userType }: { appName: string, userType: string }) {
+ const { isAuthenticated, user, logout } = useAuth()
-export default function NavBar({ appName, userType}: { appName: string, userType: string }) {
-
-
- const { isAuthenticated, user, logout } = useAuth();
-
- const [userProfile, setUserProfile] = useState
- ({}as Item);
- const items = useItems();
+ const [userProfile, setUserProfile] = useState
- ({}as Item)
+ const items = useItems()
useEffect(() => {
- const profile = user && items.find(i => (i.user_created?.id === user.id) && i.layer?.itemType.name === userType);
- profile ? setUserProfile(profile) : setUserProfile({id: crypto.randomUUID(), name: user?.first_name, text: ""});
+ const profile = user && items.find(i => (i.user_created?.id === user.id) && i.layer?.itemType.name === userType)
+ profile ? setUserProfile(profile) : setUserProfile({ id: crypto.randomUUID(), name: user?.first_name, text: '' })
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [user, items])
useEffect(() => {
-
- }, [userProfile])
-
- const nameRef = useRef(null);
- const [nameWidth, setNameWidth] = useState(0);
- const location = useLocation();
- const [showNav, setShowNav] = useState(false)
+ }, [userProfile])
+ const nameRef = useRef(null)
+ const [nameWidth, setNameWidth] = useState(0)
+ const location = useLocation()
+ const [showNav, setShowNav] = useState(false)
useEffect(() => {
- showNav && nameRef && setNameWidth(nameRef.current.scrollWidth)
+ showNav && nameRef && setNameWidth(nameRef.current.scrollWidth)
}, [nameRef, appName, showNav])
-
-
-
useEffect(() => {
- const params = new URLSearchParams(location.search);
- const embedded = params.get("embedded");
- embedded!="true" && setShowNav(true)
- }, [location]);
-
+ const params = new URLSearchParams(location.search)
+ const embedded = params.get('embedded')
+ embedded !== 'true' && setShowNav(true)
+ }, [location])
const onLogout = () => {
toast.promise(
logout(),
{
success: {
- render() {
- return `Bye bye`
+ render () {
+ return 'Bye bye'
},
// other options
- icon: "π",
+ icon: 'π'
},
error: {
- render( {data} ) {
+ render ({ data }) {
return `${data}`
- },
+ }
},
pending: 'logging out ..'
- });
+ })
}
- if(showNav) return (
+ if (showNav) {
+ return (
<>
-
-
{appName}
+
+
{appName}
-
-
- {isAuthenticated ?
-
-
+ {isAuthenticated
+ ?
+
{ userProfile?.image &&
-
+
}
-
{userProfile.name||user?.first_name}
+
{userProfile.name || user?.first_name}
- :
-
+ :
-
+
Login
-
@@ -126,11 +115,10 @@ export default function NavBar({ appName, userType}: { appName: string, userType
-
- - Login
- - Sign Up
+ - Login
+ - Sign Up
@@ -139,6 +127,6 @@ export default function NavBar({ appName, userType}: { appName: string, userType
>
- )
- else return (<>>)
+ )
+ } else return (<>>)
}
diff --git a/src/Components/AppShell/SetAssetsApi.tsx b/src/Components/AppShell/SetAssetsApi.tsx
index 410d306..e4874d4 100644
--- a/src/Components/AppShell/SetAssetsApi.tsx
+++ b/src/Components/AppShell/SetAssetsApi.tsx
@@ -1,15 +1,14 @@
import { useSetAssetApi } from './hooks/useAssets'
-import { AssetsApi } from '../../types';
-import { useEffect } from 'react';
+import { AssetsApi } from '../../types'
+import { useEffect } from 'react'
-export const SetAssetsApi = ({assetsApi}:{assetsApi: AssetsApi}) => {
- const setAssetsApi = useSetAssetApi();
+export const SetAssetsApi = ({ assetsApi }:{assetsApi: AssetsApi}) => {
+ const setAssetsApi = useSetAssetApi()
- useEffect(() => {
- setAssetsApi(assetsApi)
+ useEffect(() => {
+ setAssetsApi(assetsApi)
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [assetsApi])
-
+ }, [assetsApi])
return (
<>>
diff --git a/src/Components/AppShell/SideBar.tsx b/src/Components/AppShell/SideBar.tsx
index 7b1754c..d4509e0 100644
--- a/src/Components/AppShell/SideBar.tsx
+++ b/src/Components/AppShell/SideBar.tsx
@@ -1,13 +1,12 @@
-import { useRef, useState } from 'react'
-import { useEffect } from 'react'
-import { NavLink, useLocation } from 'react-router-dom';
+import { useRef, useState, useEffect } from 'react'
+import { NavLink, useLocation } from 'react-router-dom'
import {
Sidenav,
- initTE,
-} from "tw-elements";
-import SidebarSubmenu from './SidebarSubmenu';
-import ChevronRightIcon from '@heroicons/react/24/outline/ChevronRightIcon';
-import * as React from 'react';
+ initTE
+} from 'tw-elements'
+import SidebarSubmenu from './SidebarSubmenu'
+import ChevronRightIcon from '@heroicons/react/24/outline/ChevronRightIcon'
+import * as React from 'react'
type route = {
path: string;
@@ -18,53 +17,46 @@ type route = {
blank?: boolean
}
-
-export function SideBar({ routes, bottomRoutes }: { routes: route[], bottomRoutes?: route[] }) {
-
+export function SideBar ({ routes, bottomRoutes }: { routes: route[], bottomRoutes?: route[] }) {
// prevent react18 from calling useEffect twice
const init = useRef(false)
- const location = useLocation();
-
- const [instance, setInstance] = useState
(null);
- const [slim, setSlim] = useState(false);
-
+ const location = useLocation()
+ const [instance, setInstance] = useState(null)
+ const [slim, setSlim] = useState(false)
const toggleSlim = () => {
- setSlim(!slim);
- instance.toggleSlim();
+ setSlim(!slim)
+ instance.toggleSlim()
}
-
-
useEffect(() => {
if (!init.current) {
- initTE({ Sidenav });
+ initTE({ Sidenav })
const instance = Sidenav.getInstance(
- document.getElementById("sidenav")
- );
- setInstance(instance);
- instance.toggleSlim();
- init.current = true;
+ document.getElementById('sidenav')
+ )
+ setInstance(instance)
+ instance.toggleSlim()
+ init.current = true
}
}, [])
const [embedded, setEmbedded] = useState(true)
-
useEffect(() => {
- const params = new URLSearchParams(location.search);
- const embedded = params.get("embedded");
- embedded != "true" && setEmbedded(false)
- }, [location]);
+ const params = new URLSearchParams(location.search)
+ const embedded = params.get('embedded')
+ embedded !== 'true' && setEmbedded(false)
+ }, [location])
- const params = new URLSearchParams(window.location.search);
+ const params = new URLSearchParams(window.location.search)
return (
- )
+ )
}
-
diff --git a/src/Components/Auth/RequestPasswordPage.tsx b/src/Components/Auth/RequestPasswordPage.tsx
index 6fb4786..6eaa828 100644
--- a/src/Components/Auth/RequestPasswordPage.tsx
+++ b/src/Components/Auth/RequestPasswordPage.tsx
@@ -2,39 +2,38 @@ import { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { toast } from 'react-toastify'
import { useAuth } from './useAuth'
-import { MapOverlayPage} from '../Templates'
+import { MapOverlayPage } from '../Templates'
// eslint-disable-next-line react/prop-types
-export function RequestPasswordPage({reset_url}) {
+export function RequestPasswordPage ({ resetUrl }) {
+ const [email, setEmail] = useState
('')
- const [email, setEmail] = useState("");
+ const { requestPasswordReset, loading } = useAuth()
- const { requestPasswordReset, loading } = useAuth();
+ const navigate = useNavigate()
- const navigate = useNavigate();
+ const onReset = async () => {
+ await toast.promise(
+ requestPasswordReset(email, resetUrl),
+ {
+ success: {
+ render () {
+ navigate('/')
+ return 'Check your mailbox'
+ },
+ // other options
+ icon: 'π¬'
+ },
+ error: {
+ render ({ data }) {
+ return `${data}`
+ }
+ },
+ pending: 'sending email ...'
+ })
+ }
- const onReset = async () => {
- await toast.promise(
- requestPasswordReset( email, reset_url),
- {
- success: {
- render() {
- navigate(`/`);
- return `Check your mailbox`
- },
- // other options
- icon: "π¬",
- },
- error: {
- render({ data }) {
- return `${data}`
- },
- },
- pending: 'sending email ...'
- });
- }
-
- return (
+ return (
Reset Password
setEmail(e.target.value)} className="tw-input tw-input-bordered tw-w-full tw-max-w-xs" />
@@ -42,6 +41,5 @@ export function RequestPasswordPage({reset_url}) {
- )
+ )
}
-
diff --git a/src/Components/Auth/SetNewPasswordPage.tsx b/src/Components/Auth/SetNewPasswordPage.tsx
index d746b24..d62a700 100644
--- a/src/Components/Auth/SetNewPasswordPage.tsx
+++ b/src/Components/Auth/SetNewPasswordPage.tsx
@@ -3,39 +3,38 @@ import { useNavigate } from 'react-router-dom'
import { toast } from 'react-toastify'
import { useAuth } from './useAuth'
-import { MapOverlayPage} from '../Templates'
-
-export function SetNewPasswordPage() {
-
- const [password, setPassword] = useState
("");
-
- const { passwordReset, loading } = useAuth();
-
- const navigate = useNavigate();
-
- const onReset = async () => {
- const token = window.location.search.split("token=")[1];
- console.log(token);
-
- await toast.promise(
- passwordReset(token, password),
- {
- success: {
- render() {
- navigate(`/`);
- return `New password set`
- },
- },
- error: {
- render({ data }) {
- return `${data}`
- },
- },
- pending: 'setting password ...'
- });
- }
-
- return (
+import { MapOverlayPage } from '../Templates'
+
+export function SetNewPasswordPage () {
+ const [password, setPassword] = useState('')
+
+ const { passwordReset, loading } = useAuth()
+
+ const navigate = useNavigate()
+
+ const onReset = async () => {
+ const token = window.location.search.split('token=')[1]
+ console.log(token)
+
+ await toast.promise(
+ passwordReset(token, password),
+ {
+ success: {
+ render () {
+ navigate('/')
+ return 'New password set'
+ }
+ },
+ error: {
+ render ({ data }) {
+ return `${data}`
+ }
+ },
+ pending: 'setting password ...'
+ })
+ }
+
+ return (
Set new Password
setPassword(e.target.value)} className="tw-input tw-input-bordered tw-w-full tw-max-w-xs" />
@@ -43,6 +42,5 @@ export function SetNewPasswordPage() {
- )
+ )
}
-
diff --git a/src/Components/Auth/SignupPage.tsx b/src/Components/Auth/SignupPage.tsx
index 810afce..48ef2a1 100644
--- a/src/Components/Auth/SignupPage.tsx
+++ b/src/Components/Auth/SignupPage.tsx
@@ -5,55 +5,53 @@ import { toast } from 'react-toastify'
import { useAuth } from './useAuth'
import { MapOverlayPage } from '../Templates'
-export function SignupPage() {
+export function SignupPage () {
+ const [email, setEmail] = useState
('')
+ const [userName, setUserName] = useState('')
- const [email, setEmail] = useState("");
- const [userName, setUserName] = useState("");
+ const [password, setPassword] = useState('')
- const [password, setPassword] = useState("");
+ const { register, loading } = useAuth()
- const { register, loading } = useAuth();
+ const navigate = useNavigate()
- const navigate = useNavigate();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ const onRegister = async () => {
+ await toast.promise(
+ register({ email, password }, userName),
+ {
+ success: {
+ render ({ data }) {
+ navigate('/')
+ return `Hi ${data?.first_name}`
+ },
+ // other options
+ icon: 'βοΈ'
+ },
+ error: {
+ render ({ data }) {
+ return `${data}`
+ },
+ autoClose: 10000
+ },
+ pending: 'creating new user ...'
+ })
+ }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- const onRegister = async () => {
- await toast.promise(
- register({ email: email, password: password }, userName),
- {
- success: {
- render({ data }) {
- navigate(`/`);
- return `Hi ${data?.first_name}`
- },
- // other options
- icon: "βοΈ",
- },
- error: {
- render({ data }) {
- return `${data}`
- },
- autoClose: 10000,
- },
- pending: 'creating new user ...'
- });
+ useEffect(() => {
+ const keyDownHandler = event => {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ onRegister()
+ }
}
+ document.addEventListener('keydown', keyDownHandler)
+ return () => {
+ document.removeEventListener('keydown', keyDownHandler)
+ }
+ }, [onRegister])
- useEffect(() => {
- const keyDownHandler = event => {
- if (event.key === 'Enter') {
- event.preventDefault();
- onRegister();
- }
- };
- document.addEventListener('keydown', keyDownHandler);
- return () => {
- document.removeEventListener('keydown', keyDownHandler);
- };
- }, [onRegister]);
-
-
- return (
+ return (
Sign Up
setUserName(e.target.value)} className="tw-input tw-input-bordered tw-w-full tw-max-w-xs" />
@@ -63,6 +61,5 @@ export function SignupPage() {
- )
+ )
}
-
diff --git a/src/Components/Auth/index.tsx b/src/Components/Auth/index.tsx
index 1e3aee6..2a53f98 100644
--- a/src/Components/Auth/index.tsx
+++ b/src/Components/Auth/index.tsx
@@ -1,5 +1,5 @@
-export {AuthProvider, useAuth} from "./useAuth"
-export {LoginPage} from "./LoginPage"
-export {SignupPage} from './SignupPage'
-export {RequestPasswordPage} from './RequestPasswordPage'
-export {SetNewPasswordPage} from './SetNewPasswordPage'
\ No newline at end of file
+export { AuthProvider, useAuth } from './useAuth'
+export { LoginPage } from './LoginPage'
+export { SignupPage } from './SignupPage'
+export { RequestPasswordPage } from './RequestPasswordPage'
+export { SetNewPasswordPage } from './SetNewPasswordPage'
diff --git a/src/Components/Auth/useAuth.tsx b/src/Components/Auth/useAuth.tsx
index b181737..2139d2b 100644
--- a/src/Components/Auth/useAuth.tsx
+++ b/src/Components/Auth/useAuth.tsx
@@ -1,7 +1,6 @@
-import { createContext, useState, useContext, useEffect } from "react";
-import * as React from "react";
-import { UserApi, UserItem } from "../../types";
-
+import { createContext, useState, useContext, useEffect } from 'react'
+import * as React from 'react'
+import { UserApi, UserItem } from '../../types'
type AuthProviderProps = {
userApi: UserApi,
@@ -14,8 +13,6 @@ type AuthCredentials = {
otp?: string | undefined;
}
-
-
type AuthContextProps = {
isAuthenticated: boolean,
user: UserItem | null;
@@ -37,130 +34,123 @@ type AuthContextProps = {
const AuthContext = createContext
({
isAuthenticated: false,
user: null,
- login: () => Promise.reject(),
- register: () => Promise.reject(),
+ login: () => Promise.reject(Error('Unimplemented')),
+ register: () => Promise.reject(Error('Unimplemented')),
loading: false,
- logout: () => Promise.reject(),
- updateUser: () => Promise.reject(),
- token: "",
- requestPasswordReset: () => Promise.reject(),
- passwordReset: () => Promise.reject()
-});
+ logout: () => Promise.reject(Error('Unimplemented')),
+ updateUser: () => Promise.reject(Error('Unimplemented')),
+ token: '',
+ requestPasswordReset: () => Promise.reject(Error('Unimplemented')),
+ passwordReset: () => Promise.reject(Error('Unimplemented'))
+})
export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
- const [user, setUser] = useState(null);
- const [token, setToken] = useState(null);
- const [loading, setLoading] = useState(false);
- const isAuthenticated = !!user;
+ const [user, setUser] = useState(null)
+ const [token, setToken] = useState(null)
+ const [loading, setLoading] = useState(false)
+ const isAuthenticated = !!user
useEffect(() => {
- setLoading(true);
- loadUser();
+ setLoading(true)
+ loadUser()
setLoading(false)
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
+ }, [])
- async function loadUser(): Promise {
+ async function loadUser (): Promise {
try {
- const token = await userApi.getToken();
- setToken(token);
- if(token){
- const me = await userApi.getUser();
- setUser(me as UserItem);
- setLoading(false);
- return me as UserItem;
- }
- else return undefined;
-
+ const token = await userApi.getToken()
+ setToken(token)
+ if (token) {
+ const me = await userApi.getUser()
+ setUser(me as UserItem)
+ setLoading(false)
+ return me as UserItem
+ } else return undefined
} catch (error) {
setLoading(false)
- return undefined;
+ return undefined
}
}
-
const login = async (credentials: AuthCredentials): Promise => {
- setLoading(true);
+ setLoading(true)
try {
- const res = await userApi.login(credentials.email, credentials.password);
- setToken(res.access_token);
- return (await loadUser());
+ const res = await userApi.login(credentials.email, credentials.password)
+ setToken(res.access_token)
+ return (await loadUser())
} catch (error: any) {
- setLoading(false);
- throw error;
+ setLoading(false)
+ throw error
}
}
const register = async (credentials: AuthCredentials, userName): Promise => {
- setLoading(true);
+ setLoading(true)
try {
/* const res = */ await userApi.register(credentials.email, credentials.password, userName)
- return (await login(credentials));
+ return (await login(credentials))
} catch (error: any) {
- setLoading(false);
- throw error;
+ setLoading(false)
+ throw error
}
}
-
const logout = async () => {
try {
- await userApi.logout();
- setUser(null);
+ await userApi.logout()
+ setUser(null)
} catch (error: any) {
- setLoading(false);
- throw error;
+ setLoading(false)
+ throw error
}
}
const updateUser = async (user: UserItem) => {
- setLoading(true);
+ setLoading(true)
// eslint-disable-next-line no-unused-vars
- const { id, ...userRest } = user;
+ const { id, ...userRest } = user
try {
- const res = await userApi.updateUser(userRest);
- setUser(res as any);
- loadUser();
- setLoading(false);
- return res as any;
+ const res = await userApi.updateUser(userRest)
+ setUser(res as any)
+ loadUser()
+ setLoading(false)
+ return res as any
} catch (error: any) {
- setLoading(false);
- throw error;
+ setLoading(false)
+ throw error
}
}
- const requestPasswordReset = async (email: string, reset_url?: string): Promise => {
- setLoading(true);
+ const requestPasswordReset = async (email: string, resetUrl?: string): Promise => {
+ setLoading(true)
try {
- await userApi.requestPasswordReset(email, reset_url);
- return setLoading(false);
+ await userApi.requestPasswordReset(email, resetUrl)
+ return setLoading(false)
} catch (error: any) {
- setLoading(false);
- throw error;
+ setLoading(false)
+ throw error
}
}
-
- const passwordReset = async (token: string, new_password:string): Promise => {
- setLoading(true);
+ const passwordReset = async (token: string, newPassword:string): Promise => {
+ setLoading(true)
try {
- await userApi.passwordReset(token, new_password);
- return setLoading(false);
+ await userApi.passwordReset(token, newPassword)
+ return setLoading(false)
} catch (error: any) {
- setLoading(false);
- throw error;
+ setLoading(false)
+ throw error
}
}
-
-
return (
{children}
- );
-};
-export const useAuth = () => useContext(AuthContext);
\ No newline at end of file
+ )
+}
+export const useAuth = () => useContext(AuthContext)
diff --git a/src/Components/Gaming/Modal.tsx b/src/Components/Gaming/Modal.tsx
index db08634..4cb5354 100644
--- a/src/Components/Gaming/Modal.tsx
+++ b/src/Components/Gaming/Modal.tsx
@@ -1,16 +1,13 @@
-import * as React from "react"
-import { useEffect } from "react"
+import * as React from 'react'
+import { useEffect } from 'react'
-export function Modal({children, showOnStartup}:{children : React.ReactNode, showOnStartup?: boolean}) {
+export function Modal ({ children, showOnStartup }:{children : React.ReactNode, showOnStartup?: boolean}) {
+ useEffect(() => {
+ if (showOnStartup) { window.my_modal_3.showModal() }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [])
- useEffect(() => {
- if(showOnStartup)
- window.my_modal_3.showModal()
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [])
-
-
- return (
+ return (
<>
{/* You can open the modal using ID.showModal() method */}
@@ -24,6 +21,5 @@ export function Modal({children, showOnStartup}:{children : React.ReactNode, sho
>
- )
+ )
}
-
diff --git a/src/Components/Gaming/Quests.tsx b/src/Components/Gaming/Quests.tsx
index 1486385..d95633a 100644
--- a/src/Components/Gaming/Quests.tsx
+++ b/src/Components/Gaming/Quests.tsx
@@ -1,32 +1,30 @@
-import { useQuestsOpen, useSetQuestOpen } from './hooks/useQuests';
-import { useAuth } from '../Auth';
-import { useEffect, useState } from 'react';
-import { useItems } from '../Map/hooks/useItems';
-import { Item } from '../../types';
-
-export function Quests() {
-
- const questsOpen = useQuestsOpen();
- const setQuestsOpen = useSetQuestOpen();
- const { isAuthenticated, user } = useAuth();
-
- useEffect(() => {
- setQuestsOpen(false);
+import { useQuestsOpen, useSetQuestOpen } from './hooks/useQuests'
+import { useAuth } from '../Auth'
+import { useEffect, useState } from 'react'
+import { useItems } from '../Map/hooks/useItems'
+import { Item } from '../../types'
+
+export function Quests () {
+ const questsOpen = useQuestsOpen()
+ const setQuestsOpen = useSetQuestOpen()
+ const { isAuthenticated, user } = useAuth()
+
+ useEffect(() => {
+ setQuestsOpen(false)
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [])
+ }, [])
- const [profile, setProfie] = useState- ()
-
- const items = useItems();
+ const [profile, setProfie] = useState
- ()
- useEffect(() => {
- setProfie(items.find(i => i.user_created?.id === user?.id && i.layer?.itemType.name == "user" && i.user_created?.id != null))
- }, [items, user])
-
+ const items = useItems()
- return (
- <>{questsOpen ?
-
+ useEffect(() => {
+ setProfie(items.find(i => i.user_created?.id === user?.id && i.layer?.itemType.name === 'user' && i.user_created?.id != null))
+ }, [items, user])
+
+ return (
+ <>{questsOpen
+ ?
@@ -39,17 +37,15 @@ export function Quests() {
{ /**
*/
}
- : ""
+ : ''
}
>
- )
-
-
+ )
}
diff --git a/src/Components/Gaming/hooks/useQuests.tsx b/src/Components/Gaming/hooks/useQuests.tsx
index 475960c..872e16b 100644
--- a/src/Components/Gaming/hooks/useQuests.tsx
+++ b/src/Components/Gaming/hooks/useQuests.tsx
@@ -1,28 +1,25 @@
-import { useCallback, useState } from 'react';
-import { createContext, useContext } from "react";
-import * as React from "react";
-
-
+import { useCallback, useState, createContext, useContext } from 'react'
+import * as React from 'react'
type UseQuestManagerResult = ReturnType
;
const QuestContext = createContext({
open: false,
setQuestsOpen: () => { }
-});
+})
-function useQuestsManager(initialOpen: boolean): {
+function useQuestsManager (initialOpen: boolean): {
open: boolean;
// eslint-disable-next-line no-unused-vars
setQuestsOpen: (open: boolean) => void;
} {
- const [open, setOpen] = useState(initialOpen);
+ const [open, setOpen] = useState(initialOpen)
const setQuestsOpen = useCallback((questOpen: boolean) => {
- setOpen(questOpen);
- }, []);
+ setOpen(questOpen)
+ }, [])
- return { open, setQuestsOpen };
+ return { open, setQuestsOpen }
}
export const QuestsProvider: React.FunctionComponent<{
@@ -31,15 +28,14 @@ export const QuestsProvider: React.FunctionComponent<{
{children}
-);
+)
export const useQuestsOpen = (): boolean => {
- const { open } = useContext(QuestContext);
- return open;
-};
-
+ const { open } = useContext(QuestContext)
+ return open
+}
-export const useSetQuestOpen = (): UseQuestManagerResult["setQuestsOpen"] => {
- const { setQuestsOpen } = useContext(QuestContext);
- return setQuestsOpen;
+export const useSetQuestOpen = (): UseQuestManagerResult['setQuestsOpen'] => {
+ const { setQuestsOpen } = useContext(QuestContext)
+ return setQuestsOpen
}
diff --git a/src/Components/Gaming/index.tsx b/src/Components/Gaming/index.tsx
index d88f05c..78c873a 100644
--- a/src/Components/Gaming/index.tsx
+++ b/src/Components/Gaming/index.tsx
@@ -1,2 +1,2 @@
-export {Modal} from './Modal'
-export {Quests} from './Quests'
\ No newline at end of file
+export { Modal } from './Modal'
+export { Quests } from './Quests'
diff --git a/src/Components/Input/Autocomplete.tsx b/src/Components/Input/Autocomplete.tsx
index 6209c58..3f77440 100644
--- a/src/Components/Input/Autocomplete.tsx
+++ b/src/Components/Input/Autocomplete.tsx
@@ -1,78 +1,76 @@
import * as React from 'react'
-import { useEffect } from 'react';
-import { TagView } from '../Templates/TagView';
+import { useEffect } from 'react'
+import { TagView } from '../Templates/TagView'
// eslint-disable-next-line no-unused-vars
export const Autocomplete = ({ inputProps, suggestions, onSelected, pushFilteredSuggestions, setFocus }: { inputProps: any, suggestions: Array, onSelected: (suggestion) => void, pushFilteredSuggestions?: Array, setFocus?: boolean }) => {
-
- const [filteredSuggestions, setFilteredSuggestions] = React.useState>([]);
- const [heighlightedSuggestion, setHeighlightedSuggestion] = React.useState(0);
-
+ const [filteredSuggestions, setFilteredSuggestions] = React.useState>([])
+ const [heighlightedSuggestion, setHeighlightedSuggestion] = React.useState(0)
useEffect(() => {
pushFilteredSuggestions && setFilteredSuggestions(pushFilteredSuggestions)
}, [pushFilteredSuggestions])
useEffect(() => {
- setFocus && inputRef.current?.focus();
+ setFocus && inputRef.current?.focus()
}, [setFocus])
- const inputRef = React.useRef();
-
+ const inputRef = React.useRef()
// eslint-disable-next-line no-unused-vars
- const getSuggestionValue = suggestion => suggestion.name;
+ const getSuggestionValue = suggestion => suggestion.name
const getSuggestions = value => {
- const inputValue = value.trim().toLowerCase();
- const inputLength = inputValue.length;
-
- return inputLength === 0 ? [] : suggestions.filter(tag =>
- tag.name.toLowerCase().slice(0, inputLength) === inputValue
- );
- };
+ const inputValue = value.trim().toLowerCase()
+ const inputLength = inputValue.length
+
+ return inputLength === 0
+ ? []
+ : suggestions.filter(tag =>
+ tag.name.toLowerCase().slice(0, inputLength) === inputValue
+ )
+ }
const handleChange = (e) => {
setFilteredSuggestions(getSuggestions(e.target.value))
// Call the parent's onChange handler, if it exists
if (inputProps.onChange) {
- inputProps.onChange(e);
+ inputProps.onChange(e)
}
- };
-
+ }
- function handleSuggestionClick(suggestion) {
+ function handleSuggestionClick (suggestion) {
onSelected(suggestion)
}
- const handleKeyDown = (event) => {
+ const handleKeyDown = (event) => {
switch (event.key) {
case 'ArrowDown':
- heighlightedSuggestion < filteredSuggestions.length-1 && setHeighlightedSuggestion(current => current +1)
- break;
+ heighlightedSuggestion < filteredSuggestions.length - 1 && setHeighlightedSuggestion(current => current + 1)
+ break
case 'ArrowUp':
- heighlightedSuggestion>0 && setHeighlightedSuggestion(current => current -1)
- break;
+ heighlightedSuggestion > 0 && setHeighlightedSuggestion(current => current - 1)
+ break
case 'Enter':
- if(filteredSuggestions.length > 0) {
- onSelected(filteredSuggestions[heighlightedSuggestion]);
- setHeighlightedSuggestion(0);
+ if (filteredSuggestions.length > 0) {
+ onSelected(filteredSuggestions[heighlightedSuggestion])
+ setHeighlightedSuggestion(0)
}
- filteredSuggestions.length == 0 && inputProps.onKeyDown(event);
- break;
+ filteredSuggestions.length === 0 && inputProps.onKeyDown(event)
+ break
default:
- inputProps.onKeyDown(event);
- break;
+ inputProps.onKeyDown(event)
+ break
}
}
return (
diff --git a/src/Components/Input/ComboBoxInput.tsx b/src/Components/Input/ComboBoxInput.tsx
index 159fe19..24e0619 100644
--- a/src/Components/Input/ComboBoxInput.tsx
+++ b/src/Components/Input/ComboBoxInput.tsx
@@ -1,5 +1,5 @@
-import { useState } from "react"
-import * as React from "react"
+import { useState } from 'react'
+import * as React from 'react'
interface ComboBoxProps {
id?: string;
@@ -10,15 +10,14 @@ interface ComboBoxProps {
}
const ComboBoxInput = ({ id, options, value, onValueChange }: ComboBoxProps) => {
-
// eslint-disable-next-line no-unused-vars
- const [selectedValue, setSelectedValue] = useState(value);
+ const [selectedValue, setSelectedValue] = useState(value)
const handleChange = (e: React.ChangeEvent) => {
- const value = e.target.value;
- setSelectedValue(value);
- onValueChange(value);
- };
+ const value = e.target.value
+ setSelectedValue(value)
+ onValueChange(value)
+ }
return (
- );
+ )
}
-export default ComboBoxInput;
\ No newline at end of file
+export default ComboBoxInput
diff --git a/src/Components/Input/SelectBox.tsx b/src/Components/Input/SelectBox.tsx
index cd2ce0c..286e0bc 100644
--- a/src/Components/Input/SelectBox.tsx
+++ b/src/Components/Input/SelectBox.tsx
@@ -1,7 +1,6 @@
-
import { useState } from 'react'
import InformationCircleIcon from '@heroicons/react/24/outline/InformationCircleIcon'
-import * as React from 'react';
+import * as React from 'react'
type SelectBoxProps = {
labelTitle?: string;
@@ -11,42 +10,39 @@ type SelectBoxProps = {
defaultValue: string;
placeholder?: string;
// eslint-disable-next-line no-unused-vars
- updateFormValue: (value: string ) => void;
+ updateFormValue: (value: string) => void;
options: {name: string, value: string}[];
labelDescription?: string
}
-export function SelectBox(props : SelectBoxProps){
-
- const {labelTitle, labelDescription, defaultValue, containerStyle, placeholder, labelStyle, options, updateFormValue} = props
-
- const [value, setValue] = useState(defaultValue || "")
+export function SelectBox (props : SelectBoxProps) {
+ const { labelTitle, labelDescription, defaultValue, containerStyle, placeholder, labelStyle, options, updateFormValue } = props
+ const [value, setValue] = useState(defaultValue || '')
- const updateValue = (newValue: string) =>{
- updateFormValue(newValue)
- setValue(newValue)
- }
+ const updateValue = (newValue: string) => {
+ updateFormValue(newValue)
+ setValue(newValue)
+ }
-
- return (
+ return (
- {labelTitle?
-
- )
-}
\ No newline at end of file
+ )
+}
diff --git a/src/Components/Input/TextAreaInput.tsx b/src/Components/Input/TextAreaInput.tsx
index 528b883..638af6e 100644
--- a/src/Components/Input/TextAreaInput.tsx
+++ b/src/Components/Input/TextAreaInput.tsx
@@ -1,7 +1,7 @@
-import * as React from "react";
-import { useEffect, useRef, useState } from "react";
-import Tribute from "tributejs";
-import { useTags } from "../Map/hooks/useTags";
+import * as React from 'react'
+import { useEffect, useRef, useState } from 'react'
+import Tribute from 'tributejs'
+import { useTags } from '../Map/hooks/useTags'
type TextAreaProps = {
labelTitle?: string;
@@ -19,73 +19,75 @@ interface KeyValue {
[key: string]: string;
}
-export function TextAreaInput({ labelTitle, dataField, labelStyle, containerStyle, inputStyle, defaultValue, placeholder, updateFormValue }: TextAreaProps) {
- const ref = useRef(null);
- const [inputValue, setInputValue] = useState(defaultValue);
+export function TextAreaInput ({ labelTitle, dataField, labelStyle, containerStyle, inputStyle, defaultValue, placeholder, updateFormValue }: TextAreaProps) {
+ const ref = useRef(null)
+ const [inputValue, setInputValue] = useState(defaultValue)
- // prevent react18 from calling useEffect twice
- const init = useRef(false);
+ // prevent react18 from calling useEffect twice
+ const init = useRef(false)
- const tags = useTags();
+ const tags = useTags()
- const values: KeyValue[] = [];
+ const values: KeyValue[] = []
- tags.forEach(tag => {
- values.push({ key: tag.name, value: tag.name, color: tag.color });
- });
+ tags.forEach(tag => {
+ values.push({ key: tag.name, value: tag.name, color: tag.color })
+ })
- const tribute = new Tribute({
- containerClass: 'tw-z-3000 tw-bg-base-100 tw-p-2 tw-rounded-lg tw-shadow',
- selectClass: 'tw-font-bold',
- trigger: "#",
- values: values,
- menuShowMinLength: 3,
- noMatchTemplate: () => {
- return ""
- },
- menuItemTemplate: function (item) {
- return `#${item.string}`;
- }
- });
+ const tribute = new Tribute({
+ containerClass: 'tw-z-3000 tw-bg-base-100 tw-p-2 tw-rounded-lg tw-shadow',
+ selectClass: 'tw-font-bold',
+ trigger: '#',
+ values,
+ menuShowMinLength: 3,
+ noMatchTemplate: () => {
+ return ''
+ },
+ menuItemTemplate: function (item) {
+ return `#${item.string}`
+ }
+ })
- useEffect(() => {
- if (!init.current) {
- if (ref.current) {
- tribute.attach(ref.current);
- }
- init.current = true;
- }
+ useEffect(() => {
+ if (!init.current) {
+ if (ref.current) {
+ tribute.attach(ref.current)
+ }
+ init.current = true
+ }
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [ref]);
+ }, [ref])
- useEffect(() => {
- setInputValue(defaultValue);
- }, [defaultValue]);
+ useEffect(() => {
+ setInputValue(defaultValue)
+ }, [defaultValue])
- const handleChange = (e: React.ChangeEvent) => {
- const newValue = e.target.value;
- setInputValue(newValue);
- if (updateFormValue) {
- updateFormValue(newValue);
- }
- };
+ const handleChange = (e: React.ChangeEvent) => {
+ const newValue = e.target.value
+ setInputValue(newValue)
+ if (updateFormValue) {
+ updateFormValue(newValue)
+ }
+ }
- return (
-
- {labelTitle ? (
+ return (
+
+ {labelTitle
+ ? (
{labelTitle}
- ) : null}
+ )
+ : null}
- );
+ )
}
diff --git a/src/Components/Input/TextInput.tsx b/src/Components/Input/TextInput.tsx
index 3ac0a21..fd95ef3 100644
--- a/src/Components/Input/TextInput.tsx
+++ b/src/Components/Input/TextInput.tsx
@@ -1,5 +1,5 @@
-import { useEffect, useState } from "react"
-import * as React from "react"
+import { useEffect, useState } from 'react'
+import * as React from 'react'
type InputTextProps = {
labelTitle?: string;
@@ -12,42 +12,43 @@ type InputTextProps = {
placeholder?: string;
autocomplete?: string
// eslint-disable-next-line no-unused-vars
- updateFormValue?: (value: string ) => void;
+ updateFormValue?: (value: string) => void;
}
+export function TextInput ({ labelTitle, labelStyle, type, dataField, containerStyle, inputStyle, defaultValue, placeholder, autocomplete, updateFormValue }: InputTextProps) {
+ const [inputValue, setInputValue] = useState
(defaultValue || '')
-export function TextInput({ labelTitle, labelStyle, type, dataField, containerStyle, inputStyle, defaultValue, placeholder, autocomplete, updateFormValue }: InputTextProps) {
- const [inputValue, setInputValue] = useState(defaultValue || "");
+ useEffect(() => {
+ setInputValue(defaultValue || '')
+ }, [defaultValue])
- useEffect(() => {
- setInputValue(defaultValue || "");
- }, [defaultValue]);
+ const handleChange = (e: React.ChangeEvent) => {
+ const newValue = e.target.value
+ setInputValue(newValue)
+ if (updateFormValue) {
+ updateFormValue(newValue)
+ }
+ }
- const handleChange = (e: React.ChangeEvent) => {
- const newValue = e.target.value;
- setInputValue(newValue);
- if (updateFormValue) {
- updateFormValue(newValue);
- }
- };
-
- return (
+ return (
- {labelTitle ? (
+ {labelTitle
+ ? (
{labelTitle}
- ) : null}
+ )
+ : null}
- );
-}
\ No newline at end of file
+ )
+}
diff --git a/src/Components/Input/index.tsx b/src/Components/Input/index.tsx
index 5bcdbe5..ecce2b8 100644
--- a/src/Components/Input/index.tsx
+++ b/src/Components/Input/index.tsx
@@ -1,3 +1,3 @@
-export {TextAreaInput} from "./TextAreaInput"
-export {TextInput} from "./TextInput"
-export {SelectBox} from "./SelectBox"
\ No newline at end of file
+export { TextAreaInput } from './TextAreaInput'
+export { TextInput } from './TextInput'
+export { SelectBox } from './SelectBox'
diff --git a/src/Components/Map/ItemForm.tsx b/src/Components/Map/ItemForm.tsx
index 2ec519c..521909f 100644
--- a/src/Components/Map/ItemForm.tsx
+++ b/src/Components/Map/ItemForm.tsx
@@ -3,30 +3,31 @@ import { Item } from '../../types'
import * as PropTypes from 'prop-types'
import { useEffect } from 'react'
-
export const ItemForm = ({ children, item, title, setPopupTitle }: { children?: React.ReactNode, item?: Item, title?: string, setPopupTitle?: React.Dispatch> }) => {
- useEffect(() => {
- setPopupTitle&& title && setPopupTitle(title);
+ useEffect(() => {
+ setPopupTitle && title && setPopupTitle(title)
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [title])
-
- return (
+ }, [title])
+
+ return (
{
- children ?
- React.Children.toArray(children).map((child) =>
- React.isValidElement<{ item: Item, test: string }>(child) ?
- React.cloneElement(child, { item: item, test: "test" }) : ""
- ) : ""
+ children
+ ? React.Children.toArray(children).map((child) =>
+ React.isValidElement<{ item: Item, test: string }>(child)
+ ? React.cloneElement(child, { item, test: 'test' })
+ : ''
+ )
+ : ''
}
- )
+ )
}
ItemForm.propTypes = {
- children: PropTypes.node,
- __TYPE: PropTypes.string,
-};
+ children: PropTypes.node,
+ __TYPE: PropTypes.string
+}
ItemForm.defaultProps = {
- __TYPE: 'ItemForm',
-};
+ __TYPE: 'ItemForm'
+}
diff --git a/src/Components/Map/ItemView.tsx b/src/Components/Map/ItemView.tsx
index 50eba91..0af2612 100644
--- a/src/Components/Map/ItemView.tsx
+++ b/src/Components/Map/ItemView.tsx
@@ -2,24 +2,25 @@ import * as React from 'react'
import { Item } from '../../types'
import * as PropTypes from 'prop-types'
-
export const ItemView = ({ children, item }: { children?: React.ReactNode, item?: Item }) => {
return (
- {children ?
- React.Children.toArray(children).map((child) =>
- React.isValidElement<{ item: Item }>(child) ?
- React.cloneElement(child, { item: item }) : ""
- ) : ""}
+ {children
+ ? React.Children.toArray(children).map((child) =>
+ React.isValidElement<{ item: Item }>(child)
+ ? React.cloneElement(child, { item })
+ : ''
+ )
+ : ''}
)
}
ItemView.propTypes = {
children: PropTypes.node,
- __TYPE: PropTypes.string,
-};
+ __TYPE: PropTypes.string
+}
ItemView.defaultProps = {
- __TYPE: 'ItemView',
-};
+ __TYPE: 'ItemView'
+}
diff --git a/src/Components/Map/Layer.tsx b/src/Components/Map/Layer.tsx
index 4afb915..1f0deaf 100644
--- a/src/Components/Map/Layer.tsx
+++ b/src/Components/Map/Layer.tsx
@@ -10,7 +10,7 @@ import { useFilterTags, useIsGroupTypeVisible, useIsLayerVisible, useVisibleGrou
import { useAddTag, useAllTagsLoaded, useGetItemTags, useTags } from './hooks/useTags'
import { useAddMarker, useAddPopup, useLeafletRefs } from './hooks/useLeafletRefs'
import { Popup } from 'leaflet'
-import { useLocation } from 'react-router-dom';
+import { useLocation } from 'react-router-dom'
import { getValue } from '../../Utils/GetValue'
import { hashTagRegex } from '../../Utils/HashTagRegex'
import { randomColor } from '../../Utils/RandomColor'
@@ -18,218 +18,209 @@ import { encodeTag } from '../../Utils/FormatTags'
import { useSelectPosition, useSetMarkerClicked } from './hooks/useSelectPosition'
export const Layer = ({
- data,
- children,
- name = 'places',
- menuIcon = 'MapPinIcon',
- menuText = 'add new place',
- menuColor = '#2E7D32',
- markerIcon = 'circle-solid',
- markerShape = 'circle',
- markerDefaultColor = '#777',
- markerDefaultColor2 = "RGBA(35, 31, 32, 0.2)",
- api,
- itemType,
- itemNameField = 'name',
- itemSubnameField,
- itemTextField = 'text',
- itemAvatarField,
- itemColorField,
- itemOwnerField,
- itemLatitudeField = 'position.coordinates.1',
- itemLongitudeField = 'position.coordinates.0',
- itemTagsField,
- itemOffersField,
- itemNeedsField,
- onlyOnePerOwner = false,
- customEditLink,
- customEditParameter,
- public_edit_items,
- listed = true,
- setItemFormPopup,
- itemFormPopup,
- clusterRef
+ data,
+ children,
+ name = 'places',
+ menuIcon = 'MapPinIcon',
+ menuText = 'add new place',
+ menuColor = '#2E7D32',
+ markerIcon = 'circle-solid',
+ markerShape = 'circle',
+ markerDefaultColor = '#777',
+ markerDefaultColor2 = 'RGBA(35, 31, 32, 0.2)',
+ api,
+ itemType,
+ itemNameField = 'name',
+ itemSubnameField,
+ itemTextField = 'text',
+ itemAvatarField,
+ itemColorField,
+ itemOwnerField,
+ itemLatitudeField = 'position.coordinates.1',
+ itemLongitudeField = 'position.coordinates.0',
+ itemTagsField,
+ itemOffersField,
+ itemNeedsField,
+ onlyOnePerOwner = false,
+ customEditLink,
+ customEditParameter,
+ // eslint-disable-next-line camelcase
+ public_edit_items,
+ listed = true,
+ setItemFormPopup,
+ itemFormPopup,
+ clusterRef
}: LayerProps) => {
+ const filterTags = useFilterTags()
- const filterTags = useFilterTags();
+ const items = useItems()
+ const setItemsApi = useSetItemsApi()
+ const setItemsData = useSetItemsData()
+ const getItemTags = useGetItemTags()
+ const addMarker = useAddMarker()
+ const addPopup = useAddPopup()
+ const leafletRefs = useLeafletRefs()
- const items = useItems();
- const setItemsApi = useSetItemsApi();
- const setItemsData = useSetItemsData();
- const getItemTags = useGetItemTags();
- const addMarker = useAddMarker();
- const addPopup = useAddPopup();
- const leafletRefs = useLeafletRefs();
+ const location = useLocation()
- const location = useLocation();
+ const allTagsLoaded = useAllTagsLoaded()
+ const allItemsLoaded = useAllItemsLoaded()
- const allTagsLoaded = useAllTagsLoaded();
- const allItemsLoaded = useAllItemsLoaded();
+ const setMarkerClicked = useSetMarkerClicked()
+ const selectPosition = useSelectPosition()
- const setMarkerClicked = useSetMarkerClicked();
- const selectPosition = useSelectPosition();
+ const tags = useTags()
+ const addTag = useAddTag()
+ const [newTagsToAdd, setNewTagsToAdd] = useState([])
+ const [tagsReady, setTagsReady] = useState(false)
- const tags = useTags();
- const addTag = useAddTag();
- const [newTagsToAdd, setNewTagsToAdd] = useState([]);
- const [tagsReady, setTagsReady] = useState(false);
+ const map = useMap()
+ const isLayerVisible = useIsLayerVisible()
- const map = useMap();
+ const isGroupTypeVisible = useIsGroupTypeVisible()
- const isLayerVisible = useIsLayerVisible();
+ const visibleGroupTypes = useVisibleGroupType()
- const isGroupTypeVisible = useIsGroupTypeVisible();
-
- const visibleGroupTypes = useVisibleGroupType();
-
-
-
- useEffect(() => {
- data && setItemsData({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, markerDefaultColor2, api, itemType, itemNameField, itemSubnameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, itemTagsField, itemOffersField, itemNeedsField, onlyOnePerOwner, customEditLink, customEditParameter, public_edit_items, listed, setItemFormPopup, itemFormPopup, clusterRef });
- api && setItemsApi({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, markerDefaultColor2, api, itemType, itemNameField, itemSubnameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, itemTagsField, itemOffersField, itemNeedsField, onlyOnePerOwner, customEditLink, customEditParameter, public_edit_items, listed, setItemFormPopup, itemFormPopup, clusterRef });
+ useEffect(() => {
+ // eslint-disable-next-line camelcase
+ data && setItemsData({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, markerDefaultColor2, api, itemType, itemNameField, itemSubnameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, itemTagsField, itemOffersField, itemNeedsField, onlyOnePerOwner, customEditLink, customEditParameter, public_edit_items, listed, setItemFormPopup, itemFormPopup, clusterRef })
+ // eslint-disable-next-line camelcase
+ api && setItemsApi({ data, children, name, menuIcon, menuText, menuColor, markerIcon, markerShape, markerDefaultColor, markerDefaultColor2, api, itemType, itemNameField, itemSubnameField, itemTextField, itemAvatarField, itemColorField, itemOwnerField, itemTagsField, itemOffersField, itemNeedsField, onlyOnePerOwner, customEditLink, customEditParameter, public_edit_items, listed, setItemFormPopup, itemFormPopup, clusterRef })
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [data, api])
-
- useMapEvents({
- popupopen: (e) => {
- const item = Object.entries(leafletRefs).find(r => r[1].popup == e.popup)?.[1].item;
- if (item?.layer?.name == name && window.location.pathname.split("/")[1] != item.id) {
- const params = new URLSearchParams(window.location.search);
- if (!location.pathname.includes("/item/")) {
- window.history.pushState({}, "", `/${item.id}` + `${params.toString() !== "" ? `?${params}` : ""}`)
- }
- let title = "";
- if (item.name) title = item.name;
- else if (item.layer?.itemNameField) title = getValue(item, item.layer.itemNameField);
- document.title = `${document.title.split("-")[0]} - ${title}`;
- }
- },
- })
-
- const openPopup = () => {
- if (window.location.pathname.split("/").length <= 1 || window.location.pathname.split("/")[1] === "") {
- map.closePopup();
+ }, [data, api])
+
+ useMapEvents({
+ popupopen: (e) => {
+ const item = Object.entries(leafletRefs).find(r => r[1].popup === e.popup)?.[1].item
+ if (item?.layer?.name === name && window.location.pathname.split('/')[1] !== item.id) {
+ const params = new URLSearchParams(window.location.search)
+ if (!location.pathname.includes('/item/')) {
+ window.history.pushState({}, '', `/${item.id}` + `${params.toString() !== '' ? `?${params}` : ''}`)
}
- else {
- if (window.location.pathname.split("/")[1]) {
- const id = window.location.pathname.split("/")[1]
- const ref = leafletRefs[id];
- if (ref?.marker && ref.item.layer?.name === name) {
- ref.marker && clusterRef.hasLayer(ref.marker) && clusterRef?.zoomToShowLayer(ref.marker, () => {
- ref.marker.openPopup();
- });
- let title = "";
- if (ref.item.name) title = ref.item.name;
- else if (ref.item.layer?.itemNameField) title = getValue(ref.item.name, ref.item.layer.itemNameField);
- document.title = `${document.title.split("-")[0]} - ${title}`;
- document.querySelector('meta[property="og:title"]')?.setAttribute("content", ref.item.name);
- document.querySelector('meta[property="og:description"]')?.setAttribute("content", ref.item.text);
- }
- }
+ let title = ''
+ if (item.name) title = item.name
+ else if (item.layer?.itemNameField) title = getValue(item, item.layer.itemNameField)
+ document.title = `${document.title.split('-')[0]} - ${title}`
+ }
+ }
+ })
+
+ const openPopup = () => {
+ if (window.location.pathname.split('/').length <= 1 || window.location.pathname.split('/')[1] === '') {
+ map.closePopup()
+ } else {
+ if (window.location.pathname.split('/')[1]) {
+ const id = window.location.pathname.split('/')[1]
+ const ref = leafletRefs[id]
+ if (ref?.marker && ref.item.layer?.name === name) {
+ ref.marker && clusterRef.hasLayer(ref.marker) && clusterRef?.zoomToShowLayer(ref.marker, () => {
+ ref.marker.openPopup()
+ })
+ let title = ''
+ if (ref.item.name) title = ref.item.name
+ else if (ref.item.layer?.itemNameField) title = getValue(ref.item.name, ref.item.layer.itemNameField)
+ document.title = `${document.title.split('-')[0]} - ${title}`
+ document.querySelector('meta[property="og:title"]')?.setAttribute('content', ref.item.name)
+ document.querySelector('meta[property="og:description"]')?.setAttribute('content', ref.item.text)
}
+ }
}
+ }
- useEffect(() => {
- openPopup();
+ useEffect(() => {
+ openPopup()
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [leafletRefs, location])
-
- useEffect(() => {
- if (tagsReady) {
- const processedTags = {};
- newTagsToAdd.map(newtag => {
- if (!processedTags[newtag.name]) {
- processedTags[newtag.name] = true;
- addTag(newtag);
- }
- })
+ }, [leafletRefs, location])
+
+ useEffect(() => {
+ if (tagsReady) {
+ const processedTags = {}
+ newTagsToAdd.map(newtag => {
+ if (!processedTags[newtag.name]) {
+ processedTags[newtag.name] = true
+ addTag(newtag)
}
+ return null
+ })
+ }
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [tagsReady])
+ }, [tagsReady])
- return (
+ return (
<>
{items &&
- items.
- filter(item => item.layer?.name === name)?.
- filter(item =>
- filterTags.length == 0 ? item : filterTags.some(tag => getItemTags(item).some(filterTag => filterTag.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())))?.
- filter(item => item.layer && isLayerVisible(item.layer)).
- filter(item => item.group_type && isGroupTypeVisible(item.group_type) || visibleGroupTypes.length == 0).
- map((item: Item) => {
- if (getValue(item, itemLongitudeField) && getValue(item, itemLatitudeField)) {
-
- if (getValue(item, itemTextField)) item[itemTextField] = getValue(item, itemTextField);
- else item[itemTextField] = "";
-
- if (item?.tags) {
- item[itemTextField] = item[itemTextField] + '\n\n';
- item.tags.map(tag => {
- if (!item[itemTextField].includes(`#${encodeTag(tag)}`))
- return (item[itemTextField] = item[itemTextField] + `#${encodeTag(tag)} `)
- return item[itemTextField]
-
- });
- }
-
-
- if (allTagsLoaded && allItemsLoaded) {
- item[itemTextField].match(hashTagRegex)?.map(tag => {
- if ((!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) && !newTagsToAdd.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
- const newTag = { id: crypto.randomUUID(), name: tag.slice(1), color: randomColor() };
- setNewTagsToAdd(current => [...current, newTag]);
- }
- });
- !tagsReady && setTagsReady(true);
- }
-
-
- const itemTags = getItemTags(item);
-
- const latitude = itemLatitudeField && item ? getValue(item, itemLatitudeField) : undefined;
- const longitude = itemLongitudeField && item ? getValue(item, itemLongitudeField) : undefined;
-
- let color1 = markerDefaultColor;
- let color2 = markerDefaultColor2;
- if (itemColorField && getValue(item, itemColorField) != null) color1 = getValue(item, itemColorField);
- else if (itemTags && itemTags[0]) {
- color1 = itemTags[0].color;
- }
- if (itemTags && itemTags[0] && itemColorField) color2 = itemTags[0].color;
- else if (itemTags && itemTags[1]) {
- color2 = itemTags[1].color;
- }
- return (
+ items
+ .filter(item => item.layer?.name === name)
+ ?.filter(item =>
+ filterTags.length === 0 ? item : filterTags.some(tag => getItemTags(item).some(filterTag => filterTag.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())))
+ ?.filter(item => item.layer && isLayerVisible(item.layer))
+ .filter(item => (item.group_type && isGroupTypeVisible(item.group_type)) || visibleGroupTypes.length === 0)
+ .map((item: Item) => {
+ if (getValue(item, itemLongitudeField) && getValue(item, itemLatitudeField)) {
+ if (getValue(item, itemTextField)) item[itemTextField] = getValue(item, itemTextField)
+ else item[itemTextField] = ''
+
+ if (item?.tags) {
+ item[itemTextField] = item[itemTextField] + '\n\n'
+ item.tags.map(tag => {
+ if (!item[itemTextField].includes(`#${encodeTag(tag)}`)) { return (item[itemTextField] = item[itemTextField] + `#${encodeTag(tag)} `) }
+ return item[itemTextField]
+ })
+ }
+
+ if (allTagsLoaded && allItemsLoaded) {
+ item[itemTextField].match(hashTagRegex)?.map(tag => {
+ if ((!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) && !newTagsToAdd.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
+ const newTag = { id: crypto.randomUUID(), name: tag.slice(1), color: randomColor() }
+ setNewTagsToAdd(current => [...current, newTag])
+ }
+ return null
+ })
+ !tagsReady && setTagsReady(true)
+ }
+
+ const itemTags = getItemTags(item)
+
+ const latitude = itemLatitudeField && item ? getValue(item, itemLatitudeField) : undefined
+ const longitude = itemLongitudeField && item ? getValue(item, itemLongitudeField) : undefined
+
+ let color1 = markerDefaultColor
+ let color2 = markerDefaultColor2
+ if (itemColorField && getValue(item, itemColorField) != null) color1 = getValue(item, itemColorField)
+ else if (itemTags && itemTags[0]) {
+ color1 = itemTags[0].color
+ }
+ if (itemTags && itemTags[0] && itemColorField) color2 = itemTags[0].color
+ else if (itemTags && itemTags[1]) {
+ color2 = itemTags[1].color
+ }
+ return (
{
- if (!(item.id in leafletRefs && leafletRefs[item.id].marker == r))
- r && addMarker(item, r);
+ if (!(item.id in leafletRefs && leafletRefs[item.id].marker === r)) { r && addMarker(item, r) }
}}
eventHandlers={{
- click: () => {
- selectPosition && setMarkerClicked(item)
- },
+ click: () => {
+ selectPosition && setMarkerClicked(item)
+ }
}}
icon={MarkerIconFactory(markerShape, color1, color2, item.markerIcon ? item.markerIcon : markerIcon)} key={item.id} position={[latitude, longitude]}>
{
- (children && React.Children.toArray(children).some(child => React.isValidElement(child) && child.props.__TYPE === "ItemView") ?
- React.Children.toArray(children).map((child) =>
- React.isValidElement(child) && child.props.__TYPE === "ItemView" ?
- {
- if (!(item.id in leafletRefs && leafletRefs[item.id].popup == r))
- r && addPopup(item, r as Popup);
- }} key={item.id + item.name}
+ (children && React.Children.toArray(children).some(child => React.isValidElement(child) && child.props.__TYPE === 'ItemView')
+ ? React.Children.toArray(children).map((child) =>
+ React.isValidElement(child) && child.props.__TYPE === 'ItemView'
+ ? {
+ if (!(item.id in leafletRefs && leafletRefs[item.id].popup === r)) { r && addPopup(item, r as Popup) }
+ }} key={item.id + item.name}
item={item}
setItemFormPopup={setItemFormPopup}>
{child}
- : ""
- )
- :
- <>
+ : ''
+ )
+ : <>
{
- if (!(item.id in leafletRefs && leafletRefs[item.id].popup == r))
- r && addPopup(item, r as Popup);
+ if (!(item.id in leafletRefs && leafletRefs[item.id].popup === r)) { r && addPopup(item, r as Popup) }
}}
item={item}
setItemFormPopup={setItemFormPopup} />
@@ -237,25 +228,23 @@ export const Layer = ({
}
{item.name ? item.name : getValue(item, itemNameField)}
- );
- }
- else return null;
- })
+ )
+ } else return null
+ })
}
- {//{children}}
+ {// {children}}
}
- {itemFormPopup && itemFormPopup.layer!.name == name &&
- (children && React.Children.toArray(children).some(child => React.isValidElement(child) && child.props.__TYPE === "ItemForm") ?
- React.Children.toArray(children).map((child) =>
- React.isValidElement(child) && child.props.__TYPE === "ItemForm" ?
- {child}
- : ""
- )
- :
- <>
+ {itemFormPopup && itemFormPopup.layer!.name === name &&
+ (children && React.Children.toArray(children).some(child => React.isValidElement(child) && child.props.__TYPE === 'ItemForm')
+ ? React.Children.toArray(children).map((child) =>
+ React.isValidElement(child) && child.props.__TYPE === 'ItemForm'
+ ? {child}
+ : ''
+ )
+ : <>
>)
}
>
- )
-}
\ No newline at end of file
+ )
+}
diff --git a/src/Components/Map/Permissions.tsx b/src/Components/Map/Permissions.tsx
index bd60026..ffc414f 100644
--- a/src/Components/Map/Permissions.tsx
+++ b/src/Components/Map/Permissions.tsx
@@ -1,21 +1,21 @@
import * as React from 'react'
-import { useEffect } from 'react';
-import { ItemsApi, Permission } from '../../types';
-import { useSetPermissionData, useSetPermissionApi, useSetAdminRole } from './hooks/usePermissions'
-import { useAuth } from '../Auth';
+import { useEffect } from 'react'
+import { ItemsApi, Permission } from '../../types'
+import { useSetPermissionData, useSetPermissionApi, useSetAdminRole } from './hooks/usePermissions'
+import { useAuth } from '../Auth'
-export function Permissions({data, api, adminRole} : {data?: Permission[], api?: ItemsApi, adminRole?: string}) {
-const setPermissionData = useSetPermissionData();
-const setPermissionApi = useSetPermissionApi();
-const setAdminRole = useSetAdminRole();
-const {user} = useAuth();
+export function Permissions ({ data, api, adminRole } : {data?: Permission[], api?: ItemsApi, adminRole?: string}) {
+ const setPermissionData = useSetPermissionData()
+ const setPermissionApi = useSetPermissionApi()
+ const setAdminRole = useSetAdminRole()
+ const { user } = useAuth()
-useEffect(() => {
- adminRole && setAdminRole(adminRole);
- data && setPermissionData(data);
- api && setPermissionApi(api);
-// eslint-disable-next-line react-hooks/exhaustive-deps
-}, [api, data, adminRole, user])
+ useEffect(() => {
+ adminRole && setAdminRole(adminRole)
+ data && setPermissionData(data)
+ api && setPermissionApi(api)
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [api, data, adminRole, user])
return (
<>>
diff --git a/src/Components/Map/Subcomponents/AddButton.tsx b/src/Components/Map/Subcomponents/AddButton.tsx
index 84073aa..025c7e0 100644
--- a/src/Components/Map/Subcomponents/AddButton.tsx
+++ b/src/Components/Map/Subcomponents/AddButton.tsx
@@ -1,26 +1,24 @@
import * as React from 'react'
import { useLayers } from '../hooks/useLayers'
-import { useHasUserPermission } from '../hooks/usePermissions';
-
-
-export default function AddButton({ triggerAction }: { triggerAction: React.Dispatch> }) {
-
- const layers = useLayers();
- const hasUserPermission = useHasUserPermission();
-
- const canAddItems = () => {
- let canAdd = false;
- layers.map(layer => {
- if (layer.api?.createItem && hasUserPermission(layer.api.collectionName!, "create", undefined, layer) && layer.listed) canAdd = true;
- })
- return canAdd;
- }
-
-
- return (
+import { useHasUserPermission } from '../hooks/usePermissions'
+
+export default function AddButton ({ triggerAction }: { triggerAction: React.Dispatch> }) {
+ const layers = useLayers()
+ const hasUserPermission = useHasUserPermission()
+
+ const canAddItems = () => {
+ let canAdd = false
+ layers.map(layer => {
+ if (layer.api?.createItem && hasUserPermission(layer.api.collectionName!, 'create', undefined, layer) && layer.listed) canAdd = true
+ return null
+ })
+ return canAdd
+ }
+
+ return (
<>{
- canAddItems() ?
-
+ canAddItems()
+ ?
{layers.map((layer) => (
- layer.api?.createItem && hasUserPermission(layer.api.collectionName!, "create", undefined, layer) && layer.listed &&(
+ layer.api?.createItem && hasUserPermission(layer.api.collectionName!, 'create', undefined, layer) && layer.listed && (
-
- )
+ )
))}
-
: ""
+
+ : ''
}
>
- )
+ )
}
diff --git a/src/Components/Map/Subcomponents/Controls/Control.tsx b/src/Components/Map/Subcomponents/Controls/Control.tsx
index a7bf270..bfb6eda 100644
--- a/src/Components/Map/Subcomponents/Controls/Control.tsx
+++ b/src/Components/Map/Subcomponents/Controls/Control.tsx
@@ -1,14 +1,9 @@
import * as L from 'leaflet'
import * as React from 'react'
-
-
-export const Control = ({ position, children, zIndex, absolute }: { position: "topLeft" | "topRight" | "bottomLeft" | "bottomRight", children: React.ReactNode, zIndex: string, absolute: boolean }) => {
-
-
+export const Control = ({ position, children, zIndex, absolute }: { position: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight', children: React.ReactNode, zIndex: string, absolute: boolean }) => {
const controlContainerRef = React.createRef()
-
React.useEffect(() => {
if (controlContainerRef.current !== null) {
L.DomEvent.disableClickPropagation(controlContainerRef.current)
@@ -17,7 +12,7 @@ export const Control = ({ position, children, zIndex, absolute }: { position: "t
}, [controlContainerRef])
return (
-
+
{children}
diff --git a/src/Components/Map/Subcomponents/Controls/FilterControl.tsx b/src/Components/Map/Subcomponents/Controls/FilterControl.tsx
index 4281df0..66bfff5 100644
--- a/src/Components/Map/Subcomponents/Controls/FilterControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/FilterControl.tsx
@@ -1,34 +1,31 @@
import * as React from 'react'
-import { useAddVisibleGroupType, useIsGroupTypeVisible, useToggleVisibleGroupType, useVisibleGroupType } from '../../hooks/useFilter';
-import { useEffect } from 'react';
+import { useAddVisibleGroupType, useIsGroupTypeVisible, useToggleVisibleGroupType, useVisibleGroupType } from '../../hooks/useFilter'
+import { useEffect } from 'react'
-export function FilterControl() {
+export function FilterControl () {
+ const [open, setOpen] = React.useState(false)
- const [open, setOpen] = React.useState(false);
+ const groupTypes = [{ text: 'Regional Gruppe', value: 'wuerdekompass' }, { text: 'Themen Gruppe', value: 'themenkompass' }, { text: 'liebevoll.jetzt', value: 'liebevoll.jetzt' }]
- const groupTypes = [{ text: "Regional Gruppe", value: "wuerdekompass" }, { text: "Themen Gruppe", value: "themenkompass" }, { text: "liebevoll.jetzt", value: "liebevoll.jetzt" }]
-
-
- useEffect(() => {
- groupTypes.map(layer =>
- addVisibleGroupType(layer.value)
- )
+ useEffect(() => {
+ groupTypes.map(layer =>
+ addVisibleGroupType(layer.value)
+ )
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [])
+ }, [])
+ const isGroupTypeVisible = useIsGroupTypeVisible()
+ const toggleVisibleGroupType = useToggleVisibleGroupType()
+ const addVisibleGroupType = useAddVisibleGroupType()
+ const visibleGroupTypes = useVisibleGroupType()
- const isGroupTypeVisible = useIsGroupTypeVisible();
- const toggleVisibleGroupType = useToggleVisibleGroupType();
- const addVisibleGroupType = useAddVisibleGroupType();
- const visibleGroupTypes = useVisibleGroupType();
-
- return (
+ return (
{
- open ?
-
+ open
+ ?
{
- setOpen(false)
+ setOpen(false)
}}>
β
@@ -39,11 +36,10 @@ export function FilterControl() {
}
- :
-
+ :
{visibleGroupTypes.length < groupTypes.length &&
}
{
- setOpen(true)
+ setOpen(true)
}}>
- )
+ )
}
diff --git a/src/Components/Map/Subcomponents/Controls/GratitudeControl.tsx b/src/Components/Map/Subcomponents/Controls/GratitudeControl.tsx
index a8f7109..49eb8ca 100644
--- a/src/Components/Map/Subcomponents/Controls/GratitudeControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/GratitudeControl.tsx
@@ -1,29 +1,27 @@
-import { useNavigate } from "react-router-dom"
-import { useAuth } from "../../../Auth";
+import { useNavigate } from 'react-router-dom'
+import { useAuth } from '../../../Auth'
export const GratitudeControl = () => {
- const navigate = useNavigate();
- const {isAuthenticated} = useAuth();
-
- if(isAuthenticated) return (
+ const navigate = useNavigate()
+ const { isAuthenticated } = useAuth()
+
+ if (isAuthenticated) {
+ return (
{
-
{
- navigate("/select-user")
+ navigate('/select-user')
}}>
-
-
}
)
- else return (<>>);
+ } else return (<>>)
}
diff --git a/src/Components/Map/Subcomponents/Controls/LayerControl.tsx b/src/Components/Map/Subcomponents/Controls/LayerControl.tsx
index 6a5df98..131c89b 100644
--- a/src/Components/Map/Subcomponents/Controls/LayerControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/LayerControl.tsx
@@ -1,49 +1,44 @@
import * as React from 'react'
-import { useLayers } from '../../hooks/useLayers';
-import { useIsLayerVisible, useToggleVisibleLayer } from '../../hooks/useFilter';
+import { useLayers } from '../../hooks/useLayers'
+import { useIsLayerVisible, useToggleVisibleLayer } from '../../hooks/useFilter'
-export function LayerControl() {
+export function LayerControl () {
+ const [open, setOpen] = React.useState(false)
- const [open, setOpen] = React.useState(false);
+ const layers = useLayers()
- const layers = useLayers();
+ const isLayerVisible = useIsLayerVisible()
+ const toggleVisibleLayer = useToggleVisibleLayer()
-
-
- const isLayerVisible = useIsLayerVisible();
- const toggleVisibleLayer = useToggleVisibleLayer();
-
- return (
+ return (
{
- open ?
-
+ open
+ ?
{
- setOpen(false)
+ setOpen(false)
}}>
β
- :
-
{
- setOpen(true)
- }}>
+ :
{
+ setOpen(true)
+ }}>
-
}
- )
+ )
}
diff --git a/src/Components/Map/Subcomponents/Controls/LocateControl.tsx b/src/Components/Map/Subcomponents/Controls/LocateControl.tsx
index 16cc2f1..d3eb458 100644
--- a/src/Components/Map/Subcomponents/Controls/LocateControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/LocateControl.tsx
@@ -7,55 +7,48 @@ import { useEffect, useRef, useState } from 'react'
// Converts leaflet.locatecontrol to a React Component
export const LocateControl = () => {
+ const map = useMap()
- const map = useMap();
+ // prevent react18 from calling useEffect twice
+ const init = useRef(false)
- // prevent react18 from calling useEffect twice
- const init = useRef(false)
+ const [lc, setLc] = useState
(null)
+ const [active, setActive] = useState(false)
+ const [loading, setLoading] = useState(false)
-
- const [lc, setLc] = useState(null);
- const [active, setActive] = useState(false);
- const [loading, setLoading] = useState(false);
-
-
- useEffect(() => {
- if (!init.current) {
- //@ts-ignore
- setLc(L.control.locate().addTo(map));
- init.current = true;
- }
+ useEffect(() => {
+ if (!init.current) {
+ // @ts-ignore
+ setLc(L.control.locate().addTo(map))
+ init.current = true
+ }
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [])
+ }, [])
- useMapEvents({
- locationfound: () => {
- setLoading(false);
- setActive(true);
- },
- })
+ useMapEvents({
+ locationfound: () => {
+ setLoading(false)
+ setActive(true)
+ }
+ })
- return (<>
+ return (<>
{
- if (active) {
- lc.stop();
- setActive(false);
- }
- else {
- lc.start();
- setLoading(true);
- }
-
- }}>{loading ?
:
-
>)
-
}
-
-
diff --git a/src/Components/Map/Subcomponents/Controls/QuestControl.tsx b/src/Components/Map/Subcomponents/Controls/QuestControl.tsx
index c6b8ba9..1147509 100644
--- a/src/Components/Map/Subcomponents/Controls/QuestControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/QuestControl.tsx
@@ -1,17 +1,16 @@
import * as React from 'react'
-import { useQuestsOpen, useSetQuestOpen } from '../../../Gaming/hooks/useQuests';
+import { useQuestsOpen, useSetQuestOpen } from '../../../Gaming/hooks/useQuests'
+export function QuestControl () {
+ const questsOpen = useQuestsOpen()
+ const setQuestsOpen = useSetQuestOpen()
-export function QuestControl() {
-
- const questsOpen = useQuestsOpen();
- const setQuestsOpen = useSetQuestOpen();
-
- return (
+ return (
<>
- {questsOpen ? "" :
- e.stopPropagation()}>
-
+ {questsOpen
+ ? ''
+ :
e.stopPropagation()}>
+
@@ -19,5 +18,5 @@ export function QuestControl() {
}
>
- )
+ )
}
diff --git a/src/Components/Map/Subcomponents/Controls/SearchControl.tsx b/src/Components/Map/Subcomponents/Controls/SearchControl.tsx
index 5615975..73be8e7 100644
--- a/src/Components/Map/Subcomponents/Controls/SearchControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/SearchControl.tsx
@@ -1,97 +1,89 @@
import * as React from 'react'
import { useAddFilterTag } from '../../hooks/useFilter'
-import useWindowDimensions from '../../hooks/useWindowDimension';
-import axios from 'axios';
-import { useEffect, useRef, useState } from 'react';
-import { useMap, useMapEvents } from 'react-leaflet';
-import { LatLng, LatLngBounds } from 'leaflet';
-import { useDebounce } from '../../hooks/useDebounce';
-import { useTags } from '../../hooks/useTags';
-import { useItems } from '../../hooks/useItems';
-import { useLeafletRefs } from '../../hooks/useLeafletRefs';
-import { getValue } from '../../../../Utils/GetValue';
-import { LocateControl } from './LocateControl';
-import * as L from 'leaflet';
-import MarkerIconFactory from '../../../../Utils/MarkerIconFactory';
-import { decodeTag } from '../../../../Utils/FormatTags';
-import { useLocation, useNavigate } from 'react-router-dom';
-import { Item } from '../../../../types';
-import { SidebarControl } from './SidebarControl';
-
-
+import useWindowDimensions from '../../hooks/useWindowDimension'
+import axios from 'axios'
+import { useEffect, useRef, useState } from 'react'
+import { useMap, useMapEvents } from 'react-leaflet'
+import { LatLng, LatLngBounds } from 'leaflet'
+import { useDebounce } from '../../hooks/useDebounce'
+import { useTags } from '../../hooks/useTags'
+import { useItems } from '../../hooks/useItems'
+import { useLeafletRefs } from '../../hooks/useLeafletRefs'
+import { getValue } from '../../../../Utils/GetValue'
+import { LocateControl } from './LocateControl'
+import * as L from 'leaflet'
+import MarkerIconFactory from '../../../../Utils/MarkerIconFactory'
+import { decodeTag } from '../../../../Utils/FormatTags'
+import { useLocation, useNavigate } from 'react-router-dom'
+import { Item } from '../../../../types'
+import { SidebarControl } from './SidebarControl'
export const SearchControl = () => {
+ const windowDimensions = useWindowDimensions()
+ const [popupOpen, setPopupOpen] = useState(false)
+
+ const [value, setValue] = useState('')
+ const [geoResults, setGeoResults] = useState
>([])
+ const [tagsResults, setTagsResults] = useState>([])
+ const [itemsResults, setItemsResults] = useState>([])
+ const [hideSuggestions, setHideSuggestions] = useState(true)
+
+ const map = useMap()
+ const tags = useTags()
+ const items = useItems()
+ const leafletRefs = useLeafletRefs()
+ const addFilterTag = useAddFilterTag()
+
+ useMapEvents({
+ popupopen: () => {
+ setPopupOpen(true)
+ },
+ popupclose: () => {
+ setPopupOpen(false)
+ }
+ })
- const windowDimensions = useWindowDimensions();
- const [popupOpen, setPopupOpen] = useState(false);
-
- const [value, setValue] = useState('');
- const [geoResults, setGeoResults] = useState>([]);
- const [tagsResults, setTagsResults] = useState>([]);
- const [itemsResults, setItemsResults] = useState>([]);
- const [hideSuggestions, setHideSuggestions] = useState(true);
-
- const map = useMap();
- const tags = useTags();
- const items = useItems();
- const leafletRefs = useLeafletRefs();
- const addFilterTag = useAddFilterTag();
-
-
- useMapEvents({
- popupopen: () => {
- setPopupOpen(true);
- },
- popupclose: () => {
- setPopupOpen(false);
- }
- })
-
- const navigate = useNavigate();
+ const navigate = useNavigate()
- useDebounce(() => {
- const searchGeo = async () => {
- try {
- const { data } = await axios.get(
+ useDebounce(() => {
+ const searchGeo = async () => {
+ try {
+ const { data } = await axios.get(
`https://photon.komoot.io/api/?q=${value}&limit=5`
- );
- setGeoResults(data.features);
- } catch (error) {
- console.log(error);
- }
- };
- searchGeo();
- setItemsResults(items.filter(item => {
- if (item.layer?.itemNameField) item.name = getValue(item, item.layer.itemNameField)
- if (item.layer?.itemTextField) item.text = getValue(item, item.layer.itemTextField)
- return value.length > 2 && ((item.layer?.listed && item.name?.toLowerCase().includes(value.toLowerCase()) || item.text?.toLowerCase().includes(value.toLowerCase())))
- }))
- let phrase = value;
- if (value.startsWith("#")) phrase = value.substring(1);
- setTagsResults(tags.filter(tag => tag.name?.toLowerCase().includes(phrase.toLowerCase())))
-
- }, 500, [value]);
-
- const hide = async () => {
- setTimeout(() => {
- setHideSuggestions(true);
- }, 200);
+ )
+ setGeoResults(data.features)
+ } catch (error) {
+ console.log(error)
+ }
}
-
- const searchInput = useRef(null);
- const [embedded, setEmbedded] = useState(true)
-
-
-
- const location = useLocation();
- useEffect(() => {
- const params = new URLSearchParams(location.search);
- const embedded = params.get("embedded");
- embedded != "true" && setEmbedded(false)
- }, [location]);
-
-
- return (<>
+ searchGeo()
+ setItemsResults(items.filter(item => {
+ if (item.layer?.itemNameField) item.name = getValue(item, item.layer.itemNameField)
+ if (item.layer?.itemTextField) item.text = getValue(item, item.layer.itemTextField)
+ return value.length > 2 && (((item.layer?.listed && item.name?.toLowerCase().includes(value.toLowerCase())) || item.text?.toLowerCase().includes(value.toLowerCase())))
+ }))
+ let phrase = value
+ if (value.startsWith('#')) phrase = value.substring(1)
+ setTagsResults(tags.filter(tag => tag.name?.toLowerCase().includes(phrase.toLowerCase())))
+ }, 500, [value])
+
+ const hide = async () => {
+ setTimeout(() => {
+ setHideSuggestions(true)
+ }, 200)
+ }
+
+ const searchInput = useRef(null)
+ const [embedded, setEmbedded] = useState(true)
+
+ const location = useLocation()
+ useEffect(() => {
+ const params = new URLSearchParams(location.search)
+ const embedded = params.get('embedded')
+ embedded !== 'true' && setEmbedded(false)
+ }, [location])
+
+ return (<>
{!(windowDimensions.height < 500 && popupOpen && hideSuggestions) &&
@@ -101,21 +93,22 @@ export const SearchControl = () => {
ref={searchInput}
onChange={(e) => setValue(e.target.value)}
onFocus={() => {
- setHideSuggestions(false);
- if (windowDimensions.width < 500) map.closePopup();
+ setHideSuggestions(false)
+ if (windowDimensions.width < 500) map.closePopup()
}}
onBlur={() => hide()} />
- {value.length > 0 && }
+ {value.length > 0 && }
- {hideSuggestions || Array.from(geoResults).length == 0 && itemsResults.length == 0 && tagsResults.length == 0 && !isGeoCoordinate(value) || value.length == 0 ? "" :
-
+ {hideSuggestions || (Array.from(geoResults).length === 0 && itemsResults.length === 0 && tagsResults.length === 0 && !isGeoCoordinate(value)) || value.length === 0
+ ? ''
+ :
{tagsResults.length > 0 &&
{tagsResults.slice(0, 3).map(tag => (
{
- addFilterTag(tag)
+ addFilterTag(tag)
}}>
#{decodeTag(tag.name)}
@@ -126,14 +119,12 @@ export const SearchControl = () => {
{itemsResults.length > 0 && tagsResults.length > 0 &&
}
{itemsResults.slice(0, 5).map(item => (
{
- const marker = Object.entries(leafletRefs).find(r => r[1].item == item)?.[1].marker;
- if (marker) {
- navigate(`/${item.id}?${new URLSearchParams(window.location.search)}`)
- }
- else {
- navigate("item/" + item.id + "?" + new URLSearchParams(window.location.search))
- }
-
+ const marker = Object.entries(leafletRefs).find(r => r[1].item === item)?.[1].marker
+ if (marker) {
+ navigate(`/${item.id}?${new URLSearchParams(window.location.search)}`)
+ } else {
+ navigate('item/' + item.id + '?' + new URLSearchParams(window.location.search))
+ }
}
}>
@@ -147,11 +138,11 @@ export const SearchControl = () => {
{Array.from(geoResults).length > 0 && (itemsResults.length > 0 || tagsResults.length > 0) &&
}
{Array.from(geoResults).map((geo) => (
{
- searchInput.current?.blur();
- L.marker(new LatLng(geo.geometry.coordinates[1], geo.geometry.coordinates[0]), { icon: MarkerIconFactory("circle", "#777", "RGBA(35, 31, 32, 0.2)", "point") }).addTo(map).bindPopup(`
${geo?.properties.name ? geo?.properties.name : value}${capitalizeFirstLetter(geo?.properties?.osm_value)}`).openPopup().addEventListener("popupclose", (e) => { console.log(e.target.remove()) });
- if (geo.properties.extent) map.fitBounds(new LatLngBounds(new LatLng(geo.properties.extent[1], geo.properties.extent[0]), new LatLng(geo.properties.extent[3], geo.properties.extent[2])));
- else map.setView(new LatLng(geo.geometry.coordinates[1], geo.geometry.coordinates[0]), 15, { duration: 1 });
- hide();
+ searchInput.current?.blur()
+ L.marker(new LatLng(geo.geometry.coordinates[1], geo.geometry.coordinates[0]), { icon: MarkerIconFactory('circle', '#777', 'RGBA(35, 31, 32, 0.2)', 'point') }).addTo(map).bindPopup(`${geo?.properties.name ? geo?.properties.name : value}${capitalizeFirstLetter(geo?.properties?.osm_value)}`).openPopup().addEventListener('popupclose', (e) => { console.log(e.target.remove()) })
+ if (geo.properties.extent) map.fitBounds(new LatLngBounds(new LatLng(geo.properties.extent[1], geo.properties.extent[0]), new LatLng(geo.properties.extent[3], geo.properties.extent[2])))
+ else map.setView(new LatLng(geo.geometry.coordinates[1], geo.geometry.coordinates[0]), 15, { duration: 1 })
+ hide()
}}>
@@ -159,15 +150,15 @@ export const SearchControl = () => {
{geo?.properties.name ? geo?.properties.name : value}
-
{geo?.properties?.city && `${capitalizeFirstLetter(geo?.properties?.city)}, `} {geo?.properties?.osm_value && geo?.properties?.osm_value !== "yes" && geo?.properties?.osm_value !== "primary" && geo?.properties?.osm_value !== "path" && geo?.properties?.osm_value !== "secondary" && geo?.properties?.osm_value !== "residential" && geo?.properties?.osm_value !== "unclassified" && `${capitalizeFirstLetter(geo?.properties?.osm_value)}, `} {geo.properties.state && `${geo.properties.state}, `} {geo.properties.country && geo.properties.country}
+
{geo?.properties?.city && `${capitalizeFirstLetter(geo?.properties?.city)}, `} {geo?.properties?.osm_value && geo?.properties?.osm_value !== 'yes' && geo?.properties?.osm_value !== 'primary' && geo?.properties?.osm_value !== 'path' && geo?.properties?.osm_value !== 'secondary' && geo?.properties?.osm_value !== 'residential' && geo?.properties?.osm_value !== 'unclassified' && `${capitalizeFirstLetter(geo?.properties?.osm_value)}, `} {geo.properties.state && `${geo.properties.state}, `} {geo.properties.country && geo.properties.country}
))}
{isGeoCoordinate(value) &&
{
- L.marker(new LatLng(extractCoordinates(value)![0], extractCoordinates(value)![1]), { icon: MarkerIconFactory("circle", "#777", "RGBA(35, 31, 32, 0.2)", "point") }).addTo(map).bindPopup(`
${extractCoordinates(value)![0]}, ${extractCoordinates(value)![1]}
`).openPopup().addEventListener("popupclose", (e) => { console.log(e.target.remove()) });
- map.setView(new LatLng(extractCoordinates(value)![0], extractCoordinates(value)![1]), 15, { duration: 1 })
+ L.marker(new LatLng(extractCoordinates(value)![0], extractCoordinates(value)![1]), { icon: MarkerIconFactory('circle', '#777', 'RGBA(35, 31, 32, 0.2)', 'point') }).addTo(map).bindPopup(`
${extractCoordinates(value)![0]}, ${extractCoordinates(value)![1]}
`).openPopup().addEventListener('popupclose', (e) => { console.log(e.target.remove()) })
+ map.setView(new LatLng(extractCoordinates(value)![0], extractCoordinates(value)![1]), 15, { duration: 1 })
}}>
@@ -175,7 +166,7 @@ export const SearchControl = () => {
{value}
-
{"Coordiante"}
+
{'Coordiante'}
}
@@ -184,26 +175,26 @@ export const SearchControl = () => {
}
>
- )
+ )
}
-function isGeoCoordinate(input) {
- const geokoordinatenRegex = /^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$/;
- return geokoordinatenRegex.test(input);
+function isGeoCoordinate (input) {
+ const geokoordinatenRegex = /^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$/
+ return geokoordinatenRegex.test(input)
}
-function extractCoordinates(input): number[] | null {
- const result = input.split(",")
- if (result) {
- const latitude = parseFloat(result[0]);
- const longitude = parseFloat(result[1]);
- if (!isNaN(latitude) && !isNaN(longitude)) {
- return [latitude, longitude];
- }
+function extractCoordinates (input): number[] | null {
+ const result = input.split(',')
+ if (result) {
+ const latitude = parseFloat(result[0])
+ const longitude = parseFloat(result[1])
+ if (!isNaN(latitude) && !isNaN(longitude)) {
+ return [latitude, longitude]
}
- return null; // Invalid input or error
+ }
+ return null // Invalid input or error
}
-function capitalizeFirstLetter(string) {
- return string.charAt(0).toUpperCase() + string.slice(1);
-}
\ No newline at end of file
+function capitalizeFirstLetter (string) {
+ return string.charAt(0).toUpperCase() + string.slice(1)
+}
diff --git a/src/Components/Map/Subcomponents/Controls/SidebarControl.tsx b/src/Components/Map/Subcomponents/Controls/SidebarControl.tsx
index b342a7f..8657e7e 100644
--- a/src/Components/Map/Subcomponents/Controls/SidebarControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/SidebarControl.tsx
@@ -1,11 +1,6 @@
-
-
// Converts leaflet.locatecontrol to a React Component
export const SidebarControl = () => {
-
-
-
- return (<>
+ return (<>
@@ -19,7 +14,4 @@ export const SidebarControl = () => {
>)
-
}
-
-
diff --git a/src/Components/Map/Subcomponents/Controls/TagsControl.tsx b/src/Components/Map/Subcomponents/Controls/TagsControl.tsx
index df4c53b..48075bd 100644
--- a/src/Components/Map/Subcomponents/Controls/TagsControl.tsx
+++ b/src/Components/Map/Subcomponents/Controls/TagsControl.tsx
@@ -1,11 +1,10 @@
import * as React from 'react'
-import { useFilterTags, useRemoveFilterTag } from '../../hooks/useFilter';
-import { decodeTag } from '../../../../Utils/FormatTags';
+import { useFilterTags, useRemoveFilterTag } from '../../hooks/useFilter'
+import { decodeTag } from '../../../../Utils/FormatTags'
export const TagsControl = () => {
-
- const filterTags = useFilterTags();
- const removeFilterTag = useRemoveFilterTag();
+ const filterTags = useFilterTags()
+ const removeFilterTag = useRemoveFilterTag()
return (
@@ -20,5 +19,3 @@ export const TagsControl = () => {
}
)
}
-
-
diff --git a/src/Components/Map/Subcomponents/ItemFormPopup.tsx b/src/Components/Map/Subcomponents/ItemFormPopup.tsx
index bde1a8c..2e731d2 100644
--- a/src/Components/Map/Subcomponents/ItemFormPopup.tsx
+++ b/src/Components/Map/Subcomponents/ItemFormPopup.tsx
@@ -21,130 +21,124 @@ export interface ItemFormPopupProps {
setItemFormPopup?: React.Dispatch
>
}
-export function ItemFormPopup(props: ItemFormPopupProps) {
-
- const [spinner, setSpinner] = useState(false);
-
- // eslint-disable-next-line no-unused-vars
- const [popupTitle, setPopupTitle] = useState("");
-
- const formRef = useRef(null);
-
- const map = useMap();
-
- const addItem = useAddItem();
- const updateItem = useUpdateItem();
- const items = useItems();
- // eslint-disable-next-line no-unused-vars
- const removeItem = useRemoveItem();
-
-
- const tags = useTags();
- const addTag = useAddTag();
-
- const resetFilterTags = useResetFilterTags();
-
- const { user } = useAuth();
-
-
- const handleSubmit = async (evt: any) => {
- const formItem: Item = {} as Item;
- Array.from(evt.target).forEach((input: HTMLInputElement) => {
- if (input.name) {
- formItem[input.name] = input.value;
- }
- });
- formItem['position'] = new Geometry(props.position.lng, props.position.lat);
- evt.preventDefault();
- setSpinner(true);
-
- formItem.text && formItem.text.toLocaleLowerCase().match(hashTagRegex)?.map(tag=> {
- if (!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
- addTag({id: crypto.randomUUID(), name: tag.slice(1), color: randomColor()})
- }
- });
-
-
-
- if(props.item) {
- let success = false;
- try {
- await props.layer.api?.updateItem!({...formItem, id: props.item.id});
- success = true;
- } catch (error) {
- toast.error(error.toString());
- }
- if(success) {
- console.log(props.item);
-
- updateItem({...props.item, ...formItem});
- toast.success("Item updated");
- }
- setSpinner(false);
- map.closePopup();
- }
- else {
- const item = items.find(i => i.user_created?.id === user?.id && i.layer?.itemType.name === props.layer.itemType.name);
-
- const uuid = crypto.randomUUID();
- let success = false;
- try {
- props.layer.onlyOnePerOwner && item && await props.layer.api?.updateItem!({...formItem, id: item?.id });
- (!props.layer.onlyOnePerOwner || !item) && await props.layer.api?.createItem!({...formItem, id: uuid, name: formItem.name ? formItem.name : user?.first_name });
- success = true;
- } catch (error) {
- toast.error(error.toString());
- }
- if(success) {
- props.layer.onlyOnePerOwner && item && updateItem({...item, ...formItem});
- (!props.layer.onlyOnePerOwner || !item) && addItem({...formItem, name: formItem.name ? formItem.name : user?.first_name , user_created: user, type: props.layer.itemType, id: uuid, layer: props.layer, public_edit: !user ? true : false});
- toast.success("New item created");
- resetFilterTags();
- }
- setSpinner(false);
- map.closePopup();
- }
- props.setItemFormPopup!(null);
+export function ItemFormPopup (props: ItemFormPopupProps) {
+ const [spinner, setSpinner] = useState(false)
+
+ // eslint-disable-next-line no-unused-vars
+ const [popupTitle, setPopupTitle] = useState('')
+
+ const formRef = useRef(null)
+
+ const map = useMap()
+
+ const addItem = useAddItem()
+ const updateItem = useUpdateItem()
+ const items = useItems()
+ // eslint-disable-next-line no-unused-vars
+ const removeItem = useRemoveItem()
+
+ const tags = useTags()
+ const addTag = useAddTag()
+
+ const resetFilterTags = useResetFilterTags()
+
+ const { user } = useAuth()
+
+ const handleSubmit = async (evt: any) => {
+ const formItem: Item = {} as Item
+ Array.from(evt.target).forEach((input: HTMLInputElement) => {
+ if (input.name) {
+ formItem[input.name] = input.value
+ }
+ })
+ formItem.position = new Geometry(props.position.lng, props.position.lat)
+ evt.preventDefault()
+ setSpinner(true)
+
+ formItem.text && formItem.text.toLocaleLowerCase().match(hashTagRegex)?.map(tag => {
+ if (!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
+ addTag({ id: crypto.randomUUID(), name: tag.slice(1), color: randomColor() })
+ }
+ return null
+ })
+
+ if (props.item) {
+ let success = false
+ try {
+ await props.layer.api?.updateItem!({ ...formItem, id: props.item.id })
+ success = true
+ } catch (error) {
+ toast.error(error.toString())
+ }
+ if (success) {
+ console.log(props.item)
+
+ updateItem({ ...props.item, ...formItem })
+ toast.success('Item updated')
+ }
+ setSpinner(false)
+ map.closePopup()
+ } else {
+ const item = items.find(i => i.user_created?.id === user?.id && i.layer?.itemType.name === props.layer.itemType.name)
+
+ const uuid = crypto.randomUUID()
+ let success = false
+ try {
+ props.layer.onlyOnePerOwner && item && await props.layer.api?.updateItem!({ ...formItem, id: item?.id });
+ (!props.layer.onlyOnePerOwner || !item) && await props.layer.api?.createItem!({ ...formItem, id: uuid, name: formItem.name ? formItem.name : user?.first_name })
+ success = true
+ } catch (error) {
+ toast.error(error.toString())
+ }
+ if (success) {
+ props.layer.onlyOnePerOwner && item && updateItem({ ...item, ...formItem });
+ (!props.layer.onlyOnePerOwner || !item) && addItem({ ...formItem, name: formItem.name ? formItem.name : user?.first_name, user_created: user, type: props.layer.itemType, id: uuid, layer: props.layer, public_edit: !user })
+ toast.success('New item created')
+ resetFilterTags()
+ }
+ setSpinner(false)
+ map.closePopup()
}
+ props.setItemFormPopup!(null)
+ }
-
- const resetPopup = () => {
- if (formRef.current) {
- formRef.current.reset();
- }
+ const resetPopup = () => {
+ if (formRef.current) {
+ formRef.current.reset()
}
+ }
- useEffect(() => {
- resetPopup();
- }, [props.position])
+ useEffect(() => {
+ resetPopup()
+ }, [props.position])
- return (
+ return (
{
- setTimeout(function () {
- resetPopup()
- }, 100);
- }
+ remove: () => {
+ setTimeout(function () {
+ resetPopup()
+ }, 100)
+ }
}}
position={props.position}>
- )
+ )
}
-
-
-
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx
index e38d191..277e1a8 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx
@@ -1,12 +1,12 @@
-import * as React from "react"
-import { Item, ItemsApi } from "../../../../types";
-import { useHasUserPermission } from "../../hooks/usePermissions";
-import { getValue } from "../../../../Utils/GetValue";
+import * as React from 'react'
+import { Item, ItemsApi } from '../../../../types'
+import { useHasUserPermission } from '../../hooks/usePermissions'
+import { getValue } from '../../../../Utils/GetValue'
import { useAssetApi } from '../../../AppShell/hooks/useAssets'
-import DialogModal from "../../../Templates/DialogModal";
-import { useNavigate } from "react-router-dom";
+import DialogModal from '../../../Templates/DialogModal'
+import { useNavigate } from 'react-router-dom'
-export function HeaderView({ item, api, editCallback, deleteCallback, setPositionCallback, itemNameField, itemSubnameField, itemAvatarField, loading, hideMenu = false, big = false, truncateSubname = true, hideSubname = false, showAddress = false }: {
+export function HeaderView ({ item, api, editCallback, deleteCallback, setPositionCallback, itemNameField, itemSubnameField, itemAvatarField, loading, hideMenu = false, big = false, truncateSubname = true, hideSubname = false, showAddress = false }: {
item: Item,
api?: ItemsApi
,
editCallback?: any,
@@ -22,63 +22,58 @@ export function HeaderView({ item, api, editCallback, deleteCallback, setPositio
truncateSubname?: boolean,
showAddress?: boolean
}) {
+ const [modalOpen, setModalOpen] = React.useState(false)
+ const hasUserPermission = useHasUserPermission()
+ const navigate = useNavigate()
+ const assetsApi = useAssetApi()
- const [modalOpen, setModalOpen] = React.useState(false);
+ const avatar = itemAvatarField && getValue(item, itemAvatarField) ? assetsApi.url + getValue(item, itemAvatarField) + `${big ? '?width=160&heigth=160' : '?width=80&heigth=80'}` : item.layer?.itemAvatarField && item && getValue(item, item.layer?.itemAvatarField) && assetsApi.url + getValue(item, item.layer?.itemAvatarField) + `${big ? '?width=160&heigth=160' : '?width=80&heigth=80'}`
+ const title = itemNameField ? getValue(item, itemNameField) : item.layer?.itemNameField && item && getValue(item, item.layer?.itemNameField)
+ const subtitle = itemSubnameField ? getValue(item, itemSubnameField) : item.layer?.itemSubnameField && item && getValue(item, item.layer?.itemSubnameField)
- const hasUserPermission = useHasUserPermission();
- const navigate = useNavigate();
- const assetsApi = useAssetApi();
-
- const avatar = itemAvatarField && getValue(item, itemAvatarField) ? assetsApi.url + getValue(item, itemAvatarField) + `${big ? "?width=160&heigth=160" : "?width=80&heigth=80"}` : item.layer?.itemAvatarField && item && getValue(item, item.layer?.itemAvatarField) && assetsApi.url + getValue(item, item.layer?.itemAvatarField) + `${big ? "?width=160&heigth=160" : "?width=80&heigth=80"}`;
- const title = itemNameField ? getValue(item, itemNameField) : item.layer?.itemNameField && item && getValue(item, item.layer?.itemNameField);
- const subtitle = itemSubnameField ? getValue(item, itemSubnameField) : item.layer?.itemSubnameField && item && getValue(item, item.layer?.itemSubnameField);
-
- const [address, /* setAdress*/] = React.useState("");
-
- const params = new URLSearchParams(window.location.search);
+ const [address] = React.useState('')
+ const params = new URLSearchParams(window.location.search)
const openDeleteModal = async (event: React.MouseEvent) => {
- setModalOpen(true);
- event.stopPropagation();
+ setModalOpen(true)
+ event.stopPropagation()
}
-
-
return (
<>
-
+
{avatar && (
-
)}
-
-
+
+
{title}
- {showAddress && address && !hideSubname &&
+ {showAddress && address && !hideSubname &&
{address}
}
- {subtitle && !hideSubname &&
+ {subtitle && !hideSubname &&
{subtitle}
}
-
e.stopPropagation()} className={`${big ? "tw-mt-5" : "tw-mt-1"}`}>
- {(api?.deleteItem || item.layer?.api?.updateItem)
- && (hasUserPermission(api?.collectionName!, "delete", item) || hasUserPermission(api?.collectionName!, "update", item))
- && !hideMenu &&
+
e.stopPropagation()} className={`${big ? 'tw-mt-5' : 'tw-mt-1'}`}>
+ {(api?.deleteItem || item.layer?.api?.updateItem) &&
+ (hasUserPermission(api?.collectionName!, 'delete', item) || hasUserPermission(api?.collectionName!, 'update', item)) &&
+ !hideMenu &&
@@ -86,25 +81,25 @@ export function HeaderView({ item, api, editCallback, deleteCallback, setPositio
- {((api?.updateItem && hasUserPermission(api.collectionName!, "update", item))) && editCallback && -
- item.layer?.customEditLink ? navigate(`${item.layer.customEditLink}${item.layer.customEditParameter ? `/${getValue(item, item.layer.customEditParameter)}${params && "?"+params}` : ""} `) : editCallback(e)}>
+ {((api?.updateItem && hasUserPermission(api.collectionName!, 'update', item))) && editCallback &&
-
+ item.layer?.customEditLink ? navigate(`${item.layer.customEditLink}${item.layer.customEditParameter ? `/${getValue(item, item.layer.customEditParameter)}${params && '?' + params}` : ''} `) : editCallback(e)}>
}
- {((api?.updateItem && hasUserPermission(api.collectionName!, "update", item))) && setPositionCallback && -
+ {((api?.updateItem && hasUserPermission(api.collectionName!, 'update', item))) && setPositionCallback &&
-
}
- {api?.deleteItem && hasUserPermission(api.collectionName!, "delete", item) && deleteCallback && -
+ {api?.deleteItem && hasUserPermission(api.collectionName!, 'delete', item) && deleteCallback &&
-
- {loading ?
- :
-
+ {loading
+ ?
+ :
}
@@ -119,7 +114,7 @@ export function HeaderView({ item, api, editCallback, deleteCallback, setPositio
Do you want to delete {item.name}?
- { deleteCallback(e); setModalOpen(false); }}>Yes
+ { deleteCallback(e); setModalOpen(false) }}>Yes
setModalOpen(false)}>No
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupButton.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupButton.tsx
index b01fa60..aaed0a9 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupButton.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupButton.tsx
@@ -1,19 +1,14 @@
import { Link } from 'react-router-dom'
import { getValue } from '../../../../Utils/GetValue'
import { Item } from '../../../../types'
-import { useGetItemTags } from '../../hooks/useTags';
+import { useGetItemTags } from '../../hooks/useTags'
+export const PopupButton = ({ url, parameterField, text, colorField, item } : {url: string, parameterField?: string, text: string, colorField?: string, item? : Item}) => {
+ const params = new URLSearchParams(window.location.search)
+ const getItemTags = useGetItemTags()
-export const PopupButton = ({url, parameterField, text, colorField, item} : {url: string, parameterField?: string, text: string, colorField?: string, item? : Item}) => {
+ return (
+
- const params = new URLSearchParams(window.location.search);
- const getItemTags = useGetItemTags();
-
-
-
-
- return (
-
-
- )
+ )
}
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupCheckboxInput.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupCheckboxInput.tsx
index c38f55a..b2b4af7 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupCheckboxInput.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupCheckboxInput.tsx
@@ -6,8 +6,7 @@ export const PopupCheckboxInput = ({ dataField, label, item }:
label: string,
item?: Item
}) => {
-
- return (
+ return (
{label}
- )
+ )
}
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupStartEndInput.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupStartEndInput.tsx
index 1729044..0744237 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupStartEndInput.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupStartEndInput.tsx
@@ -6,16 +6,16 @@ type StartEndInputProps = {
item?:Item,
showLabels?: boolean
// eslint-disable-next-line no-unused-vars
- updateStartValue?: (value: string ) => void;
+ updateStartValue?: (value: string) => void;
// eslint-disable-next-line no-unused-vars
- updateEndValue?: (value: string ) => void;
+ updateEndValue?: (value: string) => void;
}
-export const PopupStartEndInput = ({item, showLabels = true, updateStartValue, updateEndValue}:StartEndInputProps) => {
- return (
+export const PopupStartEndInput = ({ item, showLabels = true, updateStartValue, updateEndValue }:StartEndInputProps) => {
+ return (
-
-
+
+
- )
+ )
}
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextAreaInput.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextAreaInput.tsx
index 693220c..b52b0d9 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextAreaInput.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextAreaInput.tsx
@@ -9,8 +9,7 @@ export const PopupTextAreaInput = ({ dataField, placeholder, style, item }:
style?: string,
item?: Item
}) => {
-
- return (
-
- )
+ return (
+
+ )
}
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextInput.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextInput.tsx
index 10f15a8..ede1a2a 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextInput.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/PopupTextInput.tsx
@@ -9,8 +9,7 @@ export const PopupTextInput = ({ dataField, placeholder, style, item }:
style?: string,
item?: Item
}) => {
-
- return (
-
- )
+ return (
+
+ )
}
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx
index c834d1d..4e5d731 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/StartEndView.tsx
@@ -1,14 +1,14 @@
import * as React from 'react'
import { Item } from '../../../../types'
-export const StartEndView = ({item} : {item?:Item}) => {
+export const StartEndView = ({ item } : {item?:Item}) => {
return (
-
+
-
@@ -17,9 +17,8 @@ export const StartEndView = ({item} : {item?:Item}) => {
-
+
)
}
-
diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx
index 89a5363..0d36a98 100644
--- a/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx
+++ b/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx
@@ -1,95 +1,95 @@
-import { Item } from '../../../../types';
-import { useTags } from '../../hooks/useTags';
-import { useAddFilterTag } from '../../hooks/useFilter';
-import { hashTagRegex } from '../../../../Utils/HashTagRegex';
-import { fixUrls, mailRegex } from '../../../../Utils/ReplaceURLs';
-import Markdown from 'react-markdown';
-import { getValue } from '../../../../Utils/GetValue';
-import remarkBreaks from 'remark-breaks';
-import { decodeTag } from '../../../../Utils/FormatTags';
-import { memo } from 'react';
+import { Item } from '../../../../types'
+import { useTags } from '../../hooks/useTags'
+import { useAddFilterTag } from '../../hooks/useFilter'
+import { hashTagRegex } from '../../../../Utils/HashTagRegex'
+import { fixUrls, mailRegex } from '../../../../Utils/ReplaceURLs'
+import Markdown from 'react-markdown'
+import { getValue } from '../../../../Utils/GetValue'
+import remarkBreaks from 'remark-breaks'
+import { decodeTag } from '../../../../Utils/FormatTags'
+import { memo } from 'react'
export const TextView = ({ item, truncate = false, itemTextField, rawText }: { item?: Item, truncate?: boolean, itemTextField?: string, rawText?: string }) => {
- const tags = useTags();
- const addFilterTag = useAddFilterTag();
+ const tags = useTags()
+ const addFilterTag = useAddFilterTag()
- let text = "";
- let replacedText = "";
+ let text = ''
+ let replacedText = ''
- if (rawText)
- text = replacedText = rawText;
- else if (itemTextField && item)
- text = getValue(item, itemTextField);
- else
- text = item?.layer?.itemTextField && item ? getValue(item, item.layer?.itemTextField) : "";
+ if (rawText) { text = replacedText = rawText } else if (itemTextField && item) { text = getValue(item, itemTextField) } else { text = item?.layer?.itemTextField && item ? getValue(item, item.layer?.itemTextField) : '' }
- if (item && text && truncate) text = truncateText(removeMarkdownKeepLinksAndParagraphs(text), 100);
+ if (item && text && truncate) text = truncateText(removeMarkdownKeepLinksAndParagraphs(text), 100)
-
- item && text ? replacedText = fixUrls(text) : "";
+ if (item && text) replacedText = fixUrls(text)
// eslint-disable-next-line no-useless-escape
- replacedText ? replacedText = replacedText.replace(/(? {
- let shortUrl = url;
- // eslint-disable-next-line no-useless-escape
- if (url.match('^https:\/\/')) {
- shortUrl = url.split('https://')[1];
- }
- // eslint-disable-next-line no-useless-escape
- if (url.match('^http:\/\/')) {
- shortUrl = url.split('http://')[1];
- }
- return `[${shortUrl}](${url})`;
- }) : "";
+ if (replacedText) {
+ replacedText = replacedText.replace(/(? {
+ let shortUrl = url
+ // eslint-disable-next-line no-useless-escape
+ if (url.match('^https:\/\/')) {
+ shortUrl = url.split('https://')[1]
+ }
+ // eslint-disable-next-line no-useless-escape
+ if (url.match('^http:\/\/')) {
+ shortUrl = url.split('http://')[1]
+ }
+ return `[${shortUrl}](${url})`
+ })
+ }
- replacedText ? replacedText = replacedText.replace(mailRegex, (url) => {
- return `[${url}](mailto:${url})`;
- }) : "";
+ if (replacedText) {
+ replacedText = replacedText.replace(mailRegex, (url) => {
+ return `[${url}](mailto:${url})`
+ })
+ }
- replacedText ? replacedText = replacedText.replace(hashTagRegex, (match) => {
- return `[${match}](${match})`;
- }) : "";
+ if (replacedText) {
+ replacedText = replacedText.replace(hashTagRegex, (match) => {
+ return `[${match}](${match})`
+ })
+ }
// eslint-disable-next-line react/prop-types
const CustomH1 = ({ children }) => (
{children}
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomH2 = ({ children }) => (
{children}
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomH3 = ({ children }) => (
{children}
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomH4 = ({ children }) => (
{children}
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomH5 = ({ children }) => (
{children}
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomH6 = ({ children }) => (
{children}
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomParagraph = ({ children }) => (
{children}
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomUnorderdList = ({ children }) => (
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomOrderdList = ({ children }) => (
{children}
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomHorizontalRow = ({ children }) => (
{children}
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomImage = ({ alt, src, title }) => (
- );
+ )
// eslint-disable-next-line react/prop-types
const CustomExternalLink = ({ href, children }) => (
{children}
- );
+ )
/* eslint-disable react/prop-types */
const CustomHashTagLink = ({ children, tag, item }) => {
return (
@@ -113,11 +113,11 @@ export const TextView = ({ item, truncate = false, itemTextField, rawText }: { i
style={{ color: tag ? tag.color : '#faa', fontWeight: 'bold', cursor: 'pointer' }}
key={tag ? tag.name + item!.id : item.id}
onClick={(e) => {
- e.stopPropagation();
- addFilterTag(tag!);
+ e.stopPropagation()
+ addFilterTag(tag!)
}}>{decodeTag(children)}
)
- };
+ }
/* eslint-enable react/prop-types */
// eslint-disable-next-line react/display-name
@@ -128,40 +128,39 @@ export const TextView = ({ item, truncate = false, itemTextField, rawText }: { i
allow="fullscreen; picture-in-picture"
allowFullScreen
/>
- ));
+ ))
return (
- {
// eslint-disable-next-line react/prop-types
- const isYouTubeVideo = href?.startsWith('https://www.youtube.com/watch?v=');
+ const isYouTubeVideo = href?.startsWith('https://www.youtube.com/watch?v=')
// eslint-disable-next-line react/prop-types
- const isRumbleVideo = href?.startsWith('https://rumble.com/embed/');
-
+ const isRumbleVideo = href?.startsWith('https://rumble.com/embed/')
if (isYouTubeVideo) {
// eslint-disable-next-line react/prop-types
- const videoId = href?.split('v=')[1].split('&')[0];
- const youtubeEmbedUrl = `https://www.youtube-nocookie.com/embed/${videoId}`;
+ const videoId = href?.split('v=')[1].split('&')[0]
+ const youtubeEmbedUrl = `https://www.youtube-nocookie.com/embed/${videoId}`
return (
- );
+ )
}
if (isRumbleVideo) {
return (
- );
+ )
}
// eslint-disable-next-line react/prop-types
- if (href?.startsWith("#")) {
- const tag = tags.find(t => t.name.toLowerCase() === decodeURI(href).slice(1).toLowerCase());
- return {children};
+ if (href?.startsWith('#')) {
+ const tag = tags.find(t => t.name.toLowerCase() === decodeURI(href).slice(1).toLowerCase())
+ return {children}
} else {
return (
{children}
- );
+ )
}
},
ul: CustomUnorderdList,
@@ -173,14 +172,14 @@ export const TextView = ({ item, truncate = false, itemTextField, rawText }: { i
h3: CustomH3,
h4: CustomH4,
h5: CustomH5,
- h6: CustomH6,
+ h6: CustomH6
}}>
{replacedText}
- );
-};
+ )
+}
-function removeMarkdownKeepLinksAndParagraphs(text) {
+function removeMarkdownKeepLinksAndParagraphs (text) {
// Remove Markdown syntax using regular expressions but keep links and paragraphs
return text
.replace(/!\[.*?\]\(.*?\)/g, '') // Remove images
@@ -189,29 +188,29 @@ function removeMarkdownKeepLinksAndParagraphs(text) {
.replace(/(#+)\s+(.*)/g, '$2') // Remove headers
.replace(/>\s+(.*)/g, '$1') // Remove blockquotes
.replace(/^\s*\n/gm, '\n') // Preserve empty lines
- .replace(/(\r\n|\n|\r)/gm, '\n'); // Preserve line breaks
+ .replace(/(\r\n|\n|\r)/gm, '\n') // Preserve line breaks
}
-function truncateText(text, limit) {
+function truncateText (text, limit) {
if (text.length <= limit) {
- return text;
+ return text
}
- let truncated = "";
- let length = 0;
+ let truncated = ''
+ let length = 0
// Split the text by paragraphs
- const paragraphs = text.split('\n');
+ const paragraphs = text.split('\n')
for (const paragraph of paragraphs) {
if (length + paragraph.length > limit) {
- truncated += paragraph.slice(0, limit - length) + '...';
- break;
+ truncated += paragraph.slice(0, limit - length) + '...'
+ break
} else {
- truncated += paragraph + '\n';
- length += paragraph.length;
+ truncated += paragraph + '\n'
+ length += paragraph.length
}
}
- return truncated.trim();
+ return truncated.trim()
}
diff --git a/src/Components/Map/Subcomponents/ItemViewPopup.tsx b/src/Components/Map/Subcomponents/ItemViewPopup.tsx
index b7566ec..e1dc56a 100644
--- a/src/Components/Map/Subcomponents/ItemViewPopup.tsx
+++ b/src/Components/Map/Subcomponents/ItemViewPopup.tsx
@@ -12,92 +12,82 @@ import { useRemoveItem, useUpdateItem } from '../hooks/useItems'
import { toast } from 'react-toastify'
import { useSetSelectPosition } from '../hooks/useSelectPosition'
-
export interface ItemViewPopupProps {
item: Item,
children?: React.ReactNode;
setItemFormPopup?: React.Dispatch>
}
-
-
-
// eslint-disable-next-line react/display-name
export const ItemViewPopup = React.forwardRef((props: ItemViewPopupProps, ref: any) => {
- const map = useMap();
- const [loading, setLoading] = React.useState(false);
- const removeItem = useRemoveItem();
- const updadateItem = useUpdateItem();
- const navigate = useNavigate();
- const setSelectPosition = useSetSelectPosition();
-
+ const map = useMap()
+ const [loading, setLoading] = React.useState(false)
+ const removeItem = useRemoveItem()
+ const updadateItem = useUpdateItem()
+ const navigate = useNavigate()
+ const setSelectPosition = useSetSelectPosition()
- const [infoExpanded, setInfoExpanded] = useState(false);
+ const [infoExpanded, setInfoExpanded] = useState(false)
const handleEdit = (event: React.MouseEvent) => {
- event.stopPropagation();
- map.closePopup();
+ event.stopPropagation()
+ map.closePopup()
props.setItemFormPopup && props.setItemFormPopup({ position: new LatLng(props.item.position?.coordinates[1]!, props.item.position?.coordinates[0]!), layer: props.item.layer!, item: props.item, setItemFormPopup: props.setItemFormPopup })
}
const handleDelete = async (event: React.MouseEvent) => {
- event.stopPropagation();
- setLoading(true);
- let success = false;
+ event.stopPropagation()
+ setLoading(true)
+ let success = false
try {
- !props.item.layer?.onlyOnePerOwner && await props.item.layer?.api?.deleteItem!(props.item.id);
- props.item.layer?.onlyOnePerOwner && await props.item.layer.api?.updateItem!({id: props.item.id, position: null})
- success = true;
+ !props.item.layer?.onlyOnePerOwner && await props.item.layer?.api?.deleteItem!(props.item.id)
+ props.item.layer?.onlyOnePerOwner && await props.item.layer.api?.updateItem!({ id: props.item.id, position: null })
+ success = true
} catch (error) {
- toast.error(error.toString());
+ toast.error(error.toString())
}
if (success) {
- !props.item.layer?.onlyOnePerOwner && removeItem(props.item);
- props.item.layer?.onlyOnePerOwner && updadateItem({...props.item, position: undefined});
- toast.success("Item deleted");
+ !props.item.layer?.onlyOnePerOwner && removeItem(props.item)
+ props.item.layer?.onlyOnePerOwner && updadateItem({ ...props.item, position: undefined })
+ toast.success('Item deleted')
}
- setLoading(false);
- map.closePopup();
- const params = new URLSearchParams(window.location.search);
- window.history.pushState({}, "", "/" + `${params ? `?${params}` : ""}`);
- navigate("/");
+ setLoading(false)
+ map.closePopup()
+ const params = new URLSearchParams(window.location.search)
+ window.history.pushState({}, '', '/' + `${params ? `?${params}` : ''}`)
+ navigate('/')
}
-
return (
-
{map.closePopup();setSelectPosition(props.item); navigate("/")}} loading={loading}/>
+ { map.closePopup(); setSelectPosition(props.item); navigate('/') }} loading={loading}/>
- {props.children ?
+ {props.children
- React.Children.toArray(props.children).map((child) =>
- React.isValidElement<{ item: Item, test: string }>(child) ?
- React.cloneElement(child, { item: props.item }) : ""
+ ? React.Children.toArray(props.children).map((child) =>
+ React.isValidElement<{ item: Item, test: string }>(child)
+ ? React.cloneElement(child, { item: props.item })
+ : ''
)
- :
-
-
+ :
}
-
{
- infoExpanded ?
-
{`${props.item.date_updated && props.item.date_updated != props.item.date_created ? "updated" : "posted" } ${props.item && props.item.user_created && props.item.user_created.first_name ? `by ${props.item.user_created.first_name}` : ""} ${props.item.date_updated ? timeAgo(props.item.date_updated) : timeAgo(props.item.date_created!)}`}
- :
-
setInfoExpanded(true)}>β
+ infoExpanded
+ ?
{`${props.item.date_updated && props.item.date_updated !== props.item.date_created ? 'updated' : 'posted'} ${props.item && props.item.user_created && props.item.user_created.first_name ? `by ${props.item.user_created.first_name}` : ''} ${props.item.date_updated ? timeAgo(props.item.date_updated) : timeAgo(props.item.date_created!)}`}
+ :
setInfoExpanded(true)}>β
}
- { //**
*/
+ { //* *
*/
}
)
})
-
diff --git a/src/Components/Map/Subcomponents/SelectPosition.tsx b/src/Components/Map/Subcomponents/SelectPosition.tsx
index a314460..c76e718 100644
--- a/src/Components/Map/Subcomponents/SelectPosition.tsx
+++ b/src/Components/Map/Subcomponents/SelectPosition.tsx
@@ -1,9 +1,8 @@
-
-export const SelectPosition = ({ setSelectNewItemPosition }: { setSelectNewItemPosition }) => {
- return (
+export const SelectPosition = ({ setSelectNewItemPosition }: { setSelectNewItemPosition }) => {
+ return (
{
- setSelectNewItemPosition(null)
+ setSelectNewItemPosition(null)
}}>
β
@@ -12,5 +11,5 @@ export const SelectPosition = ({ setSelectNewItemPosition }: { setSelectNewItem
- )
+ )
}
diff --git a/src/Components/Map/Tags.tsx b/src/Components/Map/Tags.tsx
index c52f346..400a04c 100644
--- a/src/Components/Map/Tags.tsx
+++ b/src/Components/Map/Tags.tsx
@@ -1,43 +1,42 @@
import * as React from 'react'
-import { useEffect } from 'react';
-import { ItemsApi, Tag } from '../../types';
+import { useEffect } from 'react'
+import { ItemsApi, Tag } from '../../types'
import { useSetTagData, useSetTagApi, useTags } from './hooks/useTags'
-import { useLocation } from 'react-router-dom';
-import { useAddFilterTag, useFilterTags, useResetFilterTags } from './hooks/useFilter';
-
-export function Tags({data, api} : {data?: Tag[], api?: ItemsApi
}) {
-const setTagData = useSetTagData();
-const setTagApi = useSetTagApi();
-
-useEffect(() => {
- data && setTagData(data);
- api && setTagApi(api);
-// eslint-disable-next-line react-hooks/exhaustive-deps
-}, [api, data])
-
-
-const location = useLocation();
-const addFilterTag = useAddFilterTag();
-const resetFilterTags = useResetFilterTags();
-const tags = useTags();
-const filterTags = useFilterTags()
-
-
-useEffect(() => {
- const params = new URLSearchParams(location.search);
- const urlTags = params.get("tags")
- const decodedTags = urlTags ? decodeURIComponent(urlTags) : "";
- const decodedTagsArray = decodedTags.split(";");
- if(decodedTagsArray?.some(ut => !filterTags.find(ft => ut.toLocaleLowerCase() === ft.name.toLocaleLowerCase()))||filterTags?.some(ft => !decodedTagsArray?.find(ut => ut.toLocaleLowerCase() === ft.name.toLocaleLowerCase())))
- {resetFilterTags()
- decodedTagsArray?.map(urlTag => {
- const tag = tags.find(t => t.name.toLocaleLowerCase() === urlTag.toLocaleLowerCase())
- tag && addFilterTag(tag)
- });}
-
-// eslint-disable-next-line react-hooks/exhaustive-deps
-}, [location, tags]);
-
+import { useLocation } from 'react-router-dom'
+import { useAddFilterTag, useFilterTags, useResetFilterTags } from './hooks/useFilter'
+
+export function Tags ({ data, api } : {data?: Tag[], api?: ItemsApi}) {
+ const setTagData = useSetTagData()
+ const setTagApi = useSetTagApi()
+
+ useEffect(() => {
+ data && setTagData(data)
+ api && setTagApi(api)
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [api, data])
+
+ const location = useLocation()
+ const addFilterTag = useAddFilterTag()
+ const resetFilterTags = useResetFilterTags()
+ const tags = useTags()
+ const filterTags = useFilterTags()
+
+ useEffect(() => {
+ const params = new URLSearchParams(location.search)
+ const urlTags = params.get('tags')
+ const decodedTags = urlTags ? decodeURIComponent(urlTags) : ''
+ const decodedTagsArray = decodedTags.split(';')
+ if (decodedTagsArray?.some(ut => !filterTags.find(ft => ut.toLocaleLowerCase() === ft.name.toLocaleLowerCase())) || filterTags?.some(ft => !decodedTagsArray?.find(ut => ut.toLocaleLowerCase() === ft.name.toLocaleLowerCase()))) {
+ resetFilterTags()
+ decodedTagsArray?.map(urlTag => {
+ const tag = tags.find(t => t.name.toLocaleLowerCase() === urlTag.toLocaleLowerCase())
+ tag && addFilterTag(tag)
+ return null
+ })
+ }
+
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [location, tags])
return (
<>>
diff --git a/src/Components/Map/UtopiaMap.tsx b/src/Components/Map/UtopiaMap.tsx
index a5b0e32..52715bb 100644
--- a/src/Components/Map/UtopiaMap.tsx
+++ b/src/Components/Map/UtopiaMap.tsx
@@ -1,15 +1,14 @@
-import { UtopiaMapProps } from "../../types";
-import { ContextWrapper } from "../AppShell/ContextWrapper";
-import { UtopiaMapInner } from "./UtopiaMapInner";
-import 'react-toastify/dist/ReactToastify.css';
+import { UtopiaMapProps } from '../../types'
+import { ContextWrapper } from '../AppShell/ContextWrapper'
+import { UtopiaMapInner } from './UtopiaMapInner'
+import 'react-toastify/dist/ReactToastify.css'
-
-function UtopiaMap(props: UtopiaMapProps) {
- return (
+function UtopiaMap (props: UtopiaMapProps) {
+ return (
- );
+ )
}
-export { UtopiaMap };
+export { UtopiaMap }
diff --git a/src/Components/Map/UtopiaMapInner.tsx b/src/Components/Map/UtopiaMapInner.tsx
index 7ab0874..f920914 100644
--- a/src/Components/Map/UtopiaMapInner.tsx
+++ b/src/Components/Map/UtopiaMapInner.tsx
@@ -1,107 +1,104 @@
-import { TileLayer, MapContainer, useMapEvents, GeoJSON } from "react-leaflet";
-import "leaflet/dist/leaflet.css";
-import * as React from "react";
-import { UtopiaMapProps } from "../../types";
-import "./UtopiaMap.css";
-import { LatLng } from "leaflet";
-import MarkerClusterGroup from 'react-leaflet-cluster';
-import AddButton from "./Subcomponents/AddButton";
-import { useEffect, useRef, useState } from "react";
-import { ItemFormPopupProps } from "./Subcomponents/ItemFormPopup";
-import { SearchControl } from "./Subcomponents/Controls/SearchControl";
-import { Control } from "./Subcomponents/Controls/Control";
-import { Outlet } from "react-router-dom";
-import { TagsControl } from "./Subcomponents/Controls/TagsControl";
-import { useSelectPosition, useSetMapClicked, useSetSelectPosition } from "./hooks/useSelectPosition";
-import { useClusterRef, useSetClusterRef } from "./hooks/useClusterRef";
-import { Feature, Geometry as GeoJSONGeometry } from 'geojson';
-import { FilterControl } from "./Subcomponents/Controls/FilterControl";
-import { LayerControl } from "./Subcomponents/Controls/LayerControl";
-import { useLayers } from "./hooks/useLayers";
-import { useAddVisibleLayer } from "./hooks/useFilter";
-import { GratitudeControl } from "./Subcomponents/Controls/GratitudeControl";
-import { SelectPosition } from "./Subcomponents/SelectPosition";
+import { TileLayer, MapContainer, useMapEvents, GeoJSON } from 'react-leaflet'
+import 'leaflet/dist/leaflet.css'
+import * as React from 'react'
+import { UtopiaMapProps } from '../../types'
+import './UtopiaMap.css'
+import { LatLng } from 'leaflet'
+import MarkerClusterGroup from 'react-leaflet-cluster'
+import AddButton from './Subcomponents/AddButton'
+import { useEffect, useRef, useState } from 'react'
+import { ItemFormPopupProps } from './Subcomponents/ItemFormPopup'
+import { SearchControl } from './Subcomponents/Controls/SearchControl'
+import { Control } from './Subcomponents/Controls/Control'
+import { Outlet } from 'react-router-dom'
+import { TagsControl } from './Subcomponents/Controls/TagsControl'
+import { useSelectPosition, useSetMapClicked, useSetSelectPosition } from './hooks/useSelectPosition'
+import { useClusterRef, useSetClusterRef } from './hooks/useClusterRef'
+import { Feature, Geometry as GeoJSONGeometry } from 'geojson'
+import { FilterControl } from './Subcomponents/Controls/FilterControl'
+import { LayerControl } from './Subcomponents/Controls/LayerControl'
+import { useLayers } from './hooks/useLayers'
+import { useAddVisibleLayer } from './hooks/useFilter'
+import { GratitudeControl } from './Subcomponents/Controls/GratitudeControl'
+import { SelectPosition } from './Subcomponents/SelectPosition'
import { toast } from 'react-toastify'
-import { TextView } from "./Subcomponents/ItemPopupComponents/TextView";
+import { TextView } from './Subcomponents/ItemPopupComponents/TextView'
+const mapDivRef = React.createRef()
-const mapDivRef = React.createRef();
-
-export function UtopiaMapInner({
- height = "500px",
- width = "100%",
- center = [50.6, 9.5],
- zoom = 10,
- children,
- geo,
- showFilterControl = false,
- showGratitudeControl = false,
- showLayerControl = true,
- infoText
+export function UtopiaMapInner ({
+ height = '500px',
+ width = '100%',
+ center = [50.6, 9.5],
+ zoom = 10,
+ children,
+ geo,
+ showFilterControl = false,
+ showGratitudeControl = false,
+ showLayerControl = true,
+ infoText
}: UtopiaMapProps) {
+ // Hooks that rely on contexts, called after ContextWrapper is provided
+ const selectNewItemPosition = useSelectPosition()
+ const setSelectNewItemPosition = useSetSelectPosition()
+ const setClusterRef = useSetClusterRef()
+ const clusterRef = useClusterRef()
+ const setMapClicked = useSetMapClicked()
+ const [itemFormPopup, setItemFormPopup] = useState(null)
- // Hooks that rely on contexts, called after ContextWrapper is provided
- const selectNewItemPosition = useSelectPosition();
- const setSelectNewItemPosition = useSetSelectPosition();
- const setClusterRef = useSetClusterRef();
- const clusterRef = useClusterRef();
- const setMapClicked = useSetMapClicked();
- const [itemFormPopup, setItemFormPopup] = useState(null);
+ const layers = useLayers()
+ const addVisibleLayer = useAddVisibleLayer()
- const layers = useLayers();
- const addVisibleLayer = useAddVisibleLayer();
+ useEffect(() => {
+ layers.forEach(layer => addVisibleLayer(layer))
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [layers])
- useEffect(() => {
- layers.forEach(layer => addVisibleLayer(layer));
+ const init = useRef(false)
+ useEffect(() => {
+ if (!init.current) {
+ infoText && setTimeout(() => {
+ toast(, { autoClose: false })
+ }, 4000)
+ init.current = true
+ }
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [layers]);
+ }, [])
- const init = useRef(false)
- useEffect(() => {
- if (!init.current) {
- infoText && setTimeout(() => {
- toast(, { autoClose: false});
- }, 4000);
- init.current=true;
+ function MapEventListener () {
+ useMapEvents({
+ click: (e) => {
+ resetMetaTags()
+ console.log(e.latlng.lat + ',' + e.latlng.lng)
+ if (selectNewItemPosition) {
+ setMapClicked({ position: e.latlng, setItemFormPopup })
}
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [])
-
+ },
+ moveend: () => { }
+ })
+ return null
+ }
- function MapEventListener() {
- useMapEvents({
- click: (e) => {
- resetMetaTags();
- console.log(e.latlng.lat + ',' + e.latlng.lng);
- if (selectNewItemPosition) {
- setMapClicked({ position: e.latlng, setItemFormPopup: setItemFormPopup });
- }
- },
- moveend: () => { }
- });
- return null;
+ const resetMetaTags = () => {
+ const params = new URLSearchParams(window.location.search)
+ if (!window.location.pathname.includes('/item/')) {
+ window.history.pushState({}, '', '/' + `${params.toString() !== '' ? `?${params}` : ''}`)
}
+ document.title = document.title.split('-')[0]
+ document.querySelector('meta[property="og:title"]')?.setAttribute('content', document.title)
+ document.querySelector('meta[property="og:description"]')?.setAttribute('content', `${document.querySelector('meta[name="description"]')?.getAttribute('content')}`)
+ }
- const resetMetaTags = () => {
- const params = new URLSearchParams(window.location.search);
- if (!window.location.pathname.includes("/item/")) {
- window.history.pushState({}, "", `/` + `${params.toString() !== "" ? `?${params}` : ""}`);
- }
- document.title = document.title.split("-")[0];
- document.querySelector('meta[property="og:title"]')?.setAttribute("content", document.title);
- document.querySelector('meta[property="og:description"]')?.setAttribute("content", `${document.querySelector('meta[name="description"]')?.getAttribute("content")}`);
- };
-
- // eslint-disable-next-line no-undef
- const onEachFeature = (feature: Feature, layer: L.Layer) => {
- if (feature.properties) {
- layer.bindPopup(feature.properties.name);
- }
- };
+ // eslint-disable-next-line no-undef
+ const onEachFeature = (feature: Feature, layer: L.Layer) => {
+ if (feature.properties) {
+ layer.bindPopup(feature.properties.name)
+ }
+ }
- return (
-
-
+ return (
+
+
@@ -120,9 +117,9 @@ export function UtopiaMapInner({
setClusterRef(r)} showCoverageOnHover chunkedLoading maxClusterRadius={50} removeOutsideVisibleBounds={false}>
{
React.Children.toArray(children).map((child) =>
- React.isValidElement<{ setItemFormPopup: React.Dispatch>, itemFormPopup: ItemFormPopupProps | null, clusterRef: React.MutableRefObject }>(child)
- ? React.cloneElement(child, { setItemFormPopup: setItemFormPopup, itemFormPopup: itemFormPopup, clusterRef: clusterRef })
- : child
+ React.isValidElement<{ setItemFormPopup: React.Dispatch>, itemFormPopup: ItemFormPopupProps | null, clusterRef: React.MutableRefObject }>(child)
+ ? React.cloneElement(child, { setItemFormPopup, itemFormPopup, clusterRef })
+ : child
)
}
@@ -131,12 +128,12 @@ export function UtopiaMapInner({
data={geo}
onEachFeature={onEachFeature}
eventHandlers={{
- click: (e) => {
- if (selectNewItemPosition) {
- e.layer!.closePopup();
- setMapClicked({ position: e.latlng, setItemFormPopup: setItemFormPopup });
- }
- },
+ click: (e) => {
+ if (selectNewItemPosition) {
+ e.layer!.closePopup()
+ setMapClicked({ position: e.latlng, setItemFormPopup })
+ }
+ }
}}
/>
)}
@@ -145,5 +142,5 @@ export function UtopiaMapInner({
{selectNewItemPosition != null && }
- );
+ )
}
diff --git a/src/Components/Map/hooks/useClusterRef.tsx b/src/Components/Map/hooks/useClusterRef.tsx
index a623748..1c120c1 100644
--- a/src/Components/Map/hooks/useClusterRef.tsx
+++ b/src/Components/Map/hooks/useClusterRef.tsx
@@ -1,41 +1,36 @@
import * as React from 'react'
-import { createContext, useContext, useState } from "react";
+import { createContext, useContext, useState } from 'react'
type UseClusterRefManagerResult = ReturnType;
const ClusterRefContext = createContext({
- clusterRef: {} as React.MutableRefObject,
- setClusterRef: () => { },
-});
+ clusterRef: {} as React.MutableRefObject,
+ setClusterRef: () => { }
+})
-function useClusterRefManager(): {
+function useClusterRefManager (): {
clusterRef: any
setClusterRef: React.Dispatch>>;
-} {
- const [clusterRef, setClusterRef] = useState>({} as React.MutableRefObject);
-
- return { clusterRef, setClusterRef };
+ } {
+ const [clusterRef, setClusterRef] = useState>({} as React.MutableRefObject)
+ return { clusterRef, setClusterRef }
}
-
-
-
export const ClusterRefProvider: React.FunctionComponent<{
children?: React.ReactNode
}> = ({ children }) => (
{children}
-);
-
-export const useClusterRef = (): any=> {
- const { clusterRef } = useContext(ClusterRefContext);
- return clusterRef;
-};
+)
-export const useSetClusterRef = (): UseClusterRefManagerResult["setClusterRef"] => {
- const { setClusterRef } = useContext(ClusterRefContext);
- return setClusterRef;
+export const useClusterRef = (): any => {
+ const { clusterRef } = useContext(ClusterRefContext)
+ return clusterRef
}
+export const useSetClusterRef = (): UseClusterRefManagerResult['setClusterRef'] => {
+ const { setClusterRef } = useContext(ClusterRefContext)
+ return setClusterRef
+}
diff --git a/src/Components/Map/hooks/useDebounce.tsx b/src/Components/Map/hooks/useDebounce.tsx
index 7172cee..2794ff8 100644
--- a/src/Components/Map/hooks/useDebounce.tsx
+++ b/src/Components/Map/hooks/useDebounce.tsx
@@ -1,10 +1,10 @@
-import { useEffect } from 'react';
-import { useTimeout } from './useTimeout';
+import { useEffect } from 'react'
+import { useTimeout } from './useTimeout'
export const useDebounce = (callback, delay, deps) => {
- const { reset, clear } = useTimeout(callback, delay);
+ const { reset, clear } = useTimeout(callback, delay)
- useEffect(reset, [...deps, reset]);
+ useEffect(reset, [...deps, reset])
// eslint-disable-next-line react-hooks/exhaustive-deps
- useEffect(clear, []);
-}
\ No newline at end of file
+ useEffect(clear, [])
+}
diff --git a/src/Components/Map/hooks/useFilter.tsx b/src/Components/Map/hooks/useFilter.tsx
index 3478eb8..294aafd 100644
--- a/src/Components/Map/hooks/useFilter.tsx
+++ b/src/Components/Map/hooks/useFilter.tsx
@@ -1,28 +1,28 @@
/* eslint-disable no-case-declarations */
-import { useCallback, useReducer, createContext, useContext } from "react";
-import * as React from "react";
-import { LayerProps, Tag } from "../../../types";
-import { useLayers } from "./useLayers";
-import { useNavigate } from "react-router-dom";
-import useWindowDimensions from "./useWindowDimension";
+import { useCallback, useReducer, createContext, useContext } from 'react'
+import * as React from 'react'
+import { LayerProps, Tag } from '../../../types'
+import { useLayers } from './useLayers'
+import { useNavigate } from 'react-router-dom'
+import useWindowDimensions from './useWindowDimension'
type ActionType =
- | { type: "ADD_TAG"; tag: Tag }
- | { type: "REMOVE_TAG"; name: string }
- | { type: "RESET_TAGS" }
- | { type: "TOGGLE_LAYER"; layer: LayerProps }
- | { type: "ADD_LAYER"; layer: LayerProps }
- | { type: "RESET_LAYERS" }
- | { type: "TOGGLE_GROUP_TYPE"; groupType: string }
- | { type: "ADD_GROUP_TYPE"; groupType: string }
- | { type: "RESET_GROUP_TYPE" }
+ | { type: 'ADD_TAG'; tag: Tag }
+ | { type: 'REMOVE_TAG'; name: string }
+ | { type: 'RESET_TAGS' }
+ | { type: 'TOGGLE_LAYER'; layer: LayerProps }
+ | { type: 'ADD_LAYER'; layer: LayerProps }
+ | { type: 'RESET_LAYERS' }
+ | { type: 'TOGGLE_GROUP_TYPE'; groupType: string }
+ | { type: 'ADD_GROUP_TYPE'; groupType: string }
+ | { type: 'RESET_GROUP_TYPE' }
;
type UseFilterManagerResult = ReturnType;
const FilterContext = createContext({
filterTags: [],
- searchPhrase: "",
+ searchPhrase: '',
visibleLayers: [],
visibleGroupTypes: [],
addFilterTag: () => { },
@@ -37,9 +37,9 @@ const FilterContext = createContext({
addVisibleGroupType: () => { },
toggleVisibleGroupType: () => { },
isGroupTypeVisible: () => true
-});
+})
-function useFilterManager(initialTags: Tag[]): {
+function useFilterManager (initialTags: Tag[]): {
filterTags: Tag[];
searchPhrase: string;
visibleLayers: LayerProps[];
@@ -67,182 +67,174 @@ function useFilterManager(initialTags: Tag[]): {
} {
const [filterTags, dispatchTags] = useReducer((state: Tag[], action: ActionType) => {
switch (action.type) {
- case "ADD_TAG":
+ case 'ADD_TAG':
const exist = state.find((tag) =>
- tag.id === action.tag.id ? true : false
- );
- if (!exist) return [
- ...state,
- action.tag,
- ];
- else return state;
- case "REMOVE_TAG":
- return state.filter(({ name }) => name !== action.name);
- case "RESET_TAGS":
- return initialTags;
+ tag.id === action.tag.id
+ )
+ if (!exist) {
+ return [
+ ...state,
+ action.tag
+ ]
+ } else return state
+ case 'REMOVE_TAG':
+ return state.filter(({ name }) => name !== action.name)
+ case 'RESET_TAGS':
+ return initialTags
default:
- throw new Error();
+ throw new Error()
}
- }, initialTags);
+ }, initialTags)
const initialLayers = useLayers()
const navigate = useNavigate()
- const windowDimensions = useWindowDimensions();
+ const windowDimensions = useWindowDimensions()
const [visibleLayers, dispatchLayers] = useReducer((state: LayerProps[], action: ActionType) => {
switch (action.type) {
- case "ADD_LAYER":
+ case 'ADD_LAYER':
const exist1 = state.find((layer) =>
- layer.name === action.layer.name ? true : false
- );
- if (!exist1) return [
- ...state,
- action.layer,
- ];
- else return state;
- case "TOGGLE_LAYER":
+ layer.name === action.layer.name
+ )
+ if (!exist1) {
+ return [
+ ...state,
+ action.layer
+ ]
+ } else return state
+ case 'TOGGLE_LAYER':
const exist2 = state.some((layer) =>
- layer.name === action.layer.name);
- if(exist2) return state.filter(({name}) => name != action.layer.name);
- else return [... state, action.layer];
- case "RESET_LAYERS":
- return initialLayers;
+ layer.name === action.layer.name)
+ if (exist2) return state.filter(({ name }) => name !== action.layer.name)
+ else return [...state, action.layer]
+ case 'RESET_LAYERS':
+ return initialLayers
default:
- throw new Error();
+ throw new Error()
}
- }, initialLayers);
+ }, initialLayers)
const [visibleGroupTypes, dispatchGroupTypes] = useReducer((state: string[], action: ActionType) => {
switch (action.type) {
- case "ADD_GROUP_TYPE":
+ case 'ADD_GROUP_TYPE':
const exist1 = state.find((groupType) =>
- groupType === action.groupType ? true : false
- );
- if (!exist1) return [
- ...state,
- action.groupType,
- ];
- else return state;
- case "TOGGLE_GROUP_TYPE":
+ groupType === action.groupType
+ )
+ if (!exist1) {
+ return [
+ ...state,
+ action.groupType
+ ]
+ } else return state
+ case 'TOGGLE_GROUP_TYPE':
const exist2 = state.some((groupType) =>
- groupType === action.groupType);
- if(exist2) return state.filter((groupType) => groupType != action.groupType);
- else return [... state, action.groupType];
- case "RESET_GROUP_TYPE":
- return [];
+ groupType === action.groupType)
+ if (exist2) return state.filter((groupType) => groupType !== action.groupType)
+ else return [...state, action.groupType]
+ case 'RESET_GROUP_TYPE':
+ return []
default:
- throw new Error();
+ throw new Error()
}
- },[]);
+ }, [])
- const [searchPhrase, searchPhraseSet] = React.useState("");
+ const [searchPhrase, searchPhraseSet] = React.useState('')
const addFilterTag = useCallback((tag: Tag) => {
- const params = new URLSearchParams(location.search);
- const urlTags = params.get("tags")
- const decodedTags = urlTags ? decodeURIComponent(urlTags) : "";
-
- if(!decodedTags?.includes(tag.name))
- params.set("tags", `${urlTags ? urlTags : ""}${urlTags? ';' : ''}${tag.name}`)
- if(windowDimensions.width < 786 && location.pathname.split("/").length > 2) navigate("/" + `${params ? `?${params}` : ""}`);
- else navigate(location.pathname + `${params ? `?${params}` : ""}`);
-
-
-
+ const params = new URLSearchParams(location.search)
+ const urlTags = params.get('tags')
+ const decodedTags = urlTags ? decodeURIComponent(urlTags) : ''
+
+ if (!decodedTags?.includes(tag.name)) { params.set('tags', `${urlTags || ''}${urlTags ? ';' : ''}${tag.name}`) }
+ if (windowDimensions.width < 786 && location.pathname.split('/').length > 2) navigate('/' + `${params ? `?${params}` : ''}`)
+ else navigate(location.pathname + `${params ? `?${params}` : ''}`)
dispatchTags({
- type: "ADD_TAG",
- tag,
- });
+ type: 'ADD_TAG',
+ tag
+ })
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
+ }, [])
const removeFilterTag = useCallback((name: string) => {
-
- const params = new URLSearchParams(window.location.search);
- const urlTags = params.get("tags");
- let newUrlTags = "";
- const tags = urlTags?.split(";");
- if(tags?.length==0 && urlTags?.length && urlTags?.length > 0) tags[0]=urlTags;
- tags?.map(urlTag => {
- if(!(urlTag.toLocaleLowerCase() === name.toLocaleLowerCase()))
- newUrlTags = newUrlTags + `${newUrlTags===""? urlTag : `;${urlTag}`}`
- });
- if(newUrlTags !== "") {
- params.set("tags", `${newUrlTags}`)
- navigate(location.pathname + `${params ? `?${params}` : ""}`);
- }
- else {
- params.delete("tags");
- navigate(location.pathname + `${params ? `?${params}` : ""}`);
+ const params = new URLSearchParams(window.location.search)
+ const urlTags = params.get('tags')
+ let newUrlTags = ''
+ const tags = urlTags?.split(';')
+ if (tags?.length === 0 && urlTags?.length && urlTags?.length > 0) tags[0] = urlTags
+ tags?.map(urlTag => {
+ if (!(urlTag.toLocaleLowerCase() === name.toLocaleLowerCase())) { newUrlTags = newUrlTags + `${newUrlTags === '' ? urlTag : `;${urlTag}`}` }
+ return null
+ })
+ if (newUrlTags !== '') {
+ params.set('tags', `${newUrlTags}`)
+ navigate(location.pathname + `${params ? `?${params}` : ''}`)
+ } else {
+ params.delete('tags')
+ navigate(location.pathname + `${params ? `?${params}` : ''}`)
}
dispatchTags({
- type: "REMOVE_TAG",
- name,
- });
+ type: 'REMOVE_TAG',
+ name
+ })
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
+ }, [])
const resetFilterTags = useCallback(() => {
dispatchTags({
- type: "RESET_TAGS",
- });
- }, []);
+ type: 'RESET_TAGS'
+ })
+ }, [])
const addVisibleLayer = (layer: LayerProps) => {
dispatchLayers({
- type: "ADD_LAYER",
- layer,
- });
-
- };
+ type: 'ADD_LAYER',
+ layer
+ })
+ }
const toggleVisibleLayer = (layer: LayerProps) => {
dispatchLayers({
- type: "TOGGLE_LAYER",
- layer,
- });
-
- };
-
+ type: 'TOGGLE_LAYER',
+ layer
+ })
+ }
const resetVisibleLayers = useCallback(() => {
dispatchLayers({
- type: "RESET_LAYERS",
- });
- }, []);
+ type: 'RESET_LAYERS'
+ })
+ }, [])
const isLayerVisible = useCallback((layer: LayerProps) => {
return visibleLayers.some(l => l.name === layer.name)
- }, [visibleLayers]);
+ }, [visibleLayers])
const addVisibleGroupType = (groupType: string) => {
dispatchGroupTypes({
- type: "ADD_GROUP_TYPE",
- groupType,
- });
-
- };
+ type: 'ADD_GROUP_TYPE',
+ groupType
+ })
+ }
const toggleVisibleGroupType = (groupType: string) => {
dispatchGroupTypes({
- type: "TOGGLE_GROUP_TYPE",
- groupType,
- });
-
- };
+ type: 'TOGGLE_GROUP_TYPE',
+ groupType
+ })
+ }
const isGroupTypeVisible = useCallback((groupType: string) => {
return visibleGroupTypes.some(gt => gt === groupType)
- }, [visibleGroupTypes]);
+ }, [visibleGroupTypes])
const setSearchPhrase = useCallback((phrase: string) => {
searchPhraseSet(phrase)
- }, []);
+ }, [])
- return { filterTags, addFilterTag, removeFilterTag, resetFilterTags, setSearchPhrase, searchPhrase, visibleLayers, toggleVisibleLayer, resetVisibleLayers, isLayerVisible, addVisibleLayer, visibleGroupTypes, addVisibleGroupType, toggleVisibleGroupType, isGroupTypeVisible };
+ return { filterTags, addFilterTag, removeFilterTag, resetFilterTags, setSearchPhrase, searchPhrase, visibleLayers, toggleVisibleLayer, resetVisibleLayers, isLayerVisible, addVisibleLayer, visibleGroupTypes, addVisibleGroupType, toggleVisibleGroupType, isGroupTypeVisible }
}
export const FilterProvider: React.FunctionComponent<{
@@ -251,82 +243,79 @@ export const FilterProvider: React.FunctionComponent<{
{children}
-);
+)
export const useFilterTags = (): Tag[] => {
- const { filterTags } = useContext(FilterContext);
- return filterTags;
-};
-
-export const useAddFilterTag = (): UseFilterManagerResult["addFilterTag"] => {
- const { addFilterTag } = useContext(FilterContext);
- return addFilterTag;
-};
-
-export const useRemoveFilterTag = (): UseFilterManagerResult["removeFilterTag"] => {
- const { removeFilterTag } = useContext(FilterContext);
- return removeFilterTag;
-};
-
-export const useResetFilterTags = (): UseFilterManagerResult["resetFilterTags"] => {
- const { resetFilterTags } = useContext(FilterContext);
- return resetFilterTags;
-};
-
-export const useSearchPhrase = (): UseFilterManagerResult["searchPhrase"] => {
- const { searchPhrase } = useContext(FilterContext);
- return searchPhrase;
-};
-
-export const useSetSearchPhrase = (): UseFilterManagerResult["setSearchPhrase"] => {
- const { setSearchPhrase } = useContext(FilterContext);
- return setSearchPhrase;
-};
-
-export const useVisibleLayer = (): UseFilterManagerResult["visibleLayers"] => {
- const { visibleLayers } = useContext(FilterContext);
- return visibleLayers;
-};
-
-export const useAddVisibleLayer = (): UseFilterManagerResult["addVisibleLayer"] => {
- const { addVisibleLayer } = useContext(FilterContext);
- return addVisibleLayer;
-};
-
-
-export const useToggleVisibleLayer = (): UseFilterManagerResult["toggleVisibleLayer"] => {
- const { toggleVisibleLayer } = useContext(FilterContext);
- return toggleVisibleLayer;
-};
-
-export const useResetVisibleLayers = (): UseFilterManagerResult["resetVisibleLayers"] => {
- const { resetVisibleLayers } = useContext(FilterContext);
- return resetVisibleLayers;
-};
-
-export const useIsLayerVisible = (): UseFilterManagerResult["isLayerVisible"] => {
- const { isLayerVisible } = useContext(FilterContext);
- return isLayerVisible;
-};
-
-export const useAddVisibleGroupType = (): UseFilterManagerResult["addVisibleGroupType"] => {
- const { addVisibleGroupType } = useContext(FilterContext);
- return addVisibleGroupType;
-};
-
-
-export const useToggleVisibleGroupType = (): UseFilterManagerResult["toggleVisibleGroupType"] => {
- const { toggleVisibleGroupType } = useContext(FilterContext);
- return toggleVisibleGroupType;
-};
-
-
-export const useIsGroupTypeVisible = (): UseFilterManagerResult["isGroupTypeVisible"] => {
- const { isGroupTypeVisible } = useContext(FilterContext);
+ const { filterTags } = useContext(FilterContext)
+ return filterTags
+}
+
+export const useAddFilterTag = (): UseFilterManagerResult['addFilterTag'] => {
+ const { addFilterTag } = useContext(FilterContext)
+ return addFilterTag
+}
+
+export const useRemoveFilterTag = (): UseFilterManagerResult['removeFilterTag'] => {
+ const { removeFilterTag } = useContext(FilterContext)
+ return removeFilterTag
+}
+
+export const useResetFilterTags = (): UseFilterManagerResult['resetFilterTags'] => {
+ const { resetFilterTags } = useContext(FilterContext)
+ return resetFilterTags
+}
+
+export const useSearchPhrase = (): UseFilterManagerResult['searchPhrase'] => {
+ const { searchPhrase } = useContext(FilterContext)
+ return searchPhrase
+}
+
+export const useSetSearchPhrase = (): UseFilterManagerResult['setSearchPhrase'] => {
+ const { setSearchPhrase } = useContext(FilterContext)
+ return setSearchPhrase
+}
+
+export const useVisibleLayer = (): UseFilterManagerResult['visibleLayers'] => {
+ const { visibleLayers } = useContext(FilterContext)
+ return visibleLayers
+}
+
+export const useAddVisibleLayer = (): UseFilterManagerResult['addVisibleLayer'] => {
+ const { addVisibleLayer } = useContext(FilterContext)
+ return addVisibleLayer
+}
+
+export const useToggleVisibleLayer = (): UseFilterManagerResult['toggleVisibleLayer'] => {
+ const { toggleVisibleLayer } = useContext(FilterContext)
+ return toggleVisibleLayer
+}
+
+export const useResetVisibleLayers = (): UseFilterManagerResult['resetVisibleLayers'] => {
+ const { resetVisibleLayers } = useContext(FilterContext)
+ return resetVisibleLayers
+}
+
+export const useIsLayerVisible = (): UseFilterManagerResult['isLayerVisible'] => {
+ const { isLayerVisible } = useContext(FilterContext)
+ return isLayerVisible
+}
+
+export const useAddVisibleGroupType = (): UseFilterManagerResult['addVisibleGroupType'] => {
+ const { addVisibleGroupType } = useContext(FilterContext)
+ return addVisibleGroupType
+}
+
+export const useToggleVisibleGroupType = (): UseFilterManagerResult['toggleVisibleGroupType'] => {
+ const { toggleVisibleGroupType } = useContext(FilterContext)
+ return toggleVisibleGroupType
+}
+
+export const useIsGroupTypeVisible = (): UseFilterManagerResult['isGroupTypeVisible'] => {
+ const { isGroupTypeVisible } = useContext(FilterContext)
return isGroupTypeVisible
-};
+}
-export const useVisibleGroupType = (): UseFilterManagerResult["visibleGroupTypes"] => {
- const { visibleGroupTypes } = useContext(FilterContext);
- return visibleGroupTypes;
-};
\ No newline at end of file
+export const useVisibleGroupType = (): UseFilterManagerResult['visibleGroupTypes'] => {
+ const { visibleGroupTypes } = useContext(FilterContext)
+ return visibleGroupTypes
+}
diff --git a/src/Components/Map/hooks/useItems.tsx b/src/Components/Map/hooks/useItems.tsx
index 5186134..6fb25fa 100644
--- a/src/Components/Map/hooks/useItems.tsx
+++ b/src/Components/Map/hooks/useItems.tsx
@@ -1,18 +1,16 @@
-import { useCallback, useReducer, createContext, useContext, useState } from "react";
-import * as React from "react";
-import { Item, LayerProps } from "../../../types";
-import { toast } from "react-toastify";
-import { useAddLayer } from "./useLayers";
-
+import { useCallback, useReducer, createContext, useContext, useState } from 'react'
+import * as React from 'react'
+import { Item, LayerProps } from '../../../types'
+import { toast } from 'react-toastify'
+import { useAddLayer } from './useLayers'
type ActionType =
- | { type: "ADD"; item: Item }
- | { type: "UPDATE"; item: Item }
- | { type: "REMOVE"; item: Item }
- | { type: "RESET"; layer: LayerProps }
+ | { type: 'ADD'; item: Item }
+ | { type: 'UPDATE'; item: Item }
+ | { type: 'REMOVE'; item: Item }
+ | { type: 'RESET'; layer: LayerProps }
;
-
type UseItemManagerResult = ReturnType;
const ItemContext = createContext({
@@ -24,9 +22,9 @@ const ItemContext = createContext({
setItemsApi: () => { },
setItemsData: () => { },
allItemsLoaded: false
-});
+})
-function useItemsManager(initialItems: Item[]): {
+function useItemsManager (initialItems: Item[]): {
items: Item[];
// eslint-disable-next-line no-unused-vars
addItem: (item: Item) => void;
@@ -43,106 +41,102 @@ function useItemsManager(initialItems: Item[]): {
allItemsLoaded: boolean;
} {
+ const addLayer = useAddLayer()
- const addLayer = useAddLayer();
-
- const [allItemsLoaded, setallItemsLoaded] = useState(false);
-
-
+ const [allItemsLoaded, setallItemsLoaded] = useState(false)
const [items, dispatch] = useReducer((state: Item[], action: ActionType) => {
switch (action.type) {
- case "ADD":
+ case 'ADD':
// eslint-disable-next-line no-case-declarations
const exist = state.find((item) =>
- item.id === action.item.id ? true : false
- );
- if (!exist) return [
- ...state,
- action.item,
- ];
- else return state;
- case "UPDATE":
+ item.id === action.item.id
+ )
+ if (!exist) {
+ return [
+ ...state,
+ action.item
+ ]
+ } else return state
+ case 'UPDATE':
return state.map((item) => {
if (item.id === action.item.id) {
return action.item
}
return item
- });
- case "REMOVE":
- return state.filter(item => item !== action.item);
- case "RESET":
- return state.filter(item => item.layer?.name !== action.layer.name);
+ })
+ case 'REMOVE':
+ return state.filter(item => item !== action.item)
+ case 'RESET':
+ return state.filter(item => item.layer?.name !== action.layer.name)
default:
- throw new Error();
+ throw new Error()
}
- }, initialItems);
-
+ }, initialItems)
const setItemsApi = useCallback(async (layer: LayerProps) => {
- addLayer(layer);
+ addLayer(layer)
const result = await toast.promise(
layer.api!.getItems(),
{
pending: `loading ${layer.name} ...`,
success: `${layer.name} loaded`,
error: {
- render( {data} ) {
+ render ({ data }) {
return `${data}`
- },
- },
+ }
+ }
}
- );
- if (result) {
- result.map(item => {
- dispatch({ type: "ADD", item: { ...item, layer: layer } });
+ )
+ if (result) {
+ result.map(item => {
+ dispatch({ type: 'ADD', item: { ...item, layer } })
+ return null
})
- setallItemsLoaded(true);
+ setallItemsLoaded(true)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const setItemsData = useCallback((layer: LayerProps) => {
- addLayer(layer);
+ addLayer(layer)
layer.data?.map(item => {
- dispatch({ type: "ADD", item: { ...item, layer: layer } });
+ dispatch({ type: 'ADD', item: { ...item, layer } })
+ return null
})
- setallItemsLoaded(true);
+ setallItemsLoaded(true)
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
+ }, [])
- const addItem = useCallback(async (item: Item) => {
+ const addItem = useCallback(async (item: Item) => {
dispatch({
- type: "ADD",
- item,
- });
- }, []);
+ type: 'ADD',
+ item
+ })
+ }, [])
const updateItem = useCallback(async (item: Item) => {
dispatch({
- type: "UPDATE",
- item,
- });
- }, []);
+ type: 'UPDATE',
+ item
+ })
+ }, [])
const removeItem = useCallback((item: Item) => {
dispatch({
- type: "REMOVE",
- item,
- });
- }, []);
+ type: 'REMOVE',
+ item
+ })
+ }, [])
const resetItems = useCallback((layer: LayerProps) => {
dispatch({
- type: "RESET",
+ type: 'RESET',
layer
- });
- }, []);
-
-
+ })
+ }, [])
- return { items, updateItem, addItem, removeItem, resetItems, setItemsApi, setItemsData, allItemsLoaded };
+ return { items, updateItem, addItem, removeItem, resetItems, setItemsApi, setItemsData, allItemsLoaded }
}
export const ItemsProvider: React.FunctionComponent<{
@@ -151,44 +145,44 @@ export const ItemsProvider: React.FunctionComponent<{
{children}
-);
+)
export const useItems = (): Item[] => {
- const { items } = useContext(ItemContext);
- return items;
-};
-
-export const useAddItem = (): UseItemManagerResult["addItem"] => {
- const { addItem } = useContext(ItemContext);
- return addItem;
-};
-
-export const useUpdateItem = (): UseItemManagerResult["updateItem"] => {
- const { updateItem } = useContext(ItemContext);
- return updateItem;
-};
-
-export const useRemoveItem = (): UseItemManagerResult["removeItem"] => {
- const { removeItem } = useContext(ItemContext);
- return removeItem;
-};
-
-export const useResetItems = (): UseItemManagerResult["resetItems"] => {
- const { resetItems } = useContext(ItemContext);
- return resetItems;
-};
-
-export const useSetItemsApi = (): UseItemManagerResult["setItemsApi"] => {
- const { setItemsApi } = useContext(ItemContext);
- return setItemsApi;
-};
-
-export const useSetItemsData = (): UseItemManagerResult["setItemsData"] => {
- const { setItemsData } = useContext(ItemContext);
- return setItemsData;
-};
-
-export const useAllItemsLoaded = (): UseItemManagerResult["allItemsLoaded"] => {
- const { allItemsLoaded } = useContext(ItemContext);
- return allItemsLoaded;
-}
\ No newline at end of file
+ const { items } = useContext(ItemContext)
+ return items
+}
+
+export const useAddItem = (): UseItemManagerResult['addItem'] => {
+ const { addItem } = useContext(ItemContext)
+ return addItem
+}
+
+export const useUpdateItem = (): UseItemManagerResult['updateItem'] => {
+ const { updateItem } = useContext(ItemContext)
+ return updateItem
+}
+
+export const useRemoveItem = (): UseItemManagerResult['removeItem'] => {
+ const { removeItem } = useContext(ItemContext)
+ return removeItem
+}
+
+export const useResetItems = (): UseItemManagerResult['resetItems'] => {
+ const { resetItems } = useContext(ItemContext)
+ return resetItems
+}
+
+export const useSetItemsApi = (): UseItemManagerResult['setItemsApi'] => {
+ const { setItemsApi } = useContext(ItemContext)
+ return setItemsApi
+}
+
+export const useSetItemsData = (): UseItemManagerResult['setItemsData'] => {
+ const { setItemsData } = useContext(ItemContext)
+ return setItemsData
+}
+
+export const useAllItemsLoaded = (): UseItemManagerResult['allItemsLoaded'] => {
+ const { allItemsLoaded } = useContext(ItemContext)
+ return allItemsLoaded
+}
diff --git a/src/Components/Map/hooks/useLayers.tsx b/src/Components/Map/hooks/useLayers.tsx
index 634fbdc..cafc0f7 100644
--- a/src/Components/Map/hooks/useLayers.tsx
+++ b/src/Components/Map/hooks/useLayers.tsx
@@ -1,47 +1,48 @@
-import { useCallback, useReducer, createContext, useContext } from "react";
-import * as React from "react";
-import { LayerProps } from "../../../types";
+import { useCallback, useReducer, createContext, useContext } from 'react'
+import * as React from 'react'
+import { LayerProps } from '../../../types'
type ActionType =
- | { type: "ADD LAYER"; layer: LayerProps }
+ | { type: 'ADD LAYER'; layer: LayerProps }
type UseItemManagerResult = ReturnType;
const LayerContext = createContext({
layers: [],
- addLayer: () => { },
-});
+ addLayer: () => { }
+})
-function useLayerManager(initialLayers: LayerProps[]): {
+function useLayerManager (initialLayers: LayerProps[]): {
layers: LayerProps[];
// eslint-disable-next-line no-unused-vars
addLayer: (layer: LayerProps) => void;
} {
const [layers, dispatch] = useReducer((state: LayerProps[], action: ActionType) => {
switch (action.type) {
- case "ADD LAYER":
+ case 'ADD LAYER':
// eslint-disable-next-line no-case-declarations
const exist = state.find((layer) =>
- layer.name === action.layer.name ? true : false
- );
- if (!exist) return [
- ...state,
- action.layer,
- ];
- else return state;
+ layer.name === action.layer.name
+ )
+ if (!exist) {
+ return [
+ ...state,
+ action.layer
+ ]
+ } else return state
default:
- throw new Error();
+ throw new Error()
}
- }, initialLayers);
+ }, initialLayers)
const addLayer = useCallback((layer: LayerProps) => {
dispatch({
- type: "ADD LAYER",
+ type: 'ADD LAYER',
layer
- });
- }, []);
+ })
+ }, [])
- return { layers, addLayer };
+ return { layers, addLayer }
}
export const LayersProvider: React.FunctionComponent<{
@@ -50,14 +51,14 @@ export const LayersProvider: React.FunctionComponent<{
{children}
-);
+)
export const useLayers = (): LayerProps[] => {
- const { layers } = useContext(LayerContext);
- return layers;
-};
-
-export const useAddLayer = (): UseItemManagerResult["addLayer"] => {
- const { addLayer } = useContext(LayerContext);
- return addLayer;
-};
+ const { layers } = useContext(LayerContext)
+ return layers
+}
+
+export const useAddLayer = (): UseItemManagerResult['addLayer'] => {
+ const { addLayer } = useContext(LayerContext)
+ return addLayer
+}
diff --git a/src/Components/Map/hooks/useLeafletRefs.tsx b/src/Components/Map/hooks/useLeafletRefs.tsx
index 83b511a..b04f952 100644
--- a/src/Components/Map/hooks/useLeafletRefs.tsx
+++ b/src/Components/Map/hooks/useLeafletRefs.tsx
@@ -1,75 +1,68 @@
-import { useCallback, useReducer, createContext, useContext } from "react";
-import * as React from "react";
-import { Item } from "../../../types";
-import { Marker, Popup } from "leaflet";
+import { useCallback, useReducer, createContext, useContext } from 'react'
+import * as React from 'react'
+import { Item } from '../../../types'
+import { Marker, Popup } from 'leaflet'
-type LeafletRef = {
+type LeafletRef = {
item: Item,
marker: Marker,
popup: Popup
}
type ActionType =
- | { type: "ADD_MARKER"; item: Item, marker: Marker }
- | { type: "ADD_POPUP"; item: Item, popup: Popup }
+ | { type: 'ADD_MARKER'; item: Item, marker: Marker }
+ | { type: 'ADD_POPUP'; item: Item, popup: Popup }
;
-
type UseLeafletRefsManagerResult = ReturnType;
const LeafletRefsContext = createContext({
leafletRefs: {},
addMarker: () => { },
- addPopup: () => { },
-});
+ addPopup: () => { }
+})
-function useLeafletRefsManager(initialLeafletRefs: {}): {
- leafletRefs: Record;
+function useLeafletRefsManager (initialLeafletRefs: {}): {
+ leafletRefs: Record;
// eslint-disable-next-line no-unused-vars
addMarker: (item: Item, marker: Marker) => void;
// eslint-disable-next-line no-unused-vars
addPopup: (item: Item, popup: Popup) => void;
} {
-
-
-
- const [leafletRefs, dispatch] = useReducer((state: Record, action: ActionType) => {
+ const [leafletRefs, dispatch] = useReducer((state: Record, action: ActionType) => {
switch (action.type) {
- case "ADD_MARKER":
+ case 'ADD_MARKER':
return {
...state,
- [action.item.id]: { ...state[action.item.id], marker: action.marker, item: action.item }}
- case "ADD_POPUP":
+ [action.item.id]: { ...state[action.item.id], marker: action.marker, item: action.item }
+ }
+ case 'ADD_POPUP':
return {
...state,
- [action.item.id]: { ...state[action.item.id], popup: action.popup, item: action.item }}
+ [action.item.id]: { ...state[action.item.id], popup: action.popup, item: action.item }
+ }
default:
- throw new Error();
+ throw new Error()
}
- }, initialLeafletRefs);
-
-
-
+ }, initialLeafletRefs)
const addMarker = useCallback((item: Item, marker: Marker) => {
dispatch({
- type: "ADD_MARKER",
+ type: 'ADD_MARKER',
item,
marker
- });
- }, []);
+ })
+ }, [])
const addPopup = useCallback((item: Item, popup: Popup) => {
dispatch({
- type: "ADD_POPUP",
+ type: 'ADD_POPUP',
item,
popup
- });
- }, []);
+ })
+ }, [])
-
-
- return { leafletRefs, addMarker, addPopup };
+ return { leafletRefs, addMarker, addPopup }
}
export const LeafletRefsProvider: React.FunctionComponent<{
@@ -78,20 +71,19 @@ export const LeafletRefsProvider: React.FunctionComponent<{
{children}
-);
-
-export const useLeafletRefs = (): Record => {
- const { leafletRefs } = useContext(LeafletRefsContext);
- return leafletRefs;
-};
+)
-export const useAddMarker = (): UseLeafletRefsManagerResult["addMarker"] => {
- const { addMarker } = useContext(LeafletRefsContext);
- return addMarker;
-};
+export const useLeafletRefs = (): Record => {
+ const { leafletRefs } = useContext(LeafletRefsContext)
+ return leafletRefs
+}
-export const useAddPopup = (): UseLeafletRefsManagerResult["addPopup"] => {
- const { addPopup } = useContext(LeafletRefsContext);
- return addPopup;
-};
+export const useAddMarker = (): UseLeafletRefsManagerResult['addMarker'] => {
+ const { addMarker } = useContext(LeafletRefsContext)
+ return addMarker
+}
+export const useAddPopup = (): UseLeafletRefsManagerResult['addPopup'] => {
+ const { addPopup } = useContext(LeafletRefsContext)
+ return addPopup
+}
diff --git a/src/Components/Map/hooks/usePermissions.tsx b/src/Components/Map/hooks/usePermissions.tsx
index bb1a519..2dd2939 100644
--- a/src/Components/Map/hooks/usePermissions.tsx
+++ b/src/Components/Map/hooks/usePermissions.tsx
@@ -1,11 +1,11 @@
-import { useCallback, useReducer, createContext, useContext } from "react";
-import * as React from "react";
-import { Item, ItemsApi, LayerProps, Permission, PermissionAction } from "../../../types";
-import { useAuth } from "../../Auth";
+import { useCallback, useReducer, createContext, useContext } from 'react'
+import * as React from 'react'
+import { Item, ItemsApi, LayerProps, Permission, PermissionAction } from '../../../types'
+import { useAuth } from '../../Auth'
type ActionType =
- | { type: "ADD"; permission: Permission }
- | { type: "REMOVE"; id: string };
+ | { type: 'ADD'; permission: Permission }
+ | { type: 'REMOVE'; id: string };
type UsePermissionManagerResult = ReturnType;
@@ -15,9 +15,9 @@ const PermissionContext = createContext({
setPermissionData: () => { },
setAdminRole: () => { },
hasUserPermission: () => true
-});
+})
-function usePermissionsManager(initialPermissions: Permission[]): {
+function usePermissionsManager (initialPermissions: Permission[]): {
permissions: Permission[];
// eslint-disable-next-line no-unused-vars
setPermissionApi: (api: ItemsApi) => void;
@@ -30,104 +30,99 @@ function usePermissionsManager(initialPermissions: Permission[]): {
} {
const [permissions, dispatch] = useReducer((state: Permission[], action: ActionType) => {
switch (action.type) {
- case "ADD":
+ case 'ADD':
// eslint-disable-next-line no-case-declarations
const exist = state.find((permission) =>
- permission.id === action.permission.id ? true : false
- );
- if (!exist) return [
- ...state,
- action.permission,
- ];
- else return state;
-
- case "REMOVE":
- return state.filter(({ id }) => id !== action.id);
+ permission.id === action.permission.id
+ )
+ if (!exist) {
+ return [
+ ...state,
+ action.permission
+ ]
+ } else return state
+
+ case 'REMOVE':
+ return state.filter(({ id }) => id !== action.id)
default:
- throw new Error();
+ throw new Error()
}
- }, initialPermissions);
+ }, initialPermissions)
- const [adminRole, setAdminRole] = React.useState(null);
- const { user } = useAuth();
+ const [adminRole, setAdminRole] = React.useState(null)
+ const { user } = useAuth()
-
- const setPermissionApi = useCallback(async (api: ItemsApi) => {
- const result = await api.getItems();
+ const setPermissionApi = useCallback(async (api: ItemsApi) => {
+ const result = await api.getItems()
if (result) {
result.map(permission => {
- dispatch({ type: "ADD", permission })
+ dispatch({ type: 'ADD', permission })
+ return null
})
}
}, [])
const setPermissionData = useCallback((data: Permission[]) => {
data.map(permission => {
- dispatch({ type: "ADD", permission })
+ dispatch({ type: 'ADD', permission })
+ return null
})
- }, []);
+ }, [])
const hasUserPermission = useCallback(
(
- collectionName: string,
- action: PermissionAction,
- item?: Item,
+ collectionName: string,
+ action: PermissionAction,
+ item?: Item,
layer?: LayerProps
) => {
-
const evaluateCondition = (condition: any) => {
- if (condition.user_created?._eq === "$CURRENT_USER") {
- return item?.user_created?.id === user?.id;
+ if (condition.user_created?._eq === '$CURRENT_USER') {
+ return item?.user_created?.id === user?.id
}
if (condition.public_edit?._eq === true) {
- return item?.public_edit === true;
+ return item?.public_edit === true
}
- return false;
- };
-
+ return false
+ }
+
const evaluatePermissions = (permissionConditions: any) => {
if (!permissionConditions || !permissionConditions._and) {
- return true;
+ return true
}
-
- return permissionConditions._and.every((andCondition: any) =>
- andCondition._or
+
+ return permissionConditions._and.every((andCondition: any) =>
+ andCondition._or
? andCondition._or.some((orCondition: any) => evaluateCondition(orCondition))
: evaluateCondition(andCondition)
- );
- };
- if (collectionName === "items" && action === "create" && layer?.public_edit_items) return true;
+ )
+ }
+ if (collectionName === 'items' && action === 'create' && layer?.public_edit_items) return true
// Bedingung fΓΌr leere Berechtigungen nur, wenn NICHT item und create
- if (permissions.length === 0) return true;
- else if (user && user.role.id === adminRole) return true;
+ if (permissions.length === 0) return true
+ else if (user && user.role.id === adminRole) return true
else {
return permissions.some(p =>
p.action === action &&
p.collection === collectionName &&
-
(
(p.policy?.name === user?.role.name &&
(
!item || evaluatePermissions(p.permissions)
)) ||
- (p.policy?.name === "$t:public_label" &&
+ (p.policy?.name === '$t:public_label' &&
(
(layer?.public_edit_items || item?.layer?.public_edit_items) &&
(!item || evaluatePermissions(p.permissions))
))
)
-
- );
+ )
}
},
[permissions, user, adminRole]
- );
-
-
-
-
+ )
- return { permissions, setPermissionApi, setPermissionData, setAdminRole, hasUserPermission };
+ return { permissions, setPermissionApi, setPermissionData, setAdminRole, hasUserPermission }
}
export const PermissionsProvider: React.FunctionComponent<{
@@ -136,30 +131,29 @@ export const PermissionsProvider: React.FunctionComponent<{
{children}
-);
+)
export const usePermissions = (): Permission[] => {
- const { permissions } = useContext(PermissionContext);
- return permissions;
-};
-
+ const { permissions } = useContext(PermissionContext)
+ return permissions
+}
-export const useSetPermissionApi = (): UsePermissionManagerResult["setPermissionApi"] => {
- const { setPermissionApi } = useContext(PermissionContext);
- return setPermissionApi;
+export const useSetPermissionApi = (): UsePermissionManagerResult['setPermissionApi'] => {
+ const { setPermissionApi } = useContext(PermissionContext)
+ return setPermissionApi
}
-export const useSetPermissionData = (): UsePermissionManagerResult["setPermissionData"] => {
- const { setPermissionData } = useContext(PermissionContext);
- return setPermissionData;
+export const useSetPermissionData = (): UsePermissionManagerResult['setPermissionData'] => {
+ const { setPermissionData } = useContext(PermissionContext)
+ return setPermissionData
}
-export const useHasUserPermission = (): UsePermissionManagerResult["hasUserPermission"] => {
- const { hasUserPermission } = useContext(PermissionContext);
- return hasUserPermission;
+export const useHasUserPermission = (): UsePermissionManagerResult['hasUserPermission'] => {
+ const { hasUserPermission } = useContext(PermissionContext)
+ return hasUserPermission
}
-export const useSetAdminRole = (): UsePermissionManagerResult["setAdminRole"] => {
- const { setAdminRole } = useContext(PermissionContext);
- return setAdminRole;
-}
\ No newline at end of file
+export const useSetAdminRole = (): UsePermissionManagerResult['setAdminRole'] => {
+ const { setAdminRole } = useContext(PermissionContext)
+ return setAdminRole
+}
diff --git a/src/Components/Map/hooks/useSelectPosition.tsx b/src/Components/Map/hooks/useSelectPosition.tsx
index 45cfb0a..73ecadb 100644
--- a/src/Components/Map/hooks/useSelectPosition.tsx
+++ b/src/Components/Map/hooks/useSelectPosition.tsx
@@ -1,11 +1,11 @@
import * as React from 'react'
-import { createContext, useContext, useEffect, useState } from "react";
-import { Geometry, Item, LayerProps } from '../../../types';
-import { useUpdateItem } from "./useItems";
-import { toast } from "react-toastify";
-import { useHasUserPermission } from "./usePermissions";
-import { LatLng } from "leaflet";
-import { ItemFormPopupProps } from "../Subcomponents/ItemFormPopup";
+import { createContext, useContext, useEffect, useState } from 'react'
+import { Geometry, Item, LayerProps } from '../../../types'
+import { useUpdateItem } from './useItems'
+import { toast } from 'react-toastify'
+import { useHasUserPermission } from './usePermissions'
+import { LatLng } from 'leaflet'
+import { ItemFormPopupProps } from '../Subcomponents/ItemFormPopup'
type PolygonClickedProps = {
position: LatLng
@@ -15,111 +15,106 @@ type PolygonClickedProps = {
type UseSelectPositionManagerResult = ReturnType;
const SelectPositionContext = createContext({
- selectPosition: null,
- setSelectPosition: () => { },
- setMarkerClicked: () => { },
- setMapClicked: () => {},
-});
+ selectPosition: null,
+ setSelectPosition: () => { },
+ setMarkerClicked: () => { },
+ setMapClicked: () => {}
+})
-function useSelectPositionManager(): {
+function useSelectPositionManager (): {
selectPosition: Item | LayerProps | null;
setSelectPosition: React.Dispatch>;
setMarkerClicked: React.Dispatch>;
setMapClicked: React.Dispatch>;
-} {
- const [selectPosition, setSelectPosition] = useState(null);
- const [markerClicked, setMarkerClicked] = useState- ();
- const [mapClicked, setMapClicked] = useState();
- const updateItem = useUpdateItem();
- const hasUserPermission = useHasUserPermission();
-
-
-
- useEffect(() => {
- if (selectPosition && markerClicked && 'text' in selectPosition && markerClicked.id !==selectPosition.id) {
- itemUpdateParent({ ...selectPosition, parent: markerClicked.id })
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [markerClicked])
-
- useEffect(() => {
- if (selectPosition != null) {
- if ('menuIcon' in selectPosition) {
- mapClicked && mapClicked.setItemFormPopup({ layer: selectPosition as LayerProps, position: mapClicked?.position })
- setSelectPosition(null)
- }
- if ('text' in selectPosition) {
- const position = mapClicked?.position.lng && new Geometry(mapClicked?.position.lng, mapClicked?.position.lat);
- position && itemUpdatePosition({ ...selectPosition as Item, position: position })
- setSelectPosition(null);
- }
+ } {
+ const [selectPosition, setSelectPosition] = useState(null)
+ const [markerClicked, setMarkerClicked] = useState
- ()
+ const [mapClicked, setMapClicked] = useState()
+ const updateItem = useUpdateItem()
+ const hasUserPermission = useHasUserPermission()
+
+ useEffect(() => {
+ if (selectPosition && markerClicked && 'text' in selectPosition && markerClicked.id !== selectPosition.id) {
+ itemUpdateParent({ ...selectPosition, parent: markerClicked.id })
}
-
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [mapClicked])
-
-
- const itemUpdateParent = async (updatedItem: Item) => {
- if (markerClicked?.layer?.api?.collectionName && hasUserPermission(markerClicked?.layer?.api?.collectionName, "update", markerClicked)) {
- let success = false;
- try {
- await updatedItem?.layer?.api?.updateItem!({ id: updatedItem.id, parent: updatedItem.parent, position: null })
- success = true;
- } catch (error) {
- toast.error(error.toString());
- }
- if (success) {
- await updateItem({ ...updatedItem, parent: updatedItem.parent, position: undefined })
- await linkItem(updatedItem.id);
- toast.success("Item position updated");
- setSelectPosition(null);
- setMarkerClicked(null);
- }
- }
- else {
- setSelectPosition(null);
- toast.error("you don't have permission to add items to " + markerClicked?.name);
- }
+ }, [markerClicked])
+
+ useEffect(() => {
+ if (selectPosition != null) {
+ if ('menuIcon' in selectPosition) {
+ mapClicked && mapClicked.setItemFormPopup({ layer: selectPosition as LayerProps, position: mapClicked?.position })
+ setSelectPosition(null)
+ }
+ if ('text' in selectPosition) {
+ const position = mapClicked?.position.lng && new Geometry(mapClicked?.position.lng, mapClicked?.position.lat)
+ position && itemUpdatePosition({ ...selectPosition as Item, position })
+ setSelectPosition(null)
+ }
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [mapClicked])
+
+ const itemUpdateParent = async (updatedItem: Item) => {
+ if (markerClicked?.layer?.api?.collectionName && hasUserPermission(markerClicked?.layer?.api?.collectionName, 'update', markerClicked)) {
+ let success = false
+ try {
+ await updatedItem?.layer?.api?.updateItem!({ id: updatedItem.id, parent: updatedItem.parent, position: null })
+ success = true
+ } catch (error) {
+ toast.error(error.toString())
+ }
+ if (success) {
+ await updateItem({ ...updatedItem, parent: updatedItem.parent, position: undefined })
+ await linkItem(updatedItem.id)
+ toast.success('Item position updated')
+ setSelectPosition(null)
+ setMarkerClicked(null)
+ }
+ } else {
+ setSelectPosition(null)
+ toast.error("you don't have permission to add items to " + markerClicked?.name)
+ }
+ }
+
+ const itemUpdatePosition = async (updatedItem: Item) => {
+ let success = false
+ try {
+ await updatedItem?.layer?.api?.updateItem!({ id: updatedItem.id, position: updatedItem.position })
+ success = true
+ } catch (error) {
+ toast.error(error.toString())
+ }
+ if (success) {
+ updateItem(updatedItem)
+ toast.success('Item position updated')
}
+ }
+
+ const linkItem = async (id: string) => {
+ if (markerClicked) {
+ const newRelations = markerClicked.relations || []
+
+ if (!newRelations.some(r => r.related_items_id === id)) {
+ newRelations?.push({ items_id: markerClicked.id, related_items_id: id })
+ const updatedItem = { id: markerClicked.id, relations: newRelations }
- const itemUpdatePosition = async (updatedItem: Item) => {
- let success = false;
+ let success = false
try {
- await updatedItem?.layer?.api?.updateItem!({ id: updatedItem.id, position: updatedItem.position })
- success = true;
+ await markerClicked?.layer?.api?.updateItem!(updatedItem)
+ success = true
} catch (error) {
- toast.error(error.toString());
+ toast.error(error.toString())
}
if (success) {
- updateItem(updatedItem)
- toast.success("Item position updated");
+ updateItem({ ...markerClicked, relations: newRelations })
+ toast.success('Item linked')
}
+ }
}
-
- const linkItem = async (id: string) => {
- if (markerClicked) {
- const new_relations = markerClicked.relations || [];
-
- if (!new_relations.some(r => r.related_items_id == id)) {
- new_relations?.push({ items_id: markerClicked.id, related_items_id: id })
- const updatedItem = { id: markerClicked.id, relations: new_relations }
-
- let success = false;
- try {
- await markerClicked?.layer?.api?.updateItem!(updatedItem)
- success = true;
- } catch (error) {
- toast.error(error.toString());
- }
- if (success) {
- updateItem({ ...markerClicked, relations: new_relations })
- toast.success("Item linked");
- }
- }
- }
- }
- return { selectPosition, setSelectPosition, setMarkerClicked, setMapClicked };
+ }
+ return { selectPosition, setSelectPosition, setMarkerClicked, setMapClicked }
}
export const SelectPositionProvider: React.FunctionComponent<{
@@ -128,24 +123,24 @@ export const SelectPositionProvider: React.FunctionComponent<{
{children}
-);
+)
export const useSelectPosition = (): Item | LayerProps | null => {
- const { selectPosition } = useContext(SelectPositionContext);
- return selectPosition;
-};
+ const { selectPosition } = useContext(SelectPositionContext)
+ return selectPosition
+}
-export const useSetSelectPosition = (): UseSelectPositionManagerResult["setSelectPosition"] => {
- const { setSelectPosition } = useContext(SelectPositionContext);
- return setSelectPosition;
+export const useSetSelectPosition = (): UseSelectPositionManagerResult['setSelectPosition'] => {
+ const { setSelectPosition } = useContext(SelectPositionContext)
+ return setSelectPosition
}
-export const useSetMarkerClicked = (): UseSelectPositionManagerResult["setMarkerClicked"] => {
- const { setMarkerClicked } = useContext(SelectPositionContext);
- return setMarkerClicked;
+export const useSetMarkerClicked = (): UseSelectPositionManagerResult['setMarkerClicked'] => {
+ const { setMarkerClicked } = useContext(SelectPositionContext)
+ return setMarkerClicked
}
-export const useSetMapClicked = (): UseSelectPositionManagerResult["setMapClicked"] => {
- const { setMapClicked } = useContext(SelectPositionContext);
- return setMapClicked;
-}
\ No newline at end of file
+export const useSetMapClicked = (): UseSelectPositionManagerResult['setMapClicked'] => {
+ const { setMapClicked } = useContext(SelectPositionContext)
+ return setMapClicked
+}
diff --git a/src/Components/Map/hooks/useTags.tsx b/src/Components/Map/hooks/useTags.tsx
index 33104af..9125abb 100644
--- a/src/Components/Map/hooks/useTags.tsx
+++ b/src/Components/Map/hooks/useTags.tsx
@@ -1,13 +1,13 @@
/* eslint-disable no-unused-vars */
-import { useCallback, useReducer, createContext, useContext, useState } from "react";
-import * as React from "react";
-import { Item, ItemsApi, Tag } from "../../../types";
-import { hashTagRegex } from "../../../Utils/HashTagRegex";
-import { getValue } from "../../../Utils/GetValue";
+import { useCallback, useReducer, createContext, useContext, useState } from 'react'
+import * as React from 'react'
+import { Item, ItemsApi, Tag } from '../../../types'
+import { hashTagRegex } from '../../../Utils/HashTagRegex'
+import { getValue } from '../../../Utils/GetValue'
type ActionType =
- | { type: "ADD"; tag: Tag }
- | { type: "REMOVE"; id: string };
+ | { type: 'ADD'; tag: Tag }
+ | { type: 'REMOVE'; id: string };
type UseTagManagerResult = ReturnType;
@@ -18,9 +18,9 @@ const TagContext = createContext({
setTagData: () => { },
getItemTags: () => [],
allTagsLoaded: false
-});
+})
-function useTagsManager(initialTags: Tag[]): {
+function useTagsManager (initialTags: Tag[]): {
tags: Tag[];
addTag: (tag: Tag) => void;
setTagApi: (api: ItemsApi) => void;
@@ -28,92 +28,90 @@ function useTagsManager(initialTags: Tag[]): {
getItemTags: (item: Item) => Tag[];
allTagsLoaded: boolean
} {
-
- const [allTagsLoaded, setallTagsLoaded] = useState(false);
- const [tagCount, setTagCount] = useState(0);
+ const [allTagsLoaded, setallTagsLoaded] = useState(false)
+ const [tagCount, setTagCount] = useState(0)
const [tags, dispatch] = useReducer((state: Tag[], action: ActionType) => {
switch (action.type) {
- case "ADD":
+ case 'ADD':
// eslint-disable-next-line no-case-declarations
const exist = state.find((tag) =>
- tag.name.toLocaleLowerCase() === action.tag.name.toLocaleLowerCase() ? true : false
- );
+ tag.name.toLocaleLowerCase() === action.tag.name.toLocaleLowerCase()
+ )
if (!exist) {
const newState = [
...state,
- { ...action.tag}
- ];
- if(tagCount == newState.length) setallTagsLoaded(true);
- return newState;
- }
- else return state;
+ { ...action.tag }
+ ]
+ if (tagCount === newState.length) setallTagsLoaded(true)
+ return newState
+ } else return state
default:
- throw new Error();
+ throw new Error()
}
- }, initialTags);
+ }, initialTags)
const [api, setApi] = React.useState>({} as ItemsApi)
-
const setTagApi = useCallback(async (api: ItemsApi) => {
- setApi(api);
- const result = await api.getItems();
- setTagCount(result.length);
- if(tagCount == 0) setallTagsLoaded(true);
+ setApi(api)
+ const result = await api.getItems()
+ setTagCount(result.length)
+ if (tagCount === 0) setallTagsLoaded(true)
if (result) {
result.map(tag => {
- //tag.name = tag.name.toLocaleLowerCase();
- dispatch({ type: "ADD", tag });
+ // tag.name = tag.name.toLocaleLowerCase();
+ dispatch({ type: 'ADD', tag })
+ return null
})
}
-
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const setTagData = useCallback((data: Tag[]) => {
data.map(tag => {
- //tag.name = tag.name.toLocaleLowerCase();
- dispatch({ type: "ADD", tag })
+ // tag.name = tag.name.toLocaleLowerCase();
+ dispatch({ type: 'ADD', tag })
+ return null
})
- }, []);
-
- const addTag = (tag: Tag) => {
- dispatch({
- type: "ADD",
- tag,
- });
- if (!tags.some((t) => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())) {
- api?.createItem && api.createItem(tag);
- }
-
- };
+ }, [])
+ const addTag = (tag: Tag) => {
+ dispatch({
+ type: 'ADD',
+ tag
+ })
+ if (!tags.some((t) => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())) {
+ api?.createItem && api.createItem(tag)
+ }
+ }
const getItemTags = useCallback((item: Item) => {
- const text = item?.layer?.itemTextField && item ? getValue(item, item.layer?.itemTextField) : undefined;
- const itemTagStrings = text?.match(hashTagRegex);
- const itemTags: Tag[] = [];
+ const text = item?.layer?.itemTextField && item ? getValue(item, item.layer?.itemTextField) : undefined
+ const itemTagStrings = text?.match(hashTagRegex)
+ const itemTags: Tag[] = []
itemTagStrings?.map(tag => {
if (tags.find(t => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) {
itemTags.push(tags.find(t => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())!)
}
- })
+ return null
+ })
item.layer?.itemOffersField && getValue(item, item.layer.itemOffersField)?.map(o => {
- const offer = tags.find(t=> t.id === o.tags_id)
+ const offer = tags.find(t => t.id === o.tags_id)
offer && itemTags.push(offer)
- });
+ return null
+ })
item.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField)?.map(n => {
- const need = tags.find(t=>t.id === n.tags_id);
- need && itemTags.push(need);
- });
+ const need = tags.find(t => t.id === n.tags_id)
+ need && itemTags.push(need)
+ return null
+ })
return itemTags
- }, [tags]);
+ }, [tags])
-
- return { tags, addTag, setTagApi, setTagData, getItemTags, allTagsLoaded };
+ return { tags, addTag, setTagApi, setTagData, getItemTags, allTagsLoaded }
}
export const TagsProvider: React.FunctionComponent<{
@@ -122,35 +120,34 @@ export const TagsProvider: React.FunctionComponent<{
{children}
-);
+)
export const useTags = (): Tag[] => {
- const { tags } = useContext(TagContext);
- return tags;
-};
-
-export const useAddTag = (): UseTagManagerResult["addTag"] => {
- const { addTag } = useContext(TagContext);
- return addTag;
-};
-
-export const useSetTagApi = (): UseTagManagerResult["setTagApi"] => {
- const { setTagApi } = useContext(TagContext);
- return setTagApi;
+ const { tags } = useContext(TagContext)
+ return tags
}
-export const useSetTagData = (): UseTagManagerResult["setTagData"] => {
- const { setTagData } = useContext(TagContext);
- return setTagData;
+export const useAddTag = (): UseTagManagerResult['addTag'] => {
+ const { addTag } = useContext(TagContext)
+ return addTag
}
+export const useSetTagApi = (): UseTagManagerResult['setTagApi'] => {
+ const { setTagApi } = useContext(TagContext)
+ return setTagApi
+}
-export const useGetItemTags = (): UseTagManagerResult["getItemTags"] => {
- const { getItemTags } = useContext(TagContext);
- return getItemTags;
+export const useSetTagData = (): UseTagManagerResult['setTagData'] => {
+ const { setTagData } = useContext(TagContext)
+ return setTagData
}
-export const useAllTagsLoaded = (): UseTagManagerResult["allTagsLoaded"] => {
- const { allTagsLoaded } = useContext(TagContext);
- return allTagsLoaded;
-}
\ No newline at end of file
+export const useGetItemTags = (): UseTagManagerResult['getItemTags'] => {
+ const { getItemTags } = useContext(TagContext)
+ return getItemTags
+}
+
+export const useAllTagsLoaded = (): UseTagManagerResult['allTagsLoaded'] => {
+ const { allTagsLoaded } = useContext(TagContext)
+ return allTagsLoaded
+}
diff --git a/src/Components/Map/hooks/useTimeout.tsx b/src/Components/Map/hooks/useTimeout.tsx
index ae31835..db8aa43 100644
--- a/src/Components/Map/hooks/useTimeout.tsx
+++ b/src/Components/Map/hooks/useTimeout.tsx
@@ -1,30 +1,30 @@
-import { useCallback, useEffect, useRef } from 'react';
+import { useCallback, useEffect, useRef } from 'react'
export const useTimeout = (callback, delay) => {
- const callbackRef = useRef(callback);
- const timeoutRef = useRef();
+ const callbackRef = useRef(callback)
+ const timeoutRef = useRef()
useEffect(() => {
- callbackRef.current = callback;
- }, [callback]);
+ callbackRef.current = callback
+ }, [callback])
const set = useCallback(() => {
- timeoutRef.current = setTimeout(() => callbackRef.current(), delay);
- }, [delay]);
+ timeoutRef.current = setTimeout(() => callbackRef.current(), delay)
+ }, [delay])
const clear = useCallback(() => {
- timeoutRef.current && clearTimeout(timeoutRef.current);
- }, []);
+ timeoutRef.current && clearTimeout(timeoutRef.current)
+ }, [])
useEffect(() => {
- set();
- return clear;
- }, [delay, set, clear]);
+ set()
+ return clear
+ }, [delay, set, clear])
const reset = useCallback(() => {
- clear();
- set();
- }, [clear, set]);
+ clear()
+ set()
+ }, [clear, set])
- return { reset, clear };
-}
\ No newline at end of file
+ return { reset, clear }
+}
diff --git a/src/Components/Map/hooks/useWindowDimension.tsx b/src/Components/Map/hooks/useWindowDimension.tsx
index 89f0f7b..ac27614 100644
--- a/src/Components/Map/hooks/useWindowDimension.tsx
+++ b/src/Components/Map/hooks/useWindowDimension.tsx
@@ -1,24 +1,24 @@
-import { useState, useEffect } from 'react';
+import { useState, useEffect } from 'react'
-function getWindowDimensions() {
- const { innerWidth: width, innerHeight: height } = window;
+function getWindowDimensions () {
+ const { innerWidth: width, innerHeight: height } = window
return {
width,
height
- };
+ }
}
-export default function useWindowDimensions() {
- const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions());
+export default function useWindowDimensions () {
+ const [windowDimensions, setWindowDimensions] = useState(getWindowDimensions())
useEffect(() => {
- function handleResize() {
- setWindowDimensions(getWindowDimensions());
+ function handleResize () {
+ setWindowDimensions(getWindowDimensions())
}
- window.addEventListener('resize', handleResize);
- return () => window.removeEventListener('resize', handleResize);
- }, []);
+ window.addEventListener('resize', handleResize)
+ return () => window.removeEventListener('resize', handleResize)
+ }, [])
- return windowDimensions;
+ return windowDimensions
}
diff --git a/src/Components/Map/index.tsx b/src/Components/Map/index.tsx
index fcf5fb3..df97071 100644
--- a/src/Components/Map/index.tsx
+++ b/src/Components/Map/index.tsx
@@ -1,13 +1,13 @@
-export { UtopiaMap } from './UtopiaMap';
-export { Layer } from './Layer';
-export { Tags } from "./Tags";
-export { Permissions } from "./Permissions";
-export {ItemForm} from './ItemForm';
-export {ItemView} from './ItemView';
-export {PopupTextAreaInput} from './Subcomponents/ItemPopupComponents/PopupTextAreaInput';
-export {PopupStartEndInput} from './Subcomponents/ItemPopupComponents/PopupStartEndInput';
-export {PopupTextInput} from './Subcomponents/ItemPopupComponents/PopupTextInput';
-export {PopupCheckboxInput} from './Subcomponents/ItemPopupComponents/PopupCheckboxInput'
-export {TextView} from './Subcomponents/ItemPopupComponents/TextView';
-export {StartEndView} from './Subcomponents/ItemPopupComponents/StartEndView'
-export {PopupButton} from './Subcomponents/ItemPopupComponents/PopupButton'
\ No newline at end of file
+export { UtopiaMap } from './UtopiaMap'
+export { Layer } from './Layer'
+export { Tags } from './Tags'
+export { Permissions } from './Permissions'
+export { ItemForm } from './ItemForm'
+export { ItemView } from './ItemView'
+export { PopupTextAreaInput } from './Subcomponents/ItemPopupComponents/PopupTextAreaInput'
+export { PopupStartEndInput } from './Subcomponents/ItemPopupComponents/PopupStartEndInput'
+export { PopupTextInput } from './Subcomponents/ItemPopupComponents/PopupTextInput'
+export { PopupCheckboxInput } from './Subcomponents/ItemPopupComponents/PopupCheckboxInput'
+export { TextView } from './Subcomponents/ItemPopupComponents/TextView'
+export { StartEndView } from './Subcomponents/ItemPopupComponents/StartEndView'
+export { PopupButton } from './Subcomponents/ItemPopupComponents/PopupButton'
diff --git a/src/Components/Map/setItemLocation.tsx b/src/Components/Map/setItemLocation.tsx
index f7761fa..dae30e7 100644
--- a/src/Components/Map/setItemLocation.tsx
+++ b/src/Components/Map/setItemLocation.tsx
@@ -1,9 +1,8 @@
-import { useMap } from "react-leaflet"
+import { useMap } from 'react-leaflet'
export const setItemLocation = () => {
-
// eslint-disable-next-line no-unused-vars, react-hooks/rules-of-hooks
- const map = useMap();
+ const map = useMap()
return (
diff --git a/src/Components/Profile/ProfileForm.tsx b/src/Components/Profile/ProfileForm.tsx
index fb0ae3f..e12b2e2 100644
--- a/src/Components/Profile/ProfileForm.tsx
+++ b/src/Components/Profile/ProfileForm.tsx
@@ -1,158 +1,156 @@
/* eslint-disable no-constant-condition */
import { useItems, useUpdateItem, useAddItem } from '../Map/hooks/useItems'
-import { useEffect, useState } from 'react';
-import { getValue } from '../../Utils/GetValue';
-import { useAuth } from '../Auth';
-import { useAddTag, useGetItemTags, useTags } from '../Map/hooks/useTags';
-import { useLocation, useNavigate } from 'react-router-dom';
-import { Item, Tag } from '../../types';
-import { MapOverlayPage } from '../Templates';
-import { useLayers } from '../Map/hooks/useLayers';
-import { useHasUserPermission } from '../Map/hooks/usePermissions';
-import { OnepagerForm } from './Templates/OnepagerForm';
-import { linkItem, onUpdateItem, unlinkItem } from './itemFunctions';
-import { SimpleForm } from './Templates/SimpleForm';
-import { TabsForm } from './Templates/TabsForm';
-import { FormHeader } from './Subcomponents/FormHeader';
-
-export function ProfileForm({ userType }: { userType: string }) {
-
- const [state, setState] = useState({
- color: "",
- id: "",
- groupType: "wuerdekompass",
- status: "active",
- name: "",
- subname: "",
- text: "",
- contact: "",
- telephone: "",
- nextAppointment: "",
- image: "",
- markerIcon: "",
- offers: [] as Tag[],
- needs: [] as Tag[],
- relations: [] as Item[],
- start: "",
- end: ""
- });
-
- const [updatePermission, setUpdatePermission] = useState(false);
- const [loading, setLoading] = useState(false);
- const [item, setItem] = useState
- ({} as Item)
- const { user } = useAuth();
- const updateItem = useUpdateItem();
- const addItem = useAddItem();
- const layers = useLayers();
- const location = useLocation();
- const tags = useTags();
- const addTag = useAddTag();
- const navigate = useNavigate();
- const hasUserPermission = useHasUserPermission();
- const getItemTags = useGetItemTags();
- const items = useItems();
-
- const [urlParams, setUrlParams] = useState(new URLSearchParams(location.search));
-
-
- useEffect(() => {
- item && hasUserPermission("items", "update", item) && setUpdatePermission(true);
+import { useEffect, useState } from 'react'
+import { getValue } from '../../Utils/GetValue'
+import { useAuth } from '../Auth'
+import { useAddTag, useGetItemTags, useTags } from '../Map/hooks/useTags'
+import { useLocation, useNavigate } from 'react-router-dom'
+import { Item, Tag } from '../../types'
+import { MapOverlayPage } from '../Templates'
+import { useLayers } from '../Map/hooks/useLayers'
+import { useHasUserPermission } from '../Map/hooks/usePermissions'
+import { OnepagerForm } from './Templates/OnepagerForm'
+import { linkItem, onUpdateItem, unlinkItem } from './itemFunctions'
+import { SimpleForm } from './Templates/SimpleForm'
+import { TabsForm } from './Templates/TabsForm'
+import { FormHeader } from './Subcomponents/FormHeader'
+
+export function ProfileForm ({ userType }: { userType: string }) {
+ const [state, setState] = useState({
+ color: '',
+ id: '',
+ groupType: 'wuerdekompass',
+ status: 'active',
+ name: '',
+ subname: '',
+ text: '',
+ contact: '',
+ telephone: '',
+ nextAppointment: '',
+ image: '',
+ markerIcon: '',
+ offers: [] as Tag[],
+ needs: [] as Tag[],
+ relations: [] as Item[],
+ start: '',
+ end: ''
+ })
+
+ const [updatePermission, setUpdatePermission] = useState(false)
+ const [loading, setLoading] = useState(false)
+ const [item, setItem] = useState
- ({} as Item)
+ const { user } = useAuth()
+ const updateItem = useUpdateItem()
+ const addItem = useAddItem()
+ const layers = useLayers()
+ const location = useLocation()
+ const tags = useTags()
+ const addTag = useAddTag()
+ const navigate = useNavigate()
+ const hasUserPermission = useHasUserPermission()
+ const getItemTags = useGetItemTags()
+ const items = useItems()
+
+ const [urlParams, setUrlParams] = useState(new URLSearchParams(location.search))
+
+ useEffect(() => {
+ item && hasUserPermission('items', 'update', item) && setUpdatePermission(true)
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [item])
+ }, [item])
- useEffect(() => {
- const itemId = location.pathname.split("/")[2];
+ useEffect(() => {
+ const itemId = location.pathname.split('/')[2]
- const item = items.find(i => i.id === itemId);
- item && setItem(item);
+ const item = items.find(i => i.id === itemId)
+ item && setItem(item)
- const layer = layers.find(l => l.itemType.name == userType)
+ const layer = layers.find(l => l.itemType.name === userType)
- !item && setItem({ id: crypto.randomUUID(), name: user ? user.first_name : "", text: "", layer: layer, new: true })
+ !item && setItem({ id: crypto.randomUUID(), name: user ? user.first_name : '', text: '', layer, new: true })
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [items])
-
- useEffect(() => {
- const newColor = item.layer?.itemColorField && getValue(item, item.layer?.itemColorField)
- ? getValue(item, item.layer?.itemColorField)
- : (getItemTags(item) && getItemTags(item)[0]?.color)
- ? getItemTags(item)[0].color
- : item?.layer?.markerDefaultColor;
-
- const offers = (item?.offers ?? []).reduce((acc: Tag[], o) => {
- const offer = tags.find(t => t.id === o.tags_id);
- if (offer) acc.push(offer);
- return acc;
- }, []);
-
- const needs = (item?.needs ?? []).reduce((acc: Tag[], o) => {
- const need = tags.find(t => t.id === o.tags_id);
- if (need) acc.push(need);
- return acc;
- }, []);
-
- const relations = (item?.relations ?? []).reduce((acc: Item[], r) => {
- const relatedItem = items.find(i => i.id === r.related_items_id);
- if (relatedItem) acc.push(relatedItem);
- return acc;
- }, []);
-
- setState({
- color: newColor,
- id: item?.id ?? "",
- groupType: item?.group_type ?? "wuerdekompass",
- status: item?.status ?? "active",
- name: item?.name ?? "",
- subname: item?.subname ?? "",
- text: item?.text ?? "",
- contact: item?.contact ?? "",
- telephone: item?.telephone ?? "",
- nextAppointment: item?.next_appointment ?? "",
- image: item?.image ?? "",
- markerIcon: item?.marker_icon ?? "",
- offers: offers,
- needs: needs,
- relations: relations,
- start: item?.start ?? "",
- end: item?.end ?? ""
- });
+ }, [items])
+
+ useEffect(() => {
+ const newColor = item.layer?.itemColorField && getValue(item, item.layer?.itemColorField)
+ ? getValue(item, item.layer?.itemColorField)
+ : (getItemTags(item) && getItemTags(item)[0]?.color)
+ ? getItemTags(item)[0].color
+ : item?.layer?.markerDefaultColor
+
+ const offers = (item?.offers ?? []).reduce((acc: Tag[], o) => {
+ const offer = tags.find(t => t.id === o.tags_id)
+ if (offer) acc.push(offer)
+ return acc
+ }, [])
+
+ const needs = (item?.needs ?? []).reduce((acc: Tag[], o) => {
+ const need = tags.find(t => t.id === o.tags_id)
+ if (need) acc.push(need)
+ return acc
+ }, [])
+
+ const relations = (item?.relations ?? []).reduce((acc: Item[], r) => {
+ const relatedItem = items.find(i => i.id === r.related_items_id)
+ if (relatedItem) acc.push(relatedItem)
+ return acc
+ }, [])
+
+ setState({
+ color: newColor,
+ id: item?.id ?? '',
+ groupType: item?.group_type ?? 'wuerdekompass',
+ status: item?.status ?? 'active',
+ name: item?.name ?? '',
+ subname: item?.subname ?? '',
+ text: item?.text ?? '',
+ contact: item?.contact ?? '',
+ telephone: item?.telephone ?? '',
+ nextAppointment: item?.next_appointment ?? '',
+ image: item?.image ?? '',
+ markerIcon: item?.marker_icon ?? '',
+ offers,
+ needs,
+ relations,
+ start: item?.start ?? '',
+ end: item?.end ?? ''
+ })
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [item, tags, items]);
+ }, [item, tags, items])
- const [template, setTemplate] = useState("")
+ const [template, setTemplate] = useState('')
- useEffect(() => {
- setTemplate(item.layer?.itemType.template || userType);
- }, [userType, item])
+ useEffect(() => {
+ setTemplate(item.layer?.itemType.template || userType)
+ }, [userType, item])
- return (
+ return (
<>
-
+
- {template == "onepager" && (
+ {template === 'onepager' && (
)}
- {template == "simple" &&
+ {template === 'simple' &&
}
- {template == "tabs" &&
+ {template === 'tabs' &&
linkItem(id, item, updateItem)} unlinkItem={(id) => unlinkItem(id, item, updateItem)} setUrlParams={setUrlParams}>
}
-
+
>
- )
-}
\ No newline at end of file
+ )
+}
diff --git a/src/Components/Profile/ProfileView.tsx b/src/Components/Profile/ProfileView.tsx
index d7b7e4e..ffe725a 100644
--- a/src/Components/Profile/ProfileView.tsx
+++ b/src/Components/Profile/ProfileView.tsx
@@ -1,164 +1,161 @@
import { MapOverlayPage } from '../Templates'
import { useItems, useRemoveItem, useUpdateItem } from '../Map/hooks/useItems'
import { useLocation, useNavigate } from 'react-router-dom'
-import { useEffect, useState } from 'react';
-import { Item, ItemsApi, Tag } from '../../types';
-import { useMap } from 'react-leaflet';
-import { LatLng } from 'leaflet';
-import { useHasUserPermission } from '../Map/hooks/usePermissions';
-import { HeaderView } from '../Map/Subcomponents/ItemPopupComponents/HeaderView';
-import { useSelectPosition, useSetSelectPosition } from '../Map/hooks/useSelectPosition';
-import { useClusterRef } from '../Map/hooks/useClusterRef';
-import { useLeafletRefs } from '../Map/hooks/useLeafletRefs';
-import { getValue } from '../../Utils/GetValue';
-import { TabsView } from './Templates/TabsView';
-import { OnepagerView } from './Templates/OnepagerView';
-import { SimpleView } from './Templates/SimpleView';
-import { handleDelete, linkItem, unlinkItem } from './itemFunctions';
-import { useTags } from '../Map/hooks/useTags';
-
-export function ProfileView({ userType, attestationApi }: { userType: string , attestationApi?: ItemsApi}) {
-
- const [item, setItem] = useState- ()
- const [updatePermission, setUpdatePermission] = useState(false);
- const [relations, setRelations] = useState>([]);
- const [offers, setOffers] = useState>([]);
- const [needs, setNeeds] = useState>([]);
- const [loading, setLoading] = useState(false);
- const [template, setTemplate] = useState("");
-
- const location = useLocation();
- const items = useItems();
- const updateItem = useUpdateItem();
- const map = useMap();
- const selectPosition = useSelectPosition();
- const removeItem = useRemoveItem();
- const tags = useTags();
- const navigate = useNavigate();
- const hasUserPermission = useHasUserPermission();
- const setSelectPosition = useSetSelectPosition();
- const clusterRef = useClusterRef();
- const leafletRefs = useLeafletRefs();
-
- const [attestations, setAttestations] = useState>([]);
-
- useEffect(() => {
- if (attestationApi) {
- attestationApi.getItems()
- .then(value => {
- console.log(value);
-
- setAttestations(value);
- })
- .catch(error => {
- console.error("Error fetching items:", error);
- });
- }
- }, [attestationApi])
-
-
- useEffect(() => {
- const itemId = location.pathname.split("/")[2];
- const item = items.find(i => i.id === itemId);
- item && setItem(item);
- }, [items, location])
-
- useEffect(() => {
- setOffers([]);
- setNeeds([]);
- setRelations([]);
-
- item?.layer?.itemOffersField && getValue(item, item.layer.itemOffersField)?.map(o => {
- const tag = tags.find(t => t.id === o.tags_id);
- tag && setOffers(current => [...current, tag])
+import { useEffect, useState } from 'react'
+import { Item, ItemsApi, Tag } from '../../types'
+import { useMap } from 'react-leaflet'
+import { LatLng } from 'leaflet'
+import { useHasUserPermission } from '../Map/hooks/usePermissions'
+import { HeaderView } from '../Map/Subcomponents/ItemPopupComponents/HeaderView'
+import { useSelectPosition, useSetSelectPosition } from '../Map/hooks/useSelectPosition'
+import { useClusterRef } from '../Map/hooks/useClusterRef'
+import { useLeafletRefs } from '../Map/hooks/useLeafletRefs'
+import { getValue } from '../../Utils/GetValue'
+import { TabsView } from './Templates/TabsView'
+import { OnepagerView } from './Templates/OnepagerView'
+import { SimpleView } from './Templates/SimpleView'
+import { handleDelete, linkItem, unlinkItem } from './itemFunctions'
+import { useTags } from '../Map/hooks/useTags'
+
+export function ProfileView ({ userType, attestationApi }: { userType: string, attestationApi?: ItemsApi}) {
+ const [item, setItem] = useState
- ()
+ const [updatePermission, setUpdatePermission] = useState(false)
+ const [relations, setRelations] = useState>([])
+ const [offers, setOffers] = useState>([])
+ const [needs, setNeeds] = useState>([])
+ const [loading, setLoading] = useState(false)
+ const [template, setTemplate] = useState('')
+
+ const location = useLocation()
+ const items = useItems()
+ const updateItem = useUpdateItem()
+ const map = useMap()
+ const selectPosition = useSelectPosition()
+ const removeItem = useRemoveItem()
+ const tags = useTags()
+ const navigate = useNavigate()
+ const hasUserPermission = useHasUserPermission()
+ const setSelectPosition = useSetSelectPosition()
+ const clusterRef = useClusterRef()
+ const leafletRefs = useLeafletRefs()
+
+ const [attestations, setAttestations] = useState>([])
+
+ useEffect(() => {
+ if (attestationApi) {
+ attestationApi.getItems()
+ .then(value => {
+ console.log(value)
+
+ setAttestations(value)
})
- item?.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField)?.map(n => {
- const tag = tags.find(t => t.id === n.tags_id);
- tag && setNeeds(current => [...current, tag])
- })
- item?.relations?.map(r => {
- const item = items.find(i => i.id == r.related_items_id)
- item && setRelations(current => [...current, item])
+ .catch(error => {
+ console.error('Error fetching items:', error)
})
+ }
+ }, [attestationApi])
+
+ useEffect(() => {
+ const itemId = location.pathname.split('/')[2]
+ const item = items.find(i => i.id === itemId)
+ item && setItem(item)
+ }, [items, location])
+
+ useEffect(() => {
+ setOffers([])
+ setNeeds([])
+ setRelations([])
+
+ item?.layer?.itemOffersField && getValue(item, item.layer.itemOffersField)?.map(o => {
+ const tag = tags.find(t => t.id === o.tags_id)
+ tag && setOffers(current => [...current, tag])
+ return null
+ })
+ item?.layer?.itemNeedsField && getValue(item, item.layer.itemNeedsField)?.map(n => {
+ const tag = tags.find(t => t.id === n.tags_id)
+ tag && setNeeds(current => [...current, tag])
+ return null
+ })
+ item?.relations?.map(r => {
+ const item = items.find(i => i.id === r.related_items_id)
+ item && setRelations(current => [...current, item])
+ return null
+ })
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [item, items])
-
-
- useEffect(() => {
- const setMap = async (marker, x) => {
- await map.setView(new LatLng(item?.position?.coordinates[1]!, item?.position?.coordinates[0]! + x / 4), undefined);
- setTimeout(() => {
- marker.openPopup();
- }, 500);
+ }, [item, items])
+
+ useEffect(() => {
+ const setMap = async (marker, x) => {
+ await map.setView(new LatLng(item?.position?.coordinates[1]!, item?.position?.coordinates[0]! + x / 4), undefined)
+ setTimeout(() => {
+ marker.openPopup()
+ }, 500)
+ }
+ if (item) {
+ if (item.position) {
+ const marker = Object.entries(leafletRefs).find(r => r[1].item === item)?.[1].marker
+ marker && clusterRef.hasLayer(marker) && clusterRef?.zoomToShowLayer(marker, () => {
+ const bounds = map.getBounds()
+ const x = bounds.getEast() - bounds.getWest()
+ setMap(marker, x)
}
- if (item) {
- if (item.position) {
- const marker = Object.entries(leafletRefs).find(r => r[1].item == item)?.[1].marker;
- marker && clusterRef.hasLayer(marker) && clusterRef?.zoomToShowLayer(marker, () => {
- const bounds = map.getBounds();
- const x = bounds.getEast() - bounds.getWest();
- setMap(marker, x);
- }
- );
- }
- else {
- const parent = getFirstAncestor(item);
- const marker = Object.entries(leafletRefs).find(r => r[1].item == parent)?.[1].marker;
- marker && clusterRef.hasLayer(marker) && clusterRef?.zoomToShowLayer(marker, () => {
- const bounds = map.getBounds();
- const x = bounds.getEast() - bounds.getWest();
- setMap(marker, x);
- }
- );
- }
+ )
+ } else {
+ const parent = getFirstAncestor(item)
+ const marker = Object.entries(leafletRefs).find(r => r[1].item === parent)?.[1].marker
+ marker && clusterRef.hasLayer(marker) && clusterRef?.zoomToShowLayer(marker, () => {
+ const bounds = map.getBounds()
+ const x = bounds.getEast() - bounds.getWest()
+ setMap(marker, x)
}
+ )
+ }
+ }
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [item])
-
- const getFirstAncestor = (item: Item): Item | undefined => {
- const parent = items.find(i => i.id === item.parent);
- if (parent?.parent) {
- return getFirstAncestor(parent);
- } else {
- return parent;
- }
- };
-
- useEffect(() => {
- item && hasUserPermission("items", "update", item) && setUpdatePermission(true);
+ }, [item])
+
+ const getFirstAncestor = (item: Item): Item | undefined => {
+ const parent = items.find(i => i.id === item.parent)
+ if (parent?.parent) {
+ return getFirstAncestor(parent)
+ } else {
+ return parent
+ }
+ }
+
+ useEffect(() => {
+ item && hasUserPermission('items', 'update', item) && setUpdatePermission(true)
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [item])
+ }, [item])
-
- useEffect(() => {
- selectPosition && map.closePopup();
+ useEffect(() => {
+ selectPosition && map.closePopup()
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [selectPosition])
-
- useEffect(() => {
- setTemplate(item?.layer?.itemType.template || userType);
- }, [userType, item])
+ }, [selectPosition])
+ useEffect(() => {
+ setTemplate(item?.layer?.itemType.template || userType)
+ }, [userType, item])
- return (
+ return (
<>
- {item &&
+ {item &&
<>
-
-
handleDelete(e, item, setLoading, removeItem, map, navigate)} editCallback={() => navigate("/edit-item/" + item.id)} setPositionCallback={() => { map.closePopup(); setSelectPosition(item); navigate("/") }} big truncateSubname={false} />
+
+ handleDelete(e, item, setLoading, removeItem, map, navigate)} editCallback={() => navigate('/edit-item/' + item.id)} setPositionCallback={() => { map.closePopup(); setSelectPosition(item); navigate('/') }} big truncateSubname={false} />
- {template == "onepager" &&
+ {template === 'onepager' &&
}
- {template == "simple" &&
+ {template === 'simple' &&
}
- {template == "tabs" &&
+ {template === 'tabs' &&
linkItem(id, item, updateItem)} unlinkItem={(id) => unlinkItem(id, item, updateItem)}/>
}
>
@@ -166,5 +163,5 @@ export function ProfileView({ userType, attestationApi }: { userType: string , a
}
>
- )
-}
\ No newline at end of file
+ )
+}
diff --git a/src/Components/Profile/Subcomponents/ActionsButton.tsx b/src/Components/Profile/Subcomponents/ActionsButton.tsx
index d2a701a..b6417c7 100644
--- a/src/Components/Profile/Subcomponents/ActionsButton.tsx
+++ b/src/Components/Profile/Subcomponents/ActionsButton.tsx
@@ -1,14 +1,14 @@
-import { useState } from "react";
-import { useHasUserPermission } from "../../Map/hooks/usePermissions";
-import DialogModal from "../../Templates/DialogModal";
-import { useItems } from "../../Map/hooks/useItems";
-import { HeaderView } from "../../Map/Subcomponents/ItemPopupComponents/HeaderView";
-import { Item } from "../../../types";
-import { TextInput } from "../../Input";
-import { getValue } from "../../../Utils/GetValue";
-import { useGetItemTags } from "../../Map/hooks/useTags";
-
-export function ActionButton({ item, triggerAddButton, triggerItemSelected, existingRelations, itemType, colorField, collection = "items", customStyle }: {
+import { useState } from 'react'
+import { useHasUserPermission } from '../../Map/hooks/usePermissions'
+import DialogModal from '../../Templates/DialogModal'
+import { useItems } from '../../Map/hooks/useItems'
+import { HeaderView } from '../../Map/Subcomponents/ItemPopupComponents/HeaderView'
+import { Item } from '../../../types'
+import { TextInput } from '../../Input'
+import { getValue } from '../../../Utils/GetValue'
+import { useGetItemTags } from '../../Map/hooks/useTags'
+
+export function ActionButton ({ item, triggerAddButton, triggerItemSelected, existingRelations, itemType, colorField, collection = 'items', customStyle }: {
triggerAddButton?: any,
triggerItemSelected?: any,
existingRelations: Item[],
@@ -18,39 +18,36 @@ export function ActionButton({ item, triggerAddButton, triggerItemSelected, exis
customStyle?:string,
item: Item
}) {
- const hasUserPermission = useHasUserPermission();
- const [modalOpen, setModalOpen] = useState(false);
- const [search, setSearch] = useState("");
- const getItemTags = useGetItemTags();
-
-
- const items = useItems();
-
- const filterdItems = items.filter(i => !itemType || i.layer?.itemType.name == itemType).filter(i => !existingRelations.some(s => s.id == i.id)).filter(i => i.id != item.id)
+ const hasUserPermission = useHasUserPermission()
+ const [modalOpen, setModalOpen] = useState(false)
+ const [search, setSearch] = useState('')
+ const getItemTags = useGetItemTags()
+ const items = useItems()
+ const filterdItems = items.filter(i => !itemType || i.layer?.itemType.name === itemType).filter(i => !existingRelations.some(s => s.id === i.id)).filter(i => i.id !== item.id)
- return (
- <>{hasUserPermission(collection, "update", item) &&
+ return (
+ <>{hasUserPermission(collection, 'update', item) &&
<>
- {triggerItemSelected &&
- (setModalOpen(false))} className="tw-w-xl sm:tw-w-2xl tw-min-h-80 tw-bg-base-200">
- { setSearch(val) }}>
+ (setModalOpen(false))} className="tw-w-xl sm:tw-w-2xl tw-min-h-80 tw-bg-base-200">
+ { setSearch(val) }}>
{filterdItems.filter(item => {
- return search === ''
- ? item :
- item.name.toLowerCase().includes(search.toLowerCase());
+ return search === ''
+ ? item
+ : item.name.toLowerCase().includes(search.toLowerCase())
}).map(i =>
{ triggerItemSelected(i.id); setModalOpen(false) }}>
)}
@@ -60,5 +57,5 @@ export function ActionButton({ item, triggerAddButton, triggerItemSelected, exis
}
>
- )
+ )
}
diff --git a/src/Components/Profile/Subcomponents/AvatarWidget.tsx b/src/Components/Profile/Subcomponents/AvatarWidget.tsx
index caf4012..cb60f00 100644
--- a/src/Components/Profile/Subcomponents/AvatarWidget.tsx
+++ b/src/Components/Profile/Subcomponents/AvatarWidget.tsx
@@ -1,9 +1,9 @@
-import * as React from "react";
-import { useState, useCallback, useRef } from "react";
-import ReactCrop, { Crop, centerCrop, makeAspectCrop } from 'react-image-crop';
-import { useAssetApi } from '../../AppShell/hooks/useAssets';
-import 'react-image-crop/dist/ReactCrop.css';
-import DialogModal from "../../Templates/DialogModal";
+import * as React from 'react'
+import { useState, useCallback, useRef } from 'react'
+import ReactCrop, { Crop, centerCrop, makeAspectCrop } from 'react-image-crop'
+import { useAssetApi } from '../../AppShell/hooks/useAssets'
+import 'react-image-crop/dist/ReactCrop.css'
+import DialogModal from '../../Templates/DialogModal'
interface AvatarWidgetProps {
avatar: string;
@@ -11,167 +11,166 @@ interface AvatarWidgetProps {
}
export const AvatarWidget: React.FC
= ({ avatar, setAvatar }) => {
- const [crop, setCrop] = useState();
- const [image, setImage] = useState("");
- const [cropModalOpen, setCropModalOpen] = useState(false);
- const [cropping, setCropping] = useState(false);
-
- const assetsApi = useAssetApi();
-
- const imgRef = useRef(null);
-
- const onImageChange = useCallback((event: React.ChangeEvent) => {
- const file = event.target.files && event.target.files[0];
- if (file) {
- const validFormats = ["image/jpeg", "image/png"];
- const maxSizeMB = 10;
- const maxSizeBytes = maxSizeMB * 1024 * 1024;
-
- if (!validFormats.includes(file.type)) {
- alert("Unsupported file format. Please upload a JPEG or PNG image.");
- return;
- }
+ const [crop, setCrop] = useState()
+ const [image, setImage] = useState('')
+ const [cropModalOpen, setCropModalOpen] = useState(false)
+ const [cropping, setCropping] = useState(false)
+
+ const assetsApi = useAssetApi()
+
+ const imgRef = useRef(null)
+
+ const onImageChange = useCallback((event: React.ChangeEvent) => {
+ const file = event.target.files && event.target.files[0]
+ if (file) {
+ const validFormats = ['image/jpeg', 'image/png']
+ const maxSizeMB = 10
+ const maxSizeBytes = maxSizeMB * 1024 * 1024
+
+ if (!validFormats.includes(file.type)) {
+ alert('Unsupported file format. Please upload a JPEG or PNG image.')
+ return
+ }
+
+ if (file.size > maxSizeBytes) {
+ alert(`File size exceeds ${maxSizeMB}MB. Please upload a smaller image.`)
+ return
+ }
+
+ setImage(URL.createObjectURL(file))
+ setCropModalOpen(true)
+ } else {
+ alert('No file selected or an error occurred while selecting the file.')
+ }
+ }, [])
+
+ const onImageLoad = useCallback((e: React.SyntheticEvent) => {
+ const { width, height } = e.currentTarget
+ setCrop(centerAspectCrop(width, height, 1))
+ }, [])
+
+ const centerAspectCrop = (mediaWidth: number, mediaHeight: number, aspect: number) => {
+ return centerCrop(
+ makeAspectCrop(
+ {
+ unit: 'px',
+ width: mediaWidth / 2
+ },
+ aspect,
+ mediaWidth,
+ mediaHeight
+ ),
+ mediaWidth,
+ mediaHeight
+ )
+ }
+
+ async function resizeImage (image: HTMLImageElement, maxWidth: number, maxHeight: number): Promise {
+ const canvas = document.createElement('canvas')
+ const ctx = canvas.getContext('2d')
+
+ let width = image.width
+ let height = image.height
+
+ if (width > maxWidth) {
+ height *= maxWidth / width
+ width = maxWidth
+ }
+ if (height > maxHeight) {
+ width *= maxHeight / height
+ height = maxHeight
+ }
- if (file.size > maxSizeBytes) {
- alert(`File size exceeds ${maxSizeMB}MB. Please upload a smaller image.`);
- return;
- }
+ canvas.width = width
+ canvas.height = height
- setImage(URL.createObjectURL(file));
- setCropModalOpen(true);
- } else {
- alert("No file selected or an error occurred while selecting the file.");
- }
- }, []);
-
- const onImageLoad = useCallback((e: React.SyntheticEvent) => {
- const { width, height } = e.currentTarget;
- setCrop(centerAspectCrop(width, height, 1));
- }, []);
-
- const centerAspectCrop = (mediaWidth: number, mediaHeight: number, aspect: number) => {
- return centerCrop(
- makeAspectCrop(
- {
- unit: 'px',
- width: mediaWidth / 2,
- },
- aspect,
- mediaWidth,
- mediaHeight,
- ),
- mediaWidth,
- mediaHeight,
- );
- };
-
- async function resizeImage(image: HTMLImageElement, maxWidth: number, maxHeight: number): Promise {
- const canvas = document.createElement('canvas');
- const ctx = canvas.getContext('2d');
-
- let width = image.width;
- let height = image.height;
-
- if (width > maxWidth) {
- height *= maxWidth / width;
- width = maxWidth;
- }
- if (height > maxHeight) {
- width *= maxHeight / height;
- height = maxHeight;
- }
-
- canvas.width = width;
- canvas.height = height;
-
- if (ctx) {
- ctx.drawImage(image, 0, 0, width, height);
- }
-
- const resizedImage = new Image();
- resizedImage.src = canvas.toDataURL();
-
- await resizedImage.decode();
- return resizedImage;
+ if (ctx) {
+ ctx.drawImage(image, 0, 0, width, height)
}
- const renderCrop = useCallback(async () => {
- const image = imgRef.current;
- if (crop && image) {
- const resizedImage = await resizeImage(image, 1024, 1024); // BildgrΓΆΓe vor dem Zuschneiden reduzieren
- const scaleX = resizedImage.naturalWidth / resizedImage.width;
- const scaleY = resizedImage.naturalHeight / resizedImage.height;
-
- const canvas = new OffscreenCanvas(
- crop.width * scaleX,
- crop.height * scaleY
- );
- const ctx = canvas.getContext("2d");
- const pixelRatio = window.devicePixelRatio;
- canvas.width = crop.width * pixelRatio * scaleX;
- canvas.height = crop.height * pixelRatio * scaleY;
-
- if (ctx) {
- ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
- ctx.drawImage(
- resizedImage,
- crop.x * scaleX,
- crop.y * scaleY,
- crop.width * scaleX,
- crop.height * scaleY,
- 0,
- 0,
- crop.width * scaleX,
- crop.height * scaleY
- );
- }
-
- const blob = await canvas.convertToBlob();
- await resizeBlob(blob);
- setCropping(false);
- setImage("");
- }
+ const resizedImage = new Image()
+ resizedImage.src = canvas.toDataURL()
+
+ await resizedImage.decode()
+ return resizedImage
+ }
+
+ const renderCrop = useCallback(async () => {
+ const image = imgRef.current
+ if (crop && image) {
+ const resizedImage = await resizeImage(image, 1024, 1024) // BildgrΓΆΓe vor dem Zuschneiden reduzieren
+ const scaleX = resizedImage.naturalWidth / resizedImage.width
+ const scaleY = resizedImage.naturalHeight / resizedImage.height
+
+ const canvas = new OffscreenCanvas(
+ crop.width * scaleX,
+ crop.height * scaleY
+ )
+ const ctx = canvas.getContext('2d')
+ const pixelRatio = window.devicePixelRatio
+ canvas.width = crop.width * pixelRatio * scaleX
+ canvas.height = crop.height * pixelRatio * scaleY
+
+ if (ctx) {
+ ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0)
+ ctx.drawImage(
+ resizedImage,
+ crop.x * scaleX,
+ crop.y * scaleY,
+ crop.width * scaleX,
+ crop.height * scaleY,
+ 0,
+ 0,
+ crop.width * scaleX,
+ crop.height * scaleY
+ )
+ }
+
+ const blob = await canvas.convertToBlob()
+ await resizeBlob(blob)
+ setCropping(false)
+ setImage('')
+ }
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [crop]);
+ }, [crop])
- const resizeBlob = useCallback(async (blob: Blob) => {
- const img = new Image();
- img.src = URL.createObjectURL(blob);
- await img.decode();
+ const resizeBlob = useCallback(async (blob: Blob) => {
+ const img = new Image()
+ img.src = URL.createObjectURL(blob)
+ await img.decode()
- const canvas = new OffscreenCanvas(400, 400);
- const ctx = canvas.getContext("2d");
- ctx?.drawImage(img, 0, 0, 400, 400);
+ const canvas = new OffscreenCanvas(400, 400)
+ const ctx = canvas.getContext('2d')
+ ctx?.drawImage(img, 0, 0, 400, 400)
- const resizedBlob = await canvas.convertToBlob();
- const asset = await assetsApi.upload(resizedBlob, "avatar");
- setAvatar(asset.id);
- }, [assetsApi, setAvatar]);
+ const resizedBlob = await canvas.convertToBlob()
+ const asset = await assetsApi.upload(resizedBlob, 'avatar')
+ setAvatar(asset.id)
+ }, [assetsApi, setAvatar])
- return (
+ return (
<>
- {!cropping ?
-
+ {!cropping
+ ?
- {avatar ?
-
+ {avatar
+ ?
- :
-
-
+ :
}
- :
+ :
}
@@ -179,19 +178,19 @@ export const AvatarWidget: React.FC
= ({ avatar, setAvatar })
title=""
isOpened={cropModalOpen}
onClose={() => {
- setCropModalOpen(false);
- setImage("");
+ setCropModalOpen(false)
+ setImage('')
}}
closeOnClickOutside={false}>
setCrop(c)} aspect={1} >
- {
- setCropping(true);
- setCropModalOpen(false);
- renderCrop();
+ {
+ setCropping(true)
+ setCropModalOpen(false)
+ renderCrop()
}}>Select
>
- );
-};
+ )
+}
diff --git a/src/Components/Profile/Subcomponents/ColorPicker.tsx b/src/Components/Profile/Subcomponents/ColorPicker.tsx
index 029163b..7882d76 100644
--- a/src/Components/Profile/Subcomponents/ColorPicker.tsx
+++ b/src/Components/Profile/Subcomponents/ColorPicker.tsx
@@ -1,35 +1,34 @@
-import { useCallback, useEffect, useRef, useState } from "react";
-import * as React from "react";
-import { HexColorPicker } from "react-colorful";
-import "./ColorPicker.css"
-import useClickOutside from "../hooks/useClickOutside";
+import { useCallback, useEffect, useRef, useState } from 'react'
+import * as React from 'react'
+import { HexColorPicker } from 'react-colorful'
+import './ColorPicker.css'
+import useClickOutside from '../hooks/useClickOutside'
// eslint-disable-next-line react/prop-types
export const ColorPicker = ({ color, onChange, className }) => {
- const popover = useRef(null);
- const [isOpen, toggle] = useState(false);
+ const popover = useRef(null)
+ const [isOpen, toggle] = useState(false)
- const close = useCallback(() => toggle(false), []);
- useClickOutside(popover, close);
+ const close = useCallback(() => toggle(false), [])
+ useClickOutside(popover, close)
const colorPickerRef = React.useRef(null)
useEffect(() => {
- // FΓΌge dem Color-Picker explizit Event-Listener hinzu
- const colorPickerElement = colorPickerRef.current;
- if (colorPickerElement) {
- const enablePropagation = (event) => {
- // Verhindere, dass Leaflet die Propagation stoppt
- event.stopPropagation = () => {};
- };
-
- // Event-Listener fΓΌr den Color-Picker
- ['click', 'dblclick', 'mousedown', 'touchstart'].forEach(eventType => {
- colorPickerElement.addEventListener(eventType, enablePropagation, true);
- });
- }
-
- }, []);
+ // FΓΌge dem Color-Picker explizit Event-Listener hinzu
+ const colorPickerElement = colorPickerRef.current
+ if (colorPickerElement) {
+ const enablePropagation = (event) => {
+ // Verhindere, dass Leaflet die Propagation stoppt
+ event.stopPropagation = () => {}
+ };
+
+ // Event-Listener fΓΌr den Color-Picker
+ ['click', 'dblclick', 'mousedown', 'touchstart'].forEach(eventType => {
+ colorPickerElement.addEventListener(eventType, enablePropagation, true)
+ })
+ }
+ }, [])
return (
@@ -45,6 +44,5 @@ export const ColorPicker = ({ color, onChange, className }) => {
)}
- );
-};
-
+ )
+}
diff --git a/src/Components/Profile/Subcomponents/ContactInfo.tsx b/src/Components/Profile/Subcomponents/ContactInfo.tsx
index 7006844..7f2c577 100644
--- a/src/Components/Profile/Subcomponents/ContactInfo.tsx
+++ b/src/Components/Profile/Subcomponents/ContactInfo.tsx
@@ -1,10 +1,10 @@
-import { Link } from "react-router-dom";
-import { useAssetApi } from "../../AppShell/hooks/useAssets";
+import { Link } from 'react-router-dom'
+import { useAssetApi } from '../../AppShell/hooks/useAssets'
const ContactInfo = ({ email, telephone, name, avatar, link }: { email: string, telephone: string, name: string, avatar: string, link?: string }) => {
- const assetsApi = useAssetApi();
+ const assetsApi = useAssetApi()
- return (
+ return (
Du hast Fragen?
@@ -54,21 +54,21 @@ const ContactInfo = ({ email, telephone, name, avatar, link }: { email: string,
- )
+ )
}
-export default ContactInfo;
+export default ContactInfo
// eslint-disable-next-line react/prop-types
const ConditionalLink = ({ url, children }) => {
- const params = new URLSearchParams(window.location.search);
+ const params = new URLSearchParams(window.location.search)
- if (url) {
- return (
-
+ if (url) {
+ return (
+
{children}
- );
- }
- return children;
-};
\ No newline at end of file
+ )
+ }
+ return children
+}
diff --git a/src/Components/Profile/Subcomponents/FormHeader.tsx b/src/Components/Profile/Subcomponents/FormHeader.tsx
index 72f29af..5a1ed95 100644
--- a/src/Components/Profile/Subcomponents/FormHeader.tsx
+++ b/src/Components/Profile/Subcomponents/FormHeader.tsx
@@ -1,27 +1,27 @@
/* eslint-disable react/prop-types */
-import { TextInput } from "../../Input"
-import { AvatarWidget } from "./AvatarWidget"
-import { ColorPicker } from "./ColorPicker"
+import { TextInput } from '../../Input'
+import { AvatarWidget } from './AvatarWidget'
+import { ColorPicker } from './ColorPicker'
-export const FormHeader = ({item, state, setState}) => {
+export const FormHeader = ({ item, state, setState }) => {
return (
setState(prevState => ({
- ...prevState,
- image: i
+ ...prevState,
+ image: i
}))} />
setState(prevState => ({
- ...prevState,
- color: c
- }))} className={"-tw-left-6 tw-top-14 -tw-mr-6"} />
+ ...prevState,
+ color: c
+ }))} className={'-tw-left-6 tw-top-14 -tw-mr-6'} />
- setState(prevState => ({
- ...prevState,
- name: v
+ setState(prevState => ({
+ ...prevState,
+ name: v
}))} containerStyle='tw-grow tw-input-md' />
- setState(prevState => ({
- ...prevState,
- subname: v
+ setState(prevState => ({
+ ...prevState,
+ subname: v
}))} containerStyle='tw-grow tw-input-sm tw-px-4 tw-mt-1' />
diff --git a/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx b/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx
index aba1038..0239283 100644
--- a/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx
+++ b/src/Components/Profile/Subcomponents/LinkedItemsHeaderView.tsx
@@ -1,12 +1,9 @@
-import { useEffect } from "react";
-import { getValue } from "../../../Utils/GetValue";
-import { Item } from "../../../types";
-import { useAssetApi } from "../../AppShell/hooks/useAssets";
+import { useEffect } from 'react'
+import { getValue } from '../../../Utils/GetValue'
+import { Item } from '../../../types'
+import { useAssetApi } from '../../AppShell/hooks/useAssets'
-
-
-
-export function LinkedItemsHeaderView({ item, unlinkCallback, itemNameField, itemAvatarField, loading, unlinkPermission, itemSubnameField }: {
+export function LinkedItemsHeaderView ({ item, unlinkCallback, itemNameField, itemAvatarField, loading, unlinkPermission, itemSubnameField }: {
item: Item,
unlinkCallback?: any,
itemNameField?: string,
@@ -15,35 +12,30 @@ export function LinkedItemsHeaderView({ item, unlinkCallback, itemNameField, ite
loading?: boolean,
unlinkPermission: boolean
}) {
+ const assetsApi = useAssetApi()
- const assetsApi = useAssetApi();
-
-
- const avatar = itemAvatarField && getValue(item, itemAvatarField) ? assetsApi.url + getValue(item, itemAvatarField) : item.layer?.itemAvatarField && item && getValue(item, item.layer?.itemAvatarField) && assetsApi.url + getValue(item, item.layer?.itemAvatarField);
- const title = itemNameField ? getValue(item, itemNameField) : item.layer?.itemNameField && item && getValue(item, item.layer?.itemNameField);
- const subtitle = itemSubnameField ? getValue(item, itemSubnameField) : item.layer?.itemSubnameField && item && getValue(item, item.layer?.itemSubnameField);
-
-
+ const avatar = itemAvatarField && getValue(item, itemAvatarField) ? assetsApi.url + getValue(item, itemAvatarField) : item.layer?.itemAvatarField && item && getValue(item, item.layer?.itemAvatarField) && assetsApi.url + getValue(item, item.layer?.itemAvatarField)
+ const title = itemNameField ? getValue(item, itemNameField) : item.layer?.itemNameField && item && getValue(item, item.layer?.itemNameField)
+ const subtitle = itemSubnameField ? getValue(item, itemSubnameField) : item.layer?.itemSubnameField && item && getValue(item, item.layer?.itemSubnameField)
useEffect(() => {
}, [item])
-
return (
<>
-
+
{avatar && (
)}
-
-
+
+
{title}
{subtitle &&
@@ -63,9 +55,9 @@ export function LinkedItemsHeaderView({ item, unlinkCallback, itemNameField, ite
diff --git a/src/Components/Profile/Subcomponents/PlusButton.tsx b/src/Components/Profile/Subcomponents/PlusButton.tsx
index 99e75c5..82a41ba 100644
--- a/src/Components/Profile/Subcomponents/PlusButton.tsx
+++ b/src/Components/Profile/Subcomponents/PlusButton.tsx
@@ -1,19 +1,19 @@
-import { LayerProps } from "../../../types";
-import { useHasUserPermission } from "../../Map/hooks/usePermissions";
+import { LayerProps } from '../../../types'
+import { useHasUserPermission } from '../../Map/hooks/usePermissions'
-export function PlusButton({ layer, triggerAction, color, collection="items" }: { layer?: LayerProps ,triggerAction: any, color: string, collection?:string }) {
- const hasUserPermission = useHasUserPermission();
- return (
- <>{hasUserPermission(collection, "create", undefined, layer) &&
+export function PlusButton ({ layer, triggerAction, color, collection = 'items' }: { layer?: LayerProps, triggerAction: any, color: string, collection?:string }) {
+ const hasUserPermission = useHasUserPermission()
+ return (
+ <>{hasUserPermission(collection, 'create', undefined, layer) &&
-
{ triggerAction() }} style={{ backgroundColor: color, color: "#fff"}}>
+ { triggerAction() }} style={{ backgroundColor: color, color: '#fff' }}>
-
+
}
>
- )
+ )
}
diff --git a/src/Components/Profile/Subcomponents/ProfileSubHeader.tsx b/src/Components/Profile/Subcomponents/ProfileSubHeader.tsx
index 057e644..a7c45a8 100644
--- a/src/Components/Profile/Subcomponents/ProfileSubHeader.tsx
+++ b/src/Components/Profile/Subcomponents/ProfileSubHeader.tsx
@@ -1,5 +1,4 @@
-import SocialShareBar from './SocialShareBar';
-
+import SocialShareBar from './SocialShareBar'
/* const flags = {
de: (
@@ -19,10 +18,10 @@ import SocialShareBar from './SocialShareBar';
}; */
const statusMapping = {
- 'in_planning': 'in Planung',
- 'paused': 'pausiert',
- 'active': 'aktiv'
-};
+ in_planning: 'in Planung',
+ paused: 'pausiert',
+ active: 'aktiv'
+}
// eslint-disable-next-line react/prop-types
const SubHeader = ({ type, status, url, title }) => (
@@ -30,7 +29,7 @@ const SubHeader = ({ type, status, url, title }) => (
{status &&
- {statusMapping[status]}
+ {statusMapping[status]}
}
{type &&
{type}
@@ -40,6 +39,6 @@ const SubHeader = ({ type, status, url, title }) => (
-);
+)
-export default SubHeader;
\ No newline at end of file
+export default SubHeader
diff --git a/src/Components/Profile/Subcomponents/RelationCard.tsx b/src/Components/Profile/Subcomponents/RelationCard.tsx
index 18fc616..ea2c294 100644
--- a/src/Components/Profile/Subcomponents/RelationCard.tsx
+++ b/src/Components/Profile/Subcomponents/RelationCard.tsx
@@ -1,4 +1,3 @@
-
// eslint-disable-next-line react/prop-types
const RelationCard = ({ title, description, imageSrc }) => (
@@ -12,6 +11,6 @@ const RelationCard = ({ title, description, imageSrc }) => (
{description}
-);
+)
-export default RelationCard;
\ No newline at end of file
+export default RelationCard
diff --git a/src/Components/Profile/Subcomponents/SocialShareBar.tsx b/src/Components/Profile/Subcomponents/SocialShareBar.tsx
index 42efa6e..b7fb67e 100644
--- a/src/Components/Profile/Subcomponents/SocialShareBar.tsx
+++ b/src/Components/Profile/Subcomponents/SocialShareBar.tsx
@@ -1,8 +1,8 @@
-import SocialShareButton from './SocialShareButton';
+import SocialShareButton from './SocialShareButton'
// eslint-disable-next-line react/prop-types
-const SocialShareBar = ({url, title, platforms = ['facebook', 'twitter', 'linkedin', 'xing', 'email']}) => {
- return (
+const SocialShareBar = ({ url, title, platforms = ['facebook', 'twitter', 'linkedin', 'xing', 'email'] }) => {
+ return (
{platforms.map((platform) => (
))}
- );
-};
+ )
+}
-export default SocialShareBar;
\ No newline at end of file
+export default SocialShareBar
diff --git a/src/Components/Profile/Subcomponents/SocialShareButton.tsx b/src/Components/Profile/Subcomponents/SocialShareButton.tsx
index 7c8c0b4..0b5b2ca 100644
--- a/src/Components/Profile/Subcomponents/SocialShareButton.tsx
+++ b/src/Components/Profile/Subcomponents/SocialShareButton.tsx
@@ -1,81 +1,81 @@
-import * as React from 'react';
+import * as React from 'react'
const platformConfigs = {
- facebook: {
- shareUrl: 'https://www.facebook.com/sharer/sharer.php?u={url}',
- icon: (
+ facebook: {
+ shareUrl: 'https://www.facebook.com/sharer/sharer.php?u={url}',
+ icon: (
- ),
- bgColor: '#3b5998'
- },
- twitter: {
- shareUrl: 'https://twitter.com/intent/tweet?text={title}:%20{url}',
- icon: (
+ ),
+ bgColor: '#3b5998'
+ },
+ twitter: {
+ shareUrl: 'https://twitter.com/intent/tweet?text={title}:%20{url}',
+ icon: (
- ),
- bgColor: '#55acee'
- },
- linkedin: {
- shareUrl: 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}',
- icon: (
+ ),
+ bgColor: '#55acee'
+ },
+ linkedin: {
+ shareUrl: 'http://www.linkedin.com/shareArticle?mini=true&url={url}&title={title}',
+ icon: (
- ),
- bgColor: '#4875b4'
- },
- xing: {
- shareUrl: 'https://www.xing-share.com/app/user?op=share;sc_p=xing-share;url={url}',
- icon: (
+ ),
+ bgColor: '#4875b4'
+ },
+ xing: {
+ shareUrl: 'https://www.xing-share.com/app/user?op=share;sc_p=xing-share;url={url}',
+ icon: (
- ),
- bgColor: '#026466'
- },
- email: {
- shareUrl: 'mailto:?subject={title}&body={url}',
- icon: (
+ ),
+ bgColor: '#026466'
+ },
+ email: {
+ shareUrl: 'mailto:?subject={title}&body={url}',
+ icon: (
- ),
- bgColor: '#444444'
- }
-};
+ ),
+ bgColor: '#444444'
+ }
+}
// eslint-disable-next-line react/prop-types
const SocialShareButton = ({ platform, url, title }) => {
- const config = platformConfigs[platform];
+ const config = platformConfigs[platform]
- if (!config) {
- return null;
- }
+ if (!config) {
+ return null
+ }
- const { shareUrl, icon, bgColor } = config;
- const finalShareUrl = shareUrl
- .replace('{url}', encodeURIComponent(url))
- .replace('{title}', encodeURIComponent(title));
+ const { shareUrl, icon, bgColor } = config
+ const finalShareUrl = shareUrl
+ .replace('{url}', encodeURIComponent(url))
+ .replace('{title}', encodeURIComponent(title))
- return (
+ return (
{React.cloneElement(icon, { className: 'tw-w-4 tw-h-4 tw-fill-current' })}
- );
-};
+ )
+}
-export default SocialShareButton;
\ No newline at end of file
+export default SocialShareButton
diff --git a/src/Components/Profile/Subcomponents/TagsWidget.tsx b/src/Components/Profile/Subcomponents/TagsWidget.tsx
index 4ad6838..79a71d2 100644
--- a/src/Components/Profile/Subcomponents/TagsWidget.tsx
+++ b/src/Components/Profile/Subcomponents/TagsWidget.tsx
@@ -1,99 +1,95 @@
import * as React from 'react'
-import { useEffect, useState } from 'react';
-import { useTags } from '../../Map/hooks/useTags';
-import { Tag } from '../../../types';
-import { Autocomplete } from '../../Input/Autocomplete';
-import { randomColor } from '../../../Utils/RandomColor';
-import { decodeTag, encodeTag } from '../../../Utils/FormatTags';
+import { useEffect, useState } from 'react'
+import { useTags } from '../../Map/hooks/useTags'
+import { Tag } from '../../../types'
+import { Autocomplete } from '../../Input/Autocomplete'
+import { randomColor } from '../../../Utils/RandomColor'
+import { decodeTag, encodeTag } from '../../../Utils/FormatTags'
// eslint-disable-next-line react/prop-types
-export const TagsWidget = ({placeholder, containerStyle, defaultTags, onUpdate}) => {
+export const TagsWidget = ({ placeholder, containerStyle, defaultTags, onUpdate }) => {
+ const [input, setInput] = useState('')
+ const [isKeyReleased, setIsKeyReleased] = useState(false)
+ const tags = useTags()
+ const [pushFilteredSuggestions, setPushFilteredSuggestions] = useState
>([])
- const [input, setInput] = useState('');
- const [isKeyReleased, setIsKeyReleased] = useState(false);
- const tags = useTags();
- const [pushFilteredSuggestions, setPushFilteredSuggestions] = useState>([]);
-
- const [focusInput, setFocusInput] = useState(false);
- const [currentTags, setCurrentTags] = useState>(defaultTags);
+ const [focusInput, setFocusInput] = useState(false)
+ const [currentTags, setCurrentTags] = useState>(defaultTags)
useEffect(() => {
setCurrentTags(defaultTags)
}, [defaultTags])
-
-
const onChange = (e) => {
- const { value } = e.target;
- setInput(value);
- };
+ const { value } = e.target
+ setInput(value)
+ }
const onKeyDown = (e) => {
- const { key } = e;
- const trimmedInput = input.trim();
+ const { key } = e
+ const trimmedInput = input.trim()
// eslint-disable-next-line react/prop-types
- if ((key === 'Enter' || key === ',' ) && trimmedInput.length && !defaultTags.some(tag => tag.name.toLocaleLowerCase() === trimmedInput.toLocaleLowerCase())) {
- e.preventDefault();
+ if ((key === 'Enter' || key === ',') && trimmedInput.length && !defaultTags.some(tag => tag.name.toLocaleLowerCase() === trimmedInput.toLocaleLowerCase())) {
+ e.preventDefault()
const newTag = tags.find(t => t.name === trimmedInput.toLocaleLowerCase())
- newTag && onUpdate([...currentTags, newTag]);
- !newTag && onUpdate([...currentTags, { id: crypto.randomUUID(), name: encodeTag(trimmedInput), color: randomColor() }]);
- setInput('');
- setPushFilteredSuggestions([]);
+ newTag && onUpdate([...currentTags, newTag])
+ !newTag && onUpdate([...currentTags, { id: crypto.randomUUID(), name: encodeTag(trimmedInput), color: randomColor() }])
+ setInput('')
+ setPushFilteredSuggestions([])
}
// eslint-disable-next-line react/prop-types
- if (key === "Backspace" && !input.length && defaultTags.length && isKeyReleased) {
- const defaultTagsCopy = [...defaultTags];
- const poppedTag = defaultTagsCopy.pop();
- e.preventDefault();
- onUpdate(defaultTagsCopy);
- poppedTag && setInput(poppedTag.name);
+ if (key === 'Backspace' && !input.length && defaultTags.length && isKeyReleased) {
+ const defaultTagsCopy = [...defaultTags]
+ const poppedTag = defaultTagsCopy.pop()
+ e.preventDefault()
+ onUpdate(defaultTagsCopy)
+ poppedTag && setInput(poppedTag.name)
}
- setIsKeyReleased(false);
- };
+ setIsKeyReleased(false)
+ }
const onKeyUp = () => {
- setIsKeyReleased(true);
+ setIsKeyReleased(true)
}
const deleteTag = (tag) => {
onUpdate(currentTags.filter((t) => t !== tag))
}
-
const onSelected = (tag) => {
// eslint-disable-next-line react/prop-types
- if(!defaultTags.some(t => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())) {
+ if (!defaultTags.some(t => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())) {
const newTag = tags.find(t => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())
- newTag && onUpdate([...currentTags, newTag]);
- !newTag && onUpdate([...currentTags, { id: crypto.randomUUID(), name: tag.name.toLocaleLowerCase(), color: randomColor() }]);
- setInput('');
- setPushFilteredSuggestions([]);
+ newTag && onUpdate([...currentTags, newTag])
+ !newTag && onUpdate([...currentTags, { id: crypto.randomUUID(), name: tag.name.toLocaleLowerCase(), color: randomColor() }])
+ setInput('')
+ setPushFilteredSuggestions([])
}
}
const inputProps = {
value: input,
- placeholder: placeholder,
- onKeyDown: onKeyDown,
- onKeyUp: onKeyUp,
- onChange: onChange,
+ placeholder,
+ onKeyDown,
+ onKeyUp,
+ onChange,
className: 'tw-bg-transparent tw-w-fit tw-mt-5 tw-h-fit'
}
/* eslint-disable react/prop-types */
return (
- {
- setFocusInput(true);
- setTimeout(()=> {
+
{
+ setFocusInput(true)
+ setTimeout(() => {
setFocusInput(false)
}, 200)
}} className={`tw-input tw-input-bordered tw-cursor-text ${containerStyle}`}>
{defaultTags.map((tag) => (
-
+
(deleteTag(tag))}>β
{decodeTag(tag.name)}
@@ -105,4 +101,4 @@ export const TagsWidget = ({placeholder, containerStyle, defaultTags, onUpdate})
)
/* eslint-enable react/prop-types */
-}
\ No newline at end of file
+}
diff --git a/src/Components/Profile/Templates/OnepagerForm.tsx b/src/Components/Profile/Templates/OnepagerForm.tsx
index 11dc5d9..0ab2501 100644
--- a/src/Components/Profile/Templates/OnepagerForm.tsx
+++ b/src/Components/Profile/Templates/OnepagerForm.tsx
@@ -1,8 +1,8 @@
import * as React from 'react'
-import { useEffect } from "react";
-import { Item, Tag } from "../../../types"
-import { TextAreaInput, TextInput } from "../../Input"
-import ComboBoxInput from "../../Input/ComboBoxInput"
+import { useEffect } from 'react'
+import { Item, Tag } from '../../../types'
+import { TextAreaInput, TextInput } from '../../Input'
+import ComboBoxInput from '../../Input/ComboBoxInput'
export const OnepagerForm = ({ item, state, setState }: {
state: {
@@ -25,53 +25,51 @@ export const OnepagerForm = ({ item, state, setState }: {
setState: React.Dispatch
>,
item: Item
}) => {
+ useEffect(() => {
+ switch (state.groupType) {
+ case 'wuerdekompass':
+ setState(prevState => ({
+ ...prevState,
+ color: item?.layer?.menuColor || '#1A5FB4',
+ markerIcon: 'group',
+ image: '59e6a346-d1ee-4767-9e42-fc720fb535c9'
+ }))
+ break
+ case 'themenkompass':
+ setState(prevState => ({
+ ...prevState,
+ color: '#26A269',
+ markerIcon: 'group',
+ image: '59e6a346-d1ee-4767-9e42-fc720fb535c9'
+ }))
+ break
+ case 'liebevoll.jetzt':
+ setState(prevState => ({
+ ...prevState,
+ color: '#E8B620',
+ markerIcon: 'liebevoll.jetzt',
+ image: 'e735b96c-507b-471c-8317-386ece0ca51d'
+ }))
- useEffect(() => {
- switch (state.groupType) {
- case "wuerdekompass":
- setState(prevState => ({
- ...prevState,
- color: item?.layer?.menuColor || "#1A5FB4",
- markerIcon: "group",
- image: "59e6a346-d1ee-4767-9e42-fc720fb535c9"
- }));
- break;
- case "themenkompass":
- setState(prevState => ({
- ...prevState,
- color: "#26A269",
- markerIcon: "group",
- image: "59e6a346-d1ee-4767-9e42-fc720fb535c9"
- }));
- break;
- case "liebevoll.jetzt":
- setState(prevState => ({
- ...prevState,
- color: "#E8B620",
- markerIcon: "liebevoll.jetzt",
- image: "e735b96c-507b-471c-8317-386ece0ca51d"
- }));
-
- break;
- default:
- break;
- }
+ break
+ default:
+ break
+ }
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [state.groupType])
-
+ }, [state.groupType])
- const typeMapping = [
- { value: 'wuerdekompass', label: 'Regional-Gruppe' },
- { value: 'themenkompass', label: 'Themen-Gruppe' },
- { value: 'liebevoll.jetzt', label: 'liebevoll.jetzt' }
- ];
- const statusMapping = [
- { value: 'active', label: 'aktiv' },
- { value: 'in_planning', label: 'in Planung' },
- { value: 'paused', label: 'pausiert' }
- ];
+ const typeMapping = [
+ { value: 'wuerdekompass', label: 'Regional-Gruppe' },
+ { value: 'themenkompass', label: 'Themen-Gruppe' },
+ { value: 'liebevoll.jetzt', label: 'liebevoll.jetzt' }
+ ]
+ const statusMapping = [
+ { value: 'active', label: 'aktiv' },
+ { value: 'in_planning', label: 'in Planung' },
+ { value: 'paused', label: 'pausiert' }
+ ]
- return (
+ return (