feat: 新增任务管理功能及相关组件

- 将目标页面改为任务列表,支持任务的创建、完成和跳过功能
- 新增任务卡片和任务进度卡片组件,展示任务状态和进度
- 实现任务数据的获取和管理,集成Redux状态管理
- 更新API服务,支持任务相关的CRUD操作
- 编写任务管理功能实现文档,详细描述功能和组件架构
This commit is contained in:
richarjiang
2025-08-22 17:30:14 +08:00
parent 231620d778
commit 259f10540e
21 changed files with 2756 additions and 608 deletions

View File

@@ -0,0 +1,140 @@
import { TaskListItem } from '@/types/goals';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
interface TaskProgressCardProps {
tasks: TaskListItem[];
}
export const TaskProgressCard: React.FC<TaskProgressCardProps> = ({
tasks,
}) => {
// 计算今日任务完成进度
const todayTasks = tasks.filter(task => task.isToday);
const completedTodayTasks = todayTasks.filter(task => task.status === 'completed');
const progressPercentage = todayTasks.length > 0
? Math.round((completedTodayTasks.length / todayTasks.length) * 100)
: 0;
// 计算进度角度
const progressAngle = (progressPercentage / 100) * 360;
return (
<View style={styles.container}>
{/* 左侧内容 */}
<View style={styles.leftContent}>
<View style={styles.textContainer}>
<Text style={styles.title}></Text>
<Text style={styles.subtitle}>!</Text>
</View>
</View>
{/* 右侧进度圆环 */}
<View style={styles.progressContainer}>
{/* 背景圆环 */}
<View style={[styles.progressCircle, styles.progressBackground]} />
{/* 进度圆环 */}
<View style={[styles.progressCircle, styles.progressFill]}>
<View
style={[
styles.progressArc,
{
width: 68,
height: 68,
borderRadius: 34,
borderWidth: 6,
borderColor: '#8B5CF6',
borderTopColor: progressAngle > 0 ? '#8B5CF6' : 'transparent',
borderRightColor: progressAngle > 90 ? '#8B5CF6' : 'transparent',
borderBottomColor: progressAngle > 180 ? '#8B5CF6' : 'transparent',
borderLeftColor: progressAngle > 270 ? '#8B5CF6' : 'transparent',
transform: [{ rotate: '-90deg' }],
},
]}
/>
</View>
{/* 进度文字 */}
<View style={styles.progressTextContainer}>
<Text style={styles.progressText}>{progressPercentage}%</Text>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: '#8B5CF6',
borderRadius: 16,
padding: 20,
marginHorizontal: 20,
marginBottom: 20,
flexDirection: 'row',
alignItems: 'center',
position: 'relative',
shadowColor: '#8B5CF6',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
elevation: 8,
},
leftContent: {
flex: 1,
marginRight: 20,
},
textContainer: {
marginBottom: 16,
},
title: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: '600',
marginBottom: 2,
},
subtitle: {
color: '#FFFFFF',
fontSize: 14,
fontWeight: '400',
opacity: 0.9,
},
progressContainer: {
width: 80,
height: 80,
justifyContent: 'center',
alignItems: 'center',
position: 'relative',
},
progressCircle: {
position: 'absolute',
width: 80,
height: 80,
borderRadius: 40,
},
progressBackground: {
borderWidth: 6,
borderColor: 'rgba(255, 255, 255, 0.3)',
},
progressFill: {
borderWidth: 6,
borderColor: 'transparent',
justifyContent: 'center',
alignItems: 'center',
},
progressArc: {
position: 'absolute',
},
progressTextContainer: {
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
},
progressText: {
color: '#FFFFFF',
fontSize: 16,
fontWeight: '700',
},
});