mirror of
https://github.com/multipleof4/lynchmark.git
synced 2026-01-14 16:47:55 +00:00
49 lines
1.7 KiB
JavaScript
49 lines
1.7 KiB
JavaScript
export const findAvailableSlots = async (cal1, cal2, { durationMinutes: dur, searchRange: range, workHours: wh }) => {
|
|
const { parseISO, addMinutes } = await import('https://cdn.jsdelivr.net/npm/date-fns@3.3.1/+esm');
|
|
|
|
const toTime = (d) => parseISO(d).getTime();
|
|
const rStart = toTime(range.start);
|
|
const rEnd = toTime(range.end);
|
|
|
|
const [wStart, wEnd] = [wh.start, wh.end].map(t => t.split(':').reduce((h, m) => h * 60 + +m, 0));
|
|
const getMins = (d) => d.getUTCHours() * 60 + d.getUTCMinutes();
|
|
|
|
const busy = [...cal1, ...cal2]
|
|
.map(x => ({ s: Math.max(rStart, toTime(x.start)), e: Math.min(rEnd, toTime(x.end)) }))
|
|
.filter(x => x.s < x.e)
|
|
.sort((a, b) => a.s - b.s);
|
|
|
|
const merged = [];
|
|
if (busy.length) {
|
|
let curr = busy[0];
|
|
for (const b of busy) {
|
|
if (b.s <= curr.e) curr.e = Math.max(curr.e, b.e);
|
|
else { merged.push(curr); curr = b; }
|
|
}
|
|
merged.push(curr);
|
|
}
|
|
|
|
const slots = [];
|
|
let cursor = rStart;
|
|
const blocks = [...merged, { s: rEnd, e: rEnd }];
|
|
|
|
for (const b of blocks) {
|
|
while (cursor + dur * 60000 <= b.s) {
|
|
const start = new Date(cursor);
|
|
const end = addMinutes(start, dur);
|
|
|
|
if (start.getUTCDay() === end.getUTCDay()) {
|
|
const sM = getMins(start);
|
|
const eM = getMins(end);
|
|
if (sM >= wStart && eM <= wEnd) {
|
|
slots.push({ start: start.toISOString(), end: end.toISOString() });
|
|
}
|
|
}
|
|
cursor = end.getTime();
|
|
}
|
|
cursor = Math.max(cursor, b.e);
|
|
}
|
|
|
|
return slots;
|
|
};
|
|
export default findAvailableSlots; |