import { useState } from "react"; import { useNavigate } from "react-router"; import { motion, AnimatePresence } from "motion/react"; import { ChevronLeft, Bell, Clock, CheckCircle2, ChevronRight, Stethoscope, Baby, CircleDot, AlertCircle, Calendar, } from "lucide-react"; import { Card } from "../components/ui/card"; import { Badge } from "../components/ui/badge"; import { useUser, calcPregnancyWeek } from "../context/UserContext"; import { checkupSchedule } from "../data/checkupSchedule"; interface Notification { id: string; type: "checkup_reminder" | "preparation" | "weekly_tip" | "milestone"; title: string; content: string; time: string; read: boolean; tags?: string[]; link?: string; checkupItems?: string[]; checkupPreparations?: string[]; } function generateNotifications(currentWeek: number, lastPeriodDate: string): Notification[] { const notifications: Notification[] = []; // 下次产检提醒(来源于产检日历) const nextCheckup = checkupSchedule.find((c) => c.week > currentWeek); if (nextCheckup) { let dateStr = ""; let daysInfo = ""; if (lastPeriodDate) { const lmp = new Date(lastPeriodDate); const checkupDate = new Date(lmp.getTime() + nextCheckup.week * 7 * 24 * 60 * 60 * 1000); dateStr = checkupDate.toISOString().split("T")[0]; const daysUntil = Math.max(0, Math.ceil((checkupDate.getTime() - Date.now()) / (1000 * 60 * 60 * 24))); daysInfo = `${dateStr} · 距今${daysUntil}天`; } else { daysInfo = `还有${nextCheckup.week - currentWeek}周`; } notifications.push({ id: "next-checkup", type: "checkup_reminder", title: `下次产检:${nextCheckup.title}`, content: `孕${nextCheckup.week}周 · ${daysInfo}`, time: "今天", read: false, tags: nextCheckup.preparations.filter( (p) => p.includes("空腹") || p.includes("憋尿") || p.startsWith("需") ), checkupItems: nextCheckup.items, checkupPreparations: nextCheckup.preparations, }); // 产检项目提醒 notifications.push({ id: "checkup-items", type: "preparation", title: `${nextCheckup.title}检查项目`, content: `共${nextCheckup.items.length}项:${nextCheckup.items.slice(0, 3).join("、")}${nextCheckup.items.length > 3 ? "等" : ""}`, time: "今天", read: false, link: "/calendar", }); // 特殊注意事项 const specialPreps = nextCheckup.preparations.filter( (p) => p.includes("空腹") || p.includes("憋尿") || p.includes("携带") || p.includes("预约") ); if (specialPreps.length > 0) { notifications.push({ id: "prep-reminder", type: "preparation", title: "产检准备提醒", content: specialPreps.join(";"), time: "今天", read: false, tags: specialPreps.filter((p) => p.includes("空腹") || p.includes("憋尿")), }); } } // 孕周知识推送 notifications.push({ id: "weekly-tip", type: "weekly_tip", title: `孕${currentWeek}周知识`, content: `本周宝宝正在快速发育,请注意补充营养,避免剧烈运动,保持充足睡眠。`, time: "今天", read: false, }); // 孕期里程碑 const milestones: Record = { 8: "宝宝的心脏已经开始跳动,四肢也开始发育。记得按时服用叶酸哦~", 12: "宝宝已经有了人的模样,可以做NT检查了。进入相对稳定的孕中期!", 16: "宝宝开始有了听觉,可以和宝宝说说话啦~", 20: "宝宝可以感受到外界的光线了,是做大排畸检查的好时机!", 24: "宝宝体重快速增长,记得做糖耐量检查哦~", 28: "进入孕晚期啦!产检频率要增加了,注意数胎动~", 32: "宝宝头部朝下准备入盆,可以开始准备待产包了!", 36: "宝宝随时可能发动,做好迎接宝宝的准备吧~", }; const milestoneWeek = Object.keys(milestones).map(Number).find((w) => w === currentWeek); if (milestoneWeek) { notifications.push({ id: `milestone-${milestoneWeek}`, type: "milestone", title: `孕${milestoneWeek}周里程碑`, content: `恭喜进入孕${milestoneWeek}周!${milestones[milestoneWeek]}`, time: "昨天", read: true, }); } // 下下次产检预告 const secondCheckup = checkupSchedule.find((c) => nextCheckup && c.week > nextCheckup.week); if (secondCheckup) { notifications.push({ id: "future-checkup", type: "checkup_reminder", title: `产检预告:${secondCheckup.title}`, content: `孕${secondCheckup.week}周 · ${secondCheckup.items.slice(0, 2).join("、")}等`, time: "3天前", read: true, link: "/calendar", }); } // 上周知识回顾 if (currentWeek > 1) { notifications.push({ id: "last-week-tip", type: "weekly_tip", title: `孕${currentWeek - 1}周回顾`, content: "上周的营养建议:多摄入富含蛋白质和铁元素的食物,每日补充0.4mg叶酸。", time: "一周前", read: true, }); } return notifications; } export function NotificationPage() { const navigate = useNavigate(); const { user } = useUser(); const currentWeek = user.currentWeek || 0; const [notifications, setNotifications] = useState(() => generateNotifications(currentWeek, user.lastPeriodDate) ); const [filter, setFilter] = useState<"all" | "unread">("all"); const [expandedId, setExpandedId] = useState(null); const unreadCount = notifications.filter((n) => !n.read && n.type !== "preparation").length; const filteredNotifications = filter === "unread" ? notifications.filter((n) => !n.read && n.type !== "preparation") : notifications.filter((n) => n.type !== "preparation"); const markAsRead = (id: string) => { setNotifications((prev) => prev.map((n) => (n.id === id ? { ...n, read: true } : n)) ); }; const markAllRead = () => { setNotifications((prev) => prev.map((n) => ({ ...n, read: true }))); }; const getIcon = (type: Notification["type"]) => { switch (type) { case "checkup_reminder": return ; case "preparation": return ; case "weekly_tip": return ; case "milestone": return ; } }; const getIconBg = (type: Notification["type"]) => { switch (type) { case "checkup_reminder": return "bg-morandi-100"; case "preparation": return "bg-morandi-rose-100"; case "weekly_tip": return "bg-morandi-50"; case "milestone": return "bg-morandi-sage-100"; } }; const getTypeLabel = (type: Notification["type"]) => { switch (type) { case "checkup_reminder": return "产检提醒"; case "preparation": return "注意事项"; case "weekly_tip": return "孕周知识"; case "milestone": return "孕期里程碑"; } }; return (
{/* 顶部导航 */}

消息中心

{unreadCount > 0 ? `${unreadCount}条未读消息` : "暂无未读消息"}

{unreadCount > 0 && ( )}
{/* 筛选按钮 */}

全部消息

{(["all", "unread"] as const).map((f) => ( ))}
{/* 消息列表 */} {filteredNotifications.length === 0 ? (

暂无未读消息

) : ( filteredNotifications.map((notification, index) => ( { markAsRead(notification.id); if (expandedId === notification.id) { setExpandedId(null); } else { setExpandedId(notification.id); } }} >
{getIcon(notification.type)}
{getTypeLabel(notification.type)} {notification.time} {!notification.read && ( )}

{notification.title}

{notification.content}

{/* 特殊标签 */} {notification.tags && notification.tags.length > 0 && (
{notification.tags.map((tag, i) => ( {tag} ))}
)} {/* 展开的详情 */} {expandedId === notification.id && (
{/* 检查项目 */} {notification.checkupItems && notification.checkupItems.length > 0 && (
检查项目
{notification.checkupItems.map((item, i) => (
{item}
))}
)} {/* 注意事项 */} {notification.checkupPreparations && notification.checkupPreparations.length > 0 && (
注意事项
    {notification.checkupPreparations.map((prep, i) => (
  • {prep}
  • ))}
)}
)}
)) )}
{/* 温馨提示 */}

消息说明

系统会根据您的孕周和产检计划自动推送提醒,包括产检时间、检查项目和注意事项。产检内容与产检日历同步。

); }