import { Fragment, FC } from "react"; import { useRouter } from "next/router"; import { useForm, Controller } from "react-hook-form"; import { X } from "lucide-react"; import { Transition, Dialog } from "@headlessui/react"; import type { IUserNotification } from "@plane/types"; import { Button, CustomSelect, TOAST_TYPE, setToast } from "@plane/ui"; import { DateDropdown } from "@/components/dropdowns"; // constants import { allTimeIn30MinutesInterval12HoursFormat } from "@/constants/notification"; // ui // types // helpers import { getDate } from "helpers/date-time.helper"; type SnoozeModalProps = { isOpen: boolean; onClose: () => void; onSuccess: () => void; notification: IUserNotification | null; onSubmit: (notificationId: string, dateTime?: Date | undefined) => Promise; }; type FormValues = { time: string | null; date: Date | null; period: "AM" | "PM"; }; const defaultValues: FormValues = { time: null, date: null, period: "AM", }; const timeStamps = allTimeIn30MinutesInterval12HoursFormat; export const SnoozeNotificationModal: FC = (props) => { const { isOpen, onClose, notification, onSuccess, onSubmit: handleSubmitSnooze } = props; const router = useRouter(); const { workspaceSlug } = router.query; const { formState: { isSubmitting }, reset, handleSubmit, control, watch, setValue, } = useForm({ defaultValues, }); const getTimeStamp = () => { const today = new Date(); const formDataDate = watch("date"); if (!formDataDate) return timeStamps; const isToday = today.toDateString() === getDate(formDataDate)?.toDateString(); if (!isToday) return timeStamps; const hours = today.getHours(); const minutes = today.getMinutes(); return timeStamps.filter((optionTime) => { let optionHours = parseInt(optionTime.value.split(":")[0]); const optionMinutes = parseInt(optionTime.value.split(":")[1]); const period = watch("period"); if (period === "PM" && optionHours !== 12) optionHours += 12; if (optionHours < hours) return false; if (optionHours === hours && optionMinutes < minutes) return false; return true; }); }; const onSubmit = async (formData: FormValues) => { if (!workspaceSlug || !notification || !formData.date || !formData.time) return; const period = formData.period; const time = formData.time.split(":"); const hours = parseInt( `${period === "AM" ? time[0] : parseInt(time[0]) + 12 === 24 ? "00" : parseInt(time[0]) + 12}` ); const minutes = parseInt(time[1]); const dateTime: Date | undefined = getDate(formData?.date); dateTime?.setHours(hours); dateTime?.setMinutes(minutes); await handleSubmitSnooze(notification.id, dateTime).then(() => { handleClose(); onSuccess(); setToast({ title: "Notification snoozed", message: "Notification snoozed successfully", type: TOAST_TYPE.SUCCESS, }); }); }; const handleClose = () => { // This is a workaround to fix the issue of the Notification popover modal close on closing this modal const closeTimeout = setTimeout(() => { onClose(); clearTimeout(closeTimeout); }, 50); const timeout = setTimeout(() => { reset({ ...defaultValues }); clearTimeout(timeout); }, 500); }; return (
Customize Snooze Time
Pick a date
( { setValue("time", null); onChange(val); }} minDate={new Date()} buttonVariant="border-with-text" buttonContainerClassName="w-full text-left" buttonClassName="border-custom-border-300 px-3 py-2.5" hideIcon /> )} />
Pick a time
( {value ? ( {value} {watch("period").toLowerCase()} ) : ( Select a time )}
} optionsClassName="w-full" input >
{ setValue("period", "AM"); }} className={`flex h-full w-1/2 cursor-pointer items-center justify-center text-center ${ watch("period") === "AM" ? "bg-custom-primary-100/90 text-custom-primary-0" : "bg-custom-background-80" }`} > AM
{ setValue("period", "PM"); }} className={`flex h-full w-1/2 cursor-pointer items-center justify-center text-center ${ watch("period") === "PM" ? "bg-custom-primary-100/90 text-custom-primary-0" : "bg-custom-background-80" }`} > PM
{getTimeStamp().length > 0 ? ( getTimeStamp().map((time, index) => (
{time.label}
)) ) : (

No available time for this date.

)} )} />
); };