|
1 | 1 | import {EMPTY_FT_COLLECTION, getDissolved, ZONE_LABEL_STYLE} from '@/app/constants/layers'; |
| 2 | +import { useMapMetadata } from '@/app/hooks/useMapMetadata'; |
2 | 3 | import {useDemographyStore} from '@/app/store/demography/demographyStore'; |
3 | 4 | import {useMapStore} from '@/app/store/mapStore'; |
| 5 | +import { useTooltipStore } from '@/app/store/tooltipStore'; |
| 6 | +import { saveMap } from '@/app/utils/api/apiHandlers/saveMap'; |
4 | 7 | import {demographyCache} from '@/app/utils/demography/demographyCache'; |
5 | 8 | import GeometryWorker from '@/app/utils/GeometryWorker'; |
| 9 | +import { DEFAULT_MAP_METADATA } from '@/app/utils/language'; |
6 | 10 | import React, {useLayoutEffect, useRef, useState} from 'react'; |
7 | 11 | import {useEffect} from 'react'; |
8 | | -import {Source, Layer} from 'react-map-gl/maplibre'; |
| 12 | +import {Source, Layer, Marker, MarkerDragEvent, Popup} from 'react-map-gl/maplibre'; |
| 13 | +import { Box, Button, Text, TextArea } from '@radix-ui/themes'; |
| 14 | +import { Pin } from '../Topbar/Icons'; |
9 | 15 |
|
10 | 16 | export const MetaLayers: React.FC<{isDemographicMap?: boolean}> = ({isDemographicMap}) => { |
11 | 17 | return ( |
12 | 18 | <> |
13 | 19 | {!isDemographicMap && <ZoneNumbersLayer />} |
14 | 20 | <PopulationTextLayer /> |
| 21 | + <PinCommentsLayer /> |
15 | 22 | </> |
16 | 23 | ); |
17 | 24 | }; |
@@ -272,3 +279,82 @@ const ZoneNumbersLayer = () => { |
272 | 279 | </Source> |
273 | 280 | ); |
274 | 281 | }; |
| 282 | + |
| 283 | + |
| 284 | +const PinCommentsLayer = () => { |
| 285 | + const mapMetadata = useMapMetadata(); |
| 286 | + const [openPopupIndex, setOpenPopupIndex] = useState<number | null>(null); |
| 287 | + const setErrorNotification = useMapStore(state => state.setErrorNotification); |
| 288 | + const [popupIndex, setPopupIndex] = useState<number | null>(null); |
| 289 | + const handleDrag = async (e: MarkerDragEvent, index: number) => { |
| 290 | + let locationComments = [...(mapMetadata?.location_comments || [])]; |
| 291 | + locationComments[index] = { |
| 292 | + ...locationComments[index], |
| 293 | + lng: e.lngLat.lng, |
| 294 | + lat: e.lngLat.lat, |
| 295 | + } |
| 296 | + try { |
| 297 | + |
| 298 | + const r = await saveMap({ |
| 299 | + ...(mapMetadata || DEFAULT_MAP_METADATA), |
| 300 | + location_comments: locationComments, |
| 301 | + }); |
| 302 | + } catch (e) { |
| 303 | + setErrorNotification({ |
| 304 | + message: 'Error saving map metadata or comment.', |
| 305 | + severity: 3, |
| 306 | + }); |
| 307 | + console.error(e); |
| 308 | + } |
| 309 | + } |
| 310 | + |
| 311 | + const handleSave = async (index: number) => { |
| 312 | + if (!mapMetadata?.location_comments?.[index]) { |
| 313 | + return; |
| 314 | + } |
| 315 | + const r = await saveMap({ |
| 316 | + ...(mapMetadata || DEFAULT_MAP_METADATA), |
| 317 | + location_comments: [...(mapMetadata?.location_comments || []), { |
| 318 | + lng: mapMetadata?.location_comments?.[index]?.lng || 0, |
| 319 | + lat: mapMetadata?.location_comments?.[index]?.lat || 0, |
| 320 | + comment: mapMetadata?.location_comments?.[index]?.comment || '', |
| 321 | + }, |
| 322 | + ], |
| 323 | + }); |
| 324 | + } |
| 325 | + if (!mapMetadata?.location_comments) { |
| 326 | + return null; |
| 327 | + } |
| 328 | + |
| 329 | + return ( |
| 330 | + <> |
| 331 | + {mapMetadata?.location_comments?.map((comment, index) => ( |
| 332 | + <Marker |
| 333 | + key={index} |
| 334 | + longitude={comment.lng} |
| 335 | + latitude={comment.lat} |
| 336 | + anchor="center" |
| 337 | + draggable={true} |
| 338 | + onDragEnd={(e) => handleDrag(e, index)} |
| 339 | + onClick={() => { |
| 340 | + setPopupIndex(index) |
| 341 | + }} |
| 342 | + > |
| 343 | + <Pin size="size-8" /> |
| 344 | + </Marker> |
| 345 | + ))} |
| 346 | + {popupIndex !== null && ( |
| 347 | + <Popup |
| 348 | + anchor="bottom" |
| 349 | + offset={[0, -30]} |
| 350 | + longitude={mapMetadata?.location_comments?.[popupIndex]?.lng} |
| 351 | + latitude={mapMetadata?.location_comments?.[popupIndex]?.lat} |
| 352 | + closeOnMove={false} |
| 353 | + closeOnClick={false} |
| 354 | + > |
| 355 | + <Box className="flex flex-col gap-2 p-4 z-[999]">{mapMetadata?.location_comments?.[popupIndex]?.comment}</Box> |
| 356 | + </Popup> |
| 357 | + )} |
| 358 | + </> |
| 359 | + ); |
| 360 | +}; |
0 commit comments