Merge pull request #16 from utopia-os/lint

fix(other): lint (green)
This commit is contained in:
Ulf Gebhardt 2024-10-29 12:16:12 +01:00 committed by GitHub
commit 87ec6aa8db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
89 changed files with 620 additions and 140 deletions

View File

@ -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
View File

@ -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",

View File

@ -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",

View File

@ -1,3 +1,4 @@
// eslint-disable-next-line no-undef
module.exports = {
plugins: {
tailwindcss: {},

View File

@ -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();

View File

@ -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]);

View File

@ -7,6 +7,7 @@ export const SetAssetsApi = ({assetsApi}:{assetsApi: AssetsApi}) => {
useEffect(() => {
setAssetsApi(assetsApi)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [assetsApi])

View File

@ -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

View File

@ -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 (

View File

@ -24,6 +24,7 @@ export const Sitemap = ({url}:{url:string}) => {
setSitemap(generateSitemap());
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [items]);
return (

View File

@ -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);

View File

@ -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 }),

View File

@ -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>("");

View File

@ -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),

View File

@ -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;
};
}
}

View File

@ -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
}, [])

View File

@ -12,6 +12,7 @@ export function Quests() {
useEffect(() => {
setQuestsOpen(false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const [profile, setProfie] = useState<Item>()

View File

@ -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);

View File

@ -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 => {

View File

@ -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>) => {

View File

@ -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}[];

View File

@ -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(() => {

View File

@ -11,6 +11,7 @@ type InputTextProps = {
defaultValue?: string;
placeholder?: string;
autocomplete?: string
// eslint-disable-next-line no-unused-vars
updateFormValue?: (value: string ) => void;
}

View File

@ -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 (

View File

@ -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 (

View File

@ -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 (

View File

@ -13,6 +13,7 @@ export function FilterControl() {
groupTypes.map(layer =>
addVisibleGroupType(layer.value)
)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

View File

@ -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({

View File

@ -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]);

View File

@ -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();

View File

@ -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>) => {

View File

@ -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();

View File

@ -1,5 +1,3 @@
import * as React from 'react'
import { TextInput } from '../../../Input'
import { Item } from '../../../../types'
export const PopupCheckboxInput = ({ dataField, label, item }:

View File

@ -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;
}

View File

@ -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;

View File

@ -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("/");
}

View File

@ -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]);

View File

@ -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);

View File

@ -1,3 +1,4 @@
import * as React from 'react'
import { createContext, useContext, useState } from "react";
type UseClusterRefManagerResult = ReturnType<typeof useClusterRefManager>;

View File

@ -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, []);
}

View File

@ -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(() => {

View File

@ -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
}, []);

View File

@ -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
);

View File

@ -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;
} {

View File

@ -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]
);

View File

@ -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 })

View File

@ -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[]) => {

View File

@ -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 (

View File

@ -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>("")

View File

@ -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 (

View File

@ -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";

View File

@ -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) => {

View File

@ -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);

View File

@ -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 (

View File

@ -1,3 +1,4 @@
/* eslint-disable react/prop-types */
import { TextInput } from "../../Input"
import { AvatarWidget } from "./AvatarWidget"
import { ColorPicker } from "./ColorPicker"

View File

@ -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'>

View File

@ -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 && (

View File

@ -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">

View File

@ -49,6 +49,7 @@ const platformConfigs = {
}
};
// eslint-disable-next-line react/prop-types
const SocialShareButton = ({ platform, url, title }) => {
const config = platformConfigs[platform];

View File

@ -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 */
}

View File

@ -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])

View File

@ -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'>

View File

@ -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,

View File

@ -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 (

View File

@ -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 (

View File

@ -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>("");

View File

@ -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 })

View File

@ -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('');

View File

@ -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 (

View File

@ -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()

View File

@ -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 = [
'❤️', '🙏', '👍', '🌻',, '✨', '☀️',
'❤️', '🙏', '👍', '🌻', '✨', '☀️',
'🔥', '🪵', '💧', '🎶', '🎨','🍄',
'📝', '✉️', '🧩','💡', '🎓', '💬',
'🛠', '💻', '🕹', '🖨', '🚐', '🛒',

View File

@ -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}` : ""}`)
}}>

View File

@ -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])

View File

@ -50,6 +50,7 @@ export const MarketView = () => {
})
console.log(offers);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [items])

View File

@ -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>) => {

View File

@ -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';

View File

@ -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'

View File

@ -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.

View File

@ -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>

View File

@ -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
}

View File

@ -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":

View File

@ -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();

View File

@ -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;

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;

View File

@ -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}'],
}

View File

@ -15,7 +15,7 @@
"noImplicitThis": true,
"strictNullChecks": true,
"noUnusedLocals": false,
"noUnusedParameters": true ,
"noUnusedParameters": true
},
"include": ["src"],
"exclude": ["node_modules", "dist", "example", "rollup.config.mjss"],