diff --git a/backend/app/routers/reminders.py b/backend/app/routers/reminders.py index a23d97b..9ff6d1b 100644 --- a/backend/app/routers/reminders.py +++ b/backend/app/routers/reminders.py @@ -50,7 +50,10 @@ async def get_due_reminders( Reminder.remind_at <= now, Reminder.is_dismissed == False, Reminder.is_active == True, - Reminder.recurrence_rule.is_(None), + or_( + Reminder.recurrence_rule.is_(None), + Reminder.recurrence_rule == '', + ), or_( Reminder.snoozed_until.is_(None), Reminder.snoozed_until <= now, diff --git a/frontend/src/components/reminders/ReminderForm.tsx b/frontend/src/components/reminders/ReminderForm.tsx index a06b79d..c8d1dc3 100644 --- a/frontend/src/components/reminders/ReminderForm.tsx +++ b/frontend/src/components/reminders/ReminderForm.tsx @@ -22,17 +22,48 @@ interface ReminderFormProps { onClose: () => void; } +function parseRemindAt(remindAt?: string) { + if (!remindAt) return { date: '', hour: '12', minute: '00', period: 'PM' as const }; + const d = new Date(remindAt); + const date = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`; + let hours = d.getHours(); + const period = hours >= 12 ? 'PM' as const : 'AM' as const; + hours = hours % 12 || 12; + return { + date, + hour: String(hours), + minute: String(d.getMinutes()).padStart(2, '0'), + period, + }; +} + +function buildRemindAt(date: string, hour: string, minute: string, period: 'AM' | 'PM'): string { + if (!date) return ''; + let h = parseInt(hour, 10); + if (period === 'AM' && h === 12) h = 0; + else if (period === 'PM' && h !== 12) h += 12; + return `${date}T${String(h).padStart(2, '0')}:${minute}`; +} + export default function ReminderForm({ reminder, onClose }: ReminderFormProps) { const queryClient = useQueryClient(); - const [formData, setFormData] = useState({ - title: reminder?.title || '', - description: reminder?.description || '', - remind_at: reminder?.remind_at ? reminder.remind_at.slice(0, 16) : '', - recurrence_rule: reminder?.recurrence_rule || '', - }); + const parsed = parseRemindAt(reminder?.remind_at); + const [title, setTitle] = useState(reminder?.title || ''); + const [description, setDescription] = useState(reminder?.description || ''); + const [date, setDate] = useState(parsed.date); + const [hour, setHour] = useState(parsed.hour); + const [minute, setMinute] = useState(parsed.minute); + const [period, setPeriod] = useState<'AM' | 'PM'>(parsed.period); + const [recurrenceRule, setRecurrenceRule] = useState(reminder?.recurrence_rule || ''); const mutation = useMutation({ - mutationFn: async (data: typeof formData) => { + mutationFn: async () => { + const data = { + title, + description: description || null, + remind_at: buildRemindAt(date, hour, minute, period) || null, + recurrence_rule: recurrenceRule || null, + }; if (reminder) { const response = await api.put(`/reminders/${reminder.id}`, data); return response.data; @@ -55,7 +86,7 @@ export default function ReminderForm({ reminder, onClose }: ReminderFormProps) { const handleSubmit = (e: FormEvent) => { e.preventDefault(); - mutation.mutate(formData); + mutation.mutate(); }; return ( @@ -71,8 +102,8 @@ export default function ReminderForm({ reminder, onClose }: ReminderFormProps) { setFormData({ ...formData, title: e.target.value })} + value={title} + onChange={(e) => setTitle(e.target.value)} required /> @@ -81,37 +112,67 @@ export default function ReminderForm({ reminder, onClose }: ReminderFormProps) {