import React, { useState, useEffect, useCallback, useRef } from 'react'; import { View, Text, FlatList, StyleSheet, TouchableOpacity, Image, RefreshControl, TextInput, } from 'react-native'; import { useFocusEffect, useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { RootStackParamList } from '../navigation/types'; import { Project } from '../types'; import { getAllProjects } from '../lib/db/repositories'; import { Button, Card } from '../components'; import { colors, spacing, typography, borderRadius } from '../lib/theme'; import { formatDate } from '../lib/utils/datetime'; import { useAuth } from '../contexts/AuthContext'; type NavigationProp = NativeStackNavigationProp; type SortOption = 'newest' | 'oldest' | 'name'; export const ProjectsScreen: React.FC = () => { const navigation = useNavigation(); const { user } = useAuth(); const [projects, setProjects] = useState([]); const [filteredProjects, setFilteredProjects] = useState([]); const [loading, setLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [sortBy, setSortBy] = useState('newest'); const [searchQuery, setSearchQuery] = useState(''); const sortProjects = (projectsToSort: Project[]) => { const sorted = [...projectsToSort]; switch (sortBy) { case 'newest': return sorted.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()); case 'oldest': return sorted.sort((a, b) => new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime()); case 'name': return sorted.sort((a, b) => a.title.localeCompare(b.title)); default: return sorted; } }; const filterProjects = (projectsToFilter: Project[], query: string) => { if (!query.trim()) return projectsToFilter; const lowerQuery = query.toLowerCase(); return projectsToFilter.filter(project => project.title.toLowerCase().includes(lowerQuery) || project.tags.some(tag => tag.toLowerCase().includes(lowerQuery)) ); }; const loadProjects = async () => { if (!user) return; try { const allProjects = await getAllProjects(user.id); const sorted = sortProjects(allProjects); setProjects(sorted); setFilteredProjects(filterProjects(sorted, searchQuery)); } catch (error) { console.error('Failed to load projects:', error); } finally { setLoading(false); setRefreshing(false); } }; useFocusEffect( useCallback(() => { loadProjects(); }, []) ); useEffect(() => { if (projects.length > 0) { const sorted = sortProjects(projects); setProjects(sorted); setFilteredProjects(filterProjects(sorted, searchQuery)); } }, [sortBy]); useEffect(() => { setFilteredProjects(filterProjects(projects, searchQuery)); }, [searchQuery]); const handleRefresh = () => { setRefreshing(true); loadProjects(); }; const handleCreateProject = () => { navigation.navigate('ProjectDetail', { projectId: 'new' }); }; const handleProjectPress = (projectId: string) => { navigation.navigate('ProjectDetail', { projectId }); }; const getStepCount = (projectId: string) => { // This will be calculated from actual steps return 0; // Placeholder }; const renderProject = ({ item }: { item: Project }) => { const stepCount = getStepCount(item.id); return ( handleProjectPress(item.id)} accessibilityRole="button" accessibilityLabel={`Open project ${item.title}`} > {item.coverImageUri && ( {stepCount > 0 && ( {stepCount} steps )} )} {item.title} {item.status === 'in_progress' ? 'In Progress' : 'Done'} {formatDate(item.updatedAt)} {item.tags.length > 0 && ( {item.tags.map((tag, index) => ( {tag} ))} )} ); }; if (loading) { return ( Loading projects... ); } return ( {filteredProjects.length === 0 && searchQuery.length > 0 ? ( 🔍 No matches found Try a different search term ) : projects.length === 0 ? ( 🏺 No projects yet Start your first piece! ) : ( item.id} contentContainerStyle={styles.listContent} refreshControl={ } ListHeaderComponent={ {/* MY PROJECTS Title */} My Projects {/* Create Project Button */}