Search code examples
react-nativedate-fns

date fns user availability


Any thoughts on how to get timeslots considering availability and bookings that have been made on the selected day? Get all bookings for that day and course and

var timeslots = [];

  // what is already reserved
  var bookings = [
   { id: '1', startDate: new Date(2022, 7, 15, 11, 0),  endDate: new Date(2022, 7, 15, 12, 0) },
    { id: '2', startDate: new Date(2022, 7, 15, 14, 0),  endDate: new Date(2022, 7, 15, 15, 0) }
  ];

  // what is indicated as free time
  var availability = [
    { id: '1', startDate: new Date(2022, 7, 15, 9, 0),  endDate: new Date(2022, 7, 15, 13, 0) },
    { id: '2', startDate: new Date(2022, 7, 15, 14, 0),  endDate: new Date(2022, 7, 15, 18, 0) },
  ];

// selected course with duration
  var courses = [
    { id: '1', duration: 30, title: 'Hello 30' }, 
    { id: '2', duration: 45, title: 'Hello 45' }, 
    { id: '3', duration: 60, title: 'Hello 60' }, 
    { id: '4', duration: 90, title: 'Hello 90' }
  ];

  while (isBefore(availability[0].startDate, availability[0].endDate)) {
    let currentStartDate = availability[0].startDate;
    availability[0].startDate = roundToNearestMinutes(addMinutes(availability[0].startDate, courses[0].duration), { nearestTo: 30 });
    timeslots.push(format(currentStartDate, 'p') + ' - ' + format(availability[0].startDate, 'p'));
  }

VIEW

// simple output to see timeslots
{timeslots.map((item) => 
  <Text>{item}</Text>
)}

Solution

  • I was able to solve this by slightly updating the logic and using the areIntervalsOverlapping of date-fns. The draft working solution is below.

      var timeslots = [];
    
      var bookings = [
        { id: '1', startDate: new Date(2022, 7, 15, 11, 0),  endDate: new Date(2022, 7, 15, 12, 0) },
        { id: '2', startDate: new Date(2022, 7, 15, 14, 0),  endDate: new Date(2022, 7, 15, 15, 0) }
      ];
    
      var availabilities = [
        { id: '1', startDate: new Date(2022, 7, 15, 9, 0),  endDate: new Date(2022, 7, 15, 13, 0) },
        { id: '2', startDate: new Date(2022, 7, 15, 14, 0),  endDate: new Date(2022, 7, 15, 18, 0) }
      ];
    
      var courses = [
        { id: '1', duration: 30, title: 'Hello 30' }, 
        { id: '2', duration: 45, title: 'Hello 45' }, 
        { id: '3', duration: 60, title: 'Hello 60' }, 
        { id: '4', duration: 90, title: 'Hello 90' }
      ];
    
      let SELECTED_COURSE = courses[1];
    
      for (let availability of availabilities) {
        while (isBefore(availability.startDate, availability.endDate)) {
          let currentStartDate = availability.startDate;
          availability.startDate = roundToNearestMinutes(addMinutes(availability.startDate, SELECTED_COURSE.duration), { nearestTo: 30 });
    
          timeslots.push(
            {
              startDate: currentStartDate,
              endDate: availability.startDate,
              formattedStartDate: format(currentStartDate, 'p'),
              formattedEndDate: format(availability.startDate, 'p')
            }
          );
        }
      }
    
      for (let booking of bookings) {
        for (var j = 0; j < timeslots.length; j++) {
          let isOverlapping = areIntervalsOverlapping({ start: booking.startDate, end: booking.endDate }, { start: timeslots[j].startDate, end: timeslots[j].endDate });
          
          if (isOverlapping) {
            timeslots.splice(j, 1);
          }
        }
      }