feat: 新增任务详情页面及相关功能
- 创建任务详情页面,展示任务的详细信息,包括状态、描述、优先级和进度 - 实现任务完成和跳过功能,用户可通过按钮操作更新任务状态 - 添加评论功能,用户可以对任务进行评论并发送 - 优化任务卡片,点击后可跳转至任务详情页面 - 更新相关样式,确保界面一致性和美观性
This commit is contained in:
@@ -5,6 +5,7 @@ import { useColorScheme } from '@/hooks/useColorScheme';
|
||||
import { completeTask, skipTask } from '@/store/tasksSlice';
|
||||
import { TaskListItem } from '@/types/goals';
|
||||
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
||||
import { useRouter } from 'expo-router';
|
||||
import React from 'react';
|
||||
import { Alert, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
|
||||
@@ -19,6 +20,7 @@ export const TaskCard: React.FC<TaskCardProps> = ({
|
||||
const colorTokens = Colors[theme];
|
||||
const dispatch = useAppDispatch();
|
||||
const { showConfirm } = useGlobalDialog();
|
||||
const router = useRouter();
|
||||
|
||||
|
||||
const getStatusText = (status: string) => {
|
||||
@@ -123,6 +125,10 @@ export const TaskCard: React.FC<TaskCardProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
const handleTaskPress = () => {
|
||||
router.push(`/task-detail?taskId=${task.id}`);
|
||||
};
|
||||
|
||||
const renderActionIcons = () => {
|
||||
if (task.status === 'completed' || task.status === 'overdue' || task.status === 'skipped') {
|
||||
return null;
|
||||
@@ -158,7 +164,7 @@ export const TaskCard: React.FC<TaskCardProps> = ({
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[styles.container, { backgroundColor: colorTokens.background }]}
|
||||
onPress={() => {}}
|
||||
onPress={handleTaskPress}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
{/* 头部区域 */}
|
||||
@@ -205,23 +211,21 @@ export const TaskCard: React.FC<TaskCardProps> = ({
|
||||
)}
|
||||
{/* 进度百分比文本 */}
|
||||
<View style={styles.progressTextContainer}>
|
||||
<Text style={styles.progressText}>{Math.round(task.progressPercentage)}%</Text>
|
||||
<Text style={styles.progressText}>{task.currentCount}/{task.targetCount}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 底部信息 */}
|
||||
<View style={styles.footer}>
|
||||
<View style={styles.teamSection}>
|
||||
{/* 模拟团队成员头像 */}
|
||||
{/* 团队成员头像 */}
|
||||
<View style={styles.avatars}>
|
||||
<View style={[styles.avatar, { backgroundColor: '#FBBF24' }]}>
|
||||
<Text style={styles.avatarText}>A</Text>
|
||||
</View>
|
||||
<View style={[styles.avatar, { backgroundColor: '#34D399' }]}>
|
||||
<Text style={styles.avatarText}>B</Text>
|
||||
</View>
|
||||
<View style={[styles.avatar, { backgroundColor: '#60A5FA' }]}>
|
||||
<Text style={styles.avatarText}>C</Text>
|
||||
<View style={styles.avatar}>
|
||||
<Image
|
||||
source={require('@/assets/images/Sealife.jpeg')}
|
||||
style={styles.avatarImage}
|
||||
resizeMode="cover"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
@@ -395,17 +399,15 @@ const styles = StyleSheet.create({
|
||||
avatar: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
borderRadius: 24,
|
||||
marginRight: -8,
|
||||
borderWidth: 2,
|
||||
borderColor: '#FFFFFF',
|
||||
overflow: 'hidden',
|
||||
},
|
||||
avatarText: {
|
||||
fontSize: 10,
|
||||
fontWeight: '600',
|
||||
color: '#FFFFFF',
|
||||
avatarImage: {
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
},
|
||||
infoSection: {
|
||||
flexDirection: 'row',
|
||||
|
||||
@@ -22,8 +22,7 @@ export const TaskProgressCard: React.FC<TaskProgressCardProps> = ({
|
||||
{/* 标题区域 */}
|
||||
<View style={styles.header}>
|
||||
<View style={styles.titleContainer}>
|
||||
<Text style={styles.title}>任务状态统计</Text>
|
||||
<Text style={styles.subtitle}>各状态任务数量分布</Text>
|
||||
<Text style={styles.title}>统计</Text>
|
||||
</View>
|
||||
{headerButtons && (
|
||||
<View style={styles.headerButtons}>
|
||||
@@ -82,7 +81,7 @@ const styles = StyleSheet.create({
|
||||
marginBottom: 20,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'flex-start',
|
||||
alignItems: 'center',
|
||||
},
|
||||
titleContainer: {
|
||||
flex: 1,
|
||||
|
||||
@@ -45,38 +45,6 @@ export function HeaderBar({
|
||||
}
|
||||
};
|
||||
|
||||
const getBackButtonStyle = () => {
|
||||
const baseStyle = [styles.backButton];
|
||||
|
||||
switch (variant) {
|
||||
case 'elevated':
|
||||
return [...baseStyle, {
|
||||
backgroundColor: `${theme.primary}15`, // 15% 透明度
|
||||
borderWidth: 1,
|
||||
borderColor: `${theme.primary}20`, // 20% 透明度
|
||||
}];
|
||||
case 'minimal':
|
||||
return [...baseStyle, {
|
||||
backgroundColor: `${theme.neutral100}80`, // 80% 透明度
|
||||
}];
|
||||
default:
|
||||
return [...baseStyle, {
|
||||
backgroundColor: `${theme.accentGreen}20`, // 20% 透明度
|
||||
}];
|
||||
}
|
||||
};
|
||||
|
||||
const getBackButtonIconColor = () => {
|
||||
switch (variant) {
|
||||
case 'elevated':
|
||||
return theme.primary;
|
||||
case 'minimal':
|
||||
return theme.textSecondary;
|
||||
default:
|
||||
return theme.onPrimary;
|
||||
}
|
||||
};
|
||||
|
||||
const getBorderStyle = () => {
|
||||
if (!showBottomBorder) return {};
|
||||
|
||||
@@ -110,13 +78,13 @@ export function HeaderBar({
|
||||
<TouchableOpacity
|
||||
accessibilityRole="button"
|
||||
onPress={onBack}
|
||||
style={getBackButtonStyle()}
|
||||
style={styles.backButton}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<Ionicons
|
||||
name="chevron-back"
|
||||
size={20}
|
||||
color={getBackButtonIconColor()}
|
||||
size={24}
|
||||
color={theme.text}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
@@ -157,17 +125,8 @@ const styles = StyleSheet.create({
|
||||
backButton: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: {
|
||||
width: 0,
|
||||
height: 1,
|
||||
},
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 2,
|
||||
elevation: 2,
|
||||
},
|
||||
titleContainer: {
|
||||
flex: 1,
|
||||
|
||||
Reference in New Issue
Block a user