import { bind } from 'bind-event-listener'; import { AnimatePresence, motion } from 'framer-motion'; import { useEffect, useRef, useState } from 'react'; import { MapBadgeDetailCard } from './map-badge-detail-card'; import { closeMapBadgeDetails } from './realtime-map-badge-slice'; import { useDispatch, useSelector } from '@/redux'; export function MapBadgeDetails({ containerRef, }: { containerRef: React.RefObject; }) { const dispatch = useDispatch(); const panelRef = useRef(null); const { open, marker, projectId } = useSelector( (state) => state.realtimeMapBadge ); const [overlaySize, setOverlaySize] = useState<{ width: number; height: number; } | null>(null); useEffect(() => { if (!(open && marker)) { return; } const onPointerDown = (event: MouseEvent) => { if (!panelRef.current?.contains(event.target as Node)) { dispatch(closeMapBadgeDetails()); } }; const onKeyDown = (event: KeyboardEvent) => { if (event.key === 'Escape') { dispatch(closeMapBadgeDetails()); } }; window.addEventListener('mousedown', onPointerDown); window.addEventListener('keydown', onKeyDown); return () => { window.removeEventListener('mousedown', onPointerDown); window.removeEventListener('keydown', onKeyDown); }; }, [dispatch, marker, open]); useEffect(() => { const measure = () => { const rect = containerRef.current?.getBoundingClientRect(); if (!rect) { return; } setOverlaySize({ width: rect.width, height: rect.height }); }; measure(); return bind(window, { type: 'resize', listener: measure, }); }, [containerRef]); if (!(open && marker && projectId && overlaySize)) { return null; } return ( dispatch(closeMapBadgeDetails())} type="button" /> dispatch(closeMapBadgeDetails())} panelRef={panelRef} projectId={projectId} size={overlaySize} /> ); }