import React from 'react'; import { View, Text, StyleSheet, ScrollView, TouchableOpacity, useColorScheme, RefreshControl, } from 'react-native'; import { useRouter } from 'expo-router'; import { Ionicons } from '@expo/vector-icons'; import { Colors, TaskStatusColors } from '../../constants/Colors'; import { useTasks, getTaskCounts } from '../../hooks/useTasks'; import { usePendingQuestions } from '../../hooks/useQuestions'; import { TaskStatusBadge } from '../../components/TaskStatusBadge'; import type { TaskSummary } from '../../lib/api'; interface StatCardProps { title: string; value: number; icon: keyof typeof Ionicons.glyphMap; color: string; onPress?: () => void; } function StatCard({ title, value, icon, color, onPress }: StatCardProps) { const colorScheme = useColorScheme() ?? 'light'; const colors = Colors[colorScheme]; return ( {value} {title} ); } interface QuickTaskItemProps { task: TaskSummary; onPress: () => void; } function QuickTaskItem({ task, onPress }: QuickTaskItemProps) { const colorScheme = useColorScheme() ?? 'light'; const colors = Colors[colorScheme]; return ( {task.name} {task.progressSummary && ( {task.progressSummary} )} ); } export default function DashboardScreen() { const colorScheme = useColorScheme() ?? 'light'; const colors = Colors[colorScheme]; const router = useRouter(); const { data: tasks, isLoading: isLoadingTasks, refetch: refetchTasks, isRefetching: isRefetchingTasks, } = useTasks(); const { data: questions, isLoading: isLoadingQuestions, refetch: refetchQuestions, isRefetching: isRefetchingQuestions, } = usePendingQuestions(); const isRefreshing = isRefetchingTasks || isRefetchingQuestions; const handleRefresh = () => { refetchTasks(); refetchQuestions(); }; // Calculate counts const counts = tasks ? getTaskCounts(tasks) : null; const questionCount = questions?.length ?? 0; // Get running tasks for quick access const runningTasks = tasks?.filter((t) => ['running', 'initializing', 'starting'].includes(t.status) ) ?? []; // Get tasks needing attention (blocked, paused, or with questions) const attentionTasks = tasks?.filter((t) => ['blocked', 'paused'].includes(t.status) ) ?? []; return ( } > {/* Stats Grid */} router.push('/(tabs)/tasks')} /> 0 ? () => router.push('/(tabs)/tasks') : undefined} /> router.push('/(tabs)/tasks')} /> router.push('/(tabs)/tasks') : undefined} /> {/* Pending Questions Alert */} {questionCount > 0 && ( router.push('/(tabs)/tasks')} activeOpacity={0.7} > {questionCount} Question{questionCount !== 1 ? 's' : ''} Waiting Tap to review and respond )} {/* Running Tasks */} {runningTasks.length > 0 && ( Running Tasks router.push('/(tabs)/tasks')}> See All {runningTasks.slice(0, 3).map((task) => ( router.push(`/task/${task.id}`)} /> ))} )} {/* Needs Attention */} {attentionTasks.length > 0 && ( Needs Attention router.push('/(tabs)/tasks')}> See All {attentionTasks.slice(0, 3).map((task) => ( router.push(`/task/${task.id}`)} /> ))} )} {/* Empty State */} {!isLoadingTasks && (!tasks || tasks.length === 0) && ( No tasks yet Tasks created from contracts will appear here )} ); } const styles = StyleSheet.create({ container: { flex: 1, }, content: { padding: 16, gap: 20, }, statsGrid: { flexDirection: 'row', flexWrap: 'wrap', gap: 12, }, statCard: { flex: 1, minWidth: '45%', padding: 16, borderRadius: 12, alignItems: 'center', gap: 8, }, iconContainer: { width: 48, height: 48, borderRadius: 24, alignItems: 'center', justifyContent: 'center', }, statValue: { fontSize: 28, fontWeight: '700', }, statTitle: { fontSize: 14, fontWeight: '500', }, alertBanner: { flexDirection: 'row', alignItems: 'center', padding: 16, borderRadius: 12, gap: 12, }, alertContent: { flex: 1, }, alertTitle: { fontSize: 16, fontWeight: '600', }, alertSubtitle: { fontSize: 13, marginTop: 2, }, section: { gap: 12, }, sectionHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, sectionTitle: { fontSize: 18, fontWeight: '600', }, seeAllButton: { fontSize: 14, fontWeight: '500', }, taskList: { gap: 8, }, quickTaskItem: { flexDirection: 'row', alignItems: 'center', padding: 12, borderRadius: 10, gap: 12, }, quickTaskContent: { flex: 1, gap: 2, }, quickTaskName: { fontSize: 15, fontWeight: '500', }, quickTaskSummary: { fontSize: 13, }, emptyState: { alignItems: 'center', justifyContent: 'center', paddingVertical: 48, gap: 12, }, emptyTitle: { fontSize: 18, fontWeight: '600', }, emptyMessage: { fontSize: 14, textAlign: 'center', }, });