Files
digital-pilates/components/TaskFilterTabs.tsx
richarjiang 9e719a9eda feat: 增强任务管理功能,新增任务筛选和状态统计组件
- 在目标页面中集成任务筛选标签,支持按状态(全部、待完成、已完成)过滤任务
- 更新任务卡片,展示任务状态和优先级信息
- 新增任务进度卡片,统计各状态任务数量
- 优化空状态展示,根据筛选条件动态显示提示信息
- 引入新图标和图片资源,提升界面视觉效果
2025-08-22 20:45:15 +08:00

176 lines
4.2 KiB
TypeScript

import React from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export type TaskFilterType = 'all' | 'pending' | 'completed';
interface TaskFilterTabsProps {
selectedFilter: TaskFilterType;
onFilterChange: (filter: TaskFilterType) => void;
taskCounts: {
all: number;
pending: number;
completed: number;
};
}
export const TaskFilterTabs: React.FC<TaskFilterTabsProps> = ({
selectedFilter,
onFilterChange,
taskCounts,
}) => {
return (
<View style={styles.container}>
<View style={styles.tabContainer}>
{/* 全部 Tab */}
<TouchableOpacity
style={[
styles.tab,
selectedFilter === 'all' && styles.activeTab
]}
onPress={() => onFilterChange('all')}
>
<Text style={[
styles.tabText,
selectedFilter === 'all' && styles.activeTabText
]}>
</Text>
<View style={[
styles.badge,
selectedFilter === 'all' ? styles.activeBadge : styles.inactiveBadge
]}>
<Text style={[
styles.badgeText,
selectedFilter === 'all' && styles.activeBadgeText
]}>
{taskCounts.all}
</Text>
</View>
</TouchableOpacity>
{/* 待完成 Tab */}
<TouchableOpacity
style={[
styles.tab,
selectedFilter === 'pending' && styles.activeTab
]}
onPress={() => onFilterChange('pending')}
>
<Text style={[
styles.tabText,
selectedFilter === 'pending' && styles.activeTabText
]}>
</Text>
<View style={[
styles.badge,
selectedFilter === 'pending' ? styles.activeBadge : styles.inactiveBadge
]}>
<Text style={[
styles.badgeText,
selectedFilter === 'pending' && styles.activeBadgeText
]}>
{taskCounts.pending}
</Text>
</View>
</TouchableOpacity>
{/* 已完成 Tab */}
<TouchableOpacity
style={[
styles.tab,
selectedFilter === 'completed' && styles.activeTab
]}
onPress={() => onFilterChange('completed')}
>
<Text style={[
styles.tabText,
selectedFilter === 'completed' && styles.activeTabText
]}>
</Text>
<View style={[
styles.badge,
selectedFilter === 'completed' ? styles.activeBadge : styles.inactiveBadge
]}>
<Text style={[
styles.badgeText,
selectedFilter === 'completed' && styles.activeBadgeText
]}>
{taskCounts.completed}
</Text>
</View>
</TouchableOpacity>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
paddingHorizontal: 20,
},
tabContainer: {
backgroundColor: '#FFFFFF',
borderRadius: 24,
padding: 4,
flexDirection: 'row',
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.05,
shadowRadius: 2,
elevation: 1,
borderWidth: 1,
borderColor: '#E5E7EB',
},
tab: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
paddingVertical: 10,
paddingHorizontal: 12,
borderRadius: 20,
gap: 6,
},
activeTab: {
backgroundColor: '#7A5AF8',
shadowColor: '#7A5AF8',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2,
shadowRadius: 4,
elevation: 3,
},
tabText: {
fontSize: 14,
fontWeight: '500',
color: '#374151',
},
activeTabText: {
color: '#FFFFFF',
fontWeight: '600',
},
badge: {
minWidth: 20,
height: 20,
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center',
paddingHorizontal: 6,
},
inactiveBadge: {
backgroundColor: '#E5E7EB',
},
activeBadge: {
backgroundColor: '#EF4444',
},
badgeText: {
fontSize: 12,
fontWeight: '600',
color: '#374151',
},
activeBadgeText: {
color: '#FFFFFF',
},
});