mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-24 07:53:09 +00:00
feat(collections): filters, add-place popup, category badges, map-click hardening (#1081)
- Map: markers no longer rebuild on every unrelated re-render (memoised the mappable list + only update the hero size when it really changes), the floating controls bar is click-through except its buttons, and the collection map runs with the hover tooltip off. Together these stop a marker click from landing on a mid-rebuild element / the tooltip so the pick actually registers. - Filters moved out of the hero into a compact status + category dropdown row above the places (custom dropdowns); the hero no longer carries the stat chips. - Add-place is a single popup now: search fills the location, and name / status / category / description / links are all editable together before saving. - Category shown as a badge top-left on the detail cover and next to the status in each list row (divided by a hairline). - Slimmer hero: shorter, tighter spacing, links tucked into the eyebrow row instead of their own line.
This commit is contained in:
@@ -412,6 +412,7 @@ export const MapView = memo(function MapView({
|
||||
route = null,
|
||||
routeSegments = [],
|
||||
selectedPlaceId = null,
|
||||
hoverDisabled = false,
|
||||
onMarkerClick,
|
||||
onMapClick,
|
||||
onMapContextMenu = null,
|
||||
@@ -464,9 +465,10 @@ export const MapView = memo(function MapView({
|
||||
const [tooltipPos, setTooltipPos] = useState<{ x: number; y: number } | null>(null)
|
||||
|
||||
const handleMarkerHover = useCallback((place: any, x: number, y: number) => {
|
||||
if (hoverDisabled) return
|
||||
setHoveredPlace(place)
|
||||
setTooltipPos({ x, y })
|
||||
}, [])
|
||||
}, [hoverDisabled])
|
||||
|
||||
const handleMarkerHoverOut = useCallback(() => {
|
||||
setHoveredPlace(null)
|
||||
@@ -601,7 +603,7 @@ export const MapView = memo(function MapView({
|
||||
} catch { return [] }
|
||||
}), [places])
|
||||
|
||||
const TooltipOverlay = hoveredPlace && tooltipPos && !isTouchDevice
|
||||
const TooltipOverlay = !hoverDisabled && hoveredPlace && tooltipPos && !isTouchDevice
|
||||
const CatIcon = TooltipOverlay ? getCategoryIcon(hoveredPlace.category_icon) : null
|
||||
|
||||
const { position: userPosition, mode: trackingMode, error: trackingError, cycleMode: cycleTrackingMode } = useGeolocation()
|
||||
|
||||
@@ -68,6 +68,7 @@ interface Props {
|
||||
routeSegments?: RouteSegment[]
|
||||
selectedPlaceId?: number | null
|
||||
onMarkerClick?: (id: number) => void
|
||||
hoverDisabled?: boolean
|
||||
onMapClick?: (info: { latlng: { lat: number; lng: number } }) => void
|
||||
onMapContextMenu?: ((e: { latlng: { lat: number; lng: number }; originalEvent: MouseEvent }) => void) | null
|
||||
center?: [number, number]
|
||||
@@ -184,6 +185,7 @@ export function MapViewGL({
|
||||
route = null,
|
||||
routeSegments = [],
|
||||
selectedPlaceId = null,
|
||||
hoverDisabled = false,
|
||||
onMarkerClick,
|
||||
onMapClick,
|
||||
onMapContextMenu = null,
|
||||
@@ -264,6 +266,8 @@ export function MapViewGL({
|
||||
onClickRefs.current.marker = onMarkerClick
|
||||
onClickRefs.current.map = onMapClick
|
||||
onClickRefs.current.context = onMapContextMenu
|
||||
const hoverDisabledRef = useRef(hoverDisabled)
|
||||
hoverDisabledRef.current = hoverDisabled
|
||||
|
||||
// Build/rebuild the map on provider/style/token/3d change
|
||||
useEffect(() => {
|
||||
@@ -649,14 +653,17 @@ export function MapViewGL({
|
||||
onClickRefs.current.marker?.(place.id)
|
||||
})
|
||||
el.addEventListener('mouseenter', (ev) => {
|
||||
if (hoverDisabledRef.current) return
|
||||
hoverIdRef.current = place.id
|
||||
setHoverPlace(place as Place & { category_color?: string; category_icon?: string; category_name?: string })
|
||||
setHoverPos({ x: (ev as MouseEvent).clientX, y: (ev as MouseEvent).clientY })
|
||||
})
|
||||
el.addEventListener('mousemove', (ev) => {
|
||||
if (hoverDisabledRef.current) return
|
||||
setHoverPos({ x: (ev as MouseEvent).clientX, y: (ev as MouseEvent).clientY })
|
||||
})
|
||||
el.addEventListener('mouseleave', () => {
|
||||
if (hoverDisabledRef.current) return
|
||||
hoverIdRef.current = null
|
||||
setHoverPlace(null)
|
||||
setHoverPos(null)
|
||||
@@ -946,7 +953,7 @@ export function MapViewGL({
|
||||
)}
|
||||
{/* Hover tooltip — cursor-following name/category/address card, identical to
|
||||
the Leaflet map's overlay (no anchored popup, no photo). */}
|
||||
{hoverPlace && hoverPos && !isMobile && (
|
||||
{!hoverDisabled && hoverPlace && hoverPos && !isMobile && (
|
||||
<div data-testid="tooltip" style={{
|
||||
position: 'fixed',
|
||||
left: hoverPos.x + 14,
|
||||
|
||||
Reference in New Issue
Block a user