- 创建目标管理演示页面,展示高保真的目标管理界面 - 实现待办事项卡片的横向滑动展示,支持时间筛选功能 - 新增时间轴组件,展示选中日期的具体任务 - 更新底部导航,添加目标管理和演示页面的路由 - 优化个人页面菜单项,提供目标管理的快速访问 - 编写目标管理功能实现文档,详细描述功能和组件架构
106 lines
2.7 KiB
TypeScript
106 lines
2.7 KiB
TypeScript
import { Colors } from '@/constants/Colors';
|
|
import { useColorScheme } from '@/hooks/useColorScheme';
|
|
import React, { useRef } from 'react';
|
|
import { Dimensions, ScrollView, StyleSheet, Text, View } from 'react-native';
|
|
import { TodoCard, TodoItem } from './TodoCard';
|
|
|
|
interface TodoCarouselProps {
|
|
todos: TodoItem[];
|
|
onTodoPress?: (item: TodoItem) => void;
|
|
onToggleComplete?: (item: TodoItem) => void;
|
|
}
|
|
|
|
const { width: screenWidth } = Dimensions.get('window');
|
|
|
|
export function TodoCarousel({ todos, onTodoPress, onToggleComplete }: TodoCarouselProps) {
|
|
const theme = useColorScheme() ?? 'light';
|
|
const colorTokens = Colors[theme];
|
|
const scrollViewRef = useRef<ScrollView>(null);
|
|
|
|
if (!todos || todos.length === 0) {
|
|
return (
|
|
<View style={styles.emptyContainer}>
|
|
<Text style={[styles.emptyText, { color: colorTokens.textMuted }]}>
|
|
今天暂无待办事项
|
|
</Text>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<View style={styles.container}>
|
|
<ScrollView
|
|
ref={scrollViewRef}
|
|
horizontal
|
|
showsHorizontalScrollIndicator={false}
|
|
snapToInterval={(screenWidth - 60) * 0.65 + 16} // 卡片宽度 + 间距
|
|
snapToAlignment="start"
|
|
decelerationRate="fast"
|
|
contentContainerStyle={styles.scrollContent}
|
|
style={styles.scrollView}
|
|
>
|
|
{todos.map((item, index) => (
|
|
<TodoCard
|
|
key={item.id}
|
|
item={item}
|
|
onPress={onTodoPress}
|
|
onToggleComplete={onToggleComplete}
|
|
/>
|
|
))}
|
|
{/* 占位符,确保最后一张卡片有足够的滑动空间 */}
|
|
<View style={{ width: 20 }} />
|
|
</ScrollView>
|
|
|
|
{/* 底部指示器 */}
|
|
<View style={styles.indicatorContainer}>
|
|
{todos.map((_, index) => (
|
|
<View
|
|
key={index}
|
|
style={[
|
|
styles.indicator,
|
|
{ backgroundColor: index === 0 ? colorTokens.primary : colorTokens.border }
|
|
]}
|
|
/>
|
|
))}
|
|
</View>
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
},
|
|
scrollView: {
|
|
marginBottom: 12,
|
|
},
|
|
scrollContent: {
|
|
paddingHorizontal: 20,
|
|
alignItems: 'center',
|
|
},
|
|
emptyContainer: {
|
|
height: 140,
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
marginHorizontal: 20,
|
|
borderRadius: 20,
|
|
borderWidth: 1,
|
|
borderColor: '#E5E7EB',
|
|
borderStyle: 'dashed',
|
|
},
|
|
emptyText: {
|
|
fontSize: 14,
|
|
fontWeight: '500',
|
|
},
|
|
indicatorContainer: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
gap: 6,
|
|
},
|
|
indicator: {
|
|
width: 6,
|
|
height: 6,
|
|
borderRadius: 3,
|
|
},
|
|
});
|