feat(medications): 优化药品管理功能和登录流程

- 更新默认药品图片为专用图标
- 移除未使用的 loading 状态选择器
- 优化 Apple 登录按钮样式,支持毛玻璃效果和加载状态
- 添加登录成功后返回功能(shouldBack 参数)
- 药品详情页添加信息卡片点击交互
- 添加药品添加页面的登录状态检查
- 增强时间选择器错误处理和数据验证
- 修复药品图片显示逻辑,支持网络图片
- 优化药品卡片样式和布局
- 添加图片加载错误处理
This commit is contained in:
richarjiang
2025-11-11 10:02:37 +08:00
parent 0594831c9f
commit 50525f82a1
8 changed files with 263 additions and 70 deletions

View File

@@ -44,7 +44,7 @@ const FORM_LABELS: Record<Medication['form'], string> = {
other: '其他',
};
const DEFAULT_IMAGE = require('@/assets/images/icons/icon-healthy-diet.png');
const DEFAULT_IMAGE = require('@/assets/images/medicine/image-medicine.png');
type RecordsSummary = {
takenCount: number;
@@ -413,6 +413,22 @@ export default function MedicationDetailScreen() {
}
}, [deleteLoading, dispatch, medication, router]);
const handleStartDatePress = useCallback(() => {
Alert.alert('开始日期', `开始服药日期:${startDateLabel}`);
}, [startDateLabel]);
const handleTimePress = useCallback(() => {
Alert.alert('服药时间', `设置的时间:${reminderTimes}`);
}, [reminderTimes]);
const handleDosagePress = useCallback(() => {
Alert.alert('每次剂量', `单次服用剂量:${dosageLabel}`);
}, [dosageLabel]);
const handleFormPress = useCallback(() => {
Alert.alert('剂型', `药品剂型:${formLabel}`);
}, [formLabel]);
if (!medicationId) {
return (
<View style={[styles.container, { backgroundColor: colors.pageBackgroundEmphasis }]}>
@@ -489,12 +505,16 @@ export default function MedicationDetailScreen() {
value={startDateLabel}
icon="calendar-outline"
colors={colors}
clickable={true}
onPress={handleStartDatePress}
/>
<InfoCard
label="时间"
value={reminderTimes}
icon="time-outline"
colors={colors}
clickable={true}
onPress={handleTimePress}
/>
</View>
<View style={[styles.fullCard, { backgroundColor: colors.surface }]}>
@@ -511,8 +531,22 @@ export default function MedicationDetailScreen() {
<Section title="剂量与形式" color={colors.text}>
<View style={styles.row}>
<InfoCard label="每次剂量" value={dosageLabel} icon="medkit-outline" colors={colors} />
<InfoCard label="剂型" value={formLabel} icon="cube-outline" colors={colors} />
<InfoCard
label="每次剂量"
value={dosageLabel}
icon="medkit-outline"
colors={colors}
clickable={true}
onPress={handleDosagePress}
/>
<InfoCard
label="剂型"
value={formLabel}
icon="cube-outline"
colors={colors}
clickable={true}
onPress={handleFormPress}
/>
</View>
</Section>
@@ -712,20 +746,35 @@ const InfoCard = ({
value,
icon,
colors,
onPress,
clickable = false,
}: {
label: string;
value: string;
icon: keyof typeof Ionicons.glyphMap;
colors: (typeof Colors)[keyof typeof Colors];
onPress?: () => void;
clickable?: boolean;
}) => {
const CardWrapper = clickable ? TouchableOpacity : View;
return (
<View style={[styles.infoCard, { backgroundColor: colors.surface }]}>
<CardWrapper
style={[styles.infoCard, { backgroundColor: colors.surface }]}
onPress={onPress}
activeOpacity={clickable ? 0.7 : 1}
>
{clickable && (
<View style={styles.infoCardArrow}>
<Ionicons name="chevron-forward" size={16} color={colors.textMuted} />
</View>
)}
<View style={styles.infoCardIcon}>
<Ionicons name={icon} size={16} color="#4C6EF5" />
</View>
<Text style={[styles.infoCardLabel, { color: colors.textSecondary }]}>{label}</Text>
<Text style={[styles.infoCardValue, { color: colors.text }]}>{value}</Text>
</View>
</CardWrapper>
);
};
@@ -823,6 +872,13 @@ const styles = StyleSheet.create({
shadowRadius: 8,
shadowOffset: { width: 0, height: 4 },
elevation: 2,
position: 'relative',
},
infoCardArrow: {
position: 'absolute',
top: 12,
right: 12,
zIndex: 1,
},
infoCardIcon: {
width: 28,