feat(i18n): 实现应用国际化支持,添加中英文翻译
- 为所有UI组件添加国际化支持,替换硬编码文本 - 新增useI18n钩子函数统一管理翻译 - 完善中英文翻译资源,覆盖统计、用药、通知设置等模块 - 优化Tab布局使用翻译键值替代静态文本 - 更新药品管理、个人资料编辑等页面的多语言支持
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { ThemedText } from '@/components/ThemedText';
|
||||
import { useAppDispatch } from '@/hooks/redux';
|
||||
import { useI18n } from '@/hooks/useI18n';
|
||||
import { takeMedicationAction } from '@/store/medicationsSlice';
|
||||
import type { MedicationDisplayItem } from '@/types/medication';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
@@ -19,6 +20,7 @@ export type MedicationCardProps = {
|
||||
|
||||
export function MedicationCard({ medication, colors, selectedDate, onOpenDetails, onCelebrate }: MedicationCardProps) {
|
||||
const dispatch = useAppDispatch();
|
||||
const { t } = useI18n();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [imageError, setImageError] = useState(false);
|
||||
|
||||
@@ -43,11 +45,11 @@ export function MedicationCard({ medication, colors, selectedDate, onOpenDetails
|
||||
if (timeDiffMinutes > 60) {
|
||||
// 显示二次确认弹窗
|
||||
Alert.alert(
|
||||
'尚未到服药时间',
|
||||
`该用药计划在 ${medication.scheduledTime},现在还早于1小时以上。\n\n是否确认已服用此药物?`,
|
||||
t('medications.card.earlyTakeAlert.title'),
|
||||
t('medications.card.earlyTakeAlert.message', { time: medication.scheduledTime }),
|
||||
[
|
||||
{
|
||||
text: '取消',
|
||||
text: t('medications.card.earlyTakeAlert.cancel'),
|
||||
style: 'cancel',
|
||||
onPress: () => {
|
||||
// 用户取消,不执行任何操作
|
||||
@@ -55,7 +57,7 @@ export function MedicationCard({ medication, colors, selectedDate, onOpenDetails
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '确认已服用',
|
||||
text: t('medications.card.earlyTakeAlert.confirm'),
|
||||
style: 'default',
|
||||
onPress: () => {
|
||||
// 用户确认,执行服药逻辑
|
||||
@@ -89,9 +91,9 @@ export function MedicationCard({ medication, colors, selectedDate, onOpenDetails
|
||||
} catch (error) {
|
||||
console.error('[MEDICATION_CARD] 服药操作失败', error);
|
||||
Alert.alert(
|
||||
'操作失败',
|
||||
error instanceof Error ? error.message : '记录服药时发生错误,请稍后重试',
|
||||
[{ text: '确定' }]
|
||||
t('medications.card.takeError.title'),
|
||||
error instanceof Error ? error.message : t('medications.card.takeError.message'),
|
||||
[{ text: t('medications.card.takeError.confirm') }]
|
||||
);
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
@@ -102,7 +104,7 @@ export function MedicationCard({ medication, colors, selectedDate, onOpenDetails
|
||||
if (medication.status === 'missed') {
|
||||
return (
|
||||
<View style={[styles.statusChip, styles.statusChipMissed]}>
|
||||
<ThemedText style={styles.statusChipText}>已错过</ThemedText>
|
||||
<ThemedText style={styles.statusChipText}>{t('medications.card.status.missed')}</ThemedText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -112,7 +114,7 @@ export function MedicationCard({ medication, colors, selectedDate, onOpenDetails
|
||||
return (
|
||||
<View style={[styles.statusChip, styles.statusChipUpcoming]}>
|
||||
<Ionicons name="time-outline" size={14} color="#fff" />
|
||||
<ThemedText style={styles.statusChipText}>到服药时间</ThemedText>
|
||||
<ThemedText style={styles.statusChipText}>{t('medications.card.status.timeToTake')}</ThemedText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -125,7 +127,7 @@ export function MedicationCard({ medication, colors, selectedDate, onOpenDetails
|
||||
return (
|
||||
<View style={[styles.statusChip, styles.statusChipUpcoming]}>
|
||||
<Ionicons name="time-outline" size={14} color="#fff" />
|
||||
<ThemedText style={styles.statusChipText}>剩余 {formatted}</ThemedText>
|
||||
<ThemedText style={styles.statusChipText}>{t('medications.card.status.remaining', { time: formatted })}</ThemedText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -138,7 +140,7 @@ export function MedicationCard({ medication, colors, selectedDate, onOpenDetails
|
||||
return (
|
||||
<View style={[styles.actionButton, styles.actionButtonTaken]}>
|
||||
<Ionicons name="checkmark-circle" size={18} color="#fff" />
|
||||
<ThemedText style={styles.actionButtonText}>已服用</ThemedText>
|
||||
<ThemedText style={styles.actionButtonText}>{t('medications.card.action.taken')}</ThemedText>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
@@ -158,13 +160,13 @@ export function MedicationCard({ medication, colors, selectedDate, onOpenDetails
|
||||
isInteractive={!isSubmitting}
|
||||
>
|
||||
<ThemedText style={styles.actionButtonText}>
|
||||
{isSubmitting ? '提交中...' : '立即服用'}
|
||||
{isSubmitting ? t('medications.card.action.submitting') : t('medications.card.action.takeNow')}
|
||||
</ThemedText>
|
||||
</GlassView>
|
||||
) : (
|
||||
<View style={[styles.actionButton, styles.actionButtonUpcoming, styles.fallbackActionButton]}>
|
||||
<ThemedText style={styles.actionButtonText}>
|
||||
{isSubmitting ? '提交中...' : '立即服用'}
|
||||
{isSubmitting ? t('medications.card.action.submitting') : t('medications.card.action.takeNow')}
|
||||
</ThemedText>
|
||||
</View>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user