72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import React from 'react';
|
|
import { Card, Tag } from 'antd-mobile';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { MedicineWithStock } from '../../types';
|
|
import { getExpiryStatus } from '../../utils/date';
|
|
import './index.css';
|
|
|
|
interface MedicineCardProps {
|
|
medicine: MedicineWithStock;
|
|
}
|
|
|
|
const MedicineCard: React.FC<MedicineCardProps> = ({ medicine }) => {
|
|
const navigate = useNavigate();
|
|
|
|
const expiryStatus = medicine.nearestExpiryDate
|
|
? getExpiryStatus(medicine.nearestExpiryDate, medicine.expiryGraceDays)
|
|
: null;
|
|
|
|
const getExpiryTag = () => {
|
|
if (!expiryStatus) return null;
|
|
|
|
switch (expiryStatus) {
|
|
case 'expired':
|
|
return <Tag color="danger">已过期</Tag>;
|
|
case 'warning':
|
|
return <Tag color="warning">即将过期</Tag>;
|
|
default:
|
|
return null;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Card
|
|
className="medicine-card"
|
|
onClick={() => navigate(`/medicines/${medicine.id}`)}
|
|
>
|
|
<div className="medicine-card-header">
|
|
<h3 className="medicine-name">{medicine.name}</h3>
|
|
{getExpiryTag()}
|
|
</div>
|
|
|
|
<div className="medicine-card-body">
|
|
{medicine.specification && (
|
|
<div className="medicine-info">
|
|
<span className="label">规格:</span>
|
|
<span className="value">{medicine.specification}</span>
|
|
</div>
|
|
)}
|
|
|
|
<div className="medicine-info">
|
|
<span className="label">库存:</span>
|
|
<span className={`value ${medicine.totalQuantity < 5 ? 'low-stock' : ''}`}>
|
|
{medicine.totalQuantity}
|
|
</span>
|
|
</div>
|
|
|
|
<div className="medicine-info">
|
|
<span className="label">批次:</span>
|
|
<span className="value">{medicine.batchCount}</span>
|
|
</div>
|
|
</div>
|
|
|
|
{medicine.brandName && (
|
|
<div className="medicine-card-footer">
|
|
<span className="brand-name">{medicine.brandName}</span>
|
|
</div>
|
|
)}
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
export default MedicineCard; |