diff --git a/snowpack.config.js b/snowpack.config.js index 19b404adfa8085c116531d37f90377c7a5b23d48..b7eb286d1379ab93397daad0d1a996f8d8a0ad3c 100644 --- a/snowpack.config.js +++ b/snowpack.config.js @@ -1,14 +1,14 @@ /** @type {import("snowpack").SnowpackUserConfig } */ module.exports = { mount: { - public: {url: '/', static: true}, - src: {url: '/dist'}, + public: { url: '/', static: true }, + src: { url: '/dist' }, }, plugins: [ '@snowpack/plugin-react-refresh', '@snowpack/plugin-dotenv', '@snowpack/plugin-typescript', - '@snowpack/plugin-postcss' + '@snowpack/plugin-postcss', ], routes: [ /* Enable an SPA Fallback in development: */ diff --git a/src/App.css b/src/App.css deleted file mode 100644 index 8b137891791fe96927ad78e64b0aad7bded08bdc..0000000000000000000000000000000000000000 --- a/src/App.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/App.tsx b/src/App.tsx index 66550512ba1bf9425f82d9b0b16b7343335adc78..2d1c5cd3b24aee45568746d44440bcd81e72c4b9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,4 @@ import React, { useState } from 'react'; -import './App.css'; import SidebarListView from './Sidebar/SidebarListView'; import data from './testData.json'; import type { PointOfInterest } from './types/PointOfInterest'; diff --git a/src/Map/Map.tsx b/src/Map/Map.tsx index b63102b5bbf214b81cb646a22f57a59d10ca6f48..d08b30accd02dc352d9f571be5aeee2e0d7d0d52 100644 --- a/src/Map/Map.tsx +++ b/src/Map/Map.tsx @@ -1,5 +1,6 @@ -import { MapContainer, Marker, Popup, TileLayer } from 'react-leaflet'; -import React from 'react'; +import { MapContainer, Marker, TileLayer } from 'react-leaflet'; +import React, { useMemo } from 'react'; +import { divIcon, DivIconOptions } from 'leaflet'; import type { PointOfInterest } from '../types/PointOfInterest'; import type { LatLngExpression } from 'leaflet'; import MapViewController from './MapViewController'; @@ -16,6 +17,16 @@ interface Props { const DEFAULT_CENTER: LatLngExpression = [53.550359, 9.986701]; export const Map: React.FC<Props> = (props) => { + const iconProps: DivIconOptions = { + className: 'marker', + // Source: https://fontawesome.com/icons/map-marker-alt + html: `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="currentColor" d="M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z"/></svg>`, + iconSize: [24, 32], + iconAnchor: [12, 32], + }; + const icon = useMemo(() => divIcon(iconProps), [iconProps]); + const largeIcon = useMemo(() => divIcon({ ...iconProps, iconSize: [30, 40], iconAnchor: [15, 40] }), [iconProps]); + return ( <MapContainer id={'mapid'} @@ -35,10 +46,13 @@ export const Map: React.FC<Props> = (props) => { maxZoom={18} /> <MapViewController center={props.selectedEntry?.latlng ?? DEFAULT_CENTER} zoom={13} /> - {!!props.selectedEntry && <Marker position={props.selectedEntry.latlng} />} + {/* Single marker when POI is selected */} + {!!props.selectedEntry && <Marker icon={largeIcon} position={props.selectedEntry.latlng} />} + {/* 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} diff --git a/src/index.css b/src/index.css index b0e4a4e1e1ed397e41badeaa09af28b6a25c1bc3..67041bd44a2b36d9d4ff1bd4e553a8d34704874a 100644 --- a/src/index.css +++ b/src/index.css @@ -2,16 +2,24 @@ @tailwind components; @tailwind utilities; +:root { + --fabcity-red: #ee2f45; + --fabcity-green: #08aa64; + --fabcity-blue: #19459c; +} + body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', + 'Droid Sans', 'Helvetica Neue', sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; -} \ No newline at end of file + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; +} + +.marker { + color: var(--fabcity-red); +} diff --git a/src/testData.json b/src/testData.json index 9b31ea866d01a1207a6d298a25973180a6f41f57..b19fb83458fa9147ec5a4d2a7dcc71e4f2eb0548 100644 --- a/src/testData.json +++ b/src/testData.json @@ -28,7 +28,7 @@ }, { "id": 4, - "latlng": [53.550359, 9.986701], + "latlng": [53.570359, 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", @@ -36,7 +36,7 @@ }, { "id": 5, - "latlng": [53.530359, 9.966701], + "latlng": [53.565359, 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", diff --git a/tailwind.config.js b/tailwind.config.js index 62dfdaf3fc2365a6e57ac4d4bf5b10eda19eb517..2c92327eacbda573a3d78d59c11fa5b86acb1f51 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,5 +1,5 @@ module.exports = { - purge: [], + purge: ['./src/**/*.html', './src/**/*.tsx'], darkMode: false, // or 'media' or 'class' theme: { extend: {}, @@ -8,4 +8,4 @@ module.exports = { extend: {}, }, plugins: [], -} +};