cal.pub0.org/components/booking/AvailableTimes.tsx

89 lines
3.0 KiB
TypeScript
Raw Normal View History

2021-06-19 22:50:47 +00:00
import dayjs, {Dayjs} from "dayjs";
import isBetween from 'dayjs/plugin/isBetween';
dayjs.extend(isBetween);
import {useEffect, useMemo, useState} from "react";
import getSlots from "../../lib/slots";
import Link from "next/link";
import {timeZone} from "../../lib/clock";
import {useRouter} from "next/router";
const AvailableTimes = (props) => {
const router = useRouter();
const { user, rescheduleUid } = router.query;
const [loaded, setLoaded] = useState(false);
2021-06-19 22:50:47 +00:00
const times = useMemo(() =>
getSlots({
calendarTimeZone: props.user.timeZone,
selectedTimeZone: timeZone(),
eventLength: props.eventType.length,
selectedDate: props.date,
dayStartTime: props.user.startTime,
dayEndTime: props.user.endTime,
})
, [])
const handleAvailableSlots = (busyTimes: []) => {
2021-06-19 22:50:47 +00:00
// Check for conflicts
for (let i = times.length - 1; i >= 0; i -= 1) {
busyTimes.forEach(busyTime => {
2021-06-19 22:50:47 +00:00
let startTime = dayjs(busyTime.start);
let endTime = dayjs(busyTime.end);
// Check if start times are the same
if (dayjs(times[i]).format('HH:mm') == startTime.format('HH:mm')) {
times.splice(i, 1);
}
// Check if time is between start and end times
if (dayjs(times[i]).isBetween(startTime, endTime)) {
times.splice(i, 1);
}
// Check if slot end time is between start and end time
if (dayjs(times[i]).add(props.eventType.length, 'minutes').isBetween(startTime, endTime)) {
times.splice(i, 1);
}
// Check if startTime is between slot
if (startTime.isBetween(dayjs(times[i]), dayjs(times[i]).add(props.eventType.length, 'minutes'))) {
times.splice(i, 1);
}
});
}
// Display available times
setLoaded(true);
};
2021-06-19 22:50:47 +00:00
// Re-render only when invitee changes date
useEffect(() => {
setLoaded(false);
fetch(`/api/availability/${user}?dateFrom=${props.date.startOf('day').utc().format()}&dateTo=${props.date.endOf('day').utc().format()}`)
.then( res => res.json())
.then(handleAvailableSlots);
}, [props.date]);
2021-06-19 22:50:47 +00:00
return (
<div className="sm:pl-4 mt-8 sm:mt-0 text-center sm:w-1/3 md:max-h-97 overflow-y-auto">
<div className="text-gray-600 font-light text-xl mb-4 text-left">
<span className="w-1/2">
{props.date.format("dddd DD MMMM YYYY")}
</span>
</div>
{
loaded ? times.map((time) =>
<div key={dayjs(time).utc().format()}>
<Link
href={`/${props.user.username}/book?date=${dayjs(time).utc().format()}&type=${props.eventType.id}` + (rescheduleUid ? "&rescheduleUid=" + rescheduleUid : "")}>
<a key={dayjs(time).format("hh:mma")}
className="block font-medium mb-4 text-blue-600 border border-blue-600 rounded hover:text-white hover:bg-blue-600 py-4">{dayjs(time).tz(timeZone()).format(props.timeFormat)}</a>
</Link>
</div>
) : <div className="loader"></div>
}
2021-06-19 22:50:47 +00:00
</div>
);
}
export default AvailableTimes;