mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-01-14 16:47:55 +00:00
51 lines
1.8 KiB
JavaScript
51 lines
1.8 KiB
JavaScript
const findAvailableSlots = async (calA, calB, { durationMinutes: dur, searchRange: rng, workHours: wh }) => {
|
|
const { parseISO, addMinutes } = await import('https://cdn.jsdelivr.net/npm/date-fns@2.30.0/+esm');
|
|
const [startR, endR] = [parseISO(rng.start), parseISO(rng.end)];
|
|
|
|
const busy = [...calA, ...calB]
|
|
.map(x => ({ s: parseISO(x.start), e: parseISO(x.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 = new Date(Math.max(last.e, c.e));
|
|
else acc.push(c);
|
|
return acc;
|
|
}, []);
|
|
|
|
const slots = [];
|
|
let currDate = new Date(Date.UTC(startR.getUTCFullYear(), startR.getUTCMonth(), startR.getUTCDate()));
|
|
const lastDate = new Date(Date.UTC(endR.getUTCFullYear(), endR.getUTCMonth(), endR.getUTCDate()));
|
|
|
|
while (currDate <= lastDate) {
|
|
const dStr = currDate.toISOString().split('T')[0];
|
|
const wStart = parseISO(`${dStr}T${wh.start}:00Z`);
|
|
const wEnd = parseISO(`${dStr}T${wh.end}:00Z`);
|
|
|
|
const winStart = wStart < startR ? startR : wStart;
|
|
const winEnd = wEnd > endR ? endR : wEnd;
|
|
|
|
if (winStart < winEnd) {
|
|
let cursor = winStart;
|
|
const relevant = busy.filter(b => b.s < winEnd && b.e > winStart);
|
|
|
|
for (const b of relevant) {
|
|
while (addMinutes(cursor, dur) <= b.s) {
|
|
const next = addMinutes(cursor, dur);
|
|
slots.push({ start: cursor.toISOString(), end: next.toISOString() });
|
|
cursor = next;
|
|
}
|
|
if (cursor < b.e) cursor = b.e;
|
|
}
|
|
|
|
while (addMinutes(cursor, dur) <= winEnd) {
|
|
const next = addMinutes(cursor, dur);
|
|
slots.push({ start: cursor.toISOString(), end: next.toISOString() });
|
|
cursor = next;
|
|
}
|
|
}
|
|
currDate.setUTCDate(currDate.getUTCDate() + 1);
|
|
}
|
|
|
|
return slots;
|
|
};
|
|
export default findAvailableSlots; |