JSFiddle - React, Tailwind, and code Playground

by jrunning

JavaScript

const INCREMENT = 1800;

function rangeIncl(start, end, incr = INCREMENT) {
	return start < end ? [start, ...rangeIncl(start + incr, end)] : [end];
}

function timeslotGroups(startTimeslot, endTimeslot, bookings) {
	const [booking, ...restBookings] = bookings;
  
	if (booking) {
    if (startTimeslot < booking.from) {
    	// startTimeslot is before next booking.from; create available group
      return [
      	{ available: true, timeslots: rangeIncl(startTimeslot, booking.from - INCREMENT) },
        ...timeslotGroups(booking.from, endTimeslot, bookings),
      ];
    }

    if (startTimeslot <= booking.to) {
    	// startTimeslot is between booking.from and .to; create not-available group
      return [
      	{ available: false, timeslots: rangeIncl(booking.from, booking.to) },
        ...timeslotGroups(booking.to + INCREMENT, endTimeslot, restBookings),
      ];
    }
    
    // startTimeslot is after booking.to; try again with next booking
    return timeslotGroups(startTimeslot, endTimeslot, restBookings);
  }
    
  return startTimeslot < endTimeslot ?
  	[ { available: true, timeslots: rangeIncl(startTimeslot, endTimeslot) } ] :
    [];
}

const availableTimeslots = [
  1559709000, 1559710800, 1559712600, 1559714400, 1559716200, 1559718000,
  1559719800, 1559721600, 1559723400, 1559725200, 1559727000, 1559728800,
  1559730600, 1559732400, 1559734200, 1559736000, 1559737800, 1559739600,
];

const bookedTimeslots = {
  bookings: [
    {
      timestamp: {
        from: 1559719800,
        to: 1559723400
      }
    },
    {
      timestamp: {
        from: 1559730600,
        to: 1559732400
      }
    }
  ]
};

const bookings = bookedTimeslots.bookings.map(({ timestamp }) => timestamp);

const res = timeslotGroups(availableTimeslots[0], availableTimeslots[availableTimeslots.length - 1], bookings);

console.log(res);

/* DESIRED RESULT
[
  {
    available: true,
    timeslots: [1559709000, 1559710800, 1559712600, 1559714400, 1559716200, 1559718000]
  },
 ...