diff --git a/src/components/reminder/ReminderCard.tsx b/src/components/reminder/ReminderCard.tsx index cdda94a..59e935f 100644 --- a/src/components/reminder/ReminderCard.tsx +++ b/src/components/reminder/ReminderCard.tsx @@ -1,4 +1,23 @@ -import { Card, Text, Checkbox, Group, Stack } from '@mantine/core'; +import { useMemo, useState } from 'react'; +import { + Card, + Text, + Checkbox, + Group, + Stack, + ThemeIcon, + Tooltip, + ActionIcon, + Menu, +} from '@mantine/core'; +import { + IconBell, + IconCheck, + IconDots, + IconTrash, + IconEdit, + IconClock, +} from '@tabler/icons-react'; import type { Event } from '../../types'; interface ReminderCardProps { @@ -9,6 +28,34 @@ interface ReminderCardProps { export function ReminderCard({ event, onToggle, onClick }: ReminderCardProps) { const isCompleted = event.is_completed ?? false; + const [isHovered, setIsHovered] = useState(false); + + // 计算距离提醒时间的相关显示 + const timeInfo = useMemo(() => { + const now = new Date(); + const eventDate = new Date(event.date); + const diff = eventDate.getTime() - now.getTime(); + const isPast = diff < 0; + const isToday = eventDate.toDateString() === now.toDateString(); + + // 格式化时间显示 + const timeStr = eventDate.toLocaleString('zh-CN', { + month: 'short', + day: 'numeric', + hour: '2-digit', + minute: '2-digit', + }); + + return { isPast, isToday, timeStr, diff }; + }, [event.date]); + + // 颜色主题 + const getThemeColor = () => { + if (isCompleted) return 'gray'; + if (timeInfo.isPast) return 'red'; + if (timeInfo.isToday) return 'orange'; + return 'blue'; + }; return ( setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} style={{ cursor: 'pointer', - opacity: isCompleted ? 0.6 : 1, - transition: 'transform 0.2s', - textDecoration: isCompleted ? 'line-through' : 'none', + opacity: isCompleted ? 0.5 : 1, + transition: 'all 0.2s ease', + transform: isHovered ? 'translateY(-2px)' : 'translateY(0)', + borderLeft: `3px solid var(--mantine-color-${getThemeColor()}-6)`, }} - onMouseEnter={(e) => (e.currentTarget.style.transform = 'translateY(-2px)')} - onMouseLeave={(e) => (e.currentTarget.style.transform = 'translateY(0)')} > - - - {event.title} - - - {new Date(event.date).toLocaleString('zh-CN')} - - {event.content && ( - - {event.content} - - )} - + + {/* Checkbox */} + { + e.stopPropagation(); + onToggle(); + }} + onClick={(e) => e.stopPropagation()} + color="green" + size="sm" + /> - { - e.stopPropagation(); - onToggle(); - }} - onClick={(e) => e.stopPropagation()} - /> + + {/* Title */} + + {event.title} + + + {/* Time and content */} + + + + + + {timeInfo.timeStr} + + + + {/* Content preview */} + {event.content && !isCompleted && ( + + {event.content} + + )} + + + + {/* Quick actions */} + + {isHovered && !isCompleted && ( + + { + e.stopPropagation(); + onToggle(); + }} + > + + + + )} + + + + e.stopPropagation()} + > + + + + + e.stopPropagation()}> + } + onClick={onClick} + > + 编辑 + + } + color="red" + onClick={onToggle} + > + {isCompleted ? '恢复' : '删除'} + + + + ); diff --git a/src/components/reminder/ReminderList.tsx b/src/components/reminder/ReminderList.tsx index 586bb58..1696b5b 100644 --- a/src/components/reminder/ReminderList.tsx +++ b/src/components/reminder/ReminderList.tsx @@ -1,6 +1,6 @@ import { useMemo } from 'react'; -import { Stack, Text, Paper, Group, Button } from '@mantine/core'; -import { IconPlus } from '@tabler/icons-react'; +import { Stack, Text, Paper, Group, Button, Badge, ThemeIcon, Alert } from '@mantine/core'; +import { IconPlus, IconBell, IconAlertCircle } from '@tabler/icons-react'; import { ReminderCard } from './ReminderCard'; import type { Event } from '../../types'; @@ -22,52 +22,76 @@ export function ReminderList({ const today = new Date(now.getFullYear(), now.getMonth(), now.getDate()); const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); + const nextWeek = new Date(today); + nextWeek.setDate(nextWeek.getDate() + 7); const reminders = events.filter((e) => e.type === 'reminder'); const result = { today: [] as Event[], tomorrow: [] as Event[], + thisWeek: [] as Event[], later: [] as Event[], missed: [] as Event[], + completed: [] as Event[], }; reminders.forEach((event) => { const eventDate = new Date(event.date); - if (event.is_completed) return; + // 已完成的放最后 + if (event.is_completed) { + result.completed.push(event); + return; + } + // 未完成的按时间分组 if (eventDate < today) { result.missed.push(event); } else if (eventDate < tomorrow) { result.today.push(event); + } else if (eventDate < nextWeek) { + result.thisWeek.push(event); } else { result.later.push(event); } }); - // Sort by date - Object.keys(result).forEach((key) => { - result[key as keyof typeof result].sort( - (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime() - ); - }); + // 按时间排序 + const sortByDate = (a: Event, b: Event) => + new Date(a.date).getTime() - new Date(b.date).getTime(); + + result.today.sort(sortByDate); + result.tomorrow.sort(sortByDate); + result.thisWeek.sort(sortByDate); + result.later.sort(sortByDate); + result.missed.sort(sortByDate); + result.completed.sort(sortByDate); return result; }, [events]); - const hasReminders = + const hasActiveReminders = grouped.today.length > 0 || grouped.tomorrow.length > 0 || + grouped.thisWeek.length > 0 || grouped.later.length > 0 || grouped.missed.length > 0; - if (!hasReminders) { + // 空状态 + if (!hasActiveReminders) { return ( - + + + + 暂无提醒 +
+ + 记得添加提醒事项哦 +