feat: 增强目标管理功能及相关组件
- 在 GoalsListScreen 中新增目标编辑功能,支持用户编辑现有目标 - 更新 CreateGoalModal 组件,支持编辑模式下的目标更新 - 在 NutritionRecordsScreen 中新增删除营养记录功能,允许用户删除不需要的记录 - 更新 NutritionRecordCard 组件,增加操作选项,支持删除记录 - 修改 dietRecords 服务,添加删除营养记录的 API 调用 - 优化 goalsSlice,确保目标更新逻辑与 Redux 状态管理一致
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
import { GoalCard } from '@/components/GoalCard';
|
||||
import { CreateGoalModal } from '@/components/model/CreateGoalModal';
|
||||
import { useGlobalDialog } from '@/components/ui/DialogProvider';
|
||||
import { Colors } from '@/constants/Colors';
|
||||
import { TAB_BAR_BOTTOM_OFFSET, TAB_BAR_HEIGHT } from '@/constants/TabBar';
|
||||
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
|
||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||
import { deleteGoal, fetchGoals, loadMoreGoals } from '@/store/goalsSlice';
|
||||
import { GoalListItem } from '@/types/goals';
|
||||
import { deleteGoal, fetchGoals, loadMoreGoals, updateGoal } from '@/store/goalsSlice';
|
||||
import { CreateGoalRequest, GoalListItem, UpdateGoalRequest } from '@/types/goals';
|
||||
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
@@ -18,6 +20,8 @@ export default function GoalsListScreen() {
|
||||
const colorTokens = Colors[theme];
|
||||
const dispatch = useAppDispatch();
|
||||
const router = useRouter();
|
||||
|
||||
const { showConfirm } = useGlobalDialog();
|
||||
|
||||
// Redux状态
|
||||
const {
|
||||
@@ -25,9 +29,15 @@ export default function GoalsListScreen() {
|
||||
goalsLoading,
|
||||
goalsError,
|
||||
goalsPagination,
|
||||
updateLoading,
|
||||
updateError,
|
||||
} = useAppSelector((state) => state.goals);
|
||||
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
// 编辑目标相关状态
|
||||
const [showEditModal, setShowEditModal] = useState(false);
|
||||
const [editingGoal, setEditingGoal] = useState<GoalListItem | null>(null);
|
||||
|
||||
// 页面聚焦时重新加载数据
|
||||
useFocusEffect(
|
||||
@@ -162,16 +172,11 @@ export default function GoalsListScreen() {
|
||||
if (goalsError) {
|
||||
Alert.alert('错误', goalsError);
|
||||
}
|
||||
}, [goalsError]);
|
||||
if (updateError) {
|
||||
Alert.alert('更新失败', updateError);
|
||||
}
|
||||
}, [goalsError, updateError]);
|
||||
|
||||
// 计算各状态的目标数量
|
||||
const goalCounts = useMemo(() => ({
|
||||
all: goals.length,
|
||||
active: goals.filter(goal => goal.status === 'active').length,
|
||||
paused: goals.filter(goal => goal.status === 'paused').length,
|
||||
completed: goals.filter(goal => goal.status === 'completed').length,
|
||||
cancelled: goals.filter(goal => goal.status === 'cancelled').length,
|
||||
}), [goals]);
|
||||
|
||||
// 根据筛选条件过滤目标
|
||||
const filteredGoals = useMemo(() => {
|
||||
@@ -182,6 +187,58 @@ export default function GoalsListScreen() {
|
||||
|
||||
// 处理目标点击
|
||||
const handleGoalPress = (goal: GoalListItem) => {
|
||||
setEditingGoal(goal);
|
||||
setShowEditModal(true);
|
||||
};
|
||||
|
||||
// 将 GoalListItem 转换为 CreateGoalRequest 格式
|
||||
const convertGoalToModalData = (goal: GoalListItem): Partial<CreateGoalRequest> => {
|
||||
return {
|
||||
title: goal.title,
|
||||
description: goal.description,
|
||||
repeatType: goal.repeatType,
|
||||
frequency: goal.frequency,
|
||||
category: goal.category,
|
||||
priority: goal.priority,
|
||||
hasReminder: goal.hasReminder,
|
||||
reminderTime: goal.reminderTime,
|
||||
customRepeatRule: goal.customRepeatRule,
|
||||
endDate: goal.endDate,
|
||||
};
|
||||
};
|
||||
|
||||
// 处理更新目标
|
||||
const handleUpdateGoal = async (goalId: string, goalData: UpdateGoalRequest) => {
|
||||
try {
|
||||
await dispatch(updateGoal({ goalId, goalData })).unwrap();
|
||||
setShowEditModal(false);
|
||||
setEditingGoal(null);
|
||||
|
||||
// 使用全局弹窗显示成功消息
|
||||
showConfirm(
|
||||
{
|
||||
title: '目标更新成功',
|
||||
message: '恭喜!您的目标已成功更新。',
|
||||
confirmText: '确定',
|
||||
cancelText: '',
|
||||
icon: 'checkmark-circle',
|
||||
iconColor: '#10B981',
|
||||
},
|
||||
() => {
|
||||
console.log('用户确认了目标更新成功');
|
||||
}
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Failed to update goal:', error);
|
||||
Alert.alert('错误', '更新目标失败,请重试');
|
||||
// 更新失败时不关闭弹窗,保持编辑状态
|
||||
}
|
||||
};
|
||||
|
||||
// 处理编辑弹窗关闭
|
||||
const handleCloseEditModal = () => {
|
||||
setShowEditModal(false);
|
||||
setEditingGoal(null);
|
||||
};
|
||||
|
||||
// 渲染目标项
|
||||
@@ -292,6 +349,19 @@ export default function GoalsListScreen() {
|
||||
ListFooterComponent={renderLoadMore}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* 编辑目标弹窗 */}
|
||||
{editingGoal && (
|
||||
<CreateGoalModal
|
||||
visible={showEditModal}
|
||||
onClose={handleCloseEditModal}
|
||||
onSubmit={() => {}} // 编辑模式下不使用这个回调
|
||||
onUpdate={handleUpdateGoal}
|
||||
loading={updateLoading}
|
||||
initialData={convertGoalToModalData(editingGoal)}
|
||||
editGoalId={editingGoal.id}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user