mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-01-14 16:47:55 +00:00
56 lines
1.7 KiB
JavaScript
56 lines
1.7 KiB
JavaScript
async function findAvailableSlots(
|
|
calendar1,
|
|
calendar2,
|
|
{ durationMinutes: dur, searchRange: sr, workHours: wh }
|
|
) {
|
|
const dayjs = (await import('https://cdn.skypack.dev/dayjs')).default;
|
|
const utc = (await import('https://cdn.skypack.dev/dayjs/plugin/utc')).default;
|
|
dayjs.extend(utc);
|
|
|
|
const d = (s) => dayjs.utc(s);
|
|
const rangeStart = d(sr.start);
|
|
const rangeEnd = d(sr.end);
|
|
const [whsH, whsM] = wh.start.split(':');
|
|
const [wheH, wheM] = wh.end.split(':');
|
|
|
|
const busySlots = [...calendar1, ...calendar2].map(({ start, end }) => ({
|
|
start: d(start),
|
|
end: d(end),
|
|
}));
|
|
|
|
for (let day = rangeStart.clone().startOf('d'); day.isBefore(rangeEnd); day = day.add(1, 'd')) {
|
|
busySlots.push({ start: day.startOf('d'), end: day.hour(whsH).minute(whsM) });
|
|
busySlots.push({ start: day.hour(wheH).minute(wheM), end: day.endOf('d') });
|
|
}
|
|
|
|
const merged = busySlots
|
|
.filter(({ start, end }) => start.isBefore(end))
|
|
.sort((a, b) => a.start - b.start)
|
|
.reduce((acc, cur) => {
|
|
const last = acc.at(-1);
|
|
if (!last || cur.start.isAfter(last.end)) {
|
|
acc.push(cur);
|
|
} else if (cur.end.isAfter(last.end)) {
|
|
last.end = cur.end;
|
|
}
|
|
return acc;
|
|
}, []);
|
|
|
|
const available = [];
|
|
let cursor = rangeStart;
|
|
|
|
[...merged, { start: rangeEnd, end: rangeEnd }].forEach((busy) => {
|
|
const gapEnd = busy.start;
|
|
for (let slotStart = cursor; !slotStart.add(dur, 'm').isAfter(gapEnd); slotStart = slotStart.add(dur, 'm')) {
|
|
const slotEnd = slotStart.add(dur, 'm');
|
|
available.push({
|
|
start: slotStart.toISOString(),
|
|
end: slotEnd.toISOString(),
|
|
});
|
|
}
|
|
cursor = cursor.isAfter(busy.end) ? cursor : busy.end;
|
|
});
|
|
|
|
return available;
|
|
}
|
|
export default findAvailableSlots; |