import { useState } from 'react'; import { useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from 'sonner'; import { Bell, BellOff, Trash2, Pencil } from 'lucide-react'; import { format, isPast, isToday, parseISO } from 'date-fns'; import api from '@/lib/api'; import type { Reminder } from '@/types'; import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/button'; interface ReminderItemProps { reminder: Reminder; onEdit: (reminder: Reminder) => void; } const recurrenceLabels: Record = { daily: 'Daily', weekly: 'Weekly', monthly: 'Monthly', }; const QUERY_KEYS = [['reminders'], ['dashboard'], ['upcoming']] as const; export default function ReminderItem({ reminder, onEdit }: ReminderItemProps) { const queryClient = useQueryClient(); const [confirmingDelete, setConfirmingDelete] = useState(false); const remindDate = reminder.remind_at ? parseISO(reminder.remind_at) : null; const isOverdue = !reminder.is_dismissed && remindDate && isPast(remindDate) && !isToday(remindDate); const isDueToday = remindDate ? isToday(remindDate) : false; const dismissMutation = useMutation({ mutationFn: async () => { const { data } = await api.patch(`/reminders/${reminder.id}/dismiss`); return data; }, onSuccess: () => { QUERY_KEYS.forEach((key) => queryClient.invalidateQueries({ queryKey: [...key] })); toast.success('Reminder dismissed'); }, onError: () => { toast.error('Failed to dismiss reminder'); }, }); const deleteMutation = useMutation({ mutationFn: async () => { await api.delete(`/reminders/${reminder.id}`); }, onMutate: async () => { await queryClient.cancelQueries({ queryKey: ['reminders'] }); const previous = queryClient.getQueryData(['reminders']); queryClient.setQueryData(['reminders'], (old) => old ? old.filter((r) => r.id !== reminder.id) : [] ); return { previous }; }, onSuccess: () => { QUERY_KEYS.forEach((key) => queryClient.invalidateQueries({ queryKey: [...key] })); toast.success('Reminder deleted'); }, onError: (_err, _vars, context) => { if (context?.previous) { queryClient.setQueryData(['reminders'], context.previous); } toast.error('Failed to delete reminder'); }, }); const handleDelete = () => { if (!confirmingDelete) { setConfirmingDelete(true); setTimeout(() => setConfirmingDelete(false), 4000); return; } deleteMutation.mutate(); setConfirmingDelete(false); }; return (
onEdit(reminder)} > {reminder.title} {reminder.recurrence_rule && ( {recurrenceLabels[reminder.recurrence_rule] || reminder.recurrence_rule} )} {remindDate && ( {format(remindDate, 'MMM d, h:mm a')} )} {!reminder.is_dismissed && ( )} {confirmingDelete ? ( ) : ( )}
); }