import { ThemedText } from '@/components/ThemedText'; import { useThemeColor } from '@/hooks/useThemeColor'; import { DietRecord } from '@/services/dietRecords'; import { Ionicons } from '@expo/vector-icons'; import dayjs from 'dayjs'; import React, { useMemo, useRef, useState } from 'react'; import { Alert, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { Swipeable } from 'react-native-gesture-handler'; export type NutritionRecordCardProps = { record: DietRecord; onPress?: () => void; onDelete?: () => void; }; const MEAL_TYPE_LABELS = { breakfast: '早餐', lunch: '午餐', dinner: '晚餐', snack: '加餐', other: '其他', } as const; const MEAL_TYPE_ICONS = { breakfast: 'sunny-outline', lunch: 'partly-sunny-outline', dinner: 'moon-outline', snack: 'cafe-outline', other: 'restaurant-outline', } as const; const MEAL_TYPE_COLORS = { breakfast: '#FF6B35', lunch: '#4CAF50', dinner: '#2196F3', snack: '#FF7A85', other: '#9AA3AE', } as const; export function NutritionRecordCard({ record, onPress, onDelete }: NutritionRecordCardProps) { const surfaceColor = useThemeColor({}, 'surface'); const textColor = useThemeColor({}, 'text'); const textSecondaryColor = useThemeColor({}, 'textSecondary'); // Popover 状态管理 const [showPopover, setShowPopover] = useState(false); const popoverRef = useRef(null); // 左滑删除相关 const swipeableRef = useRef(null); // 营养数据统计 const nutritionStats = useMemo(() => { return [ { label: '蛋白质', value: record.proteinGrams ? `${record.proteinGrams.toFixed(1)}g` : '-', icon: '🥩', color: '#FF6B6B' }, { label: '脂肪', value: record.fatGrams ? `${record.fatGrams.toFixed(1)}g` : '-', icon: '🥑', color: '#FFB366' }, { label: '碳水', value: record.carbohydrateGrams ? `${record.carbohydrateGrams.toFixed(1)}g` : '-', icon: '🍞', color: '#4ECDC4' }, ]; }, [record]); const mealTypeColor = MEAL_TYPE_COLORS[record.mealType]; const mealTypeLabel = MEAL_TYPE_LABELS[record.mealType]; // 处理删除操作 const handleDelete = () => { Alert.alert( '确认删除', `确定要删除这条营养记录吗?此操作无法撤销。`, [ { text: '取消', style: 'cancel', }, { text: '删除', style: 'destructive', onPress: () => { onDelete?.(); swipeableRef.current?.close(); }, }, ] ); }; // 渲染删除按钮 const renderRightActions = () => { return ( 删除 ); }; return ( {/* 主要内容区域 - 水平布局 */} {/* 左侧:食物图片 */} {record.imageUrl ? ( ) : ( )} {/* 中间:食物信息 */} {/* 食物名称 */} {record.foodName} {/* 时间 */} {record.mealTime ? dayjs(record.mealTime).format('HH:mm') : '--:--'} {/* 营养信息 - 水平排列 */} {nutritionStats.map((stat, index) => ( {stat.icon} {stat.value} ))} {/* 右侧:热量和餐次标签 */} {/* 热量显示 */} {record.estimatedCalories ? `${Math.round(record.estimatedCalories)} kcal` : '- kcal'} {/* 餐次标签 */} {mealTypeLabel} {/* 更多操作按钮 */} setShowPopover(true)} > ); } const styles = StyleSheet.create({ container: { marginBottom: 12, // iOS 阴影效果 - 更自然的阴影 shadowColor: '#000000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.08, shadowRadius: 4, // Android 阴影效果 elevation: 2, }, card: { flex: 1, height: 80, backgroundColor: '#FFFFFF', borderRadius: 12, padding: 12, }, mainContent: { flex: 1, flexDirection: 'row', alignItems: 'center', }, foodImageContainer: { width: 32, height: 32, borderRadius: 8, marginRight: 12, overflow: 'hidden', }, foodImage: { width: '100%', height: '100%', borderRadius: 8, }, foodImagePlaceholder: { backgroundColor: '#F8F9FA', justifyContent: 'center', alignItems: 'center', }, foodInfoContainer: { flex: 1, justifyContent: 'flex-start', }, foodName: { fontSize: 14, fontWeight: '600', color: '#333333', marginTop: 2, }, mealTime: { fontSize: 10, fontWeight: '400', color: '#999999', }, nutritionContainer: { flexDirection: 'row', alignItems: 'center', gap: 20, }, nutritionItem: { flexDirection: 'row', alignItems: 'center', gap: 2, }, nutritionIcon: { fontSize: 12, }, nutritionValue: { fontSize: 11, fontWeight: '500', color: '#666666', }, rightSection: { alignItems: 'flex-end', justifyContent: 'space-between', height: 48, }, caloriesContainer: { flexDirection: 'row', alignItems: 'center', marginBottom: 4, }, caloriesDot: { width: 6, height: 6, borderRadius: 3, backgroundColor: '#333333', marginRight: 6, }, caloriesText: { fontSize: 12, color: '#473c3cff', fontWeight: '500', }, mealTypeBadge: { paddingHorizontal: 8, borderRadius: 10, marginBottom: 4, }, mealTypeText: { fontSize: 10, fontWeight: '500', }, moreButton: { padding: 2, }, notesSection: { marginTop: 8, paddingTop: 12, borderTopWidth: 1, borderTopColor: 'rgba(0,0,0,0.06)', }, notesText: { fontSize: 13, fontWeight: '500', lineHeight: 18, fontStyle: 'italic', }, popoverContainer: { borderRadius: 12, backgroundColor: '#FFFFFF', // iOS 阴影效果 shadowColor: '#000000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.15, shadowRadius: 12, // Android 阴影效果 elevation: 8, // 添加边框 borderWidth: 0.5, borderColor: 'rgba(0, 0, 0, 0.08)', }, popoverBackground: { backgroundColor: 'rgba(0, 0, 0, 0.3)', }, popoverContent: { minWidth: 140, paddingVertical: 8, }, popoverItem: { flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 12, gap: 12, }, popoverText: { fontSize: 16, fontWeight: '500', }, deleteButton: { backgroundColor: '#EF4444', justifyContent: 'center', alignItems: 'center', width: 80, borderRadius: 12, marginLeft: 8, }, deleteButtonText: { color: '#FFFFFF', fontSize: 12, fontWeight: '600', marginTop: 4, }, });