- 在目标页面中集成任务筛选标签,支持按状态(全部、待完成、已完成)过滤任务 - 更新任务卡片,展示任务状态和优先级信息 - 新增任务进度卡片,统计各状态任务数量 - 优化空状态展示,根据筛选条件动态显示提示信息 - 引入新图标和图片资源,提升界面视觉效果
176 lines
4.2 KiB
TypeScript
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',
|
|
},
|
|
});
|