all repos — caroster @ 1e4cd2561ddba0d298160a89d3e9b78da1e68fe2

[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/travelsStore';
  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    // Set event bounds
 83    const {latitude, longitude} = event || {};
 84    if (latitude && longitude) bounds.push([latitude, longitude]);
 85
 86    if (meetingFilter?.latitude && meetingFilter?.longitude) {
 87      bounds.push([meetingFilter.latitude, meetingFilter.longitude]);
 88
 89      // Set travels bounds
 90      const travelCoords = travelsWithGeoloc
 91        .map(travel => ({
 92          ...travel,
 93          distance: calculateHaversineDistance(
 94            [meetingFilter.latitude, meetingFilter.longitude],
 95            [
 96              travel.attributes.meeting_latitude,
 97              travel.attributes.meeting_longitude,
 98            ]
 99          ),
100        }))
101        .sort((a, b) => a.distance - b.distance)
102        .slice(0, 3)
103        .map(travel => [
104          travel.attributes.meeting_latitude,
105          travel.attributes.meeting_longitude,
106        ]);
107      bounds.push(...travelCoords);
108    } else {
109      // Set travels bounds
110      const travelCoords = travelsWithGeoloc.map(travel => [
111        travel.attributes.meeting_latitude,
112        travel.attributes.meeting_longitude,
113      ]);
114      bounds.push(...travelCoords);
115    }
116
117    setBounds(bounds);
118  }, [event, travelsWithGeoloc, setBounds, meetingFilter]);
119};
120
121export default useDisplayMarkers;