export type ReminderOffsetUnit = "minutes" | "hours" | "days" | "weeks"; export type ReminderPreset = { label: string; offsetMinutes: number; }; export const REMINDER_PRESETS: ReminderPreset[] = [ { label: "At event time", offsetMinutes: 0 }, { label: "5 minutes before", offsetMinutes: 5 }, { label: "15 minutes before", offsetMinutes: 15 }, { label: "30 minutes before", offsetMinutes: 30 }, { label: "1 hour before", offsetMinutes: 60 }, { label: "2 hours before", offsetMinutes: 120 }, { label: "1 day before", offsetMinutes: 1440 }, { label: "2 days before", offsetMinutes: 2880 }, { label: "1 week before", offsetMinutes: 10080 }, ]; export function formatReminderOffset(offsetMinutes: number): string { const preset = REMINDER_PRESETS.find((p) => p.offsetMinutes === offsetMinutes); if (preset) return preset.label; if (offsetMinutes === 0) return "At event time"; if (offsetMinutes % 10080 === 0) { const weeks = offsetMinutes / 10080; return weeks === 1 ? "1 week before" : `${weeks} weeks before`; } if (offsetMinutes % 1440 === 0) { const days = offsetMinutes / 1440; return days === 1 ? "1 day before" : `${days} days before`; } if (offsetMinutes % 60 === 0) { const hours = offsetMinutes / 60; return hours === 1 ? "1 hour before" : `${hours} hours before`; } return offsetMinutes === 1 ? "1 minute before" : `${offsetMinutes} minutes before`; } export function customOffsetToMinutes(value: number, unit: ReminderOffsetUnit): number { const safe = Math.max(0, Math.floor(value)); switch (unit) { case "minutes": return safe; case "hours": return safe * 60; case "days": return safe * 1440; case "weeks": return safe * 10080; } } export function normalizeReminderOffsets(offsets: number[]): number[] { return [...new Set(offsets.filter((n) => Number.isFinite(n) && n >= 0))].toSorted( (a, b) => b - a, ); } export function fireAtForEventStart(startAt: Date, offsetMinutes: number): Date { return new Date(startAt.getTime() - offsetMinutes * 60_000); }