From ff033eb1a1e76e2abcd25c05b12ca7e929a7a8a0 Mon Sep 17 00:00:00 2001 From: Dariusz Niemczyk Date: Sun, 9 Feb 2025 02:51:52 +0100 Subject: [PATCH] feat: add location map --- package-lock.json | 96 ++++++++++++++++++++++--------- package.json | 3 + src/components/event-map.lazy.tsx | 29 ++++++++++ src/components/landing-page.tsx | 21 ++++++- src/components/ui/skeleton.tsx | 15 +++++ src/globals.css | 5 ++ 6 files changed, 138 insertions(+), 31 deletions(-) create mode 100644 src/components/event-map.lazy.tsx create mode 100644 src/components/ui/skeleton.tsx diff --git a/package-lock.json b/package-lock.json index 9113d90..1bf0948 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,12 +17,15 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "geist": "^1.3.1", + "leaflet": "^1.9.4", + "leaflet-defaulticon-compatibility": "^0.1.2", "lucide-react": "^0.474.0", "make-plural": "^7.4.0", "negotiator": "^1.0.0", "next": "15.1.6", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-leaflet": "^5.0.0-rc.2", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7" }, @@ -2127,25 +2130,25 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.5.tgz", - "integrity": "sha512-LaO3e5h/NOEL4OfXjxD43k9Dx+vn+8n+PCFt6uhX/BADFflllyv3WJG6rgvvSVBxpTch938Qq/LGc2MMxipXPw==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.6.tgz", + "integrity": "sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", "@radix-ui/react-context": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.4", + "@radix-ui/react-dismissable-layer": "1.1.5", "@radix-ui/react-focus-guards": "1.1.1", - "@radix-ui/react-focus-scope": "1.1.1", + "@radix-ui/react-focus-scope": "1.1.2", "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-portal": "1.1.3", + "@radix-ui/react-portal": "1.1.4", "@radix-ui/react-presence": "1.1.2", - "@radix-ui/react-primitive": "2.0.1", - "@radix-ui/react-slot": "1.1.1", + "@radix-ui/react-primitive": "2.0.2", + "@radix-ui/react-slot": "1.1.2", "@radix-ui/react-use-controllable-state": "1.1.0", "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.2" + "react-remove-scroll": "^2.6.3" }, "peerDependencies": { "@types/react": "*", @@ -2163,14 +2166,14 @@ } }, "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.4.tgz", - "integrity": "sha512-XDUI0IVYVSwjMXxM6P4Dfti7AH+Y4oS/TB+sglZ/EXc7cqLwGAmp1NlMrcUjj7ks6R5WTZuWKv44FBbLpwU3sA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.5.tgz", + "integrity": "sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.1", "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0", "@radix-ui/react-use-escape-keydown": "1.1.0" }, @@ -2205,13 +2208,13 @@ } }, "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.1.tgz", - "integrity": "sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.2.tgz", + "integrity": "sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.1", - "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-callback-ref": "1.1.0" }, "peerDependencies": { @@ -2248,12 +2251,12 @@ } }, "node_modules/@radix-ui/react-portal": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.3.tgz", - "integrity": "sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.4.tgz", + "integrity": "sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.1", + "@radix-ui/react-primitive": "2.0.2", "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { @@ -2296,12 +2299,12 @@ } }, "node_modules/@radix-ui/react-primitive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.1.tgz", - "integrity": "sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz", + "integrity": "sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==", "license": "MIT", "dependencies": { - "@radix-ui/react-slot": "1.1.1" + "@radix-ui/react-slot": "1.1.2" }, "peerDependencies": { "@types/react": "*", @@ -2319,9 +2322,9 @@ } }, "node_modules/@radix-ui/react-slot": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.1.tgz", - "integrity": "sha512-RApLLOcINYJA+dMVbOju7MYv1Mb2EBp2nH4HdDzXTSyaR5optlm6Otrz1euW3HbdOR8UmmFK06TD+A9frYWv+g==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.2.tgz", + "integrity": "sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.1" @@ -2402,6 +2405,17 @@ } } }, + "node_modules/@react-leaflet/core": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-3.0.0.tgz", + "integrity": "sha512-3EWmekh4Nz+pGcr+xjf0KNyYfC3U2JjnkWsh0zcqaexYqmmB5ZhH37kz41JXGmKzpaMZCnPofBBm64i+YrEvGQ==", + "license": "Hippocratic-2.1", + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.32.1", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.32.1.tgz", @@ -6786,6 +6800,18 @@ "node": ">=0.10" } }, + "node_modules/leaflet": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.9.4.tgz", + "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==", + "license": "BSD-2-Clause" + }, + "node_modules/leaflet-defaulticon-compatibility": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/leaflet-defaulticon-compatibility/-/leaflet-defaulticon-compatibility-0.1.2.tgz", + "integrity": "sha512-IrKagWxkTwzxUkFIumy/Zmo3ksjuAu3zEadtOuJcKzuXaD76Gwvg2Z1mLyx7y52ykOzM8rAH5ChBs4DnfdGa6Q==", + "license": "BSD-2-Clause" + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -8101,6 +8127,20 @@ "dev": true, "license": "MIT" }, + "node_modules/react-leaflet": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz", + "integrity": "sha512-CWbTpr5vcHw5bt9i4zSlPEVQdTVcML390TjeDG0cK59z1ylexpqC6M1PJFjV8jD7CF+ACBFsLIDs6DRMoLEofw==", + "license": "Hippocratic-2.1", + "dependencies": { + "@react-leaflet/core": "^3.0.0" + }, + "peerDependencies": { + "leaflet": "^1.9.0", + "react": "^19.0.0", + "react-dom": "^19.0.0" + } + }, "node_modules/react-remove-scroll": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz", diff --git a/package.json b/package.json index 5beaa2a..6b0c87a 100644 --- a/package.json +++ b/package.json @@ -22,12 +22,15 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "geist": "^1.3.1", + "leaflet": "^1.9.4", + "leaflet-defaulticon-compatibility": "^0.1.2", "lucide-react": "^0.474.0", "make-plural": "^7.4.0", "negotiator": "^1.0.0", "next": "15.1.6", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-leaflet": "^5.0.0-rc.2", "tailwind-merge": "^2.6.0", "tailwindcss-animate": "^1.0.7" }, diff --git a/src/components/event-map.lazy.tsx b/src/components/event-map.lazy.tsx new file mode 100644 index 0000000..bce002b --- /dev/null +++ b/src/components/event-map.lazy.tsx @@ -0,0 +1,29 @@ +import "leaflet/dist/leaflet.css" + +import "leaflet-defaulticon-compatibility" +import "leaflet-defaulticon-compatibility/dist/leaflet-defaulticon-compatibility.css" + +import { Translations } from "@/i18n/translations" +import { MapContainer, Marker, Popup, TileLayer } from "react-leaflet" + + +export default function Map({ t }: { + t: Translations +}) { + return ( +
+ {/* @ts-expect-error dragging IS a valid prop. */} + + {/* @ts-expect-error attribution IS a valid prop. */} + + + + {t.where.location} + + + +
+ ) +} diff --git a/src/components/landing-page.tsx b/src/components/landing-page.tsx index 19e057f..7e6cd29 100644 --- a/src/components/landing-page.tsx +++ b/src/components/landing-page.tsx @@ -1,19 +1,26 @@ "use client" +import dynamic from 'next/dynamic'; + + + import { Nav } from "@/components/nav"; import { Translations } from "@/i18n/translations"; import { cn } from "@/lib/utils"; import { ReactElement, useEffect, useRef } from "react"; import { useTheme } from "./providers"; +import { Skeleton } from './ui/skeleton'; function Section({ id, title, - paragraphs + paragraphs, + after }: { id: string title: string; paragraphs: ReactElement; + after?: ReactElement; }) { return (
@@ -21,6 +28,7 @@ function Section({
{paragraphs}
+ {after}
) } @@ -125,6 +133,12 @@ function Video({ sourceBase, hidden }: { ); } + +const LazyLeafletMap = dynamic(() => import('./event-map.lazy'), { + ssr: false, + loading: () => +}) + export default function LandingPage( { t }: { t: Translations } ) { @@ -134,7 +148,7 @@ export default function LandingPage( return (