Skip to content

Commit 55ed397

Browse files
Location pinned comments
1 parent 94f36f6 commit 55ed397

9 files changed

Lines changed: 255 additions & 65 deletions

File tree

app/src/app/components/Map/MetaLayers.tsx

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
import {EMPTY_FT_COLLECTION, getDissolved, ZONE_LABEL_STYLE} from '@/app/constants/layers';
2+
import { useMapMetadata } from '@/app/hooks/useMapMetadata';
23
import {useDemographyStore} from '@/app/store/demography/demographyStore';
34
import {useMapStore} from '@/app/store/mapStore';
5+
import { useTooltipStore } from '@/app/store/tooltipStore';
6+
import { saveMap } from '@/app/utils/api/apiHandlers/saveMap';
47
import {demographyCache} from '@/app/utils/demography/demographyCache';
58
import GeometryWorker from '@/app/utils/GeometryWorker';
9+
import { DEFAULT_MAP_METADATA } from '@/app/utils/language';
610
import React, {useLayoutEffect, useRef, useState} from 'react';
711
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';
915

1016
export const MetaLayers: React.FC<{isDemographicMap?: boolean}> = ({isDemographicMap}) => {
1117
return (
1218
<>
1319
{!isDemographicMap && <ZoneNumbersLayer />}
1420
<PopulationTextLayer />
21+
<PinCommentsLayer />
1522
</>
1623
);
1724
};
@@ -272,3 +279,82 @@ const ZoneNumbersLayer = () => {
272279
</Source>
273280
);
274281
};
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+
};

app/src/app/components/Toolbar/ToolControls.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ const ToolControlsConfig: Record<
3535
}
3636
},
3737
},
38+
pin: {
39+
Component: () => <React.Fragment />,
40+
},
3841
};
3942

4043
export const ToolControls: React.FC<{

app/src/app/components/Topbar/Icons.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,11 @@ export const ReadyIcon: React.FC = () => {
5252
</svg>
5353
);
5454
};
55+
56+
export const Pin : React.FC<{size?: string}> = ({size = 'size-4'}) => {
57+
return (
58+
<svg className={`${size}`} version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
59+
<path d="m24.875 57.48c4.457 8.4727 12.168 19.703 25.125 37.664 12.957-17.961 20.664-29.191 25.125-37.664 4.5352-8.6211 5.6602-14.387 5.6602-21.84-0.003906-17-13.785-30.785-30.785-30.785s-30.781 13.785-30.781 30.785c0 7.4531 1.1211 13.219 5.6562 21.84zm25.125-38.082c11.852 0 17.824 14.398 9.4375 22.785-8.3867 8.3867-22.785 2.4141-22.785-9.4375 0-7.3711 5.9766-13.348 13.348-13.348z" fill-rule="evenodd"/>
60+
</svg>
61+
);
62+
};

0 commit comments

Comments
 (0)