mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 07:40:59 +00:00
fix(collections): pins on the map show their place's category (#3073)
The server nests a saved place's category, while the markers and the hover card read the flat fields a trip place carries, so every pin on a collection's map was the grey default. The map now hands its places on with the category's colour, icon and name where the markers look for them.
This commit is contained in:
@@ -12,6 +12,7 @@ import L from 'leaflet';
|
||||
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { act, render, waitFor } from '../../../tests/helpers/render';
|
||||
import { resetAllStores } from '../../../tests/helpers/store';
|
||||
import { withMarkerCategory } from '../../pages/collections/collectionsModel';
|
||||
import CollectionMap from './CollectionMap';
|
||||
|
||||
vi.mock('../../hooks/useGeolocation', () => ({
|
||||
@@ -258,3 +259,26 @@ describe('CollectionMap framing', () => {
|
||||
expect(wrappedIn(map, '[--bottom-nav-h:0px]')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('CollectionMap pins (#3073)', () => {
|
||||
const MUSEUM = { id: 4, name: 'Museum', color: '#7c3aed', icon: 'Landmark' };
|
||||
|
||||
it('FE-COMP-COLMAP-008: a saved place carries its category where the markers read it', () => {
|
||||
const pin = withMarkerCategory({ ...place(1, 'Belvedere', 48.1915, 16.3809), category_id: 4, category: MUSEUM });
|
||||
expect(pin).toMatchObject({ category_name: 'Museum', category_color: '#7c3aed', category_icon: 'Landmark' });
|
||||
expect(withMarkerCategory(place(2, 'Somewhere', 48.2, 16.37))).toMatchObject({
|
||||
category_name: null,
|
||||
category_color: null,
|
||||
category_icon: null,
|
||||
});
|
||||
});
|
||||
|
||||
it('FE-COMP-COLMAP-009: the pin of a place with a category wears its colour, not the grey default', async () => {
|
||||
const { view } = await renderMap([
|
||||
{ ...place(1, 'Belvedere', 48.1915, 16.3809), category_id: 4, category: MUSEUM },
|
||||
]);
|
||||
await waitFor(() => expect(view.container.querySelector('.leaflet-marker-icon')).not.toBeNull());
|
||||
const html = view.container.querySelector('.leaflet-marker-icon')?.innerHTML ?? '';
|
||||
expect(html.toLowerCase()).toContain('#7c3aed');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useMemo } from 'react'
|
||||
import { MapViewAuto } from '../Map/MapViewAuto'
|
||||
import type { CollectionPlace } from '@trek/shared'
|
||||
import { mappablePlaces } from '../../pages/collections/collectionsModel'
|
||||
import { mappablePlaces, withMarkerCategory } from '../../pages/collections/collectionsModel'
|
||||
import { useTileUrl } from '../../hooks/useTileUrl'
|
||||
import { OFM_DARK, OFM_POSITRON } from '../../constants/mapDefaults'
|
||||
import type { ViewportPadding } from '../../utils/mapViewport'
|
||||
@@ -70,7 +70,7 @@ function framePoints(places: CollectionPlace[]): [number, number][] {
|
||||
* while the map is built rather than flying in.
|
||||
*/
|
||||
export default function CollectionMap({ places, selectedPlaceId, onOpenPlace, onDeselect, dark, underBar = false }: CollectionMapProps): React.ReactElement {
|
||||
const pts = useMemo(() => mappablePlaces(places), [places])
|
||||
const pts = useMemo(() => mappablePlaces(places).map(withMarkerCategory), [places])
|
||||
const tileUrl = useTileUrl(dark ? OFM_DARK : OFM_POSITRON)
|
||||
const focusPoints = useMemo(() => framePoints(pts), [pts])
|
||||
// The places as a set: another list, a filter or a new place frames again, while a
|
||||
|
||||
@@ -93,6 +93,25 @@ export function mappablePlaces(places: CollectionPlace[]): CollectionPlace[] {
|
||||
return places.filter(p => p && typeof p.lat === 'number' && typeof p.lng === 'number')
|
||||
}
|
||||
|
||||
/**
|
||||
* A saved place with its category where the trip map reads it. The server nests a
|
||||
* collection place's category (`category.color`), the markers and the hover card
|
||||
* read the flat fields a trip place carries, so every pin here was the grey default
|
||||
* (#3073).
|
||||
*/
|
||||
export function withMarkerCategory(place: CollectionPlace): CollectionPlace & {
|
||||
category_name: string | null
|
||||
category_color: string | null
|
||||
category_icon: string | null
|
||||
} {
|
||||
return {
|
||||
...place,
|
||||
category_name: place.category?.name ?? null,
|
||||
category_color: place.category?.color ?? null,
|
||||
category_icon: place.category?.icon ?? null,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalise a user-typed link: prepend https:// when there's no scheme so the
|
||||
* href is absolute (a bare "booking.com" would otherwise resolve relative to the
|
||||
|
||||
Reference in New Issue
Block a user