mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-01-14 08:37:56 +00:00
58 lines
2.2 KiB
JavaScript
58 lines
2.2 KiB
JavaScript
export const findAvailableSlots = async (calA, calB, { durationMinutes: dur, searchRange: range, workHours: work }) => {
|
|
const { addMinutes, parseISO } = await import('https://cdn.jsdelivr.net/npm/date-fns@4.1.0/+esm');
|
|
|
|
const toTime = d => d.getTime();
|
|
const toISO = d => d.toISOString();
|
|
|
|
const startLimit = parseISO(range.start);
|
|
const endLimit = parseISO(range.end);
|
|
|
|
let busy = [...calA, ...calB]
|
|
.map(c => ({ s: toTime(parseISO(c.start)), e: toTime(parseISO(c.end)) }))
|
|
.sort((a, b) => a.s - b.s)
|
|
.reduce((acc, c) => {
|
|
const last = acc[acc.length - 1];
|
|
if (last && c.s < last.e) last.e = Math.max(last.e, c.e);
|
|
else acc.push(c);
|
|
return acc;
|
|
}, []);
|
|
|
|
const slots = [];
|
|
let currDate = new Date(Date.UTC(startLimit.getUTCFullYear(), startLimit.getUTCMonth(), startLimit.getUTCDate()));
|
|
|
|
while (toTime(currDate) <= toTime(endLimit)) {
|
|
const dateStr = currDate.toISOString().split('T')[0];
|
|
const workStart = new Date(`${dateStr}T${work.start}:00Z`);
|
|
const workEnd = new Date(`${dateStr}T${work.end}:00Z`);
|
|
|
|
let ptr = toTime(workStart) < toTime(startLimit) ? startLimit : workStart;
|
|
const winEnd = toTime(workEnd) > toTime(endLimit) ? endLimit : workEnd;
|
|
const winEndT = toTime(winEnd);
|
|
|
|
let bIdx = 0;
|
|
|
|
while (toTime(ptr) + (dur * 60000) <= winEndT) {
|
|
const slotEnd = addMinutes(ptr, dur);
|
|
const ptrT = toTime(ptr);
|
|
const slotEndT = toTime(slotEnd);
|
|
|
|
// Fast-forward busy index
|
|
while (busy[bIdx] && busy[bIdx].e <= ptrT) bIdx++;
|
|
|
|
const conflict = busy[bIdx];
|
|
|
|
if (!conflict || conflict.s >= slotEndT) {
|
|
slots.push({ start: toISO(ptr), end: toISO(slotEnd) });
|
|
ptr = slotEnd;
|
|
} else {
|
|
// Overlap detected, jump to end of busy slot
|
|
// Ensure we reconstruct Date from timestamp correctly
|
|
ptr = new Date(conflict.e);
|
|
}
|
|
}
|
|
currDate.setUTCDate(currDate.getUTCDate() + 1);
|
|
}
|
|
|
|
return slots;
|
|
};
|
|
export default findAvailableSlots; |