Add File
This commit is contained in:
116
src/elderly/components/MedicationCard.tsx
Normal file
116
src/elderly/components/MedicationCard.tsx
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { CheckCircle, Clock, XCircle, Info } from 'lucide-react';
|
||||||
|
|
||||||
|
interface MedicationCardProps {
|
||||||
|
medicationName: string;
|
||||||
|
dosage: string;
|
||||||
|
timing: string; // 例如:"早餐后" 或 "睡前"
|
||||||
|
graceMinutes?: number; // 宽限期(分钟)
|
||||||
|
onTaken?: () => void;
|
||||||
|
onSnooze?: (minutes: number) => void;
|
||||||
|
onSkip?: () => void;
|
||||||
|
onInfo?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用药提醒卡组件
|
||||||
|
* 支持确认、稍后提醒、跳过等操作
|
||||||
|
*/
|
||||||
|
export const MedicationCard: React.FC<MedicationCardProps> = ({
|
||||||
|
medicationName,
|
||||||
|
dosage,
|
||||||
|
timing,
|
||||||
|
graceMinutes = 30,
|
||||||
|
onTaken,
|
||||||
|
onSnooze,
|
||||||
|
onSkip,
|
||||||
|
onInfo,
|
||||||
|
}) => {
|
||||||
|
const [countdown, setCountdown] = useState(graceMinutes * 60);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
setCountdown((prev) => (prev > 0 ? prev - 1 : 0));
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () => clearInterval(timer);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const formatTime = (seconds: number) => {
|
||||||
|
const mins = Math.floor(seconds / 60);
|
||||||
|
const secs = seconds % 60;
|
||||||
|
return `${mins}:${secs.toString().padStart(2, '0')}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 animate-fade-in p-6">
|
||||||
|
<div className="card-elderly max-w-2xl w-full space-y-6">
|
||||||
|
{/* 标题与信息按钮 */}
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<h2 className="text-elderly-xl font-bold text-gray-900">
|
||||||
|
早药时间到了
|
||||||
|
</h2>
|
||||||
|
{onInfo && (
|
||||||
|
<button
|
||||||
|
onClick={onInfo}
|
||||||
|
aria-label="药物信息"
|
||||||
|
className="p-3 rounded-full hover:bg-gray-100 transition-colors"
|
||||||
|
>
|
||||||
|
<Info size={32} className="text-primary-600" />
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 药物信息 */}
|
||||||
|
<div className="bg-primary-50 rounded-xl p-6 space-y-3">
|
||||||
|
<p className="text-elderly-lg font-bold text-gray-900">
|
||||||
|
{medicationName}
|
||||||
|
</p>
|
||||||
|
<p className="text-elderly-base text-gray-700">
|
||||||
|
剂量:{dosage}
|
||||||
|
</p>
|
||||||
|
<p className="text-elderly-base text-gray-600">
|
||||||
|
服用时间:{timing}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 倒计时 */}
|
||||||
|
{countdown > 0 && (
|
||||||
|
<div className="flex items-center justify-center gap-3 bg-yellow-50 rounded-xl p-4">
|
||||||
|
<Clock size={28} className="text-yellow-600" />
|
||||||
|
<p className="text-elderly-base text-gray-700">
|
||||||
|
宽限时间剩余:<span className="font-bold text-yellow-700">{formatTime(countdown)}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 操作按钮 - 纵向排列 */}
|
||||||
|
<div className="space-y-4">
|
||||||
|
<button
|
||||||
|
onClick={onTaken}
|
||||||
|
className="w-full btn-elderly bg-green-500 hover:bg-green-600 text-white flex items-center justify-center gap-4"
|
||||||
|
>
|
||||||
|
<CheckCircle size={36} />
|
||||||
|
<span>已服用</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={() => onSnooze?.(10)}
|
||||||
|
className="w-full btn-elderly bg-blue-500 hover:bg-blue-600 text-white flex items-center justify-center gap-4"
|
||||||
|
>
|
||||||
|
<Clock size={36} />
|
||||||
|
<span>稍后提醒(10分钟)</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
onClick={onSkip}
|
||||||
|
className="w-full btn-elderly bg-gray-400 hover:bg-gray-500 text-white flex items-center justify-center gap-4"
|
||||||
|
>
|
||||||
|
<XCircle size={36} />
|
||||||
|
<span>今天先不吃</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user