From 134e0f75ea81d1c07dd4d87f6270671e4e3d7a7d Mon Sep 17 00:00:00 2001 From: npub1mn7jgtj4w2pd0g0zeuhxsa6jy6p0rewxz4kujt98my82ahfmp72sxjexk7 Date: Thu, 11 Jun 2026 15:28:34 -0400 Subject: [PATCH] feat(desktop): add custom date/time picker to Remind Me Later dialog Add a "Custom date & time" section below the time presets in the RemindMeLaterDialog, using native date and time inputs styled with the existing Input component. The date picker defaults to today and prevents selecting past dates. A "Set reminder" button creates the reminder at the user-selected timestamp. Also extends the screenshot spec to 6 tests: widens the action menu screenshot clip, adds tests for the reminders panel with active and fired/overdue reminders, and adds KIND_EVENT_REMINDER mock support to the e2e bridge for seeding reminder data in tests. Co-authored-by: Will Pfleger Signed-off-by: Will Pfleger --- .../reminders/ui/RemindMeLaterDialog.tsx | 68 ++++++++- desktop/src/testing/e2eBridge.ts | 35 +++++ .../tests/e2e/reminders-screenshots.spec.ts | 135 +++++++++++++++++- 3 files changed, 235 insertions(+), 3 deletions(-) diff --git a/desktop/src/features/reminders/ui/RemindMeLaterDialog.tsx b/desktop/src/features/reminders/ui/RemindMeLaterDialog.tsx index b61b8ee08..f17ea2793 100644 --- a/desktop/src/features/reminders/ui/RemindMeLaterDialog.tsx +++ b/desktop/src/features/reminders/ui/RemindMeLaterDialog.tsx @@ -1,10 +1,11 @@ -import { Clock } from "lucide-react"; +import { CalendarClock, Clock } from "lucide-react"; import * as React from "react"; import { toast } from "sonner"; import { createReminder } from "@/features/reminders/lib/reminderService"; import type { ReminderTarget } from "@/features/reminders/lib/reminderTypes"; import { Button } from "@/shared/ui/button"; +import { Input } from "@/shared/ui/input"; import { Dialog, DialogContent, @@ -58,6 +59,14 @@ const TIME_PRESETS: TimePreset[] = [ }, ]; +function todayDateString(): string { + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, "0"); + const day = String(now.getDate()).padStart(2, "0"); + return `${year}-${month}-${day}`; +} + export function RemindMeLaterDialog({ open, onOpenChange, @@ -69,6 +78,8 @@ export function RemindMeLaterDialog({ }) { const [note, setNote] = React.useState(""); const [isSubmitting, setIsSubmitting] = React.useState(false); + const [customDate, setCustomDate] = React.useState(todayDateString); + const [customTime, setCustomTime] = React.useState("09:00"); const handleSelect = async (preset: TimePreset) => { if (!target || isSubmitting) return; @@ -86,6 +97,29 @@ export function RemindMeLaterDialog({ } }; + const handleCustomSubmit = async () => { + if (!target || isSubmitting || !customDate || !customTime) return; + setIsSubmitting(true); + try { + const timestamp = Math.floor( + new Date(`${customDate}T${customTime}`).getTime() / 1_000, + ); + if (Number.isNaN(timestamp)) { + toast.error("Invalid date or time"); + return; + } + await createReminder(target, timestamp, note || undefined); + toast.success("Reminder set"); + onOpenChange(false); + setNote(""); + } catch (error) { + toast.error("Failed to create reminder"); + console.error("[RemindMeLaterDialog] custom create failed:", error); + } finally { + setIsSubmitting(false); + } + }; + return ( @@ -113,6 +147,38 @@ export function RemindMeLaterDialog({ ))} +
+

+ + Custom date & time +

+
+ setCustomDate(e.target.value)} + min={todayDateString()} + className="flex-1" + aria-label="Reminder date" + /> + setCustomTime(e.target.value)} + className="w-[120px]" + aria-label="Reminder time" + /> +
+ +
+