Skip to content
Snippets Groups Projects
Commit 50529d33 authored by Moritz Stückler's avatar Moritz Stückler :cowboy: Committed by Moritz Stückler
Browse files

Feat/add graphql client

parent bb2771dd
No related branches found
No related tags found
No related merge requests found
SNOWPACK_PUBLIC_MAPBOX_TOKEN=abc123
SNOWPACK_PUBLIC_API_URL=http://localhost:8000/graphql
\ No newline at end of file
......@@ -5,11 +5,14 @@
"packages": {
"": {
"dependencies": {
"graphql": "^15.5.0",
"graphql-request": "^3.4.0",
"heroicons-react": "^1.3.0",
"leaflet": "^1.7.1",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-leaflet": "^3.1.0",
"swr": "^0.5.5",
"tailwindcss": "^2.0.3"
},
"devDependencies": {
......@@ -529,6 +532,11 @@
"node": ">=8"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"node_modules/at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
......@@ -761,6 +769,17 @@
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w=="
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
......@@ -799,6 +818,14 @@
"node": ">=10"
}
},
"node_modules/cross-fetch": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
"dependencies": {
"node-fetch": "2.6.1"
}
},
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
......@@ -871,6 +898,14 @@
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
"integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM="
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dependency-graph": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.9.0.tgz",
......@@ -880,6 +915,14 @@
"node": ">= 0.6.0"
}
},
"node_modules/dequal": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz",
"integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug==",
"engines": {
"node": ">=6"
}
},
"node_modules/detective": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz",
......@@ -997,6 +1040,17 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
"node_modules/extract-files": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz",
"integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==",
"engines": {
"node": "^10.17.0 || ^12.0.0 || >= 13.7.0"
},
"funding": {
"url": "https://github.com/sponsors/jaydenseric"
}
},
"node_modules/fast-glob": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
......@@ -1041,6 +1095,19 @@
"node": ">=8"
}
},
"node_modules/form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/fraction.js": {
"version": "4.0.13",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz",
......@@ -1194,6 +1261,27 @@
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
},
"node_modules/graphql": {
"version": "15.5.0",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz",
"integrity": "sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA==",
"engines": {
"node": ">= 10.x"
}
},
"node_modules/graphql-request": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.4.0.tgz",
"integrity": "sha512-acrTzidSlwAj8wBNO7Q/UQHS8T+z5qRGquCQRv9J1InwR01BBWV9ObnoE+JS5nCCEj8wSGS0yrDXVDoRiKZuOg==",
"dependencies": {
"cross-fetch": "^3.0.6",
"extract-files": "^9.0.0",
"form-data": "^3.0.0"
},
"peerDependencies": {
"graphql": "14.x || 15.x"
}
},
"node_modules/has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
......@@ -1565,6 +1653,25 @@
"node": ">=8"
}
},
"node_modules/mime-db": {
"version": "1.47.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
"integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.30",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
"integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
"dependencies": {
"mime-db": "1.47.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
......@@ -1626,6 +1733,14 @@
"lodash.toarray": "^4.4.0"
}
},
"node_modules/node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
"engines": {
"node": "4.x || >=6.0.0"
}
},
"node_modules/node-releases": {
"version": "1.1.71",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz",
......@@ -2429,6 +2544,17 @@
"node": ">=4"
}
},
"node_modules/swr": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/swr/-/swr-0.5.5.tgz",
"integrity": "sha512-u4mUorK9Ipt+6LEITvWRWiRWAQjAysI6cHxbMmMV1dIdDzxMnswWo1CyGoyBHXX91CchxcuoqgFZ/ycx+YfhCA==",
"dependencies": {
"dequal": "2.0.2"
},
"peerDependencies": {
"react": "^16.11.0 || ^17.0.0"
}
},
"node_modules/tailwindcss": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-2.0.4.tgz",
......@@ -3163,6 +3289,11 @@
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
"dev": true
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
......@@ -3337,6 +3468,14 @@
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w=="
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"commander": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
......@@ -3369,6 +3508,14 @@
"yaml": "^1.10.0"
}
},
"cross-fetch": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
"requires": {
"node-fetch": "2.6.1"
}
},
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
......@@ -3421,12 +3568,22 @@
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
"integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM="
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"dependency-graph": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.9.0.tgz",
"integrity": "sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w==",
"dev": true
},
"dequal": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz",
"integrity": "sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug=="
},
"detective": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz",
......@@ -3516,6 +3673,11 @@
"strip-final-newline": "^2.0.0"
}
},
"extract-files": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/extract-files/-/extract-files-9.0.0.tgz",
"integrity": "sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ=="
},
"fast-glob": {
"version": "3.2.5",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz",
......@@ -3554,6 +3716,16 @@
"to-regex-range": "^5.0.1"
}
},
"form-data": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
"integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"fraction.js": {
"version": "4.0.13",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.13.tgz",
......@@ -3658,6 +3830,21 @@
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
"integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ=="
},
"graphql": {
"version": "15.5.0",
"resolved": "https://registry.npmjs.org/graphql/-/graphql-15.5.0.tgz",
"integrity": "sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA=="
},
"graphql-request": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-3.4.0.tgz",
"integrity": "sha512-acrTzidSlwAj8wBNO7Q/UQHS8T+z5qRGquCQRv9J1InwR01BBWV9ObnoE+JS5nCCEj8wSGS0yrDXVDoRiKZuOg==",
"requires": {
"cross-fetch": "^3.0.6",
"extract-files": "^9.0.0",
"form-data": "^3.0.0"
}
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
......@@ -3942,6 +4129,19 @@
"picomatch": "^2.0.5"
}
},
"mime-db": {
"version": "1.47.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
"integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw=="
},
"mime-types": {
"version": "2.1.30",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
"integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
"requires": {
"mime-db": "1.47.0"
}
},
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
......@@ -3985,6 +4185,11 @@
"lodash.toarray": "^4.4.0"
}
},
"node-fetch": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
},
"node-releases": {
"version": "1.1.71",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz",
......@@ -4546,6 +4751,14 @@
"has-flag": "^3.0.0"
}
},
"swr": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/swr/-/swr-0.5.5.tgz",
"integrity": "sha512-u4mUorK9Ipt+6LEITvWRWiRWAQjAysI6cHxbMmMV1dIdDzxMnswWo1CyGoyBHXX91CchxcuoqgFZ/ycx+YfhCA==",
"requires": {
"dequal": "2.0.2"
}
},
"tailwindcss": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-2.0.4.tgz",
......
......@@ -6,11 +6,14 @@
"lint": "prettier --check \"src/**/*.{js,jsx,ts,tsx}\""
},
"dependencies": {
"graphql": "^15.5.0",
"graphql-request": "^3.4.0",
"heroicons-react": "^1.3.0",
"leaflet": "^1.7.1",
"react": "^17.0.0",
"react-dom": "^17.0.0",
"react-leaflet": "^3.1.0",
"swr": "^0.5.5",
"tailwindcss": "^2.0.3"
},
"devDependencies": {
......
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import useSWR from 'swr';
import SidebarListView from './Sidebar/SidebarListView';
import data from './testData.json';
// import mockData from './testData.json';
import type { PointOfInterest } from './types/PointOfInterest';
import SidebarSingleView from './Sidebar/SidebarSingleView';
import Map from './Map/Map';
interface AppProps {}
function App({}: AppProps) {
function App() {
const [poiData, setPoiData] = useState<PointOfInterest[]>([]);
const [selectedPoi, setSelectedPoi] = useState<null | PointOfInterest>(null);
const [hoveredPoiId, setHoveredPoiId] = useState<null | number>(null);
const handlePoiClick = (id: number) => {
const newPoi = (data as PointOfInterest[]).find((poi) => poi.id === id);
const newPoi = poiData.find((poi) => poi.id === id);
newPoi && setSelectedPoi(newPoi);
};
......@@ -28,13 +28,37 @@ function App({}: AppProps) {
setHoveredPoiId(null);
};
const { data, error } = useSWR(
`{
pois {
id
name
description
website
lat
lng
pathToBanner
}
}
`,
);
useEffect(() => {
data && console.log('Fetched new data', data);
data && data.pois && setPoiData(data.pois);
}, [data]);
useEffect(() => {
error && console.error('Error while fetching', error);
}, [error]);
return (
<div className={'flex md:flex-row-reverse flex-col h-full'}>
<Map
onMouseEnter={handlePoiHoverOn}
onMouseLeave={handlePoiHoverOff}
hoveredPoiId={hoveredPoiId}
values={data as PointOfInterest[]}
values={poiData}
onSelect={handlePoiClick}
selectedEntry={selectedPoi}
/>
......@@ -45,7 +69,7 @@ function App({}: AppProps) {
onMouseEnter={handlePoiHoverOn}
onMouseLeave={handlePoiHoverOff}
className="sidebar"
values={data as PointOfInterest[]}
values={poiData}
onClick={handlePoiClick}
/>
)}
......
......@@ -26,6 +26,9 @@ export const Map: React.FC<Props> = (props) => {
};
const icon = useMemo(() => divIcon(iconProps), [iconProps]);
const largeIcon = useMemo(() => divIcon({ ...iconProps, iconSize: [30, 40], iconAnchor: [15, 40] }), [iconProps]);
const selectedLatlng: LatLngExpression | undefined = props.selectedEntry
? [props.selectedEntry?.lat, props.selectedEntry?.lng]
: undefined;
return (
<MapContainer
......@@ -45,28 +48,32 @@ export const Map: React.FC<Props> = (props) => {
zoomOffset={-1}
maxZoom={18}
/>
<MapViewController center={props.selectedEntry?.latlng ?? DEFAULT_CENTER} zoom={13} />
<MapViewController center={selectedLatlng ?? DEFAULT_CENTER} zoom={13} />
{/* Single marker when POI is selected */}
{!!props.selectedEntry && <Marker icon={largeIcon} position={props.selectedEntry.latlng} />}
{!!(props.selectedEntry && selectedLatlng) && <Marker icon={largeIcon} position={selectedLatlng} />}
{/* Multiple markers, when no POI is selected */}
{!props.selectedEntry &&
props.values.map((poi) => (
<Marker
icon={props.hoveredPoiId === poi.id ? largeIcon : icon}
opacity={props.hoveredPoiId === poi.id ? 1 : 0.7}
key={poi.id}
position={poi.latlng}
eventHandlers={{
click: () => props.onSelect(poi.id),
mouseover: () => {
props.onMouseEnter && props.onMouseEnter(poi.id);
},
mouseout: () => {
props.onMouseLeave && props.onMouseLeave();
},
}}
/>
))}
props.values &&
props.values.map((poi) => {
const poiLatLng: LatLngExpression = [poi.lat, poi.lng];
return (
<Marker
icon={props.hoveredPoiId === poi.id ? largeIcon : icon}
opacity={props.hoveredPoiId === poi.id ? 1 : 0.7}
key={poi.id}
position={poiLatLng}
eventHandlers={{
click: () => props.onSelect(poi.id),
mouseover: () => {
props.onMouseEnter && props.onMouseEnter(poi.id);
},
mouseout: () => {
props.onMouseLeave && props.onMouseLeave();
},
}}
/>
);
})}
</MapContainer>
);
};
......
......@@ -13,7 +13,7 @@ const SidebarListElement: React.FC<Props> = ({ value, ...restProps }) => {
className="border-2 border-black border-opacity-20 hover:border-opacity-40 cursor-pointer rounded-lg md:overflow-hidden mx-4 my-2"
>
<div className="p-3">
<h2 className="tracking-widest text-xs title-font font-medium text-gray-400 mb-1">{value.category}</h2>
<h2 className="tracking-widest text-xs title-font font-medium text-gray-400 mb-1">OFFENE WERKSTATT</h2>
<h1 className="title-font text-lg font-medium text-gray-900">{value.name}</h1>
</div>
</div>
......
......@@ -17,15 +17,16 @@ const SidebarListView: React.FC<Props> = ({ values, onMouseEnter, onMouseLeave,
values && (
<SidebarContainer {...restProps}>
<h1 className="text-xl font-medium title-font m-4 text-gray-900 mb-2">{values.length} Orte:</h1>
{values.map((poi) => (
<SidebarListElement
key={poi.id}
{...(onMouseLeave ? { onMouseLeave: () => onMouseLeave() } : {})}
{...(onMouseEnter ? { onMouseEnter: () => onMouseEnter(poi.id) } : {})}
{...(onClick ? { onClick: () => onClick(poi.id) } : {})}
value={poi}
/>
))}
{values &&
values.map((poi) => (
<SidebarListElement
key={poi.id}
{...(onMouseLeave ? { onMouseLeave: () => onMouseLeave() } : {})}
{...(onMouseEnter ? { onMouseEnter: () => onMouseEnter(poi.id) } : {})}
{...(onClick ? { onClick: () => onClick(poi.id) } : {})}
value={poi}
/>
))}
</SidebarContainer>
)
);
......
......@@ -14,14 +14,20 @@ const SidebarSingleView: React.FC<Props> = ({ value, onClose, className, ...rest
const strippedUrl = value?.website?.replace(/(^\w+:|^)\/\//, '');
return (
<SidebarContainer className={`relative p-0 ${className || ''}`} {...restProps}>
<CloseIcon
size={32}
className="absolute left-5 top-5 p-1 text-gray-500 inline-block cursor-pointer hover:bg-gray-300 hover:bg-opacity-50 rounded-full"
onClick={onClose}
/>
<img className="lg:h-48 md:h-36 h-24 w-full object-cover object-center" src={value.image} alt="blog" />
<div className={`${value.pathToBanner ? '' : 'pl-5 pt-5'}`}>
<CloseIcon
size={32}
className={`${
value.pathToBanner ? 'absolute left-5 top-5 ' : ''
}p-1 text-gray-500 inline-block cursor-pointer hover:bg-gray-300 hover:bg-opacity-50 rounded-full`}
onClick={onClose}
/>
</div>
{value.pathToBanner && (
<img className="lg:h-48 md:h-36 w-full object-cover object-center" src={value.pathToBanner} alt="blog" />
)}
<div className="p-6">
<h2 className="tracking-widest text-xs title-font font-medium text-gray-400 mb-1">{value.category}</h2>
<h2 className="tracking-widest text-xs title-font font-medium text-gray-400 mb-1">OFFENE WERKSTATT</h2>
<h1 className="title-font text-lg font-medium text-gray-900 mb-3">{value.name}</h1>
<p className="leading-relaxed mb-6">{value.description}</p>
{value.website && (
......
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { SWRConfig } from 'swr';
import { request } from 'graphql-request';
import './index.css';
ReactDOM.render(
<React.StrictMode>
<App />
<SWRConfig value={{ fetcher: (query: string) => request(import.meta.env.SNOWPACK_PUBLIC_API_URL, query) }}>
<App />
</SWRConfig>
</React.StrictMode>,
document.getElementById('root'),
);
......
[
{
"id": 1,
"latlng": [53.550359, 9.986701],
"lat": 53.550359,
"lng": 9.986701,
"name": "Welcome Werkstatt e. V.",
"description": "Eine offene Stadtteilwerkstatt in Barmbek-Süd. Hier kann mit Holz, Metall und Elektronik gearbeitet werden.",
"address": "Bachstr. 98, 22083 Hamburg",
......@@ -11,7 +12,8 @@
},
{
"id": 2,
"latlng": [53.560359, 9.976701],
"lat": 53.560359,
"lng": 9.976701,
"name": "Fabulous St. Pauli",
"description": "Photo booth fam kinfolk cold-pressed sriracha leggings jianbing microdosing tousled waistcoat.",
"address": "Mozartstr. 8, 22081 Hamburg",
......@@ -21,7 +23,8 @@
},
{
"id": 3,
"latlng": [53.540359, 9.996701],
"lat": 53.540359,
"lng": 9.996701,
"name": "HoFaLab Wilhelmsburg",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text.",
"address": "Langer-Straßen-Name. 128, 22089 Hamburg",
......@@ -31,7 +34,8 @@
},
{
"id": 4,
"latlng": [53.570359, 9.986701],
"lat": 53.570359,
"lng": 9.986701,
"name": "Fab City Haus",
"description": "Eine offene Stadtteilwerkstatt in Barmbek-Süd. Hier kann mit Holz, Metall und Elektronik gearbeitet werden.",
"address": "Jungfernstieg 1, 22083 Hamburg",
......@@ -40,7 +44,8 @@
},
{
"id": 5,
"latlng": [53.565359, 9.966701],
"lat": 53.565359,
"lng": 9.966701,
"name": "Haus Drei e. V.",
"description": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text.",
"address": "Hein-Hoyer-Allee 36, 22083 Hamburg",
......
......@@ -2,23 +2,12 @@ import type { LatLngExpression } from 'leaflet';
export interface PointOfInterest {
id: number;
latlng: LatLngExpression;
lat: number;
lng: number;
name: string;
description: string;
address: string;
category: string;
website?: string;
image: string;
}
interface Map {
values: PointOfInterest[];
onSelect: (entry: PointOfInterest) => void;
selectedEntry: PointOfInterest;
}
interface Sidebar {
values: PointOfInterest[];
onSelect: (entry: PointOfInterest) => void;
selectedEntry: PointOfInterest;
website: string;
category?: string;
pathToBanner?: string;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment