import type { FormValues } from "@pages/settings/my-account/general"; import { useState } from "react"; import type { UseFormSetValue } from "react-hook-form"; import dayjs from "@calcom/dayjs"; import { useTimePreferences } from "@calcom/features/bookings/lib/timePreferences"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { Dialog, DialogContent, DialogFooter, DialogClose, Button, Label, DateRangePicker, TimezoneSelect, SettingsToggle, DatePicker, } from "@calcom/ui"; interface TravelScheduleModalProps { open: boolean; onOpenChange: () => void; setValue: UseFormSetValue; existingSchedules: FormValues["travelSchedules"]; } const TravelScheduleModal = ({ open, onOpenChange, setValue, existingSchedules, }: TravelScheduleModalProps) => { const { t } = useLocale(); const { timezone: preferredTimezone } = useTimePreferences(); const [startDate, setStartDate] = useState(new Date()); const [endDate, setEndDate] = useState(new Date()); const [selectedTimeZone, setSelectedTimeZone] = useState(preferredTimezone); const [isNoEndDate, setIsNoEndDate] = useState(false); const [errorMessage, setErrorMessage] = useState(""); const isOverlapping = (newSchedule: { startDate: Date; endDate?: Date }) => { const newStart = dayjs(newSchedule.startDate); const newEnd = newSchedule.endDate ? dayjs(newSchedule.endDate) : null; for (const schedule of existingSchedules) { const start = dayjs(schedule.startDate); const end = schedule.endDate ? dayjs(schedule.endDate) : null; if (!newEnd) { // if the start date is after or on the existing schedule's start date and before the existing schedule's end date (if it has one) if (newStart.isSame(start) || newStart.isAfter(start)) { if (!end || newStart.isSame(end) || newStart.isBefore(end)) return true; } } else { // For schedules with an end date, check for any overlap if (newStart.isSame(end) || newStart.isBefore(end) || end === null) { if (newEnd.isSame(start) || newEnd.isAfter(start)) { return true; } } } } }; const resetValues = () => { setStartDate(new Date()); setEndDate(new Date()); setSelectedTimeZone(preferredTimezone); setIsNoEndDate(false); }; const createNewSchedule = () => { const newSchedule = { startDate, endDate, timeZone: selectedTimeZone, }; if (!isOverlapping(newSchedule)) { setValue("travelSchedules", existingSchedules.concat(newSchedule), { shouldDirty: true }); onOpenChange(); resetValues(); } else { setErrorMessage(t("overlaps_with_existing_schedule")); } }; return (
{!isNoEndDate ? ( <> { // If newStartDate does become undefined - we resort back to to-todays date setStartDate(newStartDate ?? new Date()); setEndDate(newEndDate); setErrorMessage(""); }} /> ) : ( <> { setStartDate(newDate); setErrorMessage(""); }} /> )}
{errorMessage}
{ setEndDate(!e ? startDate : undefined); setIsNoEndDate(e); setErrorMessage(""); }} />
setSelectedTimeZone(value)} className="mb-11 mt-2 w-full rounded-md text-sm" />
); }; export default TravelScheduleModal;