feat(medications): 添加药品停用确认弹窗
在药品详情页和管理页面添加停用药品的确认弹窗,防止用户误操作。 当用户尝试停用药品时,会显示确认对话框提醒用户停用后当天已生成的用药计划会被删除且无法恢复。
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { ThemedText } from '@/components/ThemedText';
|
||||
import { ConfirmationSheet } from '@/components/ui/ConfirmationSheet';
|
||||
import { HeaderBar } from '@/components/ui/HeaderBar';
|
||||
import { IconSymbol } from '@/components/ui/IconSymbol';
|
||||
import { Colors } from '@/constants/Colors';
|
||||
@@ -42,7 +43,7 @@ const FORM_LABELS: Record<MedicationForm, string> = {
|
||||
other: '其他',
|
||||
};
|
||||
|
||||
const FILTER_CONFIG: Array<{ key: FilterType; label: string }> = [
|
||||
const FILTER_CONFIG: { key: FilterType; label: string }[] = [
|
||||
{ key: 'all', label: '全部' },
|
||||
{ key: 'active', label: '进行中' },
|
||||
{ key: 'inactive', label: '已停用' },
|
||||
@@ -60,6 +61,9 @@ export default function ManageMedicationsScreen() {
|
||||
const loading = useAppSelector(selectMedicationsLoading);
|
||||
const [activeFilter, setActiveFilter] = useState<FilterType>('all');
|
||||
const [pendingMedicationId, setPendingMedicationId] = useState<string | null>(null);
|
||||
const [deactivateSheetVisible, setDeactivateSheetVisible] = useState(false);
|
||||
const [medicationToDeactivate, setMedicationToDeactivate] = useState<Medication | null>(null);
|
||||
const [deactivateLoading, setDeactivateLoading] = useState(false);
|
||||
|
||||
const listLoading = loading.medications && medications.length === 0;
|
||||
|
||||
@@ -98,6 +102,15 @@ export default function ManageMedicationsScreen() {
|
||||
const handleToggleMedication = useCallback(
|
||||
async (medication: Medication, nextValue: boolean) => {
|
||||
if (pendingMedicationId) return;
|
||||
|
||||
// 如果是关闭激活状态,显示确认弹窗
|
||||
if (!nextValue) {
|
||||
setMedicationToDeactivate(medication);
|
||||
setDeactivateSheetVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是开启激活状态,直接执行
|
||||
try {
|
||||
setPendingMedicationId(medication.id);
|
||||
await dispatch(
|
||||
@@ -116,6 +129,28 @@ export default function ManageMedicationsScreen() {
|
||||
[dispatch, pendingMedicationId]
|
||||
);
|
||||
|
||||
const handleDeactivateMedication = useCallback(async () => {
|
||||
if (!medicationToDeactivate || deactivateLoading) return;
|
||||
|
||||
try {
|
||||
setDeactivateLoading(true);
|
||||
setDeactivateSheetVisible(false); // 立即关闭确认对话框
|
||||
|
||||
await dispatch(
|
||||
updateMedicationAction({
|
||||
id: medicationToDeactivate.id,
|
||||
isActive: false,
|
||||
})
|
||||
).unwrap();
|
||||
} catch (error) {
|
||||
console.error('停用药物失败', error);
|
||||
Alert.alert('操作失败', '停用药物时发生问题,请稍后重试。');
|
||||
} finally {
|
||||
setDeactivateLoading(false);
|
||||
setMedicationToDeactivate(null);
|
||||
}
|
||||
}, [dispatch, medicationToDeactivate, deactivateLoading]);
|
||||
|
||||
// 创建独立的药品卡片组件,使用 React.memo 优化渲染
|
||||
const MedicationCard = React.memo(({ medication, onPress }: { medication: Medication; onPress: () => void }) => {
|
||||
const dosageLabel = `${medication.dosageValue} ${medication.dosageUnit || ''} ${FORM_LABELS[medication.form] ?? ''}`.trim();
|
||||
@@ -320,6 +355,24 @@ export default function ManageMedicationsScreen() {
|
||||
<View style={styles.list}>{filteredMedications.map(renderMedicationCard)}</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
|
||||
{/* 停用药品确认弹窗 */}
|
||||
{medicationToDeactivate ? (
|
||||
<ConfirmationSheet
|
||||
visible={deactivateSheetVisible}
|
||||
onClose={() => {
|
||||
setDeactivateSheetVisible(false);
|
||||
setMedicationToDeactivate(null);
|
||||
}}
|
||||
onConfirm={handleDeactivateMedication}
|
||||
title={`停用 ${medicationToDeactivate.name}?`}
|
||||
description="停用后,当天已生成的用药计划会一并删除,且无法恢复。"
|
||||
confirmText="确认停用"
|
||||
cancelText="取消"
|
||||
destructive
|
||||
loading={deactivateLoading}
|
||||
/>
|
||||
) : null}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user