import { GoalListItem } from '@/types/goals'; import MaterialIcons from '@expo/vector-icons/MaterialIcons'; import React, { useRef } from 'react'; import { Alert, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { Swipeable } from 'react-native-gesture-handler'; interface GoalCardProps { goal: GoalListItem; onPress?: (goal: GoalListItem) => void; onDelete?: (goalId: string) => void; showStatus?: boolean; } export const GoalCard: React.FC = ({ goal, onPress, onDelete, showStatus = true }) => { const swipeableRef = useRef(null); // 获取重复类型显示文本 const getRepeatTypeText = (goal: GoalListItem) => { switch (goal.repeatType) { case 'daily': return '每日'; case 'weekly': return '每周'; case 'monthly': return '每月'; default: return '每日'; } }; // 获取目标状态显示文本 const getStatusText = (goal: GoalListItem) => { switch (goal.status) { case 'active': return '进行中'; case 'paused': return '已暂停'; case 'completed': return '已完成'; case 'cancelled': return '已取消'; default: return '进行中'; } }; // 获取目标状态颜色 const getStatusColor = (goal: GoalListItem) => { switch (goal.status) { case 'active': return '#10B981'; case 'paused': return '#F59E0B'; case 'completed': return '#3B82F6'; case 'cancelled': return '#EF4444'; default: return '#10B981'; } }; // 获取目标图标 const getGoalIcon = (goal: GoalListItem) => { // 根据目标类别或标题返回不同的图标 const title = goal.title.toLowerCase(); const category = goal.category?.toLowerCase(); if (title.includes('运动') || title.includes('健身') || title.includes('跑步')) { return 'fitness-center'; } else if (title.includes('喝水') || title.includes('饮水')) { return 'local-drink'; } else if (title.includes('睡眠') || title.includes('睡觉')) { return 'bedtime'; } else if (title.includes('学习') || title.includes('读书')) { return 'school'; } else if (title.includes('冥想') || title.includes('放松')) { return 'self-improvement'; } else if (title.includes('早餐') || title.includes('午餐') || title.includes('晚餐')) { return 'restaurant'; } else { return 'flag'; } }; // 处理删除操作 const handleDelete = () => { Alert.alert( '确认删除', `确定要删除目标"${goal.title}"吗?此操作无法撤销。`, [ { text: '取消', style: 'cancel', }, { text: '删除', style: 'destructive', onPress: () => { onDelete?.(goal.id); swipeableRef.current?.close(); }, }, ] ); }; // 渲染删除按钮 const renderRightActions = () => { return ( ); }; return ( onPress?.(goal)} activeOpacity={0.7} > {/* 左侧图标 */} {/* 中间内容 */} {goal.title} {/* 底部信息行 */} {/* 积分 */} +1 {/* 目标数量 */} {goal.targetCount || goal.frequency} {/* 提醒图标(如果有提醒) */} {goal.hasReminder && ( )} {/* 提醒时间(如果有提醒) */} {goal.hasReminder && goal.reminderTime && ( {goal.reminderTime} )} {/* 重复图标 */} {/* 重复类型 */} {getRepeatTypeText(goal)} {/* 结束日期 */} {goal.endDate && ( {goal.endDate} )} {/* 右侧状态指示器 */} {showStatus && ( {getStatusText(goal)} )} ); }; const styles = StyleSheet.create({ goalCard: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#FFFFFF', borderRadius: 16, padding: 16, marginBottom: 12, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.05, shadowRadius: 8, elevation: 2, }, goalIcon: { width: 32, height: 32, borderRadius: 20, backgroundColor: '#F3F4F6', alignItems: 'center', justifyContent: 'center', marginRight: 12, position: 'relative', }, iconStars: { position: 'absolute', top: -2, right: -2, flexDirection: 'row', gap: 1, }, star: { width: 4, height: 4, borderRadius: 2, backgroundColor: '#FFFFFF', }, goalContent: { flex: 1, marginRight: 12, }, goalTitle: { fontSize: 14, fontWeight: '600', color: '#1F2937', marginBottom: 8, }, goalInfo: { flexDirection: 'row', alignItems: 'center', gap: 8, }, infoItem: { flexDirection: 'row', alignItems: 'center', }, infoText: { fontSize: 12, color: '#9CA3AF', fontWeight: '500', }, statusIndicator: { paddingHorizontal: 8, paddingVertical: 4, borderRadius: 12, minWidth: 60, alignItems: 'center', }, statusText: { fontSize: 10, color: '#FFFFFF', fontWeight: '600', }, deleteButton: { width: 60, height: '100%', justifyContent: 'center', alignItems: 'center', }, deleteButtonText: { color: '#FFFFFF', fontSize: 12, fontWeight: '600', marginTop: 4, }, });