mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
dynamic map creation
This commit is contained in:
parent
fce13e8be3
commit
8d07bd99f9
11
index.html
11
index.html
@ -3,12 +3,13 @@
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" href="/3markers-globe.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, interactive-widget=resizes-visual" />
|
||||
<meta name="description" content="Check out the Community Ecosystem Map">
|
||||
<title>Moos Ecosystem</title>
|
||||
<meta property="og:title" content="Community Map" />
|
||||
<meta property="og:description" content="Check out the Community Ecosystem Map" />
|
||||
<meta name="description" content="collaborative and interactive Maps for Utopians">
|
||||
<link rel="icon" type="image/png" href="/3markers-globe.svg" />
|
||||
<title>Utopia Map</title>
|
||||
|
||||
<meta property="og:title" content="Utopia Map" />
|
||||
<meta property="og:description" content="collaborative and interactive Maps for Utopians" />
|
||||
<meta property="og:image" content="/3markers-globe_256.png" />
|
||||
</head>
|
||||
|
||||
|
||||
96
package-lock.json
generated
96
package-lock.json
generated
@ -8,7 +8,7 @@
|
||||
"name": "utopia-game",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@directus/sdk": "^12.0.1",
|
||||
"@directus/sdk": "^13.0.2",
|
||||
"@heroicons/react": "^2.1.1",
|
||||
"@types/geojson": "^7946.0.10",
|
||||
"axios": "^1.6.5",
|
||||
@ -17,11 +17,11 @@
|
||||
"react-dom": "^18.2.0",
|
||||
"react-rnd": "^10.4.1",
|
||||
"react-router-dom": "^6.11.2",
|
||||
"utopia-ui": "^3.0.0-alpha.118"
|
||||
"utopia-ui": "^3.0.0-alpha.126"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.60",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"@types/react": "^18.2.79",
|
||||
"@types/react-dom": "^18.2.25",
|
||||
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
||||
"@typescript-eslint/parser": "^5.57.1",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
@ -1722,8 +1722,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@directus/sdk": {
|
||||
"version": "12.0.1",
|
||||
"license": "MIT",
|
||||
"version": "13.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@directus/sdk/-/sdk-13.0.2.tgz",
|
||||
"integrity": "sha512-KECQM0w8xlgr5EklX+Jb9+dIzXyvJFjRfhiIAI7l/b0WEtVaCfvRMIrJXR3XsLeVW9u2nu+b/TffOyTMSLjm2w==",
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
@ -1967,20 +1968,20 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/query-core": {
|
||||
"version": "5.28.9",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.28.9.tgz",
|
||||
"integrity": "sha512-hNlfCiqZevr3GRVPXS3MhaGW5hjcxvCsIQ4q6ff7EPlvFwYZaS+0d9EIIgofnegDaU2BbCDlyURoYfRl5rmzow==",
|
||||
"version": "5.32.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.32.0.tgz",
|
||||
"integrity": "sha512-Z3flEgCat55DRXU5UMwYU1U+DgFZKA3iufyOKs+II7iRAo0uXkeU7PH5e6sOH1CGEag0IpKmZxlUFpCg6roSKw==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/react-query": {
|
||||
"version": "5.28.9",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.28.9.tgz",
|
||||
"integrity": "sha512-vwifBkGXsydsLxFOBMe3+f8kvtDoqDRDwUNjPHVDDt+FoBetCbOWAUHgZn4k+CVeZgLmy7bx6aKeDbe3e8koOQ==",
|
||||
"version": "5.32.0",
|
||||
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.32.0.tgz",
|
||||
"integrity": "sha512-+E3UudQtarnx9A6xhpgMZapyF+aJfNBGFMgI459FnduEZqT/9KhOWnMOneZahLRt52yzskSA0AuOyLkXHK0yBA==",
|
||||
"dependencies": {
|
||||
"@tanstack/query-core": "5.28.9"
|
||||
"@tanstack/query-core": "5.32.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
@ -2055,19 +2056,19 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.2.60",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.60.tgz",
|
||||
"integrity": "sha512-dfiPj9+k20jJrLGOu9Nf6eqxm2EyJRrq2NvwOFsfbb7sFExZ9WELPs67UImHj3Ayxg8ruTtKtNnbjaF8olPq0A==",
|
||||
"version": "18.2.79",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.79.tgz",
|
||||
"integrity": "sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w==",
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "*",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-dom": {
|
||||
"version": "18.2.4",
|
||||
"version": "18.2.25",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.25.tgz",
|
||||
"integrity": "sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
@ -2080,10 +2081,6 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/scheduler": {
|
||||
"version": "0.16.3",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/semver": {
|
||||
"version": "7.5.0",
|
||||
"dev": true,
|
||||
@ -3706,6 +3703,19 @@
|
||||
"version": "1.0.0",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"license": "MIT"
|
||||
@ -4921,9 +4931,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromark-core-commonmark": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz",
|
||||
"integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.1.tgz",
|
||||
"integrity": "sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "GitHub Sponsors",
|
||||
@ -5257,9 +5267,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromark-util-subtokenize": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz",
|
||||
"integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.1.tgz",
|
||||
"integrity": "sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "GitHub Sponsors",
|
||||
@ -5755,9 +5765,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/property-information": {
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz",
|
||||
"integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==",
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz",
|
||||
"integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
@ -6481,9 +6491,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/stringify-entities": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz",
|
||||
"integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==",
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz",
|
||||
"integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==",
|
||||
"dependencies": {
|
||||
"character-entities-html4": "^2.0.0",
|
||||
"character-entities-legacy": "^3.0.0"
|
||||
@ -7005,9 +7015,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.0.4",
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz",
|
||||
"integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@ -7230,9 +7241,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/utopia-ui": {
|
||||
"version": "3.0.0-alpha.118",
|
||||
"resolved": "https://registry.npmjs.org/utopia-ui/-/utopia-ui-3.0.0-alpha.118.tgz",
|
||||
"integrity": "sha512-LKMSRCPr190sK3oFdt+AsL2jcLK3iOG4DZyaA/5LcpwjZypeMjSpakLrPrISdpECJExOm3HvrtT19ByI3BXBdQ==",
|
||||
"version": "3.0.0-alpha.126",
|
||||
"resolved": "https://registry.npmjs.org/utopia-ui/-/utopia-ui-3.0.0-alpha.126.tgz",
|
||||
"integrity": "sha512-RM4N4NNwLp+5fUwcboD/8Y7V/ocu9X3qEH/F5Isz45M7q3qymeshMn/ytQEvFdPKJq5aWBplvbnCYzfSUELqHw==",
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"@tanstack/react-query": "^5.17.8",
|
||||
@ -7287,9 +7298,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "4.5.2",
|
||||
"version": "4.5.3",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.5.3.tgz",
|
||||
"integrity": "sha512-kQL23kMeX92v3ph7IauVkXkikdDRsYMGTVl5KY2E9OY4ONLvkHf04MDTbnfo6NKxZiDLWzVpP5oTa8hQD8U3dg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.18.10",
|
||||
"postcss": "^8.4.27",
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@directus/sdk": "^12.0.1",
|
||||
"@directus/sdk": "^13.0.2",
|
||||
"@heroicons/react": "^2.1.1",
|
||||
"@types/geojson": "^7946.0.10",
|
||||
"axios": "^1.6.5",
|
||||
@ -19,11 +19,11 @@
|
||||
"react-dom": "^18.2.0",
|
||||
"react-rnd": "^10.4.1",
|
||||
"react-router-dom": "^6.11.2",
|
||||
"utopia-ui": "^3.0.0-alpha.118"
|
||||
"utopia-ui": "^3.0.0-alpha.126"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.60",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"@types/react": "^18.2.79",
|
||||
"@types/react-dom": "^18.2.25",
|
||||
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
||||
"@typescript-eslint/parser": "^5.57.1",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
|
||||
77
src/App.tsx
77
src/App.tsx
@ -12,6 +12,8 @@ import { useEffect, useState } from 'react'
|
||||
import { itemsApi } from './api/itemsApi'
|
||||
import { permissionsApi } from './api/permissionsApi'
|
||||
import { Tag } from 'utopia-ui/dist/types'
|
||||
import { mapApi } from './api/mapApi'
|
||||
import { layersApi } from './api/layersApi'
|
||||
|
||||
|
||||
function App() {
|
||||
@ -19,31 +21,78 @@ function App() {
|
||||
|
||||
const [permissionsApiInstance, setPermissionsApiInstance] = useState<permissionsApi>();
|
||||
const [tagsApi, setTagsApi] = useState<itemsApi<Tag>>();
|
||||
const [mapApiInstance, setMapApiInstance] = useState<mapApi>();
|
||||
const [layersApiInstance, setLayersApiInstance] = useState<layersApi>();
|
||||
const [map, setMap] = useState<any>();
|
||||
const [layers, setLayers] = useState<any>();
|
||||
const [layerPageRoutes, setLayerPageRoutes] = useState<any>();
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
setPermissionsApiInstance(new permissionsApi());
|
||||
setTagsApi(new itemsApi<Tag>('tags', undefined, "36fc9ba7-1a6b-4fc2-9db1-39d67aaf6918"));
|
||||
setMapApiInstance(new mapApi(window.location.origin));
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
mapApiInstance && getMap();
|
||||
}, [mapApiInstance])
|
||||
|
||||
return (
|
||||
|
||||
const getMap = async () => {
|
||||
const map = await mapApiInstance?.getItems();
|
||||
map && setMap(map);
|
||||
map && setLayersApiInstance(new layersApi(map.id));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
layersApiInstance && getLayers();
|
||||
}, [layersApiInstance])
|
||||
|
||||
|
||||
const getLayers = async () => {
|
||||
const layers = await layersApiInstance?.getItems();
|
||||
layers && setLayers(layers);
|
||||
setLayerPageRoutes(layers?.map((l: any) => ({
|
||||
path: '/' + l.name, // url
|
||||
icon: <img src={"https://api.utopia-lab.org/assets/" + l.indexIcon}></img>,
|
||||
name: l.name, // name that appear in Sidebar
|
||||
})));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if(map && map.name){
|
||||
document.title = map?.name && map.name;
|
||||
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement
|
||||
if (!link) {
|
||||
link = document.createElement('link');
|
||||
link.rel = 'icon';
|
||||
document.getElementsByTagName('head')[0].appendChild(link);
|
||||
}
|
||||
link.href = map?.logo && "https://api.utopia-lab.org/assets/"+map.logo; // Specify the path to your favicon
|
||||
|
||||
}
|
||||
|
||||
}, [map])
|
||||
|
||||
|
||||
|
||||
if (map && layers) return (
|
||||
|
||||
<div className="App overflow-x-hidden">
|
||||
|
||||
<AuthProvider userApi={new userApi}>
|
||||
<AppShell assetsApi={new assetsApi("https://api.utopia-lab.org/assets/")} appName="Community Map" nameWidth={220}>
|
||||
<AppShell assetsApi={new assetsApi("https://api.utopia-lab.org/assets/")} appName={map.name}>
|
||||
<Permissions api={permissionsApiInstance} adminRole='8ed0b24e-3320-48cd-8444-bc152304e580'></Permissions>
|
||||
<Tags api={tagsApi}></Tags>
|
||||
<Modal>
|
||||
<ModalContent />
|
||||
</Modal>
|
||||
<SideBar routes={routes} bottomRoutes={bottomRoutes} />
|
||||
<SideBar routes={[...routes, ...layerPageRoutes]} bottomRoutes={bottomRoutes} />
|
||||
<Content>
|
||||
<Quests />
|
||||
<Routes>
|
||||
<Route path="/*" element={<MapContainer />}>
|
||||
<Route path="/*" element={<MapContainer map={map} layers={layers} />}>
|
||||
<Route path='login' element={<LoginPage />} />
|
||||
<Route path='signup' element={<SignupPage />} />
|
||||
<Route path='reset-password' element={<RequestPasswordPage reset_url="https://map.collaborative-finance.org/set-new-password/" />} />
|
||||
@ -55,18 +104,26 @@ function App() {
|
||||
<Route path="user-settings" element={<OverlayUserSettings />} />
|
||||
<Route path="moon-calendar" element={<MoonCalendar />} />
|
||||
<Route path="landingpage" element={<Landingpage />} />
|
||||
<Route path="items" element={<OverlayItemsIndexPage type='project' breadcrumbs={[{ name: "Home", path: "/" }, { name: "Projects", path: "/items/" }]} itemNameField={'name'} itemTextField={'text'} itemImageField={'image'} url={'/item/'} parameterField={'id'} itemSymbolField={'symbol'} itemSubnameField={'subname'} />} />
|
||||
<Route path="calendar" element={<OverlayItemsIndexPage type="event" breadcrumbs={[{ name: "Home", path: "/" }, { name: "Events", path: "/calendar/" }]} itemNameField={'name'} itemTextField={'text'} itemImageField={'image'} url={'/item/'} parameterField={'id'} itemSymbolField={'symbol'} itemSubnameField={'subname'} />} />
|
||||
<Route path="community" element={<OverlayItemsIndexPage type='user' breadcrumbs={[{ name: "Home", path: "/" }, { name: "Community", path: "/community/" }]} itemNameField={'name'} itemTextField={'text'} itemImageField={'image'} url={'/item/'} parameterField={'id'} itemSymbolField={'symbol'} itemSubnameField={'subname'} plusButton={false}/>} />
|
||||
|
||||
{
|
||||
layers.map((l: any) =>
|
||||
<Route key={l.id} path={l.name} element={<OverlayItemsIndexPage layerName={l.name} breadcrumbs={[{ name: "Home", path: "/" }, { name: l.name, path: "/" + l.name }]} itemNameField={'name'} itemTextField={'text'} itemImageField={'image'} url={'/item/'} parameterField={'id'} itemSymbolField={'symbol'} itemSubnameField={'subname'} />} />
|
||||
)
|
||||
}
|
||||
</Route>
|
||||
|
||||
</Routes>
|
||||
</Content>
|
||||
</AppShell>
|
||||
</AuthProvider>
|
||||
</div>
|
||||
)
|
||||
|
||||
else return (
|
||||
<div className="flex items-center justify-center h-screen">
|
||||
<div>
|
||||
<p className='text-xl font-semibold'>This map does not exist</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
|
||||
25
src/api/layersApi.ts
Normal file
25
src/api/layersApi.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { readItems } from '@directus/sdk';
|
||||
import { directusClient } from './directus';
|
||||
|
||||
|
||||
|
||||
export class layersApi {
|
||||
mapId : string
|
||||
|
||||
constructor(mapId: string) {
|
||||
this.mapId = mapId;
|
||||
}
|
||||
|
||||
async getItems() {
|
||||
try {
|
||||
const layers = await directusClient.request(readItems("layers" as any, { fields: ['*', {itemType : ['*']}], filter: { "maps": { "maps_id": { "id": { "_eq": this.mapId } } } }, limit: 500 }));
|
||||
return layers;
|
||||
} catch (error: any) {
|
||||
console.log(error);
|
||||
if (error.errors[0]?.message)
|
||||
throw error.errors[0].message;
|
||||
else throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
25
src/api/mapApi.ts
Normal file
25
src/api/mapApi.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { readItems } from '@directus/sdk';
|
||||
import { directusClient } from './directus';
|
||||
|
||||
|
||||
|
||||
export class mapApi {
|
||||
url : string
|
||||
|
||||
constructor(url: string) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
async getItems() {
|
||||
try {
|
||||
const map = await directusClient.request(readItems("maps" as any, { fields: ['*'], filter: { "url": { "_eq": this.url } } as any, limit: 500 }));
|
||||
return map[0];
|
||||
} catch (error: any) {
|
||||
console.log(error);
|
||||
if (error.errors[0]?.message)
|
||||
throw error.errors[0].message;
|
||||
else throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,101 +1,73 @@
|
||||
import { UtopiaMap, Layer, ItemForm, ItemView, PopupTextAreaInput, PopupTextInput, PopupStartEndInput, TextView, StartEndView, PopupButton } from 'utopia-ui'
|
||||
import { UtopiaMap, Layer, ItemView, PopupButton, StartEndView, TextView, ItemForm, PopupStartEndInput, PopupTextAreaInput, PopupTextInput } from 'utopia-ui'
|
||||
import { itemsApi } from '../api/itemsApi';
|
||||
import { Place, Event } from '../api/directus';
|
||||
import { Place } from '../api/directus';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { CalendarDaysIcon, MapPinIcon, UserIcon } from '@heroicons/react/20/solid'
|
||||
import { LayerProps } from 'utopia-ui/dist/types';
|
||||
|
||||
function MapContainer() {
|
||||
type layerApi = {
|
||||
id: string;
|
||||
api: itemsApi<Place>
|
||||
}
|
||||
|
||||
const [placesApi, setPlacesApi] = useState<itemsApi<Place>>();
|
||||
const [eventsApi, setEventsApi] = useState<itemsApi<Event>>();
|
||||
const [updatesApiInstance, setUpdatesApiInstance] = useState<itemsApi<Place>>();
|
||||
function MapContainer({ layers, map }: { layers: Array<LayerProps>, map: any }) {
|
||||
const [apis, setApis] = useState<Array<layerApi>>([]);
|
||||
|
||||
useEffect(() => {
|
||||
setPlacesApi(new itemsApi<Place>('items', undefined, undefined, {"type":{"_eq":"project"}}, {type: "project", autogenerated: "false"}));
|
||||
setEventsApi(new itemsApi<Event>('items', undefined, undefined, {"type":{"_eq":"event"}}, {type: "event"}));
|
||||
setUpdatesApiInstance(new itemsApi<Event>('items', undefined, undefined, {"type":{"_eq":"user"}}, {type: "user"}));
|
||||
}, []);
|
||||
layers.map(layer => {
|
||||
apis && setApis(current => [...current, { id: layer.id!, api: new itemsApi<Place>('items', layer.id) }])
|
||||
})
|
||||
}, [layers])
|
||||
|
||||
useEffect(() => {
|
||||
}, [apis])
|
||||
|
||||
const icon = CalendarDaysIcon;
|
||||
|
||||
return (
|
||||
|
||||
<UtopiaMap zoom={12} height='calc(100dvh - 64px)' width="100%" center={[52.49, 13.46]}>
|
||||
<Layer
|
||||
name='Events'
|
||||
menuIcon={icon}
|
||||
menuText='add new event'
|
||||
menuColor='#f9a825'
|
||||
markerIcon='calendar-days-solid'
|
||||
markerShape='square'
|
||||
markerDefaultColor='#3D3846'
|
||||
itemType='event'
|
||||
itemAvatarField='image'
|
||||
itemSubnameField='subname'
|
||||
customEditLink='/edit-item'
|
||||
customEditParameter='id'
|
||||
// data={events}
|
||||
api={eventsApi}>
|
||||
<ItemForm>
|
||||
<PopupTextInput dataField='name' placeholder='Name'></PopupTextInput>
|
||||
<PopupStartEndInput></PopupStartEndInput>
|
||||
<PopupTextAreaInput dataField='text' placeholder={'Text ...'} style="tw-h-40"></PopupTextAreaInput>
|
||||
</ItemForm>
|
||||
<ItemView>
|
||||
<StartEndView></StartEndView>
|
||||
<TextView></TextView>
|
||||
</ItemView>
|
||||
</Layer>
|
||||
<Layer
|
||||
name='Projects'
|
||||
menuIcon={MapPinIcon}
|
||||
menuText='add new project'
|
||||
menuColor='#2E7D32'
|
||||
markerIcon='circle-solid'
|
||||
markerShape='circle'
|
||||
markerDefaultColor='#3D3846'
|
||||
itemType='project'
|
||||
itemAvatarField='image'
|
||||
itemColorField='color'
|
||||
itemOwnerField='user_created'
|
||||
itemSubnameField='subname'
|
||||
customEditLink='/edit-item'
|
||||
customEditParameter='id'
|
||||
// data={places}
|
||||
api={placesApi}>
|
||||
<ItemView>
|
||||
<PopupButton url={'/item'} parameterField={'id'} text={'Profile'} colorField={'color'} />
|
||||
<TextView truncate></TextView>
|
||||
</ItemView>
|
||||
</Layer>
|
||||
<Layer
|
||||
name='People'
|
||||
menuIcon={UserIcon}
|
||||
menuText='place your profile on the map'
|
||||
menuColor='#C62828'
|
||||
markerIcon='user'
|
||||
markerShape='square'
|
||||
markerDefaultColor='#818583'
|
||||
itemType='user'
|
||||
itemAvatarField='image'
|
||||
itemColorField='color'
|
||||
itemOwnerField="user_created"
|
||||
itemSubnameField='subname'
|
||||
customEditLink='/edit-item'
|
||||
customEditParameter='id'
|
||||
onlyOnePerOwner={true}
|
||||
// data={places}
|
||||
api={updatesApiInstance}>
|
||||
<ItemView>
|
||||
<PopupButton url={'/item'} parameterField={'id'} text={'Profile'} colorField={'color'} />
|
||||
<TextView truncate></TextView>
|
||||
</ItemView>
|
||||
<ItemForm title='Place yor Profile'>
|
||||
<div className='flex justify-center'>
|
||||
<p>Press Save to place your Profile to the Map</p>
|
||||
</div>
|
||||
</ItemForm>
|
||||
</Layer>
|
||||
<UtopiaMap zoom={map.zoom || 5} center={map.center? [map.center?.coordinates[1], map.center?.coordinates[0]] : [50.6, 9.5]} height='calc(100dvh - 64px)' width="100%" >
|
||||
{layers && apis &&
|
||||
layers.map(layer =>
|
||||
<Layer
|
||||
key={layer.id}
|
||||
name={layer.name}
|
||||
menuIcon={"https://api.utopia-lab.org/assets/" + layer.menuIcon}
|
||||
menuText={layer.menuText}
|
||||
menuColor={layer.menuColor}
|
||||
markerIcon={layer.markerIcon}
|
||||
markerShape={layer.markerShape}
|
||||
onlyOnePerOwner={layer.onlyOnePerOwner}
|
||||
markerDefaultColor='#3D3846'
|
||||
itemType={layer.itemType}
|
||||
itemNameField='name'
|
||||
itemTextField='text'
|
||||
itemAvatarField='image'
|
||||
itemSubnameField='subname'
|
||||
itemColorField='color'
|
||||
itemOwnerField='user_created'
|
||||
customEditLink='/edit-item'
|
||||
customEditParameter='id'
|
||||
api={apis?.find(api => api.id === layer.id)?.api}>
|
||||
<ItemView>
|
||||
{layer.itemType.show_start_end &&
|
||||
<StartEndView></StartEndView>
|
||||
}
|
||||
{layer.itemType.show_profile_button &&
|
||||
<PopupButton url={'/item'} parameterField={'id'} text={'Profile'} colorField={'color'} />
|
||||
}
|
||||
{layer.itemType.show_text &&
|
||||
<TextView truncate></TextView>
|
||||
}
|
||||
</ItemView>
|
||||
<ItemForm>
|
||||
{layer.itemType.show_name_input && <PopupTextInput dataField='name' placeholder='Name'></PopupTextInput>}
|
||||
{layer.itemType.show_start_end_input && <PopupStartEndInput></PopupStartEndInput>}
|
||||
{layer.itemType.show_text_input &&<PopupTextAreaInput dataField='text' placeholder={'Text ...'} style="tw-h-40"></PopupTextAreaInput>}
|
||||
{layer.itemType.custom_text && <div className='flex justify-center'>
|
||||
<p>Press Save to place your Profile to the Map</p>
|
||||
</div>}
|
||||
</ItemForm>
|
||||
</Layer>)
|
||||
}
|
||||
</UtopiaMap>
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
|
||||
import { RectangleGroupIcon, CalendarDaysIcon, UserGroupIcon } from '@heroicons/react/24/outline'
|
||||
import { MapIcon } from '@heroicons/react/24/outline'
|
||||
|
||||
//const iconClasses = `h-6 w-6`
|
||||
//const submenuIconClasses = `h-5 w-5`
|
||||
|
||||
export const routes = [
|
||||
|
||||
@ -11,21 +8,6 @@ export const routes = [
|
||||
path: '/',
|
||||
icon: <MapIcon style={{width: 24 }}/>,
|
||||
name: 'Map',
|
||||
},
|
||||
{
|
||||
path: '/items', // url
|
||||
icon: <RectangleGroupIcon style={{width: 24 }}/>, // icon component
|
||||
name: 'Projects', // name that appear in Sidebar
|
||||
},
|
||||
{
|
||||
path: '/calendar', // url
|
||||
icon: <CalendarDaysIcon style={{width: 24 }}/>, // icon component
|
||||
name: 'Calendar', // name that appear in Sidebar
|
||||
},
|
||||
{
|
||||
path: '/community', // url
|
||||
icon: <UserGroupIcon style={{width: 24 }}/>, // icon component
|
||||
name: 'Community', // name that appear in Sidebar
|
||||
}/**
|
||||
{
|
||||
path: '/people', // url
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user