From ef32b67e6c618fd2000f7b6ef3b69666d2f0fae5 Mon Sep 17 00:00:00 2001
From: jeafreezy
Date: Mon, 30 Sep 2024 16:31:48 +0200
Subject: [PATCH 01/26] chore: initialized models page
---
frontend/src/app/router.tsx | 18 +++++------
frontend/src/app/routes/landing.tsx | 25 ++++++++--------
frontend/src/app/routes/models.tsx | 7 +++--
.../src/components/layouts/root-layout.tsx | 6 ++--
frontend/src/components/models/index.ts | 1 +
frontend/src/components/models/model-card.tsx | 7 +++++
frontend/src/components/models/model-list.tsx | 7 +++++
frontend/src/components/models/skeleton.tsx | 30 +++++++++++++++++++
8 files changed, 74 insertions(+), 27 deletions(-)
create mode 100644 frontend/src/components/models/index.ts
create mode 100644 frontend/src/components/models/model-card.tsx
create mode 100644 frontend/src/components/models/model-list.tsx
create mode 100644 frontend/src/components/models/skeleton.tsx
diff --git a/frontend/src/app/router.tsx b/frontend/src/app/router.tsx
index d7bfa9ed..d000a87c 100644
--- a/frontend/src/app/router.tsx
+++ b/frontend/src/app/router.tsx
@@ -10,15 +10,15 @@ import { ProtectedPage } from "@/app/routes/protected-route";
const router = createBrowserRouter([
{
path: APPLICATION_ROUTES.HOMEPAGE,
+ lazy: async () => {
+ const { LandingPage } = await import("@/app/routes/landing");
+ return { Component: LandingPage };
+ },
+ },
+ {
element: ,
children: [
- {
- path: APPLICATION_ROUTES.HOMEPAGE,
- lazy: async () => {
- const { LandingPage } = await import("@/app/routes/landing");
- return { Component: LandingPage };
- },
- },
+
{
path: APPLICATION_ROUTES.LEARN,
lazy: async () => {
@@ -53,9 +53,7 @@ const router = createBrowserRouter([
const { ModelsPage } = await import("@/app/routes/models");
return {
Component: () => (
-
-
-
+
),
};
},
diff --git a/frontend/src/app/routes/landing.tsx b/frontend/src/app/routes/landing.tsx
index ddbdeb60..8c4d9f60 100644
--- a/frontend/src/app/routes/landing.tsx
+++ b/frontend/src/app/routes/landing.tsx
@@ -1,5 +1,5 @@
import { Footer } from "@/components/ui/footer";
-import { Header } from "@/components/ui/header";
+import { Header, NavBar } from "@/components/ui/header";
import WhatIsFAIR from "@/components/landing/about-fair/about-fair";
import CoreFeatures from "@/components/landing/core-features/core-features";
import Corevalues from "@/components/landing/core-values/core-values";
@@ -14,18 +14,17 @@ export const LandingPage = () => {
return (
<>
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
>
);
};
diff --git a/frontend/src/app/routes/models.tsx b/frontend/src/app/routes/models.tsx
index 1c800102..03f9a461 100644
--- a/frontend/src/app/routes/models.tsx
+++ b/frontend/src/app/routes/models.tsx
@@ -1,7 +1,10 @@
-import { PageUnderConstruction } from "@/components/errors"
+
+import { ModelsPageSkeleton } from "@/components/models"
export const ModelsPage = () => {
return (
-
+
+
+
);
};
diff --git a/frontend/src/components/layouts/root-layout.tsx b/frontend/src/components/layouts/root-layout.tsx
index cd698a40..79a217cd 100644
--- a/frontend/src/components/layouts/root-layout.tsx
+++ b/frontend/src/components/layouts/root-layout.tsx
@@ -5,9 +5,11 @@ import { Outlet } from "react-router-dom";
const RootLayout = () => {
return (
-
+
-
+
+
+
);
};
diff --git a/frontend/src/components/models/index.ts b/frontend/src/components/models/index.ts
new file mode 100644
index 00000000..08920d4a
--- /dev/null
+++ b/frontend/src/components/models/index.ts
@@ -0,0 +1 @@
+export { default as ModelsPageSkeleton } from "./skeleton";
diff --git a/frontend/src/components/models/model-card.tsx b/frontend/src/components/models/model-card.tsx
new file mode 100644
index 00000000..7d7f0a1b
--- /dev/null
+++ b/frontend/src/components/models/model-card.tsx
@@ -0,0 +1,7 @@
+const ModelCard = () => {
+ return (
+
+ models card
+
+ )
+}
\ No newline at end of file
diff --git a/frontend/src/components/models/model-list.tsx b/frontend/src/components/models/model-list.tsx
new file mode 100644
index 00000000..48bb8cef
--- /dev/null
+++ b/frontend/src/components/models/model-list.tsx
@@ -0,0 +1,7 @@
+const ModelList = () => {
+ return (
+
+ model list
+
+ )
+}
\ No newline at end of file
diff --git a/frontend/src/components/models/skeleton.tsx b/frontend/src/components/models/skeleton.tsx
new file mode 100644
index 00000000..de542283
--- /dev/null
+++ b/frontend/src/components/models/skeleton.tsx
@@ -0,0 +1,30 @@
+const ModelsPageSkeleton = () => {
+ return (
+
+ {
+ new Array(16).fill(1).map(_ =>
+
+ )
+ }
+
+ )
+}
+
+
+export default ModelsPageSkeleton
\ No newline at end of file
From 5ba0358b1456dc3c185c9f3b182e8ceaa3021b56 Mon Sep 17 00:00:00 2001
From: Emmanuel Jolaiya
Date: Tue, 1 Oct 2024 22:25:19 +0200
Subject: [PATCH 02/26] chore: deleted build files
---
frontend/tsconfig.app.tsbuildinfo | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 frontend/tsconfig.app.tsbuildinfo
diff --git a/frontend/tsconfig.app.tsbuildinfo b/frontend/tsconfig.app.tsbuildinfo
deleted file mode 100644
index 3e4f6258..00000000
--- a/frontend/tsconfig.app.tsbuildinfo
+++ /dev/null
@@ -1 +0,0 @@
-{"root":["./src/main.tsx","./src/vite-env.d.ts","./src/app/index.tsx","./src/app/router.tsx","./src/app/routes/landing.tsx","./src/components/index.ts","./src/components/landing/index.ts","./src/components/landing/about-fair/about-fair.tsx","./src/components/landing/fair-process/fair-process.tsx","./src/components/landing/faqs/faqs.tsx","./src/components/landing/features/core-features/core-features.tsx","./src/components/landing/kpi/kpi.tsx","./src/components/ui/index.ts","./src/components/ui/animated-beam/animated-beam.tsx","./src/components/ui/animated-beam/index.ts","./src/components/ui/button/button.tsx","./src/components/ui/button/index.ts","./src/components/ui/header/header.tsx","./src/components/ui/header/index.ts","./src/components/ui/header/navbar.tsx","./src/components/ui/icons/bot-icon.tsx","./src/components/ui/icons/desktop-flow-icon.tsx","./src/components/ui/icons/feedback-icon.tsx","./src/components/ui/icons/guage-icon.tsx","./src/components/ui/icons/index.ts","./src/components/ui/icons/loop-icon.tsx","./src/components/ui/icons/predictions-icon.tsx","./src/components/ui/icons/timer-icon.tsx","./src/components/ui/link/index.ts","./src/components/ui/link/link.tsx","./src/utils/cn.ts","./src/utils/index.ts","./src/utils/types.ts"],"version":"5.6.2"}
\ No newline at end of file
From 0cd0b56896d5b6458026a88d5a895ae1e4e7def5 Mon Sep 17 00:00:00 2001
From: Emmanuel Jolaiya
Date: Tue, 1 Oct 2024 22:25:29 +0200
Subject: [PATCH 03/26] chore: deleted build files
---
frontend/tsconfig.node.tsbuildinfo | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 frontend/tsconfig.node.tsbuildinfo
diff --git a/frontend/tsconfig.node.tsbuildinfo b/frontend/tsconfig.node.tsbuildinfo
deleted file mode 100644
index 33fa51e2..00000000
--- a/frontend/tsconfig.node.tsbuildinfo
+++ /dev/null
@@ -1 +0,0 @@
-{"root":["./vite.config.mts"],"version":"5.6.2"}
\ No newline at end of file
From 86a8965466e78d973dcf3150b059ee099ed9f081 Mon Sep 17 00:00:00 2001
From: jeafreezy
Date: Thu, 3 Oct 2024 09:26:16 +0200
Subject: [PATCH 04/26] feat: models page wip
---
frontend/README.md | 17 +
frontend/eslint.config.js | 5 +-
frontend/package.json | 4 +
frontend/pnpm-lock.yaml | 476 ++++++++++++++++++
frontend/src/app/index.tsx | 9 +-
frontend/src/app/routes/models.tsx | 425 +++++++++++++++-
.../assets/fair_model_placeholder_image.png | Bin 0 -> 146433 bytes
frontend/src/components/models/index.ts | 1 -
frontend/src/components/models/model-card.tsx | 7 -
frontend/src/components/models/model-list.tsx | 7 -
frontend/src/components/models/skeleton.tsx | 30 --
frontend/src/components/ui/button/button.css | 3 +-
frontend/src/components/ui/button/button.tsx | 35 +-
.../src/components/ui/dropdown/dropdown.tsx | 36 +-
frontend/src/components/ui/form/index.ts | 2 +
.../components/ui/form/input/input.module.css | 23 +
.../src/components/ui/form/input/input.tsx | 28 ++
.../ui/form/switch/switch.module.css | 18 +
.../src/components/ui/form/switch/switch.tsx | 23 +
.../src/components/ui/header/user-profile.tsx | 19 +-
frontend/src/components/ui/icons/add-icon.tsx | 11 +
.../src/components/ui/icons/category-icon.tsx | 11 +
.../src/components/ui/icons/chevron-down.tsx | 2 +-
frontend/src/components/ui/icons/index.ts | 4 +
.../src/components/ui/icons/list-icon.tsx | 12 +
.../src/components/ui/icons/search-icon.tsx | 10 +
frontend/src/config/index.ts | 26 +
.../src/features/models/api/get-models.ts | 80 +++
.../src/features/models/components/index.ts | 3 +
.../features/models/components/model-card.tsx | 36 ++
.../features/models/components/model-list.tsx | 21 +
.../features/models/components/models-map.tsx | 163 ++++++
.../features/models/components/skeleton.tsx | 49 ++
frontend/src/hooks/use-debounce.ts | 18 +
frontend/src/hooks/use-dropdown-menu.ts | 20 +
frontend/src/services/api-routes.ts | 4 +
frontend/src/services/index.ts | 1 +
frontend/src/services/react-query.ts | 26 +
frontend/src/styles/index.css | 2 +-
frontend/src/types/api.ts | 26 +
frontend/src/utils/date-utils.ts | 3 +
frontend/src/utils/index.ts | 3 +-
frontend/tailwind.config.js | 1 +
43 files changed, 1609 insertions(+), 91 deletions(-)
create mode 100644 frontend/src/assets/fair_model_placeholder_image.png
delete mode 100644 frontend/src/components/models/index.ts
delete mode 100644 frontend/src/components/models/model-card.tsx
delete mode 100644 frontend/src/components/models/model-list.tsx
delete mode 100644 frontend/src/components/models/skeleton.tsx
create mode 100644 frontend/src/components/ui/form/index.ts
create mode 100644 frontend/src/components/ui/form/input/input.module.css
create mode 100644 frontend/src/components/ui/form/input/input.tsx
create mode 100644 frontend/src/components/ui/form/switch/switch.module.css
create mode 100644 frontend/src/components/ui/form/switch/switch.tsx
create mode 100644 frontend/src/components/ui/icons/add-icon.tsx
create mode 100644 frontend/src/components/ui/icons/category-icon.tsx
create mode 100644 frontend/src/components/ui/icons/list-icon.tsx
create mode 100644 frontend/src/components/ui/icons/search-icon.tsx
create mode 100644 frontend/src/config/index.ts
create mode 100644 frontend/src/features/models/api/get-models.ts
create mode 100644 frontend/src/features/models/components/index.ts
create mode 100644 frontend/src/features/models/components/model-card.tsx
create mode 100644 frontend/src/features/models/components/model-list.tsx
create mode 100644 frontend/src/features/models/components/models-map.tsx
create mode 100644 frontend/src/features/models/components/skeleton.tsx
create mode 100644 frontend/src/hooks/use-debounce.ts
create mode 100644 frontend/src/hooks/use-dropdown-menu.ts
create mode 100644 frontend/src/services/react-query.ts
create mode 100644 frontend/src/utils/date-utils.ts
diff --git a/frontend/README.md b/frontend/README.md
index 78c4fc98..5301bcd4 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -112,3 +112,20 @@ See [LICENSE](../LICENSE).
## Notes
The **@hotosm/ui** installation directory behavior is not consisitent and failed while deploying. However using the CDN and injecting it in the `index.html` works for now.
+
+
+# Todo
+- Table view and skeleton for list view
+- move texts to the content file
+- Error boundary
+- Componentize models page further if some component will be reused
+- revisit model card - clip long titles and descriptions (depends on limit set in form)
+- use tailwind cn where necessary
+- Reorganize things - move some things to config. Inspiration from TM.
+- move repeating styles to styles.css
+- abstract grid to e.g two-column, three-column etc
+- todo - use tab to indicate active page.
+
+## Note to Kshitij
+- Don't paginate centroids since it's geoson, there is no way to handle pagination on the map.
+ just return a feature collection straight.
\ No newline at end of file
diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js
index 79a552ea..8b94ffd7 100644
--- a/frontend/eslint.config.js
+++ b/frontend/eslint.config.js
@@ -7,7 +7,9 @@ import tseslint from "typescript-eslint";
export default tseslint.config(
{ ignores: ["dist"] },
{
- extends: [js.configs.recommended, ...tseslint.configs.recommended],
+ extends: [js.configs.recommended,
+ ...tseslint.configs.recommended,
+ "plugin:@tanstack/eslint-plugin-query/recommended", 'plugin:tailwindcss/recommended',],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
@@ -16,6 +18,7 @@ export default tseslint.config(
plugins: {
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
+ "@tanstack/query": "@tanstack/query"
},
rules: {
...reactHooks.configs.recommended.rules,
diff --git a/frontend/package.json b/frontend/package.json
index 9bef2737..8fafb0bc 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -11,9 +11,12 @@
},
"dependencies": {
"@shoelace-style/shoelace": "^2.16.0",
+ "@tanstack/react-query": "^5.59.0",
+ "@tanstack/react-query-devtools": "^5.59.0",
"axios": "^1.7.7",
"clsx": "^2.1.1",
"framer-motion": "^11.5.4",
+ "maplibre-gl": "^4.7.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^4.0.13",
@@ -23,6 +26,7 @@
},
"devDependencies": {
"@eslint/js": "^9.9.0",
+ "@tanstack/eslint-plugin-query": "^5.58.1",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml
index ee512a42..5568e397 100644
--- a/frontend/pnpm-lock.yaml
+++ b/frontend/pnpm-lock.yaml
@@ -11,6 +11,12 @@ importers:
'@shoelace-style/shoelace':
specifier: ^2.16.0
version: 2.17.1(@types/react@18.3.10)
+ '@tanstack/react-query':
+ specifier: ^5.59.0
+ version: 5.59.0(react@18.3.1)
+ '@tanstack/react-query-devtools':
+ specifier: ^5.59.0
+ version: 5.59.0(@tanstack/react-query@5.59.0(react@18.3.1))(react@18.3.1)
axios:
specifier: ^1.7.7
version: 1.7.7
@@ -20,6 +26,9 @@ importers:
framer-motion:
specifier: ^11.5.4
version: 11.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ maplibre-gl:
+ specifier: ^4.7.1
+ version: 4.7.1
react:
specifier: ^18.3.1
version: 18.3.1
@@ -42,6 +51,9 @@ importers:
'@eslint/js':
specifier: ^9.9.0
version: 9.11.1
+ '@tanstack/eslint-plugin-query':
+ specifier: ^5.58.1
+ version: 5.58.1(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2)
'@types/react':
specifier: ^18.3.3
version: 18.3.10
@@ -421,6 +433,34 @@ packages:
'@lit/reactive-element@2.0.4':
resolution: {integrity: sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==}
+ '@mapbox/geojson-rewind@0.5.2':
+ resolution: {integrity: sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==}
+ hasBin: true
+
+ '@mapbox/jsonlint-lines-primitives@2.0.2':
+ resolution: {integrity: sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==}
+ engines: {node: '>= 0.6'}
+
+ '@mapbox/point-geometry@0.1.0':
+ resolution: {integrity: sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==}
+
+ '@mapbox/tiny-sdf@2.0.6':
+ resolution: {integrity: sha512-qMqa27TLw+ZQz5Jk+RcwZGH7BQf5G/TrutJhspsca/3SHwmgKQ1iq+d3Jxz5oysPVYTGP6aXxCo5Lk9Er6YBAA==}
+
+ '@mapbox/unitbezier@0.0.1':
+ resolution: {integrity: sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==}
+
+ '@mapbox/vector-tile@1.3.1':
+ resolution: {integrity: sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==}
+
+ '@mapbox/whoots-js@3.1.0':
+ resolution: {integrity: sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==}
+ engines: {node: '>=6.0.0'}
+
+ '@maplibre/maplibre-gl-style-spec@20.3.1':
+ resolution: {integrity: sha512-5ueL4UDitzVtceQ8J4kY+Px3WK+eZTsmGwha3MBKHKqiHvKrjWWwBCIl1K8BuJSc5OFh83uI8IFNoFvQxX2uUw==}
+ hasBin: true
+
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -535,6 +575,28 @@ packages:
resolution: {integrity: sha512-fB9+bPHLg5zVwPbBKEqY3ghyttkJq9RuUzFMTZKweKrNKKDMUACtI8DlMYUqNwpdZMJhf7a0xeak6vFVBSxcbQ==}
engines: {node: '>=14.17.0'}
+ '@tanstack/eslint-plugin-query@5.58.1':
+ resolution: {integrity: sha512-hJR3N5ilK60gCgDWr7pWHV/vDiDVczT95F8AGIcg1gf9117aLPK+LDu+xP2JuEWpWKpsQ6OpWdVMim9kKlMybw==}
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0
+
+ '@tanstack/query-core@5.59.0':
+ resolution: {integrity: sha512-WGD8uIhX6/deH/tkZqPNcRyAhDUqs729bWKoByYHSogcshXfFbppOdTER5+qY7mFvu8KEFJwT0nxr8RfPTVh0Q==}
+
+ '@tanstack/query-devtools@5.58.0':
+ resolution: {integrity: sha512-iFdQEFXaYYxqgrv63ots+65FGI+tNp5ZS5PdMU1DWisxk3fez5HG3FyVlbUva+RdYS5hSLbxZ9aw3yEs97GNTw==}
+
+ '@tanstack/react-query-devtools@5.59.0':
+ resolution: {integrity: sha512-Kz7577FQGU8qmJxROIT/aOwmkTcxfBqgTP6r1AIvuJxVMVHPkp8eQxWQ7BnfBsy/KTJHiV9vMtRVo1+R1tB3vg==}
+ peerDependencies:
+ '@tanstack/react-query': ^5.59.0
+ react: ^18 || ^19
+
+ '@tanstack/react-query@5.59.0':
+ resolution: {integrity: sha512-YDXp3OORbYR+8HNQx+lf4F73NoiCmCcSvZvgxE29OifmQFk0sBlO26NWLHpcNERo92tVk3w+JQ53/vkcRUY1hA==}
+ peerDependencies:
+ react: ^18 || ^19
+
'@types/babel__core@7.20.5':
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
@@ -550,9 +612,24 @@ packages:
'@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
+ '@types/geojson-vt@3.2.5':
+ resolution: {integrity: sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==}
+
+ '@types/geojson@7946.0.14':
+ resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==}
+
'@types/json-schema@7.0.15':
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
+ '@types/mapbox__point-geometry@0.1.4':
+ resolution: {integrity: sha512-mUWlSxAmYLfwnRBmgYV86tgYmMIICX4kza8YnE/eIlywGe2XoOxlpVnXWwir92xRLjwyarqwpu2EJKD2pk0IUA==}
+
+ '@types/mapbox__vector-tile@1.3.4':
+ resolution: {integrity: sha512-bpd8dRn9pr6xKvuEBQup8pwQfD4VUyqO/2deGjfpe6AwC8YRlyEipvefyRJUSiCJTZuCb8Pl1ciVV5ekqJ96Bg==}
+
+ '@types/pbf@3.0.5':
+ resolution: {integrity: sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA==}
+
'@types/prop-types@15.7.13':
resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==}
@@ -562,6 +639,9 @@ packages:
'@types/react@18.3.10':
resolution: {integrity: sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==}
+ '@types/supercluster@7.1.3':
+ resolution: {integrity: sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==}
+
'@types/trusted-types@2.0.7':
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
@@ -674,6 +754,14 @@ packages:
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+ arr-union@3.1.0:
+ resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==}
+ engines: {node: '>=0.10.0'}
+
+ assign-symbols@1.0.0:
+ resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==}
+ engines: {node: '>=0.10.0'}
+
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
@@ -709,6 +797,12 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
+ bytewise-core@1.2.3:
+ resolution: {integrity: sha512-nZD//kc78OOxeYtRlVk8/zXqTB4gf/nlguL1ggWA8FuchMyOxcyHR4QPQZMUmA7czC+YnaBrPUCubqAWe50DaA==}
+
+ bytewise@1.1.0:
+ resolution: {integrity: sha512-rHuuseJ9iQ0na6UDhnrRVDh8YnWVlU6xM3VH6q/+yHDeUH2zIhUzP+2/h3LIrhLDBtTqzWpE3p3tP/boefskKQ==}
+
callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
@@ -800,6 +894,9 @@ packages:
dlv@1.1.3:
resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+ earcut@3.0.0:
+ resolution: {integrity: sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==}
+
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
@@ -902,6 +999,14 @@ packages:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
+ extend-shallow@2.0.1:
+ resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
+ engines: {node: '>=0.10.0'}
+
+ extend-shallow@3.0.2:
+ resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==}
+ engines: {node: '>=0.10.0'}
+
fast-deep-equal@3.1.3:
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
@@ -986,6 +1091,20 @@ packages:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
+ geojson-vt@4.0.2:
+ resolution: {integrity: sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==}
+
+ get-stream@6.0.1:
+ resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
+ engines: {node: '>=10'}
+
+ get-value@2.0.6:
+ resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==}
+ engines: {node: '>=0.10.0'}
+
+ gl-matrix@3.4.3:
+ resolution: {integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==}
+
glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -998,6 +1117,10 @@ packages:
resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
hasBin: true
+ global-prefix@4.0.0:
+ resolution: {integrity: sha512-w0Uf9Y9/nyHinEk5vMJKRie+wa4kR5hmDbEhGGds/kG1PwGLLHKRoNMeJOyCQjjBkANlnScqgzcFwGHgmgLkVA==}
+ engines: {node: '>=16'}
+
globals@11.12.0:
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
engines: {node: '>=4'}
@@ -1028,6 +1151,9 @@ packages:
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
engines: {node: '>= 0.4'}
+ ieee754@1.2.1:
+ resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+
ignore@5.3.2:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'}
@@ -1040,6 +1166,10 @@ packages:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
+ ini@4.1.3:
+ resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==}
+ engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+
invariant@2.2.4:
resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==}
@@ -1051,6 +1181,14 @@ packages:
resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
engines: {node: '>= 0.4'}
+ is-extendable@0.1.1:
+ resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
+ engines: {node: '>=0.10.0'}
+
+ is-extendable@1.0.1:
+ resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==}
+ engines: {node: '>=0.10.0'}
+
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@@ -1071,9 +1209,21 @@ packages:
resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
engines: {node: '>=8'}
+ is-plain-object@2.0.4:
+ resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==}
+ engines: {node: '>=0.10.0'}
+
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+ isexe@3.1.1:
+ resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==}
+ engines: {node: '>=16'}
+
+ isobject@3.0.1:
+ resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
+ engines: {node: '>=0.10.0'}
+
jackspeak@3.4.3:
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
@@ -1102,14 +1252,24 @@ packages:
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
+ json-stringify-pretty-compact@4.0.0:
+ resolution: {integrity: sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==}
+
json5@2.2.3:
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
engines: {node: '>=6'}
hasBin: true
+ kdbush@4.0.2:
+ resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==}
+
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
+ kind-of@6.0.3:
+ resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
+ engines: {node: '>=0.10.0'}
+
levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@@ -1151,6 +1311,10 @@ packages:
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+ maplibre-gl@4.7.1:
+ resolution: {integrity: sha512-lgL7XpIwsgICiL82ITplfS7IGwrB1OJIw/pCvprDp2dhmSSEBgmPzYRvwYYYvJGJD7fxUv1Tvpih4nZ6VrLuaA==}
+ engines: {node: '>=16.14.0', npm: '>=8.1.0'}
+
merge2@1.4.1:
resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
engines: {node: '>= 8'}
@@ -1174,6 +1338,9 @@ packages:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
minipass@7.1.2:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -1181,6 +1348,9 @@ packages:
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ murmurhash-js@1.0.0:
+ resolution: {integrity: sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==}
+
mz@2.7.0:
resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
@@ -1245,6 +1415,10 @@ packages:
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
engines: {node: '>=16 || 14 >=14.18'}
+ pbf@3.3.0:
+ resolution: {integrity: sha512-XDF38WCH3z5OV/OVa8GKUNtLAyneuzbCisx7QUCF8Q6Nutx0WnJrQe5O+kOtBlLfRNUws98Y58Lblp+NJG5T4Q==}
+ hasBin: true
+
picocolors@1.1.0:
resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
@@ -1301,6 +1475,9 @@ packages:
resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==}
engines: {node: ^10 || ^12 || >=14}
+ potpack@2.0.0:
+ resolution: {integrity: sha512-Q+/tYsFU9r7xoOJ+y/ZTtdVQwTWfzjbiXBDMM/JKUux3+QPP02iUuIoeBQ+Ot6oEDlC+/PGjB/5A3K7KKb7hcw==}
+
prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
@@ -1314,6 +1491,9 @@ packages:
engines: {node: '>=14'}
hasBin: true
+ protocol-buffers-schema@3.6.0:
+ resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==}
+
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
@@ -1327,6 +1507,12 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ quickselect@2.0.0:
+ resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==}
+
+ quickselect@3.0.0:
+ resolution: {integrity: sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==}
+
react-dom@18.3.1:
resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==}
peerDependencies:
@@ -1380,6 +1566,9 @@ packages:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
+ resolve-protobuf-schema@2.1.0:
+ resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==}
+
resolve@1.22.8:
resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
hasBin: true
@@ -1396,6 +1585,9 @@ packages:
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+ rw@1.3.3:
+ resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
+
scheduler@0.23.2:
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
@@ -1408,6 +1600,10 @@ packages:
engines: {node: '>=10'}
hasBin: true
+ set-value@2.0.1:
+ resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
+ engines: {node: '>=0.10.0'}
+
shallowequal@1.1.0:
resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==}
@@ -1423,10 +1619,26 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
+ sort-asc@0.2.0:
+ resolution: {integrity: sha512-umMGhjPeHAI6YjABoSTrFp2zaBtXBej1a0yKkuMUyjjqu6FJsTF+JYwCswWDg+zJfk/5npWUUbd33HH/WLzpaA==}
+ engines: {node: '>=0.10.0'}
+
+ sort-desc@0.2.0:
+ resolution: {integrity: sha512-NqZqyvL4VPW+RAxxXnB8gvE1kyikh8+pR+T+CXLksVRN9eiQqkQlPwqWYU0mF9Jm7UnctShlxLyAt1CaBOTL1w==}
+ engines: {node: '>=0.10.0'}
+
+ sort-object@3.0.3:
+ resolution: {integrity: sha512-nK7WOY8jik6zaG9CRwZTaD5O7ETWDLZYMM12pqY8htll+7dYeqGfEUPcUBHOpSJg2vJOrvFIY2Dl5cX2ih1hAQ==}
+ engines: {node: '>=0.10.0'}
+
source-map-js@1.2.1:
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
engines: {node: '>=0.10.0'}
+ split-string@3.1.0:
+ resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==}
+ engines: {node: '>=0.10.0'}
+
string-width@4.2.3:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
@@ -1452,6 +1664,9 @@ packages:
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
+ supercluster@8.0.1:
+ resolution: {integrity: sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==}
+
supports-color@5.5.0:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
@@ -1486,6 +1701,9 @@ packages:
thenify@3.3.1:
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+ tinyqueue@3.0.0:
+ resolution: {integrity: sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==}
+
to-fast-properties@2.0.0:
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
engines: {node: '>=4'}
@@ -1534,6 +1752,16 @@ packages:
engines: {node: '>=14.17'}
hasBin: true
+ typewise-core@1.2.0:
+ resolution: {integrity: sha512-2SCC/WLzj2SbUwzFOzqMCkz5amXLlxtJqDKTICqg30x+2DZxcfZN2MvQZmGfXWKNWaKK9pBPsvkcwv8bF/gxKg==}
+
+ typewise@1.0.3:
+ resolution: {integrity: sha512-aXofE06xGhaQSPzt8hlTY+/YWQhm9P0jYUp1f2XtmW/3Bk0qzXcyFWAtPoo2uTGQj1ZwbDuSyuxicq+aDo8lCQ==}
+
+ union-value@1.0.1:
+ resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==}
+ engines: {node: '>=0.10.0'}
+
update-browserslist-db@1.1.1:
resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
hasBin: true
@@ -1585,11 +1813,19 @@ packages:
terser:
optional: true
+ vt-pbf@3.1.3:
+ resolution: {integrity: sha512-2LzDFzt0mZKZ9IpVF2r69G9bXaP2Q2sArJCmcCgvfTdCCZzSyz4aCLoQyUilu37Ll56tCblIZrXFIjNUpGIlmA==}
+
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
hasBin: true
+ which@4.0.0:
+ resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==}
+ engines: {node: ^16.13.0 || >=18.0.0}
+ hasBin: true
+
word-wrap@1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
@@ -1912,6 +2148,36 @@ snapshots:
dependencies:
'@lit-labs/ssr-dom-shim': 1.2.1
+ '@mapbox/geojson-rewind@0.5.2':
+ dependencies:
+ get-stream: 6.0.1
+ minimist: 1.2.8
+
+ '@mapbox/jsonlint-lines-primitives@2.0.2': {}
+
+ '@mapbox/point-geometry@0.1.0': {}
+
+ '@mapbox/tiny-sdf@2.0.6': {}
+
+ '@mapbox/unitbezier@0.0.1': {}
+
+ '@mapbox/vector-tile@1.3.1':
+ dependencies:
+ '@mapbox/point-geometry': 0.1.0
+
+ '@mapbox/whoots-js@3.1.0': {}
+
+ '@maplibre/maplibre-gl-style-spec@20.3.1':
+ dependencies:
+ '@mapbox/jsonlint-lines-primitives': 2.0.2
+ '@mapbox/unitbezier': 0.0.1
+ json-stringify-pretty-compact: 4.0.0
+ minimist: 1.2.8
+ quickselect: 2.0.0
+ rw: 1.3.3
+ sort-object: 3.0.3
+ tinyqueue: 3.0.0
+
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -1996,6 +2262,29 @@ snapshots:
transitivePeerDependencies:
- '@types/react'
+ '@tanstack/eslint-plugin-query@5.58.1(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2)':
+ dependencies:
+ '@typescript-eslint/utils': 8.8.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2)
+ eslint: 9.11.1(jiti@1.21.6)
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
+ '@tanstack/query-core@5.59.0': {}
+
+ '@tanstack/query-devtools@5.58.0': {}
+
+ '@tanstack/react-query-devtools@5.59.0(@tanstack/react-query@5.59.0(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@tanstack/query-devtools': 5.58.0
+ '@tanstack/react-query': 5.59.0(react@18.3.1)
+ react: 18.3.1
+
+ '@tanstack/react-query@5.59.0(react@18.3.1)':
+ dependencies:
+ '@tanstack/query-core': 5.59.0
+ react: 18.3.1
+
'@types/babel__core@7.20.5':
dependencies:
'@babel/parser': 7.25.6
@@ -2019,8 +2308,24 @@ snapshots:
'@types/estree@1.0.6': {}
+ '@types/geojson-vt@3.2.5':
+ dependencies:
+ '@types/geojson': 7946.0.14
+
+ '@types/geojson@7946.0.14': {}
+
'@types/json-schema@7.0.15': {}
+ '@types/mapbox__point-geometry@0.1.4': {}
+
+ '@types/mapbox__vector-tile@1.3.4':
+ dependencies:
+ '@types/geojson': 7946.0.14
+ '@types/mapbox__point-geometry': 0.1.4
+ '@types/pbf': 3.0.5
+
+ '@types/pbf@3.0.5': {}
+
'@types/prop-types@15.7.13': {}
'@types/react-dom@18.3.0':
@@ -2032,6 +2337,10 @@ snapshots:
'@types/prop-types': 15.7.13
csstype: 3.1.3
+ '@types/supercluster@7.1.3':
+ dependencies:
+ '@types/geojson': 7946.0.14
+
'@types/trusted-types@2.0.7': {}
'@typescript-eslint/eslint-plugin@8.8.0(@typescript-eslint/parser@8.8.0(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2))(eslint@9.11.1(jiti@1.21.6))(typescript@5.6.2)':
@@ -2164,6 +2473,10 @@ snapshots:
argparse@2.0.1: {}
+ arr-union@3.1.0: {}
+
+ assign-symbols@1.0.0: {}
+
asynckit@0.4.0: {}
autoprefixer@10.4.20(postcss@8.4.47):
@@ -2208,6 +2521,15 @@ snapshots:
node-releases: 2.0.18
update-browserslist-db: 1.1.1(browserslist@4.24.0)
+ bytewise-core@1.2.3:
+ dependencies:
+ typewise-core: 1.2.0
+
+ bytewise@1.1.0:
+ dependencies:
+ bytewise-core: 1.2.3
+ typewise: 1.0.3
+
callsites@3.1.0: {}
camelcase-css@2.0.1: {}
@@ -2285,6 +2607,8 @@ snapshots:
dlv@1.1.3: {}
+ earcut@3.0.0: {}
+
eastasianwidth@0.2.0: {}
electron-to-chromium@1.5.30: {}
@@ -2417,6 +2741,15 @@ snapshots:
esutils@2.0.3: {}
+ extend-shallow@2.0.1:
+ dependencies:
+ is-extendable: 0.1.1
+
+ extend-shallow@3.0.2:
+ dependencies:
+ assign-symbols: 1.0.0
+ is-extendable: 1.0.1
+
fast-deep-equal@3.1.3: {}
fast-diff@1.3.0: {}
@@ -2486,6 +2819,14 @@ snapshots:
gensync@1.0.0-beta.2: {}
+ geojson-vt@4.0.2: {}
+
+ get-stream@6.0.1: {}
+
+ get-value@2.0.6: {}
+
+ gl-matrix@3.4.3: {}
+
glob-parent@5.1.2:
dependencies:
is-glob: 4.0.3
@@ -2503,6 +2844,12 @@ snapshots:
package-json-from-dist: 1.0.1
path-scurry: 1.11.1
+ global-prefix@4.0.0:
+ dependencies:
+ ini: 4.1.3
+ kind-of: 6.0.3
+ which: 4.0.0
+
globals@11.12.0: {}
globals@14.0.0: {}
@@ -2521,6 +2868,8 @@ snapshots:
dependencies:
function-bind: 1.1.2
+ ieee754@1.2.1: {}
+
ignore@5.3.2: {}
import-fresh@3.3.0:
@@ -2530,6 +2879,8 @@ snapshots:
imurmurhash@0.1.4: {}
+ ini@4.1.3: {}
+
invariant@2.2.4:
dependencies:
loose-envify: 1.4.0
@@ -2542,6 +2893,12 @@ snapshots:
dependencies:
hasown: 2.0.2
+ is-extendable@0.1.1: {}
+
+ is-extendable@1.0.1:
+ dependencies:
+ is-plain-object: 2.0.4
+
is-extglob@2.1.1: {}
is-fullwidth-code-point@3.0.0: {}
@@ -2554,8 +2911,16 @@ snapshots:
is-path-inside@3.0.3: {}
+ is-plain-object@2.0.4:
+ dependencies:
+ isobject: 3.0.1
+
isexe@2.0.0: {}
+ isexe@3.1.1: {}
+
+ isobject@3.0.1: {}
+
jackspeak@3.4.3:
dependencies:
'@isaacs/cliui': 8.0.2
@@ -2578,12 +2943,18 @@ snapshots:
json-stable-stringify-without-jsonify@1.0.1: {}
+ json-stringify-pretty-compact@4.0.0: {}
+
json5@2.2.3: {}
+ kdbush@4.0.2: {}
+
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
+ kind-of@6.0.3: {}
+
levn@0.4.1:
dependencies:
prelude-ls: 1.2.1
@@ -2627,6 +2998,35 @@ snapshots:
dependencies:
yallist: 3.1.1
+ maplibre-gl@4.7.1:
+ dependencies:
+ '@mapbox/geojson-rewind': 0.5.2
+ '@mapbox/jsonlint-lines-primitives': 2.0.2
+ '@mapbox/point-geometry': 0.1.0
+ '@mapbox/tiny-sdf': 2.0.6
+ '@mapbox/unitbezier': 0.0.1
+ '@mapbox/vector-tile': 1.3.1
+ '@mapbox/whoots-js': 3.1.0
+ '@maplibre/maplibre-gl-style-spec': 20.3.1
+ '@types/geojson': 7946.0.14
+ '@types/geojson-vt': 3.2.5
+ '@types/mapbox__point-geometry': 0.1.4
+ '@types/mapbox__vector-tile': 1.3.4
+ '@types/pbf': 3.0.5
+ '@types/supercluster': 7.1.3
+ earcut: 3.0.0
+ geojson-vt: 4.0.2
+ gl-matrix: 3.4.3
+ global-prefix: 4.0.0
+ kdbush: 4.0.2
+ murmurhash-js: 1.0.0
+ pbf: 3.3.0
+ potpack: 2.0.0
+ quickselect: 3.0.0
+ supercluster: 8.0.1
+ tinyqueue: 3.0.0
+ vt-pbf: 3.1.3
+
merge2@1.4.1: {}
micromatch@4.0.8:
@@ -2648,10 +3048,14 @@ snapshots:
dependencies:
brace-expansion: 2.0.1
+ minimist@1.2.8: {}
+
minipass@7.1.2: {}
ms@2.1.3: {}
+ murmurhash-js@1.0.0: {}
+
mz@2.7.0:
dependencies:
any-promise: 1.3.0
@@ -2706,6 +3110,11 @@ snapshots:
lru-cache: 10.4.3
minipass: 7.1.2
+ pbf@3.3.0:
+ dependencies:
+ ieee754: 1.2.1
+ resolve-protobuf-schema: 2.1.0
+
picocolors@1.1.0: {}
picomatch@2.3.1: {}
@@ -2751,6 +3160,8 @@ snapshots:
picocolors: 1.1.0
source-map-js: 1.2.1
+ potpack@2.0.0: {}
+
prelude-ls@1.2.1: {}
prettier-linter-helpers@1.0.0:
@@ -2759,6 +3170,8 @@ snapshots:
prettier@3.3.3: {}
+ protocol-buffers-schema@3.6.0: {}
+
proxy-from-env@1.1.0: {}
punycode@2.3.1: {}
@@ -2767,6 +3180,10 @@ snapshots:
queue-microtask@1.2.3: {}
+ quickselect@2.0.0: {}
+
+ quickselect@3.0.0: {}
+
react-dom@18.3.1(react@18.3.1):
dependencies:
loose-envify: 1.4.0
@@ -2817,6 +3234,10 @@ snapshots:
resolve-from@4.0.0: {}
+ resolve-protobuf-schema@2.1.0:
+ dependencies:
+ protocol-buffers-schema: 3.6.0
+
resolve@1.22.8:
dependencies:
is-core-module: 2.15.1
@@ -2851,6 +3272,8 @@ snapshots:
dependencies:
queue-microtask: 1.2.3
+ rw@1.3.3: {}
+
scheduler@0.23.2:
dependencies:
loose-envify: 1.4.0
@@ -2859,6 +3282,13 @@ snapshots:
semver@7.6.3: {}
+ set-value@2.0.1:
+ dependencies:
+ extend-shallow: 2.0.1
+ is-extendable: 0.1.1
+ is-plain-object: 2.0.4
+ split-string: 3.1.0
+
shallowequal@1.1.0: {}
shebang-command@2.0.0:
@@ -2869,8 +3299,25 @@ snapshots:
signal-exit@4.1.0: {}
+ sort-asc@0.2.0: {}
+
+ sort-desc@0.2.0: {}
+
+ sort-object@3.0.3:
+ dependencies:
+ bytewise: 1.1.0
+ get-value: 2.0.6
+ is-extendable: 0.1.1
+ sort-asc: 0.2.0
+ sort-desc: 0.2.0
+ union-value: 1.0.1
+
source-map-js@1.2.1: {}
+ split-string@3.1.0:
+ dependencies:
+ extend-shallow: 3.0.2
+
string-width@4.2.3:
dependencies:
emoji-regex: 8.0.0
@@ -2903,6 +3350,10 @@ snapshots:
pirates: 4.0.6
ts-interface-checker: 0.1.13
+ supercluster@8.0.1:
+ dependencies:
+ kdbush: 4.0.2
+
supports-color@5.5.0:
dependencies:
has-flag: 3.0.0
@@ -2957,6 +3408,8 @@ snapshots:
dependencies:
any-promise: 1.3.0
+ tinyqueue@3.0.0: {}
+
to-fast-properties@2.0.0: {}
to-regex-range@5.0.1:
@@ -2992,6 +3445,19 @@ snapshots:
typescript@5.6.2: {}
+ typewise-core@1.2.0: {}
+
+ typewise@1.0.3:
+ dependencies:
+ typewise-core: 1.2.0
+
+ union-value@1.0.1:
+ dependencies:
+ arr-union: 3.1.0
+ get-value: 2.0.6
+ is-extendable: 0.1.1
+ set-value: 2.0.1
+
update-browserslist-db@1.1.1(browserslist@4.24.0):
dependencies:
browserslist: 4.24.0
@@ -3023,10 +3489,20 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
+ vt-pbf@3.1.3:
+ dependencies:
+ '@mapbox/point-geometry': 0.1.0
+ '@mapbox/vector-tile': 1.3.1
+ pbf: 3.3.0
+
which@2.0.2:
dependencies:
isexe: 2.0.0
+ which@4.0.0:
+ dependencies:
+ isexe: 3.1.1
+
word-wrap@1.2.5: {}
wrap-ansi@7.0.0:
diff --git a/frontend/src/app/index.tsx b/frontend/src/app/index.tsx
index d60b5c8d..449788f6 100644
--- a/frontend/src/app/index.tsx
+++ b/frontend/src/app/index.tsx
@@ -6,6 +6,8 @@ import { MainErrorFallback } from "@/components/errors";
import { ToastProvider } from "@/app/providers/toast-provider";
import { useEffect } from "react";
import { ENVS } from "@/config/env";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
export const App = () => {
@@ -26,13 +28,16 @@ export const App = () => {
setupHotTracking();
return
}, []);
-
+ const queryClient = new QueryClient();
return (
-
+
+
+
+
diff --git a/frontend/src/app/routes/models.tsx b/frontend/src/app/routes/models.tsx
index 03f9a461..9c8e5bd9 100644
--- a/frontend/src/app/routes/models.tsx
+++ b/frontend/src/app/routes/models.tsx
@@ -1,10 +1,427 @@
-import { ModelsPageSkeleton } from "@/components/models"
+import { useModels, useModelsMapData } from "@/features/models/api/get-models";
+import { ModelsPageSkeleton } from "@/features/models/components"
+import { useToast } from "@/app/providers/toast-provider";
+import { useCallback, useEffect, useState } from "react";
+import { useSearchParams } from "react-router-dom";
+import { Button } from "@/components/ui/button";
+import { CategoryIcon, ListIcon, SearchIcon } from "@/components/ui/icons";
+import { DropDown } from "@/components/ui/dropdown";
+import { DropdownMenuItem } from "@/components/ui/dropdown/dropdown";
+import { useDropdownMenu } from "@/hooks/use-dropdown-menu";
+import { Input, Switch } from "@/components/ui/form";
+import { ModelList, ModelsMap } from "@/features/models/components";
+import useDebounce from "@/hooks/use-debounce";
+import ChevronDownIcon from "@/components/ui/icons/chevron-down";
+
+
+export enum LayoutView {
+ LIST = 'list',
+ GRID = 'grid'
+}
+
+const PAGE_LIMIT = 20;
export const ModelsPage = () => {
+
+ const { notify } = useToast();
+
+ const [searchParams, setSearchParams] = useSearchParams();
+ const [offset, setOffset] = useState(Number(searchParams.get('offset')) || 0);
+ const [searchQuery, setSearchQuery] = useState(searchParams.get('q') || '');
+ const [category, setCategory] = useState(searchParams.get('category') || '');
+ const [date, setDate] = useState(searchParams.get('date') || '');
+ const [author, setAuthor] = useState(searchParams.get('author') || '');
+ const [mapview, setMapview] = useState(searchParams.get('map') === 'true');
+ const [layoutView, setLayoutView] = useState(
+ //default to grid
+ searchParams.get('view') === 'list' ? LayoutView.LIST : LayoutView.GRID
+ );
+
+
+ const debouncedSearchTerm = useDebounce(searchQuery, 300);
+
+ const { data, isPending, error, isPlaceholderData } = useModels({ searchQuery: debouncedSearchTerm, limit: PAGE_LIMIT, offset });
+ const { data: mapData, isPending: modelMapDataIsPending, error: modelsMapDataError } = useModelsMapData()
+ console.log(mapData)
+ const handleNextPage = () => {
+ if (!isPlaceholderData && data?.hasNext) {
+ setOffset((prevOffset) => prevOffset + PAGE_LIMIT);
+ }
+ };
+
+ const handlePreviousPage = () => {
+ if (data?.hasPrev) {
+ setOffset((prevOffset) => Math.max(prevOffset - PAGE_LIMIT, 0));
+ }
+ };
+
+ // Can be moved to a hook later if it's needed to be used in another component.
+
+ useEffect(() => {
+ const params: any = {};
+ if (debouncedSearchTerm) params.q = debouncedSearchTerm;
+ if (category) params.category = category;
+ if (date) params.date = date;
+ if (author) params.author = author;
+ if (offset > 0) params.offset = String(offset);
+ params.map = mapview ? 'true' : 'false';
+ params.view = layoutView === LayoutView.GRID ? 'grid' : 'list';
+ setSearchParams(params);
+ }, [offset, debouncedSearchTerm, category, date, author, mapview, layoutView]);
+
+
+ // Category
+
+ const categoryFilters: DropdownMenuItem[] = [
+ {
+ value: 'Category1',
+ },
+ {
+ value: 'Category2',
+ }
+ ]
+
+ function handleCategorySelection(event: any) {
+ const selectedItem: DropdownMenuItem = event.detail.item;
+ setCategory(selectedItem.value)
+ }
+ const {
+ dropdownIsOpened: categoryDropdownMenuIsOpened,
+ onDropdownHide: onCategoryDropdownMenuHide,
+ onDropdownShow: onCategoryDropdownMenuShow
+ } = useDropdownMenu();
+
+ // Date
+
+ // todo - will it be a date picker?
+ const dateFilters: DropdownMenuItem[] = [
+ {
+ value: '2024/10/24',
+ },
+ {
+ value: '2025/10/23',
+ }
+ ]
+
+ function handleDateSelection(event: any) {
+ const selectedItem: DropdownMenuItem = event.detail.item;
+ setDate(selectedItem.value)
+ }
+ const {
+ dropdownIsOpened: dateDropdownMenuIsOpened,
+ onDropdownHide: onDateDropdownMenuHide,
+ onDropdownShow: onDateDropdownMenuShow
+ } = useDropdownMenu();
+
+ // Author
+ const authorFilters: DropdownMenuItem[] = [
+ {
+ value: 'Author 1',
+ },
+ {
+ value: 'Author 2',
+ }
+ ]
+
+ function handleAuthorSelection(event: any) {
+ const selectedItem: DropdownMenuItem = event.detail.item;
+ setAuthor(selectedItem.value)
+ }
+ const {
+ dropdownIsOpened: authorDropdownMenuIsOpened,
+ onDropdownHide: onAuthorDropdownMenuHide,
+ onDropdownShow: onAuthorDropdownMenuShow
+ } = useDropdownMenu();
+
+ // Search
+ const handleSearchInput = useCallback((event: any) => {
+ setSearchQuery(event.target.value)
+ }, [searchQuery]);
+
+ //layout
+ const handleLayoutView = () => {
+ setLayoutView(layoutView === LayoutView.GRID ? LayoutView.LIST : LayoutView.GRID)
+ }
+
+ // create the key using the filters
+
+ // handle error notification ? - handle here or from the query hook?
+ if (error) {
+ console.error(error);
+ notify('An error occured while fetching models. Please try again later.', 'danger');
+ }
+
return (
-
-
-
+
+ {/* Header */}
+
+ {/* Filters */}
+
+
+ {/* Paginator */}
+
+
+
+ {
+ isPending ?
+
:
+ mapview ?
+
+
+ {/* Filtered model result will be here. So column span will change to accommodate it. */}
+
+
+
+
+
+
:
+
+ }
+
+
);
};
+
+
+type PaginatorProps = {
+ isPending: boolean
+ totalLength?: number
+ parameter: string
+ offset: number,
+ hasNextPage?: boolean
+ hasPrevPage?: boolean
+ handleNextPage: () => void
+ handlePreviousPage: () => void
+ isPlaceholderData: boolean
+}
+const ModelPaginator: React.FC = (
+ { handleNextPage,
+ handlePreviousPage,
+ offset,
+ isPending,
+ totalLength,
+ parameter,
+ hasNextPage,
+ hasPrevPage, isPlaceholderData
+ }
+) => {
+
+ return (
+ <>
+ {
+ isPending ?
+
+ :
+
+
+
{totalLength} {parameter}
+
+
+
+ {offset + 1} - {offset + PAGE_LIMIT < totalLength ? offset + PAGE_LIMIT : totalLength} of {totalLength}
+
+
+
+
+
+
+
+
+
+
+
+ }
+ >
+ )
+}
+
+
+const ModelPageHeader = () => {
+ return (
+
+
+
+
fAIr AI models
+
+
+
+ Create Model
+
+
+
+
+ Each model is trained using one of the training datasets. Published models can be used to find mappable features in imagery that is similar to the training areas that dataset comes from.
+
+
+ )
+}
+
+type ModelPageFiltersProps = {
+ searchQuery: string
+ handleSearchInput: (args: string) => void
+ isPending: boolean
+ categoryFilters: DropdownMenuItem[]
+ categoryDropdownMenuIsOpened: boolean
+ onCategoryDropdownMenuShow: () => void
+ onCategoryDropdownMenuHide: () => void
+ handleCategorySelection: (event: any) => void
+ category: string
+ dateFilters: DropdownMenuItem[]
+ dateDropdownMenuIsOpened: boolean
+ onDateDropdownMenuHide: () => void
+ onDateDropdownMenuShow: () => void
+ handleDateSelection: (event: string) => void
+ date: string
+ author: string
+ authorFilters: DropdownMenuItem[]
+ mapview: boolean
+ authorDropdownMenuIsOpened: boolean
+ onAuthorDropdownMenuHide: () => void
+ onAuthorDropdownMenuShow: () => void
+ handleAuthorSelection: (arg: string) => void
+ setMapview: (arg: boolean) => void
+ layoutView: LayoutView
+ handleLayoutView: (event: any) => void
+
+}
+
+const ModelPageFilters: React.FC = (
+ { handleAuthorSelection,
+ onAuthorDropdownMenuShow,
+ onAuthorDropdownMenuHide,
+ setMapview,
+ authorDropdownMenuIsOpened,
+ mapview,
+ author,
+ authorFilters,
+ date,
+ handleDateSelection,
+ onDateDropdownMenuShow,
+ onDateDropdownMenuHide,
+ dateDropdownMenuIsOpened,
+ dateFilters,
+ category,
+ handleCategorySelection,
+ onCategoryDropdownMenuHide,
+ onCategoryDropdownMenuShow,
+ searchQuery,
+ handleSearchInput,
+ isPending,
+ categoryFilters,
+ categoryDropdownMenuIsOpened, layoutView, handleLayoutView }) => {
+ return (
+
+
+
+ {/* Search */}
+
+
+
+
+
+ {/* Categories */}
+
+
+ {category ? category : 'Category'}
+
+
+
+
+ {/* Date */}
+
+
+ {date ? date : 'Date'}
+
+
+
+ {/* Author */}
+
+
+ {author ? author : 'Author'}
+
+
+
+
+
+
+
+
Map View
+
{
+ setMapview(!mapview)
+ }} />
+
+
+ {layoutView !== LayoutView.LIST ? : }
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/frontend/src/assets/fair_model_placeholder_image.png b/frontend/src/assets/fair_model_placeholder_image.png
new file mode 100644
index 0000000000000000000000000000000000000000..c5ead12907720b28d118f2035448a6a6a5d8b4d9
GIT binary patch
literal 146433
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%0ATynurcn7pa9
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