Skip to content

Commit

Permalink
feat: setup geojson and implement selectable countries (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukas0912 authored Nov 9, 2024
1 parent 0adcbda commit 9c35bb1
Show file tree
Hide file tree
Showing 9 changed files with 103 additions and 62 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"version": "detect"
},
"import/resolver": {
"typescript": {},
"alias": {
"map": [["@", "./src/"]],
"extensions": [".ts", ".tsx", ""]
Expand Down
4 changes: 1 addition & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,5 @@
"editor.tabSize": 2,
"eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
"files.eol": "\n",
"cSpell.words": [
"nextui"
]
"cSpell.words": ["nextui"]
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@tanstack/react-query": "^5.59.17",
"clsx": "2.1.1",
"framer-motion": "~11.1.1",
"geojson": "^0.5.0",
"highcharts": "^11.4.8",
"highcharts-react-official": "^3.2.1",
"iconsax-react": "^0.0.8",
Expand All @@ -58,6 +59,7 @@
"devDependencies": {
"@commitlint/cli": "^19.5.0",
"@commitlint/config-conventional": "^19.5.0",
"@types/geojson": "^7946.0.14",
"@types/leaflet": "^1.9.14",
"@types/node": "20.5.7",
"@types/react": "^18.3.12",
Expand Down
21 changes: 0 additions & 21 deletions src/components/Map/CountryPolygon.tsx

This file was deleted.

20 changes: 0 additions & 20 deletions src/components/Map/CountryPopup.tsx

This file was deleted.

74 changes: 63 additions & 11 deletions src/components/Map/Map.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,71 @@
'use client';

import 'leaflet/dist/leaflet.css';

import { MapContainer, TileLayer, ZoomControl } from 'react-leaflet';
import { Feature, FeatureCollection } from 'geojson';
import { LeafletMouseEvent } from 'leaflet';
import { GeoJSON, MapContainer, TileLayer, ZoomControl } from 'react-leaflet';

import { CountryMapData } from '@/domain/entities/country/CountryMapData.ts';
import { MapProps } from '@/domain/props/MapProps';

import { CountryPolygon } from './CountryPolygon';

export default function Map({ countries }: MapProps) {
const countryStyle: L.PathOptions = {
fillColor: 'var(--color-active-countries)',
weight: 0.5,
color: 'var(--color-background)',
fillOpacity: 0.4,
};

const highlightCountry = (event: LeafletMouseEvent) => {
const layer = event.target;
const countryData: CountryMapData = layer.feature as CountryMapData;
if (countryData.properties.interactive) {
layer.setStyle({
fillColor: 'var(--color-hover)',
fillOpacity: 0.8,
});
} else {
layer.getElement().style.cursor = 'grab';
}
};

const resetHighlight = (event: LeafletMouseEvent) => {
const layer = event.target;
const countryData: CountryMapData = layer.feature as CountryMapData;
if (countryData.properties.interactive) {
layer.setStyle(countryStyle);
}
};

const onCountryClick = (event: LeafletMouseEvent) => {
const countryData: CountryMapData = event.target.feature as CountryMapData;
if (countryData.properties.interactive) {
alert(`You clicked on ${countryData.properties.adm0_name}`);

Check warning on line 42 in src/components/Map/Map.tsx

View workflow job for this annotation

GitHub Actions / lint-and-format

Unexpected alert
}
};

const onEachCountry = (country: Feature, layer: L.Layer) => {
if ((layer as L.GeoJSON).feature) {
const leafletLayer = layer as L.Path;
leafletLayer.setStyle(countryStyle);
if (!(country as CountryMapData).properties.interactive) {
leafletLayer.setStyle({ fillColor: 'var(--color-inactive-countries)', fillOpacity: 0.85 });
}
leafletLayer.on({
mouseover: highlightCountry,
mouseout: resetHighlight,
click: onCountryClick,
mousedown: () => {
const element = leafletLayer.getElement() as HTMLElement | null;
if (element) element.style.cursor = 'grabbing';
},
mouseup: () => {
const element = leafletLayer.getElement() as HTMLElement | null;
if (element) element.style.cursor = 'grab';
},
});
}
};

return (
<MapContainer
center={[21.505, -0.09]}
Expand All @@ -27,13 +84,8 @@ export default function Map({ countries }: MapProps) {
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{countries && <GeoJSON data={countries as FeatureCollection} onEachFeature={onEachCountry} />}
<ZoomControl position="bottomright" />
{countries.features
.filter((c) => c.properties.interactive)
.map((c) => (
// TODO fix the layout, this is just an example
<CountryPolygon country={c} key={c.properties.adm0_id} />
))}
</MapContainer>
);
}
2 changes: 1 addition & 1 deletion src/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ canvas.react-pdf__Page__canvas {

.dot-delay-3 {
animation-delay: 0.6s;
}
}
34 changes: 29 additions & 5 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,19 @@ import { nextui } from '@nextui-org/theme';
/** @type {import('tailwindcss').Config} */
module.exports = {
safelist: [
'w-[215px]', 'w-[179px]', 'w-[636px]', 'w-[500px]',
'h-[657px]', 'h-[600px]', 'rounded-[12px_0_0_12px]',
'max-w-[80%]', 'max-w-[250px]', 'max-w-[400px]', 'pl-[215px]', 'pl-[179px]', 'z-[9999]'
'w-[215px]',
'w-[179px]',
'w-[636px]',
'w-[500px]',
'h-[657px]',
'h-[600px]',
'rounded-[12px_0_0_12px]',
'max-w-[80%]',
'max-w-[250px]',
'max-w-[400px]',
'pl-[215px]',
'pl-[179px]',
'z-[9999]',
],
content: [
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
Expand Down Expand Up @@ -43,7 +53,7 @@ module.exports = {
'12px_0_0_12px': '12px 0 0 12px',
},
zIndex: {
'9999': '9999',
9999: '9999',
},
animation: {
blink: 'blink 1s step-end infinite',
Expand All @@ -56,12 +66,22 @@ module.exports = {
pulse: {
'0%, 100%': { transform: 'scale(1)', opacity: '0.6' },
'50%': { transform: 'scale(1.3)', opacity: '1' },
}
},
},
},
},
darkMode: 'class',
plugins: [
function ({ addBase, theme }) {
addBase({
':root': {
'--color-hover': theme('colors.hover'),
'--color-background': theme('colors.background'),
'--color-active-countries': theme('colors.activeCountries'),
'--color-inactive-countries': theme('colors.inactiveCountries'),
},
});
},
nextui({
themes: {
light: {
Expand Down Expand Up @@ -89,6 +109,8 @@ module.exports = {
chatbotUserMsg: '#E6F1FE',
chatbotDivider: '#292d32',
surfaceGrey: '#B0B0B0',
activeCountries: '#82bce0',
inactiveCountries: '#a7b3ba',
},
},
dark: {
Expand Down Expand Up @@ -116,6 +138,8 @@ module.exports = {
chatbotUserMsg: '#26262A',
chatbotDivider: '#556372',
surfaceGrey: '#444444',
activeCountries: '#115884',
inactiveCountries: '#85929b',
},
},
},
Expand Down
7 changes: 6 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2774,7 +2774,7 @@
dependencies:
"@types/node" "*"

"@types/geojson@*":
"@types/geojson@*", "@types/geojson@^7946.0.14":
version "7946.0.14"
resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.14.tgz#319b63ad6df705ee2a65a73ef042c8271e696613"
integrity sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==
Expand Down Expand Up @@ -4216,6 +4216,11 @@ gauge@^3.0.0:
strip-ansi "^6.0.1"
wide-align "^1.1.2"

geojson@^0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/geojson/-/geojson-0.5.0.tgz#3cd6c96399be65b56ee55596116fe9191ce701c0"
integrity sha512-/Bx5lEn+qRF4TfQ5aLu6NH+UKtvIv7Lhc487y/c8BdludrCTpiWf9wyI0RTyqg49MFefIAvFDuEi5Dfd/zgNxQ==

get-caller-file@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
Expand Down

0 comments on commit 9c35bb1

Please sign in to comment.