Skip to content

Commit f3ce6d7

Browse files
committed
enh: improve interactive pink line mapping with pending markers and showing replaced segments with reduced opacity
- Added functionality to display pending pink and memorial markers on the map. - Updated the buildIntegratedRoute function to return removed routes for better route management. - Improved route rendering by adding styles for removed routes in both MapPage and PinkLineMapPage components.
1 parent 383eb74 commit f3ce6d7

4 files changed

Lines changed: 77 additions & 6 deletions

File tree

src/pages/MapPage/PinkLineMapPage.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const PinkLineMapPage = () => {
3535
const [pendingNode, setPendingNode] = useState<{ lat: number; lng: number } | null>(null);
3636
const [defaultLineLoaded, setDefaultLineLoaded] = useState(false);
3737
const busyRef = useRef(false);
38+
const pendingMarkerRef = useRef<L.Marker | null>(null);
3839

3940
// Nuke every route polyline from the map. Called before every re-render.
4041
const clearAllRouteLayers = (map: L.Map) => {
@@ -183,10 +184,15 @@ const PinkLineMapPage = () => {
183184
// Step 3: Rebuild route via buildIntegratedRoute (handles both 0 and >0 nodes)
184185
if (hasBase) {
185186
const userPoints = nodes.map((n) => [n.lat, n.lng] as [number, number]);
186-
const { solid, dashed } = buildIntegratedRoute(basePaths, userPoints);
187+
const { solid, dashed, removed } = buildIntegratedRoute(basePaths, userPoints);
187188
const solidStyle: L.PolylineOptions = { color: "#FF69B4", weight: 5, opacity: 0.9 };
188189
const dashedStyle: L.PolylineOptions = { color: "#FF69B4", weight: 5, opacity: 0.9, dashArray: "10, 10" };
190+
const removedStyle: L.PolylineOptions = { color: "#FF69B4", weight: 5, opacity: 0.6 };
189191

192+
for (const pts of removed) {
193+
const layer = L.polyline(pts as L.LatLngExpression[], removedStyle).addTo(map);
194+
routeLayersRef.current.push(layer);
195+
}
190196
for (const pts of solid) {
191197
const layer = L.polyline(pts as L.LatLngExpression[], solidStyle).addTo(map);
192198
routeLayersRef.current.push(layer);
@@ -251,6 +257,24 @@ const PinkLineMapPage = () => {
251257
});
252258
}, [nodes, defaultLineLoaded]);
253259

260+
useEffect(() => {
261+
if (!mapRef.current) return;
262+
if (pendingMarkerRef.current) {
263+
try { mapRef.current.removeLayer(pendingMarkerRef.current); } catch (_) {}
264+
pendingMarkerRef.current = null;
265+
}
266+
if (pendingNode) {
267+
pendingMarkerRef.current = L.marker([pendingNode.lat, pendingNode.lng], {
268+
icon: L.divIcon({
269+
className: "pink-line-node-marker",
270+
html: `<div class="pink-line-node">+</div>`,
271+
iconSize: [30, 30],
272+
iconAnchor: [15, 15],
273+
}),
274+
}).addTo(mapRef.current);
275+
}
276+
}, [pendingNode]);
277+
254278
const handleRemoveNode = async (nodeId: string) => {
255279
if (busyRef.current) return;
256280
busyRef.current = true;

src/pages/MapPage/PinkLineNodeForm.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ interface PinkLineNodeFormProps {
66
}
77

88
const NAME_QUESTION = "מה השם של נקודת עניין הזו?";
9-
const DESCRIPTION_QUESTION = "הסבר מה קרה כאן ב-7 באוקטובר ולמה הקו צריך לעבור כאן?";
9+
const DESCRIPTION_QUESTION =
10+
"הסבר מה קרה כאן ב-7 באוקטובר ולמה הקו צריך לעבור כאן?";
1011

1112
const PinkLineNodeForm = ({ onSubmit, onCancel }: PinkLineNodeFormProps) => {
1213
const [step, setStep] = useState<1 | 2>(1);

src/pages/MapPage/index.tsx

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ const MapPage = () => {
6565
const [defaultLineLoaded, setDefaultLineLoaded] = useState(false);
6666

6767
const defaultLinePathsRef = useRef<[number, number][][]>([]);
68+
const pendingPinkMarkerRef = useRef<L.Marker | null>(null);
69+
const pendingMemorialMarkerRef = useRef<L.Marker | null>(null);
6870

6971
useEffect(() => {
7072
activeProjectRef.current = activeProject;
@@ -184,15 +186,19 @@ const MapPage = () => {
184186

185187
if (defaultLineLoaded && defaultLinePathsRef.current.length > 0) {
186188
const userPoints = pinkNodes.map((n) => [n.lat, n.lng] as [number, number]);
187-
const { solid, dashed } = buildIntegratedRoute(defaultLinePathsRef.current, userPoints);
189+
const { solid, dashed, removed } = buildIntegratedRoute(defaultLinePathsRef.current, userPoints);
188190
const solidStyle: L.PolylineOptions = { color: "#FF69B4", weight: 5, opacity: 0.9 };
189191
const dashedStyle: L.PolylineOptions = {
190192
color: "#FF69B4",
191193
weight: 5,
192194
opacity: 0.9,
193195
dashArray: "10, 10",
194196
};
197+
const removedStyle: L.PolylineOptions = { color: "#FF69B4", weight: 5, opacity: 0.6 };
195198

199+
for (const points of removed) {
200+
routeLayersRef.current.push(L.polyline(points as L.LatLngExpression[], removedStyle).addTo(map));
201+
}
196202
for (const points of solid) {
197203
routeLayersRef.current.push(L.polyline(points as L.LatLngExpression[], solidStyle).addTo(map));
198204
}
@@ -257,6 +263,43 @@ const MapPage = () => {
257263
localSites.forEach((site) => placeMemorial(site, false));
258264
}, [pinkNodes, centralSite, localSites, defaultLineLoaded]);
259265

266+
useEffect(() => {
267+
if (!mapRef.current) return;
268+
if (pendingPinkMarkerRef.current) {
269+
try { mapRef.current.removeLayer(pendingPinkMarkerRef.current); } catch (_) {}
270+
pendingPinkMarkerRef.current = null;
271+
}
272+
if (pendingPinkTarget) {
273+
pendingPinkMarkerRef.current = L.marker([pendingPinkTarget.lat, pendingPinkTarget.lng], {
274+
icon: L.divIcon({
275+
className: "pink-line-node-marker",
276+
html: `<div class="pink-line-node">+</div>`,
277+
iconSize: [30, 30],
278+
iconAnchor: [15, 15],
279+
}),
280+
}).addTo(mapRef.current);
281+
}
282+
}, [pendingPinkTarget]);
283+
284+
useEffect(() => {
285+
if (!mapRef.current) return;
286+
if (pendingMemorialMarkerRef.current) {
287+
try { mapRef.current.removeLayer(pendingMemorialMarkerRef.current); } catch (_) {}
288+
pendingMemorialMarkerRef.current = null;
289+
}
290+
if (pendingMemorialTarget) {
291+
const iconUrl = pendingMemorialTarget.type === "central" ? regionalMemorialIconUrl : localMemorialIconUrl;
292+
pendingMemorialMarkerRef.current = L.marker([pendingMemorialTarget.lat, pendingMemorialTarget.lng], {
293+
icon: L.icon({
294+
iconUrl,
295+
iconSize: [40, 40],
296+
iconAnchor: [20, 20],
297+
popupAnchor: [0, -20],
298+
}),
299+
}).addTo(mapRef.current);
300+
}
301+
}, [pendingMemorialTarget]);
302+
260303
const hasPink = pinkNodes.length > 0;
261304
const hasMemorial = useMemo(() => Boolean(centralSite) || localSites.length > 0, [centralSite, localSites.length]);
262305

src/utils/pinkLineRoute.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ function orderPointsBetweenEndpoints(
146146
export interface IntegratedRoute {
147147
solid: LatLng[][];
148148
dashed: LatLng[][];
149+
removed: LatLng[][];
149150
}
150151

151152
export function buildIntegratedRoute(
@@ -154,13 +155,14 @@ export function buildIntegratedRoute(
154155
): IntegratedRoute {
155156
const solid: LatLng[][] = [];
156157
const dashed: LatLng[][] = [];
158+
const removed: LatLng[][] = [];
157159

158160
const basePath = mergePaths(basePaths);
159-
if (basePath.length === 0) return { solid, dashed };
161+
if (basePath.length === 0) return { solid, dashed, removed };
160162

161163
if (userPoints.length === 0) {
162164
solid.push([...basePath]);
163-
return { solid, dashed };
165+
return { solid, dashed, removed };
164166
}
165167

166168
const prefix = buildPrefixDistances(basePath);
@@ -188,6 +190,7 @@ export function buildIntegratedRoute(
188190
inThisDetour.map((x) => x.point)
189191
);
190192
dashed.push([leave, ...pointsInOrder, rejoin]);
193+
removed.push(basePath.slice(intr.start, intr.end + 1));
191194
}
192195

193196
let lastEnd = 0;
@@ -201,5 +204,5 @@ export function buildIntegratedRoute(
201204
solid.push(basePath.slice(lastEnd, basePath.length));
202205
}
203206

204-
return { solid, dashed };
207+
return { solid, dashed, removed };
205208
}

0 commit comments

Comments
 (0)