From 65eaf0587f5c6c72e29a7ed05c099dd76baed579 Mon Sep 17 00:00:00 2001 From: 15945162479 <15945162479@qq.com> Date: Sat, 13 Dec 2025 14:46:13 +0800 Subject: [PATCH] Add File --- .../components/ScheduleReminderToast.tsx | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/elderly/components/ScheduleReminderToast.tsx diff --git a/src/elderly/components/ScheduleReminderToast.tsx b/src/elderly/components/ScheduleReminderToast.tsx new file mode 100644 index 0000000..fb7efba --- /dev/null +++ b/src/elderly/components/ScheduleReminderToast.tsx @@ -0,0 +1,137 @@ +import React, { useEffect, useState } from 'react'; +import { Clock, CheckCircle, XCircle, Ban, X } from 'lucide-react'; +import * as scheduleService from '../services/scheduleService'; + +interface ScheduleReminderToastProps { + schedule: scheduleService.Schedule; + onComplete: () => void; + onSkip: () => void; + onDismiss: () => void; + onMissed: () => void; // 30分钟后自动标记为已错过 + onClose: () => void; // 手动关闭(不做任何操作) +} + +/** + * 日程提醒 Toast 组件 + * 以半透明悬浮卡片形式显示在屏幕下方 + * 30分钟后自动标记为已错过并关闭 + */ +export const ScheduleReminderToast: React.FC = ({ + schedule, + onComplete, + onSkip, + onDismiss, + onMissed, + onClose, +}) => { + const [remainingSeconds, setRemainingSeconds] = useState(30 * 60); // 30分钟 + const typeIcon = scheduleService.getScheduleTypeIcon(schedule.schedule_type || 'other'); + const typeLabel = scheduleService.getScheduleTypeLabel(schedule.schedule_type || 'other'); + const time = scheduleService.formatTime(schedule.schedule_time); + + // 倒计时:30分钟后自动标记为已错过 + useEffect(() => { + const interval = setInterval(() => { + setRemainingSeconds((prev) => { + if (prev <= 1) { + clearInterval(interval); + console.log('提醒已显示30分钟无操作,自动标记为已错过'); + onMissed(); + return 0; + } + return prev - 1; + }); + }, 1000); + + return () => clearInterval(interval); + }, [onMissed]); + + // 格式化剩余时间 (MM:SS) + const formatTime = (seconds: number) => { + const mins = Math.floor(seconds / 60); + const secs = seconds % 60; + return `${mins}:${secs.toString().padStart(2, '0')}`; + }; + + return ( +
+ {/* 媒体内容容器 - 数字人中部,下调10% */} +
+
+ {/* 头部 */} +
+
+
{typeIcon}
+
+
+ + {time} +
+

{typeLabel}

+
+
+ + {/* 右上角:倒计时 + 关闭按钮 */} +
+
+ {formatTime(remainingSeconds)} +
+ +
+
+ + {/* 内容区域 */} +
+

+ {schedule.title} +

+ + {schedule.description && ( +

+ {schedule.description} +

+ )} +
+ + {/* 操作按钮 */} +
+
+ {/* 标记完成 */} + + + {/* 推迟10分钟 */} + + + {/* 忽略 */} + +
+
+
+
+
+ ); +};