all repos — caroster @ mdraps-main-patch-e989

[Octree] Group carpool to your event https://caroster.io

frontend/containers/TravelColumns/useDisplayMarkers.tsx (view raw)

  1import moment from 'moment';
  2import {useEffect, useMemo} from 'react';
  3import useMapStore from '../../stores/useMapStore';
  4import dynamic from 'next/dynamic';
  5import {Event} from '../../generated/graphql';
  6import useTravelsStore from '../../stores/useTravelsStore';
  7import {calculateHaversineDistance} from '../../lib/geography';
  8
  9const EventMarker = dynamic(() => import('../Markers/EventMarker'), {
 10  ssr: false,
 11});
 12const TravelMarker = dynamic(() => import('../Markers/TravelMarker'), {
 13  ssr: false,
 14});
 15const MeetingFilterMarker = dynamic(
 16  () => import('../Markers/MeetingFilterMarker'),
 17  {ssr: false}
 18);
 19
 20interface Props {
 21  event: Event & {id: string};
 22}
 23
 24const useDisplayMarkers = ({event}: Props) => {
 25  const setMarkers = useMapStore(s => s.setMarkers);
 26  const setBounds = useMapStore(s => s.setBounds);
 27  const focusedTravel = useMapStore(s => s.focusedTravel);
 28  const datesFilters = useTravelsStore(s => s.datesFilter);
 29  const meetingFilter = useTravelsStore(s => s.meetingFilter);
 30
 31  const travelsWithGeoloc = useMemo(() => {
 32    const travels = event?.travels?.data || [];
 33    const filteredTravels =
 34      datesFilters.length >= 1
 35        ? travels.filter(travel => {
 36            const departureDate = moment(travel?.attributes?.departureDate);
 37            return datesFilters.some(date => date.isSame(departureDate, 'day'));
 38          })
 39        : travels;
 40
 41    return filteredTravels.filter(
 42      travel =>
 43        travel.attributes.meeting_latitude &&
 44        travel.attributes.meeting_longitude
 45    );
 46  }, [event, datesFilters]);
 47
 48  // Set markers
 49  useEffect(() => {
 50    let markers = [];
 51
 52    // Set event marker
 53    const {latitude, longitude} = event || {};
 54    if (latitude && longitude)
 55      markers.push(<EventMarker key="event" event={event} />);
 56
 57    // Set meeting filter marker
 58    if (meetingFilter?.latitude && meetingFilter?.longitude)
 59      markers.push(
 60        <MeetingFilterMarker
 61          center={[meetingFilter.latitude, meetingFilter.longitude]}
 62        />
 63      );
 64
 65    // Set travels markers
 66    const travelMarkers = travelsWithGeoloc.map(travel => (
 67      <TravelMarker
 68        key={travel.id}
 69        travel={travel}
 70        focused={focusedTravel === travel.id}
 71      />
 72    ));
 73    markers.push(...travelMarkers);
 74
 75    setMarkers(markers);
 76  }, [event, travelsWithGeoloc, focusedTravel, setMarkers, meetingFilter]);
 77
 78  // Set bounds
 79  useEffect(() => {
 80    let bounds = [];
 81
 82    if (meetingFilter?.latitude && meetingFilter?.longitude) {
 83      bounds.push([meetingFilter.latitude, meetingFilter.longitude]);
 84
 85      // Set travels bounds
 86      const travelCoords = travelsWithGeoloc
 87        .map(travel => ({
 88          ...travel,
 89          distance: calculateHaversineDistance(
 90            [meetingFilter.latitude, meetingFilter.longitude],
 91            [
 92              travel.attributes.meeting_latitude,
 93              travel.attributes.meeting_longitude,
 94            ]
 95          ),
 96        }))
 97        .sort((a, b) => a.distance - b.distance)
 98        .slice(0, 3)
 99        .map(travel => [
100          travel.attributes.meeting_latitude,
101          travel.attributes.meeting_longitude,
102        ]);
103      bounds.push(...travelCoords);
104    } else {
105      // Set event bounds
106      const {latitude, longitude} = event || {};
107      if (latitude && longitude) bounds.push([latitude, longitude]);
108      // Set travels bounds
109      const travelCoords = travelsWithGeoloc.map(travel => [
110        travel.attributes.meeting_latitude,
111        travel.attributes.meeting_longitude,
112      ]);
113      bounds.push(...travelCoords);
114    }
115
116    setBounds(bounds);
117  }, [event, travelsWithGeoloc, setBounds, meetingFilter]);
118};
119
120export default useDisplayMarkers;