mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
commit
87ec6aa8db
227
.eslintrc.js
227
.eslintrc.js
@ -1,27 +1,212 @@
|
||||
// eslint-disable-next-line no-undef
|
||||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true
|
||||
env: {
|
||||
browser: true,
|
||||
es2021: true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:react/recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
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',
|
||||
],
|
||||
"overrides": [
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": "latest",
|
||||
"sourceType": "module"
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
parser: '@typescript-eslint/parser',
|
||||
sourceType: 'module',
|
||||
},
|
||||
"plugins": [
|
||||
"react",
|
||||
"react-hooks",
|
||||
"@typescript-eslint"
|
||||
plugins: [
|
||||
//'@typescript-eslint',
|
||||
//'import',
|
||||
//'promise',
|
||||
//'security',
|
||||
//'no-catch-all',
|
||||
'react',
|
||||
'react-hooks',
|
||||
],
|
||||
"rules": {
|
||||
"react-hooks/rules-of-hooks": "error", // Checks rules of Hooks
|
||||
"react-hooks/exhaustive-deps": "warn" // Checks effect dependencies
|
||||
}
|
||||
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',
|
||||
// camelcase: 'error',
|
||||
// indent: ['error', 2],
|
||||
// 'linebreak-style': ['error', 'unix'],
|
||||
// semi: ['error', 'never'],
|
||||
// // This makes sure our vike router does not throw errors
|
||||
// 'vue/multi-word-component-names': [
|
||||
// 'error',
|
||||
// {
|
||||
// ignores: ['+Page'],
|
||||
// },
|
||||
// ],
|
||||
// // Optional eslint-comments rule
|
||||
// '@eslint-community/eslint-comments/no-unused-disable': 'error',
|
||||
// '@eslint-community/eslint-comments/disable-enable-pair': ['error', { allowWholeFile: true }],
|
||||
// // import
|
||||
// 'import/export': 'error',
|
||||
// 'import/no-deprecated': 'error',
|
||||
// 'import/no-empty-named-blocks': 'error',
|
||||
// 'import/no-extraneous-dependencies': 'error',
|
||||
// 'import/no-mutable-exports': 'error',
|
||||
// 'import/no-unused-modules': 'error',
|
||||
// 'import/no-named-as-default': 'error',
|
||||
// 'import/no-named-as-default-member': 'error',
|
||||
// 'import/no-amd': 'error',
|
||||
// 'import/no-commonjs': 'error',
|
||||
// 'import/no-import-module-exports': 'error',
|
||||
// 'import/no-nodejs-modules': 'off',
|
||||
// 'import/unambiguous': 'off', // not compatible with scriptless vue files
|
||||
// 'import/default': 'error',
|
||||
// 'import/named': 'error',
|
||||
// 'import/namespace': 'error',
|
||||
// 'import/no-absolute-path': 'error',
|
||||
// 'import/no-cycle': 'error',
|
||||
// 'import/no-dynamic-require': 'error',
|
||||
// 'import/no-internal-modules': 'off',
|
||||
// 'import/no-relative-packages': 'error',
|
||||
// 'import/no-relative-parent-imports': [
|
||||
// 'error',
|
||||
// {
|
||||
// ignore: [
|
||||
// '#[src,root,components,pages,assets,layouts,queries,stores,plugins,context,types]/*',
|
||||
// ],
|
||||
// },
|
||||
// ],
|
||||
// 'import/no-self-import': 'error',
|
||||
// 'import/no-unresolved': 'error',
|
||||
// 'import/no-useless-path-segments': 'error',
|
||||
// 'import/no-webpack-loader-syntax': 'error',
|
||||
// 'import/consiste@typescript-eslint
|
||||
// {
|
||||
// json: 'always',
|
||||
// },
|
||||
// ],
|
||||
// 'import/first': 'error',
|
||||
// 'import/group-exports': 'off',
|
||||
// 'import/newline-after-import': 'error',
|
||||
// 'import/no-anonymous-default-export': 'off', // todo - consider to enable again
|
||||
// 'import/no-default-export': 'off', // incompatible with vite & vike
|
||||
// 'import/no-duplicates': 'error',
|
||||
// 'import/no-named-default': 'error',
|
||||
// 'import/no-namespace': 'error',
|
||||
// 'import/no-unassigned-import': 'error',
|
||||
// 'import/order': [
|
||||
// 'error',
|
||||
// {
|
||||
// groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index', 'object', 'type'],
|
||||
// 'newlines-between': 'always',
|
||||
// alphabetize: {
|
||||
// order: 'asc', // sort in ascending order. Options: ["ignore", "asc", "desc"]
|
||||
// caseInsensitive: true, // ignore case. Options: [true, false]
|
||||
// },
|
||||
// distinctGroup: true,
|
||||
// },
|
||||
// ],
|
||||
// 'import/prefer-default-export': 'off',
|
||||
// // promise
|
||||
// 'promise/catch-or-return': 'error',
|
||||
// 'promise/no-return-wrap': 'error',
|
||||
// 'promise/param-names': 'error',
|
||||
// 'promise/always-return': 'error',
|
||||
// 'promise/no-native': 'off',
|
||||
// 'promise/no-nesting': 'warn',
|
||||
// 'promise/no-promise-in-callback': 'warn',
|
||||
// 'promise/no-callback-in-promise': 'warn',
|
||||
// 'promise/avoid-new': 'warn',
|
||||
// 'promise/no-new-statics': 'error',
|
||||
// 'promise/no-return-in-finally': 'warn',
|
||||
// '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',
|
||||
// },
|
||||
},
|
||||
{
|
||||
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'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
155
package-lock.json
generated
155
package-lock.json
generated
@ -39,8 +39,10 @@
|
||||
"autoprefixer": "^10.4.14",
|
||||
"daisyui": "^4.6.1",
|
||||
"eslint": "^8.24.0",
|
||||
"eslint-plugin-json": "^3.1.0",
|
||||
"eslint-plugin-react": "^7.31.8",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-yml": "^1.14.0",
|
||||
"postcss": "^8.4.21",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
@ -1650,6 +1652,49 @@
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-compat-utils": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz",
|
||||
"integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^7.5.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-compat-utils/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",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-json": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-json/-/eslint-plugin-json-3.1.0.tgz",
|
||||
"integrity": "sha512-MrlG2ynFEHe7wDGwbUuFPsaT2b1uhuEFhJ+W1f1u+1C2EkXmTYJp4B1aAdQQ8M+CC3t//N/oRKiIVw14L2HR1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.21",
|
||||
"vscode-json-languageservice": "^4.1.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.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",
|
||||
@ -1719,6 +1764,29 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-yml": {
|
||||
"version": "1.14.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.14.0.tgz",
|
||||
"integrity": "sha512-ESUpgYPOcAYQO9czugcX5OqRvn/ydDVwGCPXY4YjPqc09rHaUVUA6IE6HLQys4rXk/S+qx3EwTd1wHCwam/OWQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.2",
|
||||
"eslint-compat-utils": "^0.5.0",
|
||||
"lodash": "^4.17.21",
|
||||
"natural-compare": "^1.4.0",
|
||||
"yaml-eslint-parser": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ota-meshi"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||
@ -2891,6 +2959,13 @@
|
||||
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/jsonc-parser": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
|
||||
"integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
@ -2981,6 +3056,13 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
@ -5998,6 +6080,48 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-json-languageservice": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz",
|
||||
"integrity": "sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"vscode-languageserver-textdocument": "^1.0.3",
|
||||
"vscode-languageserver-types": "^3.16.0",
|
||||
"vscode-nls": "^5.0.0",
|
||||
"vscode-uri": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-languageserver-textdocument": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz",
|
||||
"integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vscode-languageserver-types": {
|
||||
"version": "3.17.5",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
|
||||
"integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vscode-nls": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.2.0.tgz",
|
||||
"integrity": "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vscode-uri": {
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz",
|
||||
"integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
@ -6057,6 +6181,37 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/yaml-eslint-parser": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.3.tgz",
|
||||
"integrity": "sha512-4wZWvE398hCP7O8n3nXKu/vdq1HcH01ixYlCREaJL5NUMwQ0g3MaGFUBNSlmBtKmhbtVG/Cm6lyYmSVTEVil8A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eslint-visitor-keys": "^3.0.0",
|
||||
"lodash": "^4.17.21",
|
||||
"yaml": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.17.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ota-meshi"
|
||||
}
|
||||
},
|
||||
"node_modules/yaml-eslint-parser/node_modules/yaml": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz",
|
||||
"integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
|
||||
@ -27,8 +27,10 @@
|
||||
"autoprefixer": "^10.4.14",
|
||||
"daisyui": "^4.6.1",
|
||||
"eslint": "^8.24.0",
|
||||
"eslint-plugin-json": "^3.1.0",
|
||||
"eslint-plugin-react": "^7.31.8",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-yml": "^1.14.0",
|
||||
"postcss": "^8.4.21",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
// eslint-disable-next-line no-undef
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
|
||||
@ -17,12 +17,14 @@ import { BrowserRouter as Router, useLocation } from 'react-router-dom';
|
||||
// Helper context to determine if the ContextWrapper is already present.
|
||||
const ContextCheckContext = createContext(false);
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
export const ContextWrapper = ({ children }) => {
|
||||
const isWrapped = useContext(ContextCheckContext);
|
||||
|
||||
// Check if we are already inside a Router
|
||||
let location;
|
||||
try {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
location = useLocation();
|
||||
} catch (e) {
|
||||
location = null;
|
||||
@ -63,6 +65,7 @@ export const ContextWrapper = ({ children }) => {
|
||||
return children;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
export const Wrappers = ({ children }) => {
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@ export default function NavBar({ appName, userType}: { appName: string, userType
|
||||
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: ""});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [user, items])
|
||||
|
||||
useEffect(() => {
|
||||
@ -39,8 +40,8 @@ export default function NavBar({ appName, userType}: { appName: string, userType
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let embedded = params.get("embedded");
|
||||
const params = new URLSearchParams(location.search);
|
||||
const embedded = params.get("embedded");
|
||||
embedded!="true" && setShowNav(true)
|
||||
}, [location]);
|
||||
|
||||
|
||||
@ -7,6 +7,7 @@ export const SetAssetsApi = ({assetsApi}:{assetsApi: AssetsApi}) => {
|
||||
|
||||
useEffect(() => {
|
||||
setAssetsApi(assetsApi)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [assetsApi])
|
||||
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ import * as React from 'react';
|
||||
|
||||
type route = {
|
||||
path: string;
|
||||
// eslint-disable-next-line no-undef
|
||||
icon: JSX.Element;
|
||||
name: string;
|
||||
submenu?: route;
|
||||
@ -53,12 +54,12 @@ export function SideBar({ routes, bottomRoutes }: { routes: route[], bottomRoute
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let embedded = params.get("embedded");
|
||||
const params = new URLSearchParams(location.search);
|
||||
const embedded = params.get("embedded");
|
||||
embedded != "true" && setEmbedded(false)
|
||||
}, [location]);
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
return (
|
||||
<nav
|
||||
|
||||
@ -4,6 +4,7 @@ import { Link, useLocation } from 'react-router-dom'
|
||||
|
||||
|
||||
function SidebarSubmenu({submenu, name, icon} : { path: string;
|
||||
// eslint-disable-next-line no-undef
|
||||
icon: JSX.Element;
|
||||
name: string;
|
||||
submenu?: any | undefined}){
|
||||
@ -14,6 +15,7 @@ function SidebarSubmenu({submenu, name, icon} : { path: string;
|
||||
/** Open Submenu list if path found in routes, this is for directly loading submenu routes first time */
|
||||
useEffect(() => {
|
||||
if(submenu.filter(m => {return m.path === location.pathname})[0])setIsExpanded(true)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
||||
@ -24,6 +24,7 @@ export const Sitemap = ({url}:{url:string}) => {
|
||||
|
||||
setSitemap(generateSitemap());
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [items]);
|
||||
|
||||
return (
|
||||
|
||||
@ -16,6 +16,7 @@ const AssetContext = createContext<UseAssetManagerResult>({
|
||||
|
||||
function useAssetsManager(): {
|
||||
api: AssetsApi;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setAssetsApi: (api: AssetsApi) => void;
|
||||
} {
|
||||
const [api, setApi] = useState<AssetsApi>({} as AssetsApi);
|
||||
|
||||
@ -13,6 +13,7 @@ export function LoginPage() {
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const onLogin = async () => {
|
||||
await toast.promise(
|
||||
login({ email: email, password: password }),
|
||||
|
||||
@ -4,6 +4,7 @@ import { toast } from 'react-toastify'
|
||||
import { useAuth } from './useAuth'
|
||||
import { MapOverlayPage} from '../Templates'
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
export function RequestPasswordPage({reset_url}) {
|
||||
|
||||
const [email, setEmail] = useState<string>("");
|
||||
|
||||
@ -16,6 +16,7 @@ export function SignupPage() {
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const onRegister = async () => {
|
||||
await toast.promise(
|
||||
register({ email: email, password: password }, userName),
|
||||
|
||||
@ -19,13 +19,18 @@ type AuthCredentials = {
|
||||
type AuthContextProps = {
|
||||
isAuthenticated: boolean,
|
||||
user: UserItem | null;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
login: (credentials: AuthCredentials) => Promise<UserItem | undefined>,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
register: (credentials: AuthCredentials, userName: string) => Promise<UserItem | undefined>,
|
||||
loading: Boolean,
|
||||
loading: boolean,
|
||||
logout: () => Promise<any>,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
updateUser: (user: UserItem) => any,
|
||||
token: String | null,
|
||||
token: string | null,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
requestPasswordReset: (email:string, reset_url: string) => Promise<any>,
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
passwordReset: (token:string, new_password:string) => Promise<any>
|
||||
}
|
||||
|
||||
@ -44,7 +49,7 @@ const AuthContext = createContext<AuthContextProps>({
|
||||
|
||||
export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
|
||||
const [user, setUser] = useState<UserItem | null>(null);
|
||||
const [token, setToken] = useState<String | null>(null);
|
||||
const [token, setToken] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const isAuthenticated = !!user;
|
||||
|
||||
@ -52,6 +57,7 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
|
||||
setLoading(true);
|
||||
loadUser();
|
||||
setLoading(false)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
async function loadUser(): Promise<UserItem | undefined> {
|
||||
@ -82,18 +88,18 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
|
||||
} catch (error: any) {
|
||||
setLoading(false);
|
||||
throw error;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const register = async (credentials: AuthCredentials, userName): Promise<UserItem | undefined> => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const res = await userApi.register(credentials.email, credentials.password, userName)
|
||||
/* const res = */ await userApi.register(credentials.email, credentials.password, userName)
|
||||
return (await login(credentials));
|
||||
} catch (error: any) {
|
||||
setLoading(false);
|
||||
throw error;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -104,11 +110,12 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
|
||||
} catch (error: any) {
|
||||
setLoading(false);
|
||||
throw error;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const updateUser = async (user: UserItem) => {
|
||||
setLoading(true);
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { id, ...userRest } = user;
|
||||
|
||||
try {
|
||||
@ -120,7 +127,7 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
|
||||
} catch (error: any) {
|
||||
setLoading(false);
|
||||
throw error;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const requestPasswordReset = async (email: string, reset_url?: string): Promise<any> => {
|
||||
@ -131,7 +138,7 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
|
||||
} catch (error: any) {
|
||||
setLoading(false);
|
||||
throw error;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -143,7 +150,7 @@ export const AuthProvider = ({ userApi, children }: AuthProviderProps) => {
|
||||
} catch (error: any) {
|
||||
setLoading(false);
|
||||
throw error;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ export function Modal({children, showOnStartup}:{children : React.ReactNode, sho
|
||||
useEffect(() => {
|
||||
if(showOnStartup)
|
||||
window.my_modal_3.showModal()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@ export function Quests() {
|
||||
|
||||
useEffect(() => {
|
||||
setQuestsOpen(false);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const [profile, setProfie] = useState<Item>()
|
||||
|
||||
@ -13,6 +13,7 @@ const QuestContext = createContext<UseQuestManagerResult>({
|
||||
|
||||
function useQuestsManager(initialOpen: boolean): {
|
||||
open: boolean;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setQuestsOpen: (open: boolean) => void;
|
||||
} {
|
||||
const [open, setOpen] = useState<boolean>(initialOpen);
|
||||
|
||||
@ -2,6 +2,7 @@ import * as React from 'react'
|
||||
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<any>, onSelected: (suggestion) => void, pushFilteredSuggestions?: Array<any>, setFocus?: boolean }) => {
|
||||
|
||||
const [filteredSuggestions, setFilteredSuggestions] = React.useState<Array<any>>([]);
|
||||
@ -19,6 +20,7 @@ export const Autocomplete = ({ inputProps, suggestions, onSelected, pushFiltered
|
||||
const inputRef = React.useRef<HTMLInputElement>();
|
||||
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const getSuggestionValue = suggestion => suggestion.name;
|
||||
|
||||
const getSuggestions = value => {
|
||||
|
||||
@ -5,11 +5,13 @@ interface ComboBoxProps {
|
||||
id?: string;
|
||||
options: { value: string, label: string }[];
|
||||
value: string;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
onValueChange: (newValue: string) => void;
|
||||
}
|
||||
|
||||
const ComboBoxInput = ({ id, options, value, onValueChange }: ComboBoxProps) => {
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const [selectedValue, setSelectedValue] = useState(value);
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
|
||||
@ -10,6 +10,7 @@ type SelectBoxProps = {
|
||||
containerStyle?: string;
|
||||
defaultValue: string;
|
||||
placeholder?: string;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
updateFormValue: (value: string ) => void;
|
||||
|
||||
options: {name: string, value: string}[];
|
||||
|
||||
@ -11,6 +11,7 @@ type TextAreaProps = {
|
||||
inputStyle?: string;
|
||||
defaultValue: string;
|
||||
placeholder?: string;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
updateFormValue?: (value: string) => void;
|
||||
}
|
||||
|
||||
@ -27,13 +28,13 @@ export function TextAreaInput({ labelTitle, dataField, labelStyle, containerStyl
|
||||
|
||||
const tags = useTags();
|
||||
|
||||
let values: KeyValue[] = [];
|
||||
const values: KeyValue[] = [];
|
||||
|
||||
tags.forEach(tag => {
|
||||
values.push({ key: tag.name, value: tag.name, color: tag.color });
|
||||
});
|
||||
|
||||
var tribute = new Tribute({
|
||||
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: "#",
|
||||
@ -54,6 +55,7 @@ export function TextAreaInput({ labelTitle, dataField, labelStyle, containerStyl
|
||||
}
|
||||
init.current = true;
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [ref]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@ -11,6 +11,7 @@ type InputTextProps = {
|
||||
defaultValue?: string;
|
||||
placeholder?: string;
|
||||
autocomplete?: string
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
updateFormValue?: (value: string ) => void;
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ export const ItemForm = ({ children, item, title, setPopupTitle }: { children?:
|
||||
useEffect(() => {
|
||||
setPopupTitle&& title && setPopupTitle(title);
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [title])
|
||||
|
||||
return (
|
||||
|
||||
@ -88,13 +88,14 @@ export const Layer = ({
|
||||
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 });
|
||||
// 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) {
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
if (!location.pathname.includes("/item/")) {
|
||||
window.history.pushState({}, "", `/${item.id}` + `${params.toString() !== "" ? `?${params}` : ""}`)
|
||||
}
|
||||
@ -131,6 +132,7 @@ export const Layer = ({
|
||||
|
||||
useEffect(() => {
|
||||
openPopup();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [leafletRefs, location])
|
||||
|
||||
useEffect(() => {
|
||||
@ -143,6 +145,7 @@ export const Layer = ({
|
||||
}
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [tagsReady])
|
||||
|
||||
return (
|
||||
|
||||
@ -14,6 +14,7 @@ useEffect(() => {
|
||||
adminRole && setAdminRole(adminRole);
|
||||
data && setPermissionData(data);
|
||||
api && setPermissionApi(api);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [api, data, adminRole, user])
|
||||
|
||||
return (
|
||||
|
||||
@ -13,6 +13,7 @@ export function FilterControl() {
|
||||
groupTypes.map(layer =>
|
||||
addVisibleGroupType(layer.value)
|
||||
)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import * as React from 'react'
|
||||
import * as L from 'leaflet'
|
||||
import { useMap, useMapEvents } from 'react-leaflet'
|
||||
import 'leaflet.locatecontrol'
|
||||
@ -26,6 +25,7 @@ export const LocateControl = () => {
|
||||
setLc(L.control.locate().addTo(map));
|
||||
init.current = true;
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
useMapEvents({
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import * as React from 'react'
|
||||
import { useAddFilterTag, useFilterTags, useResetFilterTags } from '../../hooks/useFilter'
|
||||
import { useAddFilterTag } from '../../hooks/useFilter'
|
||||
import useWindowDimensions from '../../hooks/useWindowDimension';
|
||||
import axios from 'axios';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
@ -15,7 +15,6 @@ import * as L from 'leaflet';
|
||||
import MarkerIconFactory from '../../../../Utils/MarkerIconFactory';
|
||||
import { decodeTag } from '../../../../Utils/FormatTags';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { useClusterRef } from '../../hooks/useClusterRef';
|
||||
import { Item } from '../../../../types';
|
||||
import { SidebarControl } from './SidebarControl';
|
||||
|
||||
@ -86,8 +85,8 @@ export const SearchControl = () => {
|
||||
|
||||
const location = useLocation();
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let embedded = params.get("embedded");
|
||||
const params = new URLSearchParams(location.search);
|
||||
const embedded = params.get("embedded");
|
||||
embedded != "true" && setEmbedded(false)
|
||||
}, [location]);
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ import { LatLng } from 'leaflet'
|
||||
import { Popup as LeafletPopup, useMap } from 'react-leaflet'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useAddItem, useItems, useRemoveItem, useUpdateItem } from '../hooks/useItems'
|
||||
import { Geometry, LayerProps, Item, ItemsApi } from '../../../types'
|
||||
import { Geometry, LayerProps, Item } from '../../../types'
|
||||
import { TextAreaInput } from '../../Input/TextAreaInput'
|
||||
import { TextInput } from '../../Input/TextInput'
|
||||
import { toast } from 'react-toastify'
|
||||
@ -25,6 +25,7 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
||||
|
||||
const [spinner, setSpinner] = useState(false);
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const [popupTitle, setPopupTitle] = useState<string>("");
|
||||
|
||||
const formRef = useRef<HTMLFormElement>(null);
|
||||
@ -34,6 +35,7 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
||||
const addItem = useAddItem();
|
||||
const updateItem = useUpdateItem();
|
||||
const items = useItems();
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const removeItem = useRemoveItem();
|
||||
|
||||
|
||||
|
||||
@ -5,11 +5,6 @@ import { getValue } from "../../../../Utils/GetValue";
|
||||
import { useAssetApi } from '../../../AppShell/hooks/useAssets'
|
||||
import DialogModal from "../../../Templates/DialogModal";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useMap } from "react-leaflet";
|
||||
import { useEffect } from "react";
|
||||
|
||||
|
||||
|
||||
|
||||
export function HeaderView({ item, api, editCallback, deleteCallback, setPositionCallback, itemNameField, itemSubnameField, itemAvatarField, loading, hideMenu = false, big = false, truncateSubname = true, hideSubname = false, showAddress = false }: {
|
||||
item: Item,
|
||||
@ -39,9 +34,9 @@ export function HeaderView({ item, api, editCallback, deleteCallback, setPositio
|
||||
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<string>("");
|
||||
const [address, /* setAdress*/] = React.useState<string>("");
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
|
||||
const openDeleteModal = async (event: React.MouseEvent<HTMLElement>) => {
|
||||
|
||||
@ -6,7 +6,7 @@ import { useGetItemTags } from '../../hooks/useTags';
|
||||
|
||||
export const PopupButton = ({url, parameterField, text, colorField, item} : {url: string, parameterField?: string, text: string, colorField?: string, item? : Item}) => {
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const getItemTags = useGetItemTags();
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
import * as React from 'react'
|
||||
import { TextInput } from '../../../Input'
|
||||
import { Item } from '../../../../types'
|
||||
|
||||
export const PopupCheckboxInput = ({ dataField, label, item }:
|
||||
|
||||
@ -5,7 +5,9 @@ import { Item } from '../../../../types'
|
||||
type StartEndInputProps = {
|
||||
item?:Item,
|
||||
showLabels?: boolean
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
updateStartValue?: (value: string ) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
updateEndValue?: (value: string ) => void;
|
||||
}
|
||||
|
||||
|
||||
@ -28,11 +28,14 @@ export const TextView = ({ item, truncate = false, itemTextField, rawText }: { i
|
||||
|
||||
item && text ? replacedText = fixUrls(text) : "";
|
||||
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
replacedText ? replacedText = replacedText.replace(/(?<!\]?\()https?:\/\/[^\s\)]+(?!\))/g, (url) => {
|
||||
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];
|
||||
}
|
||||
@ -47,36 +50,47 @@ export const TextView = ({ item, truncate = false, itemTextField, rawText }: { i
|
||||
return `[${match}](${match})`;
|
||||
}) : "";
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomH1 = ({ children }) => (
|
||||
<h1 className="tw-text-xl tw-font-bold">{children}</h1>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomH2 = ({ children }) => (
|
||||
<h2 className="tw-text-lg tw-font-bold">{children}</h2>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomH3 = ({ children }) => (
|
||||
<h3 className="tw-text-base tw-font-bold">{children}</h3>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomH4 = ({ children }) => (
|
||||
<h4 className="tw-text-base tw-font-bold">{children}</h4>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomH5 = ({ children }) => (
|
||||
<h5 className="tw-text-sm tw-font-bold">{children}</h5>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomH6 = ({ children }) => (
|
||||
<h6 className="tw-text-sm tw-font-bold">{children}</h6>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomParagraph = ({ children }) => (
|
||||
<p className="!tw-my-2">{children}</p>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomUnorderdList = ({ children }) => (
|
||||
<ul className="tw-list-disc tw-list-inside">{children}</ul>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomOrderdList = ({ children }) => (
|
||||
<ol className="tw-list-decimal tw-list-inside">{children}</ol>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomHorizontalRow = ({ children }) => (
|
||||
<hr className="tw-border-current">{children}</hr>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomImage = ({ alt, src, title }) => (
|
||||
<img
|
||||
className="tw-max-w-full tw-rounded tw-shadow"
|
||||
@ -85,12 +99,14 @@ export const TextView = ({ item, truncate = false, itemTextField, rawText }: { i
|
||||
title={title}
|
||||
/>
|
||||
);
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const CustomExternalLink = ({ href, children }) => (
|
||||
<a className='tw-font-bold tw-underline'
|
||||
href={href}
|
||||
target='_blank'
|
||||
target='_blank' rel="noreferrer"
|
||||
> {children}</a>
|
||||
);
|
||||
/* eslint-disable react/prop-types */
|
||||
const CustomHashTagLink = ({ children, tag, item }) => {
|
||||
return (
|
||||
<a
|
||||
@ -102,7 +118,9 @@ export const TextView = ({ item, truncate = false, itemTextField, rawText }: { i
|
||||
}}>{decodeTag(children)}</a>
|
||||
)
|
||||
};
|
||||
/* eslint-enable react/prop-types */
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
const MemoizedVideoEmbed = memo(({ url }: { url: string }) => (
|
||||
<iframe
|
||||
className='tw-w-full'
|
||||
@ -116,11 +134,14 @@ export const TextView = ({ item, truncate = false, itemTextField, rawText }: { i
|
||||
<Markdown className={`tw-text-map tw-leading-map tw-text-sm`} remarkPlugins={[remarkBreaks]} components={{
|
||||
p: CustomParagraph,
|
||||
a: ({ href, children }) => {
|
||||
// eslint-disable-next-line react/prop-types
|
||||
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/');
|
||||
|
||||
|
||||
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}`;
|
||||
|
||||
@ -133,6 +154,7 @@ export const TextView = ({ item, truncate = false, itemTextField, rawText }: { i
|
||||
<MemoizedVideoEmbed url={href!}></MemoizedVideoEmbed>
|
||||
);
|
||||
}
|
||||
// eslint-disable-next-line react/prop-types
|
||||
if (href?.startsWith("#")) {
|
||||
const tag = tags.find(t => t.name.toLowerCase() === decodeURI(href).slice(1).toLowerCase());
|
||||
return <CustomHashTagLink tag={tag} item={item}>{children}</CustomHashTagLink>;
|
||||
@ -181,7 +203,7 @@ function truncateText(text, limit) {
|
||||
// Split the text by paragraphs
|
||||
const paragraphs = text.split('\n');
|
||||
|
||||
for (let paragraph of paragraphs) {
|
||||
for (const paragraph of paragraphs) {
|
||||
if (length + paragraph.length > limit) {
|
||||
truncated += paragraph.slice(0, limit - length) + '...';
|
||||
break;
|
||||
|
||||
@ -5,7 +5,7 @@ import { ItemFormPopupProps } from './ItemFormPopup'
|
||||
import { HeaderView } from './ItemPopupComponents/HeaderView'
|
||||
import { TextView } from './ItemPopupComponents/TextView'
|
||||
import { timeAgo } from '../../../Utils/TimeAgo'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { LatLng } from 'leaflet'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useRemoveItem, useUpdateItem } from '../hooks/useItems'
|
||||
@ -22,6 +22,7 @@ export interface ItemViewPopupProps {
|
||||
|
||||
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
export const ItemViewPopup = React.forwardRef((props: ItemViewPopupProps, ref: any) => {
|
||||
const map = useMap();
|
||||
const [loading, setLoading] = React.useState<boolean>(false);
|
||||
@ -31,7 +32,7 @@ export const ItemViewPopup = React.forwardRef((props: ItemViewPopupProps, ref: a
|
||||
const setSelectPosition = useSetSelectPosition();
|
||||
|
||||
|
||||
const [infoExpanded, setInfoExpanded] = useState<Boolean>(false);
|
||||
const [infoExpanded, setInfoExpanded] = useState<boolean>(false);
|
||||
|
||||
const handleEdit = (event: React.MouseEvent<HTMLElement>) => {
|
||||
event.stopPropagation();
|
||||
@ -57,7 +58,7 @@ export const ItemViewPopup = React.forwardRef((props: ItemViewPopupProps, ref: a
|
||||
}
|
||||
setLoading(false);
|
||||
map.closePopup();
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
window.history.pushState({}, "", "/" + `${params ? `?${params}` : ""}`);
|
||||
navigate("/");
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ const setTagApi = useSetTagApi();
|
||||
useEffect(() => {
|
||||
data && setTagData(data);
|
||||
api && setTagApi(api);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [api, data])
|
||||
|
||||
|
||||
@ -23,10 +24,10 @@ const filterTags = useFilterTags()
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let urlTags = params.get("tags")
|
||||
let decodedTags = urlTags ? decodeURIComponent(urlTags) : "";
|
||||
let decodedTagsArray = decodedTags.split(";");
|
||||
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 => {
|
||||
@ -34,6 +35,7 @@ useEffect(() => {
|
||||
tag && addFilterTag(tag)
|
||||
});}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [location, tags]);
|
||||
|
||||
|
||||
|
||||
@ -53,6 +53,7 @@ export function UtopiaMapInner({
|
||||
|
||||
useEffect(() => {
|
||||
layers.forEach(layer => addVisibleLayer(layer));
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [layers]);
|
||||
|
||||
const init = useRef(false)
|
||||
@ -63,6 +64,7 @@ export function UtopiaMapInner({
|
||||
}, 4000);
|
||||
init.current=true;
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
|
||||
@ -81,7 +83,7 @@ export function UtopiaMapInner({
|
||||
}
|
||||
|
||||
const resetMetaTags = () => {
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
if (!window.location.pathname.includes("/item/")) {
|
||||
window.history.pushState({}, "", `/` + `${params.toString() !== "" ? `?${params}` : ""}`);
|
||||
}
|
||||
@ -90,6 +92,7 @@ export function UtopiaMapInner({
|
||||
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<GeoJSONGeometry, any>, layer: L.Layer) => {
|
||||
if (feature.properties) {
|
||||
layer.bindPopup(feature.properties.name);
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import * as React from 'react'
|
||||
import { createContext, useContext, useState } from "react";
|
||||
|
||||
type UseClusterRefManagerResult = ReturnType<typeof useClusterRefManager>;
|
||||
|
||||
@ -5,5 +5,6 @@ export const useDebounce = (callback, delay, deps) => {
|
||||
const { reset, clear } = useTimeout(callback, delay);
|
||||
|
||||
useEffect(reset, [...deps, reset]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
useEffect(clear, []);
|
||||
}
|
||||
@ -1,8 +1,9 @@
|
||||
/* 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 { useLocation, useNavigate } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import useWindowDimensions from "./useWindowDimension";
|
||||
|
||||
type ActionType =
|
||||
@ -43,16 +44,25 @@ function useFilterManager(initialTags: Tag[]): {
|
||||
searchPhrase: string;
|
||||
visibleLayers: LayerProps[];
|
||||
visibleGroupTypes: string[];
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
addFilterTag: (tag: Tag) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
removeFilterTag: (name: string) => void;
|
||||
resetFilterTags: () => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setSearchPhrase: (phrase: string) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
addVisibleLayer: (layer: LayerProps) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
toggleVisibleLayer: (layer: LayerProps) => void;
|
||||
resetVisibleLayers: () => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
isLayerVisible: (layer: LayerProps) => boolean;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
addVisibleGroupType: (groupType: string) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
toggleVisibleGroupType: (groupType: string) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
isGroupTypeVisible: (groupType: string) => boolean;
|
||||
} {
|
||||
const [filterTags, dispatchTags] = useReducer((state: Tag[], action: ActionType) => {
|
||||
@ -128,9 +138,9 @@ function useFilterManager(initialTags: Tag[]): {
|
||||
const [searchPhrase, searchPhraseSet] = React.useState<string>("");
|
||||
|
||||
const addFilterTag = useCallback((tag: Tag) => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let urlTags = params.get("tags")
|
||||
let decodedTags = urlTags ? decodeURIComponent(urlTags) : "";
|
||||
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}`)
|
||||
@ -145,14 +155,15 @@ function useFilterManager(initialTags: Tag[]): {
|
||||
tag,
|
||||
});
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const removeFilterTag = useCallback((name: string) => {
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
let urlTags = params.get("tags");
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const urlTags = params.get("tags");
|
||||
let newUrlTags = "";
|
||||
let tags = urlTags?.split(";");
|
||||
const tags = urlTags?.split(";");
|
||||
if(tags?.length==0 && urlTags?.length && urlTags?.length > 0) tags[0]=urlTags;
|
||||
tags?.map(urlTag => {
|
||||
if(!(urlTag.toLocaleLowerCase() === name.toLocaleLowerCase()))
|
||||
@ -171,6 +182,7 @@ function useFilterManager(initialTags: Tag[]): {
|
||||
type: "REMOVE_TAG",
|
||||
name,
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const resetFilterTags = useCallback(() => {
|
||||
|
||||
@ -28,11 +28,17 @@ const ItemContext = createContext<UseItemManagerResult>({
|
||||
|
||||
function useItemsManager(initialItems: Item[]): {
|
||||
items: Item[];
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
addItem: (item: Item) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
updateItem: (item: Item) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
removeItem: (item: Item) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
resetItems: (layer: LayerProps) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setItemsApi: (layer: LayerProps) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setItemsData: (layer: LayerProps) => void;
|
||||
allItemsLoaded: boolean;
|
||||
|
||||
@ -47,6 +53,7 @@ function useItemsManager(initialItems: Item[]): {
|
||||
const [items, dispatch] = useReducer((state: Item[], action: ActionType) => {
|
||||
switch (action.type) {
|
||||
case "ADD":
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const exist = state.find((item) =>
|
||||
item.id === action.item.id ? true : false
|
||||
);
|
||||
@ -92,6 +99,7 @@ function useItemsManager(initialItems: Item[]): {
|
||||
})
|
||||
setallItemsLoaded(true);
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const setItemsData = useCallback((layer: LayerProps) => {
|
||||
@ -100,6 +108,7 @@ function useItemsManager(initialItems: Item[]): {
|
||||
dispatch({ type: "ADD", item: { ...item, layer: layer } });
|
||||
})
|
||||
setallItemsLoaded(true);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
|
||||
|
||||
@ -14,11 +14,13 @@ const LayerContext = createContext<UseItemManagerResult>({
|
||||
|
||||
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":
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const exist = state.find((layer) =>
|
||||
layer.name === action.layer.name ? true : false
|
||||
);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useCallback, useReducer, createContext, useContext, useEffect } from "react";
|
||||
import { useCallback, useReducer, createContext, useContext } from "react";
|
||||
import * as React from "react";
|
||||
import { Item } from "../../../types";
|
||||
import { Marker, Popup } from "leaflet";
|
||||
@ -25,7 +25,9 @@ const LeafletRefsContext = createContext<UseLeafletRefsManagerResult>({
|
||||
|
||||
function useLeafletRefsManager(initialLeafletRefs: {}): {
|
||||
leafletRefs: Record<string,LeafletRef>;
|
||||
// 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;
|
||||
} {
|
||||
|
||||
|
||||
@ -19,14 +19,19 @@ const PermissionContext = createContext<UsePermissionManagerResult>({
|
||||
|
||||
function usePermissionsManager(initialPermissions: Permission[]): {
|
||||
permissions: Permission[];
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setPermissionApi: (api: ItemsApi<any>) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setPermissionData: (data: Permission[]) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
setAdminRole: (adminRole: string) => void;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
hasUserPermission: (collectionName: string, action: PermissionAction, item?: Item, layer?: LayerProps) => boolean;
|
||||
} {
|
||||
const [permissions, dispatch] = useReducer((state: Permission[], action: ActionType) => {
|
||||
switch (action.type) {
|
||||
case "ADD":
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const exist = state.find((permission) =>
|
||||
permission.id === action.permission.id ? true : false
|
||||
);
|
||||
@ -111,6 +116,7 @@ function usePermissionsManager(initialPermissions: Permission[]): {
|
||||
);
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[permissions, user]
|
||||
);
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import * as React from 'react'
|
||||
import { createContext, useContext, useEffect, useState } from "react";
|
||||
import { Geometry, Item, LayerProps } from '../../../types';
|
||||
import { useUpdateItem } from "./useItems";
|
||||
@ -5,7 +6,6 @@ import { toast } from "react-toastify";
|
||||
import { useHasUserPermission } from "./usePermissions";
|
||||
import { LatLng } from "leaflet";
|
||||
import { ItemFormPopupProps } from "../Subcomponents/ItemFormPopup";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
type PolygonClickedProps = {
|
||||
position: LatLng
|
||||
@ -39,6 +39,7 @@ function useSelectPositionManager(): {
|
||||
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(() => {
|
||||
@ -54,6 +55,7 @@ function useSelectPositionManager(): {
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [mapClicked])
|
||||
|
||||
|
||||
@ -97,7 +99,7 @@ function useSelectPositionManager(): {
|
||||
|
||||
const linkItem = async (id: string) => {
|
||||
if (markerClicked) {
|
||||
let new_relations = markerClicked.relations || [];
|
||||
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 })
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import { useCallback, useReducer, createContext, useContext, useState } from "react";
|
||||
import * as React from "react";
|
||||
import { Item, ItemsApi, Tag } from "../../../types";
|
||||
@ -34,6 +35,7 @@ function useTagsManager(initialTags: Tag[]): {
|
||||
const [tags, dispatch] = useReducer((state: Tag[], action: ActionType) => {
|
||||
switch (action.type) {
|
||||
case "ADD":
|
||||
// eslint-disable-next-line no-case-declarations
|
||||
const exist = state.find((tag) =>
|
||||
tag.name.toLocaleLowerCase() === action.tag.name.toLocaleLowerCase() ? true : false
|
||||
);
|
||||
@ -67,6 +69,7 @@ function useTagsManager(initialTags: Tag[]): {
|
||||
}
|
||||
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const setTagData = useCallback((data: Tag[]) => {
|
||||
|
||||
@ -2,6 +2,7 @@ import { useMap } from "react-leaflet"
|
||||
|
||||
export const setItemLocation = () => {
|
||||
|
||||
// eslint-disable-next-line no-unused-vars, react-hooks/rules-of-hooks
|
||||
const map = useMap();
|
||||
|
||||
return (
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-constant-condition */
|
||||
import { useItems, useUpdateItem, useAddItem } from '../Map/hooks/useItems'
|
||||
import { useEffect, useState } from 'react';
|
||||
import { getValue } from '../../Utils/GetValue';
|
||||
@ -56,6 +57,7 @@ export function ProfileForm({ userType }: { userType: string }) {
|
||||
|
||||
useEffect(() => {
|
||||
item && hasUserPermission("items", "update", item) && setUpdatePermission(true);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [item])
|
||||
|
||||
useEffect(() => {
|
||||
@ -68,6 +70,7 @@ export function ProfileForm({ userType }: { userType: string }) {
|
||||
|
||||
!item && setItem({ id: crypto.randomUUID(), name: user ? user.first_name : "", text: "", layer: layer, new: true })
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [items])
|
||||
|
||||
useEffect(() => {
|
||||
@ -114,6 +117,7 @@ export function ProfileForm({ userType }: { userType: string }) {
|
||||
start: item?.start ?? "",
|
||||
end: item?.end ?? ""
|
||||
});
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [item, tags, items]);
|
||||
|
||||
const [template, setTemplate] = useState<string>("")
|
||||
|
||||
@ -81,6 +81,7 @@ export function ProfileView({ userType, attestationApi }: { userType: string , a
|
||||
item && setRelations(current => [...current, item])
|
||||
})
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [item, items])
|
||||
|
||||
|
||||
@ -112,6 +113,7 @@ export function ProfileView({ userType, attestationApi }: { userType: string , a
|
||||
);
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [item])
|
||||
|
||||
const getFirstAncestor = (item: Item): Item | undefined => {
|
||||
@ -125,18 +127,20 @@ export function ProfileView({ userType, attestationApi }: { userType: string , a
|
||||
|
||||
useEffect(() => {
|
||||
item && hasUserPermission("items", "update", item) && setUpdatePermission(true);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [item])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
selectPosition && map.closePopup();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectPosition])
|
||||
|
||||
useEffect(() => {
|
||||
setTemplate(item?.layer?.itemType.template || userType);
|
||||
}, [userType, item])
|
||||
|
||||
const [urlParams, setUrlParams] = useState(new URLSearchParams(location.search));
|
||||
const [/* urlParams, */ setUrlParams] = useState(new URLSearchParams(location.search));
|
||||
|
||||
|
||||
return (
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState } from "react";
|
||||
import { useHasUserPermission, usePermissions } from "../../Map/hooks/usePermissions";
|
||||
import { useHasUserPermission } from "../../Map/hooks/usePermissions";
|
||||
import DialogModal from "../../Templates/DialogModal";
|
||||
import { useItems } from "../../Map/hooks/useItems";
|
||||
import { HeaderView } from "../../Map/Subcomponents/ItemPopupComponents/HeaderView";
|
||||
|
||||
@ -131,6 +131,7 @@ export const AvatarWidget: React.FC<AvatarWidgetProps> = ({ avatar, setAvatar })
|
||||
setCropping(false);
|
||||
setImage("");
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [crop]);
|
||||
|
||||
const resizeBlob = useCallback(async (blob: Blob) => {
|
||||
|
||||
@ -4,6 +4,7 @@ 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<HTMLDivElement>(null);
|
||||
const [isOpen, toggle] = useState(false);
|
||||
|
||||
@ -59,8 +59,9 @@ const ContactInfo = ({ email, telephone, name, avatar, link }: { email: string,
|
||||
|
||||
export default ContactInfo;
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const ConditionalLink = ({ url, children }) => {
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
if (url) {
|
||||
return (
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { TextInput } from "../../Input"
|
||||
import { AvatarWidget } from "./AvatarWidget"
|
||||
import { ColorPicker } from "./ColorPicker"
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import SocialShareBar from './SocialShareBar';
|
||||
|
||||
|
||||
const flags = {
|
||||
/* const flags = {
|
||||
de: (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 5 3" className="tw-w-5 tw-h-3">
|
||||
<rect width="5" height="3" fill="#FFCE00" />
|
||||
@ -16,7 +16,7 @@ const flags = {
|
||||
<rect width="5" height="1" fill="#ED2939" />
|
||||
</svg>
|
||||
)
|
||||
};
|
||||
}; */
|
||||
|
||||
const statusMapping = {
|
||||
'in_planning': 'in Planung',
|
||||
@ -24,6 +24,7 @@ const statusMapping = {
|
||||
'active': 'aktiv'
|
||||
};
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const SubHeader = ({ type, status, url, title }) => (
|
||||
<div>
|
||||
<div className='tw-float-left tw-mt-2 tw-mb-4 tw-flex tw-items-center'>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const RelationCard = ({ title, description, imageSrc }) => (
|
||||
<div className={`tw-mb-6 ${imageSrc ? 'md:tw-flex md:tw-space-x-4' : ''}`}>
|
||||
{imageSrc && (
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import SocialShareButton from './SocialShareButton';
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const SocialShareBar = ({url, title, platforms = ['facebook', 'twitter', 'linkedin', 'xing', 'email']}) => {
|
||||
return (
|
||||
<div className="tw-flex tw-place-content-end tw-justify-end tw-space-x-2 tw-grow tw-min-w-fit tw-pl-2">
|
||||
|
||||
@ -49,6 +49,7 @@ const platformConfigs = {
|
||||
}
|
||||
};
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
const SocialShareButton = ({ platform, url, title }) => {
|
||||
const config = platformConfigs[platform];
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ 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}) => {
|
||||
|
||||
const [input, setInput] = useState('');
|
||||
@ -31,6 +32,7 @@ export const TagsWidget = ({placeholder, containerStyle, defaultTags, onUpdate})
|
||||
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();
|
||||
const newTag = tags.find(t => t.name === trimmedInput.toLocaleLowerCase())
|
||||
@ -40,6 +42,7 @@ export const TagsWidget = ({placeholder, containerStyle, defaultTags, onUpdate})
|
||||
setPushFilteredSuggestions([]);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
if (key === "Backspace" && !input.length && defaultTags.length && isKeyReleased) {
|
||||
const defaultTagsCopy = [...defaultTags];
|
||||
const poppedTag = defaultTagsCopy.pop();
|
||||
@ -61,6 +64,7 @@ export const TagsWidget = ({placeholder, containerStyle, defaultTags, onUpdate})
|
||||
|
||||
|
||||
const onSelected = (tag) => {
|
||||
// eslint-disable-next-line react/prop-types
|
||||
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]);
|
||||
@ -79,6 +83,7 @@ export const TagsWidget = ({placeholder, containerStyle, defaultTags, onUpdate})
|
||||
className: 'tw-bg-transparent tw-w-fit tw-mt-5 tw-h-fit'
|
||||
}
|
||||
|
||||
/* eslint-disable react/prop-types */
|
||||
return (
|
||||
<div onClick={()=> {
|
||||
setFocusInput(true);
|
||||
@ -99,4 +104,5 @@ export const TagsWidget = ({placeholder, containerStyle, defaultTags, onUpdate})
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
/* eslint-enable react/prop-types */
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
import * as React from 'react'
|
||||
import { useEffect } from "react";
|
||||
import { Item, Tag } from "../../../types"
|
||||
import { TextAreaInput, TextInput } from "../../Input"
|
||||
@ -55,6 +56,7 @@ export const OnepagerForm = ({ item, state, setState }: {
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [state.groupType])
|
||||
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { Item } from "utopia-ui/dist/types"
|
||||
import { Item } from "../../../types"
|
||||
import { TextView } from "../../Map"
|
||||
import ContactInfo from "../Subcomponents/ContactInfo"
|
||||
import ProfileSubHeader from "../Subcomponents/ProfileSubHeader"
|
||||
@ -14,6 +14,7 @@ export const OnepagerView = ({item, userType}:{item: Item, userType: string}) =>
|
||||
|
||||
useEffect(() => {
|
||||
setProfileOwner(items.find(i => (i.user_created?.id === item.user_created?.id) && i.layer?.itemType.name === userType));
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [item, items])
|
||||
|
||||
const typeMapping = {
|
||||
@ -22,8 +23,8 @@ export const OnepagerView = ({item, userType}:{item: Item, userType: string}) =>
|
||||
'liebevoll.jetzt': 'liebevoll.jetzt',
|
||||
};
|
||||
|
||||
let groupType = item.group_type ? item.group_type : 'default';
|
||||
let groupTypeText = typeMapping[groupType];
|
||||
const groupType = item.group_type ? item.group_type : 'default';
|
||||
const groupTypeText = typeMapping[groupType];
|
||||
|
||||
return (
|
||||
<div className='tw-h-full tw-overflow-y-auto fade'>
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { TextAreaInput } from "../../Input";
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
export const SimpleForm = ({ state, setState }) => {
|
||||
return (
|
||||
<TextAreaInput
|
||||
placeholder="About me ..."
|
||||
// eslint-disable-next-line react/prop-types
|
||||
defaultValue={state?.text || ""}
|
||||
updateFormValue={(v) => setState(prevState => ({
|
||||
...prevState,
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { useCallback, useEffect, useState } from "react"
|
||||
import { TextAreaInput } from "../../Input"
|
||||
import { PopupStartEndInput, TextView } from "../../Map"
|
||||
@ -7,6 +8,7 @@ import { TagsWidget } from "../Subcomponents/TagsWidget"
|
||||
import { useNavigate } from "react-router-dom"
|
||||
import { useUpdateItem } from "../../Map/hooks/useItems"
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
export const TabsForm = ({ item, state, setState, updatePermission, linkItem, unlinkItem, loading, setUrlParams }) => {
|
||||
|
||||
const [activeTab, setActiveTab] = useState<number>(1);
|
||||
@ -16,18 +18,20 @@ export const TabsForm = ({ item, state, setState, updatePermission, linkItem, un
|
||||
const updateActiveTab = useCallback((id: number) => {
|
||||
setActiveTab(id);
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
|
||||
params.set("tab", `${id}`);
|
||||
const newUrl = location.pathname + "?" + params.toString();
|
||||
window.history.pushState({}, '', newUrl);
|
||||
setUrlParams(params);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [location.pathname]);
|
||||
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let urlTab = params.get("tab");
|
||||
const params = new URLSearchParams(location.search);
|
||||
const urlTab = params.get("tab");
|
||||
setActiveTab(urlTab ? Number(urlTab) : 1);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [location.search]);
|
||||
|
||||
return (
|
||||
|
||||
@ -4,20 +4,20 @@ import { LinkedItemsHeaderView } from '../Subcomponents/LinkedItemsHeaderView'
|
||||
import { ActionButton } from '../Subcomponents/ActionsButton'
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useAddFilterTag } from '../../Map/hooks/useFilter'
|
||||
import { Item, Tag } from 'utopia-ui/dist/types'
|
||||
import { Item, Tag } from '../../../types'
|
||||
import { Link, useNavigate } from 'react-router-dom'
|
||||
import { useItems } from '../../Map/hooks/useItems'
|
||||
import { useAssetApi } from '../../AppShell/hooks/useAssets'
|
||||
import { timeAgo } from '../../../Utils/TimeAgo'
|
||||
import { useAuth } from '../../Auth'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
export const TabsView = ({ attestations, userType, item, offers, needs, relations, updatePermission, loading, linkItem, unlinkItem, setUrlParams }: { attestations: Array<any>, userType: string, item: Item, offers: Array<Tag>, needs: Array<Tag>, relations: Array<Item>, updatePermission: boolean, loading: boolean, linkItem: (id: string) => Promise<void>, unlinkItem: (id: string) => Promise<void>, setUrlParams: any }) => {
|
||||
|
||||
const addFilterTag = useAddFilterTag();
|
||||
const [activeTab, setActiveTab] = useState<number>();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [addItemPopupType, setAddItemPopupType] = useState<string>("");
|
||||
const [addItemPopupType, /* setAddItemPopupType */] = useState<string>("");
|
||||
|
||||
const items = useItems();
|
||||
const assetsApi = useAssetApi();
|
||||
@ -38,18 +38,20 @@ export const TabsView = ({ attestations, userType, item, offers, needs, relation
|
||||
const updateActiveTab = useCallback((id: number) => {
|
||||
setActiveTab(id);
|
||||
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
params.set("tab", `${id}`);
|
||||
const newUrl = location.pathname + "?" + params.toString();
|
||||
window.history.pushState({}, '', newUrl);
|
||||
setUrlParams(params);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [location.pathname]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let urlTab = params.get("tab");
|
||||
const params = new URLSearchParams(location.search);
|
||||
const urlTab = params.get("tab");
|
||||
setActiveTab(urlTab ? Number(urlTab) : 1);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [location.search]);
|
||||
|
||||
return (
|
||||
|
||||
@ -1,20 +1,14 @@
|
||||
import * as React from 'react'
|
||||
import { CardPage, MapOverlayPage } from '../Templates'
|
||||
import { useItems } from '../Map/hooks/useItems'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { MapOverlayPage } from '../Templates'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useState } from 'react';
|
||||
import { Item, UserItem } from '../../types';
|
||||
import { getValue } from '../../Utils/GetValue';
|
||||
import { useMap } from 'react-leaflet';
|
||||
import { LatLng } from 'leaflet';
|
||||
import { TextView } from '../Map';
|
||||
import useWindowDimensions from '../Map/hooks/useWindowDimension';
|
||||
import { UserItem } from '../../types';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useAuth } from '../Auth';
|
||||
import { TextInput } from '../Input';
|
||||
|
||||
export function UserSettings() {
|
||||
const { user, updateUser, loading, token } = useAuth();
|
||||
const { user, updateUser, loading, /* token */ } = useAuth();
|
||||
|
||||
const [id, setId] = useState<string>("");
|
||||
const [email, setEmail] = useState<string>("");
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { Item, Tag } from '../../types';
|
||||
import * as React from 'react'
|
||||
import { Item } from '../../types';
|
||||
import { encodeTag } from '../../Utils/FormatTags';
|
||||
import { hashTagRegex } from '../../Utils/HashTagRegex';
|
||||
import { randomColor } from '../../Utils/RandomColor';
|
||||
@ -42,7 +43,7 @@ export const submitNewItem = async (evt: any, type: string, item, user, setLoadi
|
||||
}
|
||||
|
||||
export const linkItem = async (id: string, item, updateItem) => {
|
||||
let new_relations = item.relations || [];
|
||||
const new_relations = item.relations || [];
|
||||
new_relations?.push({ items_id: item.id, related_items_id: id })
|
||||
const updatedItem = { id: item.id, relations: new_relations }
|
||||
|
||||
@ -60,7 +61,7 @@ export const linkItem = async (id: string, item, updateItem) => {
|
||||
}
|
||||
|
||||
export const unlinkItem = async (id: string, item, updateItem) => {
|
||||
let new_relations = item.relations?.filter(r => r.related_items_id !== id)
|
||||
const new_relations = item.relations?.filter(r => r.related_items_id !== id)
|
||||
const updatedItem = { id: item.id, relations: new_relations }
|
||||
|
||||
|
||||
@ -94,7 +95,7 @@ export const handleDelete = async (event: React.MouseEvent<HTMLElement>, item, s
|
||||
}
|
||||
setLoading(false);
|
||||
map.closePopup();
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
window.history.pushState({}, "", "/" + `${params ? `?${params}` : ""}`);
|
||||
navigate("/");
|
||||
}
|
||||
@ -103,7 +104,7 @@ export const handleDelete = async (event: React.MouseEvent<HTMLElement>, item, s
|
||||
export const onUpdateItem = async (state, item, tags, addTag, setLoading, navigate, updateItem, addItem, user, params) => {
|
||||
let changedItem = {} as Item;
|
||||
|
||||
let offer_updates: Array<any> = [];
|
||||
const offer_updates: Array<any> = [];
|
||||
//check for new offers
|
||||
await state.offers?.map(o => {
|
||||
const existingOffer = item?.offers?.find(t => t.tags_id === o.id)
|
||||
@ -112,7 +113,7 @@ export const onUpdateItem = async (state, item, tags, addTag, setLoading, naviga
|
||||
!existingOffer && offer_updates.push({ items_id: item?.id, tags_id: o.id })
|
||||
});
|
||||
|
||||
let needs_updates: Array<any> = [];
|
||||
const needs_updates: Array<any> = [];
|
||||
|
||||
await state.needs?.map(n => {
|
||||
const existingNeed = item?.needs?.find(t => t.tags_id === n.id)
|
||||
@ -142,8 +143,8 @@ export const onUpdateItem = async (state, item, tags, addTag, setLoading, naviga
|
||||
...state.needs.length > 0 && { needs: needs_updates }
|
||||
};
|
||||
|
||||
let offers_state: Array<any> = [];
|
||||
let needs_state: Array<any> = [];
|
||||
const offers_state: Array<any> = [];
|
||||
const needs_state: Array<any> = [];
|
||||
|
||||
state.offers.map(o => {
|
||||
offers_state.push({ items_id: item?.id, tags_id: o.id })
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
|
||||
import * as React from 'react'
|
||||
import { MapOverlayPage } from './MapOverlayPage'
|
||||
import { useItems } from '../Map/hooks/useItems'
|
||||
import { useAssetApi } from '../AppShell/hooks/useAssets'
|
||||
import { EmojiPicker } from './EmojiPicker';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useRef, useState } from 'react';
|
||||
import { Item, ItemsApi } from '../../types';
|
||||
import { useEffect } from 'react';
|
||||
@ -17,9 +17,10 @@ export const AttestationForm = ({api}:{api?:ItemsApi<any>}) => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
let params = new URLSearchParams(location.search);
|
||||
let to_user_ids = params.get("to");
|
||||
const params = new URLSearchParams(location.search);
|
||||
const to_user_ids = params.get("to");
|
||||
setUsers(items.filter(i => to_user_ids?.includes(i.id)))
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [items, location])
|
||||
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
|
||||
@ -17,6 +17,7 @@ export const CircleLayout = ({ items,radius, fontSize } : {items: any, radius: n
|
||||
child.style.transform = `translate(${x}px, ${y}px)`;
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [items]);
|
||||
|
||||
return (
|
||||
|
||||
@ -52,6 +52,7 @@ const DialogModal = ({
|
||||
<dialog className={`${className ? className: ""} tw-card tw-shadow-xl tw-absolute tw-right-0 tw-top-0 tw-bottom-0 tw-left-0 tw-m-auto tw-transition-opacity tw-duration-300 tw-p-4 tw-max-w-xl tw-bg-base-100`}
|
||||
|
||||
ref={ref}
|
||||
// eslint-disable-next-line react/no-unknown-property
|
||||
onCancel={onClose}
|
||||
onClick={(e) =>
|
||||
ref.current && !isClickInsideRectangle(e, ref.current) && closeOnClickOutside &&onClose()
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
export const EmojiPicker = ({selectedEmoji, selectedColor, selectedShape, setSelectedEmoji, setSelectedColor, setSelectedShape}) => {
|
||||
|
||||
|
||||
@ -7,7 +8,7 @@ export const EmojiPicker = ({selectedEmoji, selectedColor, selectedShape, setSel
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
const emojis = [
|
||||
'❤️', '🙏', '👍', '🌻',, '✨', '☀️',
|
||||
'❤️', '🙏', '👍', '🌻', '✨', '☀️',
|
||||
'🔥', '🪵', '💧', '🎶', '🎨','🍄',
|
||||
'📝', '✉️', '🧩','💡', '🎓', '💬',
|
||||
'🛠', '💻', '🕹', '🖨', '🚐', '🛒',
|
||||
|
||||
@ -12,7 +12,7 @@ export const ItemCard = ({ i, loading, url, parameterField, deleteCallback }: {
|
||||
|
||||
return (
|
||||
<div className='tw-cursor-pointer tw-card tw-border-[1px] tw-border-base-300 tw-card-body tw-shadow-xl tw-bg-base-100 tw-text-base-content tw-p-4 tw-mb-4 tw-h-fit' onClick={() => {
|
||||
let params = new URLSearchParams(window.location.search);
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
if (windowDimensions.width < 786 && i.position) navigate("/" + getValue(i, parameterField) + `${params ? `?${params}` : ""}`)
|
||||
else navigate(url + getValue(i, parameterField) + `${params ? `?${params}` : ""}`)
|
||||
}}>
|
||||
|
||||
@ -26,6 +26,7 @@ export function MapOverlayPage({ children, className, backdrop, card = true }: {
|
||||
L.DomEvent.disableClickPropagation(backdropRef.current)
|
||||
L.DomEvent.disableScrollPropagation(backdropRef.current)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [overlayRef, backdropRef])
|
||||
|
||||
|
||||
|
||||
@ -50,6 +50,7 @@ export const MarketView = () => {
|
||||
})
|
||||
console.log(offers);
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [items])
|
||||
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ export const MoonCalendar = () => {
|
||||
|
||||
|
||||
const [currMonth, setCurrMonth] = useState(() => format(today, "MMM-yyyy"));
|
||||
let firstDayOfMonth = parse(currMonth, "MMM-yyyy", new Date());
|
||||
const firstDayOfMonth = parse(currMonth, "MMM-yyyy", new Date());
|
||||
|
||||
|
||||
const getPrevMonth = (event: React.MouseEvent<SVGSVGElement>) => {
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
import { ReactNode, useEffect, useRef, useState } from 'react'
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { Item, ItemsApi, LayerProps } from '../../types';
|
||||
import { getValue } from '../../Utils/GetValue';
|
||||
import { PopupStartEndInput, StartEndView, TextView } from '../Map';
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { Item} from '../../types';
|
||||
import { PopupStartEndInput } from '../Map';
|
||||
import { PlusButton } from '../Profile/Subcomponents/PlusButton';
|
||||
import { TextInput, TextAreaInput } from '../Input';
|
||||
import { useAddTag, useGetItemTags, useTags } from '../Map/hooks/useTags';
|
||||
@ -11,10 +9,8 @@ import { hashTagRegex } from '../../Utils/HashTagRegex';
|
||||
import { randomColor } from '../../Utils/RandomColor';
|
||||
import { useAuth } from '../Auth';
|
||||
import { useLayers } from '../Map/hooks/useLayers';
|
||||
import { HeaderView } from '../Map/Subcomponents/ItemPopupComponents/HeaderView';
|
||||
import { MapOverlayPage } from './MapOverlayPage';
|
||||
import { useAddItem, useItems, useRemoveItem } from '../Map/hooks/useItems';
|
||||
import { DateUserInfo } from './DateUserInfo';
|
||||
import { ItemCard } from './ItemCard';
|
||||
import { Control } from '../Map/Subcomponents/Controls/Control';
|
||||
import { SearchControl } from '../Map/Subcomponents/Controls/SearchControl';
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { useState } from 'react'
|
||||
import { useState } from 'react'
|
||||
import { MapOverlayPage } from './MapOverlayPage'
|
||||
import { useItems } from '../Map/hooks/useItems'
|
||||
import { useAssetApi } from '../AppShell/hooks/useAssets'
|
||||
|
||||
@ -2,7 +2,7 @@ import * as React from 'react'
|
||||
import { decodeTag } from '../../Utils/FormatTags'
|
||||
import { Tag } from '../../types'
|
||||
|
||||
export const TagView = ({ tag, heighlight, onClick, count }: { tag: Tag, heighlight?: boolean, onClick?: (e) => void, count?: number }) => {
|
||||
export const TagView = ({ tag, heighlight, onClick, count }: { tag: Tag, heighlight?: boolean, onClick?: (/* e */) => void, count?: number }) => {
|
||||
return (
|
||||
// Use your imagination to render suggestions.
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import * as React from "react"
|
||||
|
||||
// eslint-disable-next-line react/prop-types
|
||||
function ErrorText({styleClass, children}){
|
||||
return(
|
||||
<p className={`tw-text-center tw-text-error ${styleClass}`}>{children}</p>
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
export function getValue(obj, path) {
|
||||
if (!obj || typeof path !== 'string') return undefined;
|
||||
|
||||
var pathArray = path.split('.'); // Use a different variable for the split path
|
||||
for (var i = 0, len = pathArray.length; i < len; i++) {
|
||||
const pathArray = path.split('.'); // Use a different variable for the split path
|
||||
for (let i = 0, len = pathArray.length; i < len; i++) {
|
||||
if (!obj) return undefined; // Check if obj is falsy at each step
|
||||
obj = obj[pathArray[i]]; // Dive one level deeper
|
||||
}
|
||||
|
||||
@ -14,10 +14,8 @@ const addIcon = (icon: string) => {
|
||||
switch (icon) {
|
||||
case "point":
|
||||
return '<svg fill="#fff" class="circle-icon" width="13"xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M512 256C512 397.4 397.4 512 256 512C114.6 512 0 397.4 0 256C0 114.6 114.6 0 256 0C397.4 0 512 114.6 512 256z"/></svg>';
|
||||
break;
|
||||
case "calendar":
|
||||
return '<svg fill="#fff" class="calendar-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M160 32V64H288V32C288 14.33 302.3 0 320 0C337.7 0 352 14.33 352 32V64H400C426.5 64 448 85.49 448 112V160H0V112C0 85.49 21.49 64 48 64H96V32C96 14.33 110.3 0 128 0C145.7 0 160 14.33 160 32zM0 192H448V464C448 490.5 426.5 512 400 512H48C21.49 512 0 490.5 0 464V192zM64 304C64 312.8 71.16 320 80 320H112C120.8 320 128 312.8 128 304V272C128 263.2 120.8 256 112 256H80C71.16 256 64 263.2 64 272V304zM192 304C192 312.8 199.2 320 208 320H240C248.8 320 256 312.8 256 304V272C256 263.2 248.8 256 240 256H208C199.2 256 192 263.2 192 272V304zM336 256C327.2 256 320 263.2 320 272V304C320 312.8 327.2 320 336 320H368C376.8 320 384 312.8 384 304V272C384 263.2 376.8 256 368 256H336zM64 432C64 440.8 71.16 448 80 448H112C120.8 448 128 440.8 128 432V400C128 391.2 120.8 384 112 384H80C71.16 384 64 391.2 64 400V432zM208 384C199.2 384 192 391.2 192 400V432C192 440.8 199.2 448 208 448H240C248.8 448 256 440.8 256 432V400C256 391.2 248.8 384 240 384H208zM320 432C320 440.8 327.2 448 336 448H368C376.8 448 384 440.8 384 432V400C384 391.2 376.8 384 368 384H336C327.2 384 320 391.2 320 400V432z"/></svg>';
|
||||
break;
|
||||
case "user":
|
||||
return '<svg fill="#fff" class="user-icon" xmlns="http://www.w3.org/2000/svg" height="1.5em" viewBox="0 0 448 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z"/></svg>'
|
||||
case "fire":
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
export const LUNAR_MONTH: number = 29.530588853;
|
||||
export const LUNAR_MONTH = 29.530588853;
|
||||
|
||||
export const getJulianDate = (date: Date = new Date()): number => {
|
||||
const time: number = date.getTime();
|
||||
|
||||
@ -5,12 +5,12 @@ export const randomColor = () => {
|
||||
const golden_ratio_conjugate = 0.618033988749895;
|
||||
|
||||
function hsvToHex(h, s, v) {
|
||||
var r, g, b;
|
||||
var i = (Math.floor(h * 6));
|
||||
var f = h * 6 - i;
|
||||
var p = v * (1 - s);
|
||||
var q = v * (1 - f * s);
|
||||
var t = v * (1 - (1 - f) * s);
|
||||
let r, g, b;
|
||||
const i = (Math.floor(h * 6));
|
||||
const f = h * 6 - i;
|
||||
const p = v * (1 - s);
|
||||
const q = v * (1 - f * s);
|
||||
const t = v * (1 - (1 - f) * s);
|
||||
|
||||
switch (i % 6) {
|
||||
case 0: r = v, g = t, b = p; break;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
export const urlRegex = /(^| )(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,10}(:[0-9]{1,10})?(\/.*)?$/gm
|
||||
export const mailRegex = /([a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)/gi;
|
||||
|
||||
@ -6,6 +7,7 @@ export function fixUrls(message: string): string {
|
||||
|
||||
message = message.replace(urlRegex, function (url) {
|
||||
let hyperlink = url.replace(' ', '');
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
if (!hyperlink.match('^https?:\/\/')) {
|
||||
hyperlink = 'https://' + hyperlink;
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ export const timeAgo = (date: string | number | Date) => {
|
||||
};
|
||||
|
||||
const calculateTimeDifference = (time: number) => {
|
||||
for (let { label, seconds } of units) {
|
||||
for (const { label, seconds } of units) {
|
||||
const interval = Math.floor(time / seconds);
|
||||
if (interval >= 1) {
|
||||
return {
|
||||
|
||||
@ -9,6 +9,7 @@ export {TextInput, TextAreaInput, SelectBox} from './Components/Input'
|
||||
import "./index.css"
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
interface Window {
|
||||
my_modal_3: any;
|
||||
}
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
import * as React from 'react'
|
||||
import { ItemFormPopupProps } from "./Components/Map/Subcomponents/ItemFormPopup";
|
||||
|
||||
export interface UtopiaMapProps {
|
||||
@ -72,6 +75,7 @@ export class Item {
|
||||
parent?:string;
|
||||
subname?: string;
|
||||
public_edit?: boolean;
|
||||
// eslint-disable-next-line no-undef
|
||||
[key: string]: any;
|
||||
constructor(id:string,name:string,text:string,position:Geometry, layer?: LayerProps, api?: ItemsApi<any>){
|
||||
this.id = id;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
/* eslint-disable no-undef */
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
@ -85,6 +86,6 @@ module.exports = {
|
||||
},]
|
||||
},
|
||||
prefix: 'tw-',
|
||||
content: ['./src/**/*.{js,jsx,ts,tsx}'],
|
||||
// content: ['./src/**/*.{js,jsx,ts,tsx}'],
|
||||
|
||||
}
|
||||
@ -15,7 +15,7 @@
|
||||
"noImplicitThis": true,
|
||||
"strictNullChecks": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": true ,
|
||||
"noUnusedParameters": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", "dist", "example", "rollup.config.mjss"],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user