Add Chinese translations for medication management and personal settings

- Introduced new translation files for medication, personal, and weight management in Chinese.
- Updated the main index file to include the new translation modules.
- Enhanced the medication type definitions to include 'ointment'.
- Refactored workout type labels to utilize i18n for better localization support.
- Improved sleep quality descriptions and recommendations with i18n integration.
This commit is contained in:
richarjiang
2025-11-28 17:29:51 +08:00
parent fbe0c92f0f
commit bca6670390
42 changed files with 7972 additions and 6632 deletions

View File

@@ -1,5 +1,6 @@
import { HeaderBar } from '@/components/ui/HeaderBar';
import { Colors } from '@/constants/Colors';
import { useI18n } from '@/hooks/useI18n';
import { useSafeAreaTop } from '@/hooks/useSafeAreaWithPadding';
import {
deleteNutritionAnalysisRecord,
@@ -30,6 +31,7 @@ import {
import ImageViewing from 'react-native-image-viewing';
export default function NutritionAnalysisHistoryScreen() {
const { t } = useI18n();
const safeAreaTop = useSafeAreaTop();
const router = useRouter();
@@ -95,15 +97,15 @@ export default function NutritionAnalysisHistoryScreen() {
setHasMore(page < response.data.totalPages);
setCurrentPage(page);
} else {
const errorMessage = response.message || '获取历史记录失败';
const errorMessage = response.message || t('nutritionAnalysisHistory.errors.fetchFailed');
setError(errorMessage);
Alert.alert('错误', errorMessage);
Alert.alert(t('nutritionAnalysisHistory.errors.error'), errorMessage);
}
} catch (error) {
console.error('[HISTORY] 获取历史记录失败:', error);
const errorMessage = '获取历史记录失败,请稍后重试';
const errorMessage = t('nutritionAnalysisHistory.errors.fetchFailedRetry');
setError(errorMessage);
Alert.alert('错误', errorMessage);
Alert.alert(t('nutritionAnalysisHistory.errors.error'), errorMessage);
} finally {
setLoading(false);
setRefreshing(false);
@@ -173,13 +175,13 @@ export default function NutritionAnalysisHistoryScreen() {
const getStatusText = (status: string) => {
switch (status) {
case 'success':
return '成功';
return t('nutritionAnalysisHistory.status.success');
case 'failed':
return '失败';
return t('nutritionAnalysisHistory.status.failed');
case 'processing':
return '处理中';
return t('nutritionAnalysisHistory.status.processing');
default:
return '未知';
return t('nutritionAnalysisHistory.status.unknown');
}
};
@@ -208,15 +210,15 @@ export default function NutritionAnalysisHistoryScreen() {
// 处理删除记录
const handleDeleteRecord = useCallback((recordId: number) => {
Alert.alert(
'确认删除',
'确定要删除这条营养分析记录吗?此操作无法撤销。',
t('nutritionAnalysisHistory.delete.confirmTitle'),
t('nutritionAnalysisHistory.delete.confirmMessage'),
[
{
text: '取消',
text: t('nutritionAnalysisHistory.delete.cancel'),
style: 'cancel',
},
{
text: '删除',
text: t('nutritionAnalysisHistory.delete.delete'),
style: 'destructive',
onPress: async () => {
try {
@@ -231,10 +233,10 @@ export default function NutritionAnalysisHistoryScreen() {
triggerLightHaptic();
// 显示成功提示
Alert.alert('成功', '记录已删除');
Alert.alert(t('nutritionAnalysisHistory.delete.successTitle'), t('nutritionAnalysisHistory.delete.successMessage'));
} catch (error) {
console.error('[HISTORY] 删除记录失败:', error);
Alert.alert('错误', '删除失败,请稍后重试');
Alert.alert(t('nutritionAnalysisHistory.errors.error'), t('nutritionAnalysisHistory.errors.deleteFailed'));
} finally {
setDeletingId(null);
}
@@ -256,11 +258,11 @@ export default function NutritionAnalysisHistoryScreen() {
<View style={styles.recordInfo}>
{isSuccess && (
<Text style={styles.recordTitle}>
{item.nutritionCount}
{t('nutritionAnalysisHistory.recognized', { count: item.nutritionCount })}
</Text>
)}
<Text style={styles.recordDate}>
{dayjs(item.createdAt).format('YYYY年M月D日 HH:mm')}
{dayjs(item.createdAt).format(t('nutritionAnalysisHistory.dateFormat'))}
</Text>
<View style={[styles.statusBadge, { backgroundColor: getStatusColor(item.status) }]}>
<Text style={styles.statusText}>{getStatusText(item.status)}</Text>
@@ -327,25 +329,25 @@ export default function NutritionAnalysisHistoryScreen() {
<>
{mainNutrients.energy && (
<View style={styles.nutritionItem}>
<Text style={styles.nutritionLabel}></Text>
<Text style={styles.nutritionLabel}>{t('nutritionAnalysisHistory.nutrients.energy')}</Text>
<Text style={styles.nutritionValue}>{mainNutrients.energy}</Text>
</View>
)}
{mainNutrients.protein && (
<View style={styles.nutritionItem}>
<Text style={styles.nutritionLabel}></Text>
<Text style={styles.nutritionLabel}>{t('nutritionAnalysisHistory.nutrients.protein')}</Text>
<Text style={styles.nutritionValue}>{mainNutrients.protein}</Text>
</View>
)}
{mainNutrients.carbs && (
<View style={styles.nutritionItem}>
<Text style={styles.nutritionLabel}></Text>
<Text style={styles.nutritionLabel}>{t('nutritionAnalysisHistory.nutrients.carbs')}</Text>
<Text style={styles.nutritionValue}>{mainNutrients.carbs}</Text>
</View>
)}
{mainNutrients.fat && (
<View style={styles.nutritionItem}>
<Text style={styles.nutritionLabel}></Text>
<Text style={styles.nutritionLabel}>{t('nutritionAnalysisHistory.nutrients.fat')}</Text>
<Text style={styles.nutritionValue}>{mainNutrients.fat}</Text>
</View>
)}
@@ -371,7 +373,7 @@ export default function NutritionAnalysisHistoryScreen() {
activeOpacity={0.7}
>
<Text style={styles.expandButtonText}>
{isExpanded ? '收起详情' : '展开详情'}
{isExpanded ? t('nutritionAnalysisHistory.actions.collapse') : t('nutritionAnalysisHistory.actions.expand')}
</Text>
<Ionicons
name={isExpanded ? 'chevron-up-outline' : 'chevron-down-outline'}
@@ -383,7 +385,7 @@ export default function NutritionAnalysisHistoryScreen() {
{/* 详细信息 */}
{isExpanded && isSuccess && item.analysisResult && item.analysisResult.data && (
<View style={styles.detailsContainer}>
<Text style={styles.detailsTitle}></Text>
<Text style={styles.detailsTitle}>{t('nutritionAnalysisHistory.details.title')}</Text>
{item.analysisResult.data.map((nutritionItem: NutritionItem) => (
<View key={nutritionItem.key} style={styles.detailItem}>
<View style={styles.nutritionInfo}>
@@ -397,8 +399,8 @@ export default function NutritionAnalysisHistoryScreen() {
))}
<View style={styles.metaInfo}>
<Text style={styles.metaText}>AI : {item.aiModel}</Text>
<Text style={styles.metaText}>: {item.aiProvider}</Text>
<Text style={styles.metaText}>{t('nutritionAnalysisHistory.details.aiModel')}: {item.aiModel}</Text>
<Text style={styles.metaText}>{t('nutritionAnalysisHistory.details.provider')}: {item.aiProvider}</Text>
</View>
</View>
)}
@@ -410,8 +412,8 @@ export default function NutritionAnalysisHistoryScreen() {
const renderEmptyState = () => (
<View style={styles.emptyState}>
<Ionicons name="document-text-outline" size={64} color="#CCC" />
<Text style={styles.emptyStateText}></Text>
<Text style={styles.emptyStateSubtext}></Text>
<Text style={styles.emptyStateText}>{t('nutritionAnalysisHistory.empty.title')}</Text>
<Text style={styles.emptyStateSubtext}>{t('nutritionAnalysisHistory.empty.subtitle')}</Text>
</View>
);
@@ -419,8 +421,8 @@ export default function NutritionAnalysisHistoryScreen() {
const renderErrorState = () => (
<View style={styles.errorState}>
<Ionicons name="alert-circle-outline" size={64} color="#F44336" />
<Text style={styles.errorStateText}></Text>
<Text style={styles.errorStateSubtext}>{error || '未知错误'}</Text>
<Text style={styles.errorStateText}>{t('nutritionAnalysisHistory.errors.loadFailed')}</Text>
<Text style={styles.errorStateSubtext}>{error || t('nutritionAnalysisHistory.errors.unknownError')}</Text>
<TouchableOpacity
style={styles.retryButton}
onPress={() => {
@@ -428,7 +430,7 @@ export default function NutritionAnalysisHistoryScreen() {
fetchRecords(1, true);
}}
>
<Text style={styles.retryButtonText}></Text>
<Text style={styles.retryButtonText}>{t('nutritionAnalysisHistory.actions.retry')}</Text>
</TouchableOpacity>
</View>
);
@@ -440,7 +442,7 @@ export default function NutritionAnalysisHistoryScreen() {
return (
<View style={styles.loadingFooter}>
<ActivityIndicator size="small" color={Colors.light.primary} />
<Text style={styles.loadingFooterText}>...</Text>
<Text style={styles.loadingFooterText}>{t('nutritionAnalysisHistory.loadingMore')}</Text>
</View>
);
};
@@ -456,7 +458,7 @@ export default function NutritionAnalysisHistoryScreen() {
/>
<HeaderBar
title="历史记录"
title={t('nutritionAnalysisHistory.title')}
onBack={() => router.back()}
transparent={true}
/>
@@ -477,7 +479,7 @@ export default function NutritionAnalysisHistoryScreen() {
activeOpacity={0.7}
>
<Text style={[styles.filterButtonText, !statusFilter && styles.filterButtonTextActive]}>
{t('nutritionAnalysisHistory.filter.all')}
</Text>
</TouchableOpacity>
<TouchableOpacity
@@ -494,7 +496,7 @@ export default function NutritionAnalysisHistoryScreen() {
activeOpacity={0.7}
>
<Text style={[styles.filterButtonText, statusFilter === 'success' && styles.filterButtonTextActive]}>
{t('nutritionAnalysisHistory.status.success')}
</Text>
</TouchableOpacity>
<TouchableOpacity
@@ -511,7 +513,7 @@ export default function NutritionAnalysisHistoryScreen() {
activeOpacity={0.7}
>
<Text style={[styles.filterButtonText, statusFilter === 'failed' && styles.filterButtonTextActive]}>
{t('nutritionAnalysisHistory.status.failed')}
</Text>
</TouchableOpacity>
</View>
@@ -520,7 +522,7 @@ export default function NutritionAnalysisHistoryScreen() {
{loading ? (
<View style={styles.loadingContainer}>
<ActivityIndicator size="large" color={Colors.light.primary} />
<Text style={styles.loadingText}>...</Text>
<Text style={styles.loadingText}>{t('nutritionAnalysisHistory.loading')}</Text>
</View>
) : (
<FlatList
@@ -555,7 +557,7 @@ export default function NutritionAnalysisHistoryScreen() {
HeaderComponent={() => (
<View style={styles.imageViewerHeader}>
<Text style={styles.imageViewerHeaderText}>
{dayjs().format('YYYY年M月D日 HH:mm')}
{dayjs().format(t('nutritionAnalysisHistory.dateFormat'))}
</Text>
</View>
)}
@@ -565,7 +567,7 @@ export default function NutritionAnalysisHistoryScreen() {
style={styles.imageViewerFooterButton}
onPress={() => setShowImagePreview(false)}
>
<Text style={styles.imageViewerFooterButtonText}></Text>
<Text style={styles.imageViewerFooterButtonText}>{t('nutritionLabelAnalysis.actions.close')}</Text>
</TouchableOpacity>
</View>
)}