- Added a new DocumentsScreen for managing user documents with search and date filtering capabilities. - Created AddDocumentModal for uploading documents with file selection and custom title options. - Introduced SiteDocumentsScreen to display documents related to specific construction sites. - Implemented SitesScreen for listing construction sites with search functionality. - Updated ProfileScreen to link to the new DocumentsScreen. - Refactored RangePickerModal for selecting date ranges in document filtering. - Improved date formatting utilities for better timestamp handling. - Added necessary API calls for document and site management. - Updated types to reflect changes in document structure and site information. - Added expo-document-picker dependency for document selection functionality.
124 lines
5.5 KiB
TypeScript
124 lines
5.5 KiB
TypeScript
import { Building2, ChevronRight, MapPin, Search } from 'lucide-react-native';
|
|
import React, { useEffect, useState } from 'react';
|
|
import { Alert, RefreshControl, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native';
|
|
import { useRouter } from 'expo-router';
|
|
import api from '@/utils/api';
|
|
import LoadingScreen from '@/components/LoadingScreen';
|
|
import { ConstructionSite } from '@/types/types';
|
|
|
|
export default function SitesScreen() {
|
|
const [searchTerm, setSearchTerm] = useState('');
|
|
const [constructionSites, setConstructionSites] = useState<ConstructionSite[]>([]);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [refreshing, setRefreshing] = useState(false);
|
|
const router = useRouter();
|
|
|
|
// Fetch cantieri e documenti
|
|
const fetchConstructionSites = async () => {
|
|
try {
|
|
if (!refreshing) setIsLoading(true);
|
|
|
|
// Fetch Cantieri
|
|
const response = await api.get('/construction-site/sites-attachments');
|
|
setConstructionSites(response.data);
|
|
} catch (error) {
|
|
console.error('Errore nel recupero dei cantieri:', error);
|
|
Alert.alert('Errore', 'Impossibile recuperare i cantieri. Riprova più tardi.');
|
|
} finally {
|
|
setIsLoading(false);
|
|
setRefreshing(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchConstructionSites();
|
|
}, []);
|
|
|
|
const onRefresh = () => {
|
|
setRefreshing(true);
|
|
fetchConstructionSites();
|
|
};
|
|
|
|
// Filtriamo i cantieri in base alla ricerca
|
|
const filteredSites = constructionSites.filter(site =>
|
|
site.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
site.code.toLowerCase().includes(searchTerm.toLowerCase())
|
|
);
|
|
|
|
if (isLoading && !refreshing) {
|
|
return <LoadingScreen />;
|
|
}
|
|
|
|
return (
|
|
<View className="flex-1 bg-gray-50">
|
|
{/* Header */}
|
|
<View className="bg-white p-6 pt-16 shadow-sm border-b border-gray-100">
|
|
<Text className="text-3xl font-bold text-gray-800 mb-1">Cantieri</Text>
|
|
<Text className="text-base text-gray-500">Seleziona un cantiere per vedere i documenti</Text>
|
|
</View>
|
|
|
|
<View className="px-5 mt-5 gap-6 flex-1">
|
|
{/* Search Bar */}
|
|
<View className={`relative justify-center`}>
|
|
<View className="absolute left-4 z-10">
|
|
<Search size={24} color="#9ca3af" />
|
|
</View>
|
|
<TextInput
|
|
placeholder="Cerca per codice o nome cantiere..."
|
|
placeholderTextColor="#9ca3af"
|
|
className={`w-full pl-12 pr-4 py-4 bg-white shadow-sm rounded-2xl border ${searchTerm ? 'border-[#099499]' : 'border-gray-200'} text-gray-800 text-lg`}
|
|
value={searchTerm}
|
|
onChangeText={setSearchTerm}
|
|
/>
|
|
</View>
|
|
|
|
{/* Lista Cantieri */}
|
|
{/* TODO: Rimuovere lo ScrollIndicator? */}
|
|
<ScrollView
|
|
contentContainerStyle={{ gap: 16, paddingBottom: 40 }}
|
|
showsVerticalScrollIndicator={true}
|
|
refreshControl={
|
|
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} colors={['#099499']} />
|
|
}
|
|
>
|
|
{filteredSites.map((site, index) => (
|
|
<TouchableOpacity
|
|
key={index}
|
|
onPress={() => router.push({
|
|
pathname: '/(protected)/sites/[id]',
|
|
params: {
|
|
id: site.id ,
|
|
siteData: JSON.stringify(site),
|
|
}
|
|
})}
|
|
className="bg-white p-5 rounded-3xl shadow-sm flex-row items-center justify-between border border-gray-100 active:bg-gray-50"
|
|
>
|
|
<View className="flex-row items-center gap-5 flex-1">
|
|
<View className="bg-blue-50 p-4 rounded-2xl">
|
|
<Building2 size={32} color="#2563eb" />
|
|
</View>
|
|
<View className="flex-1">
|
|
<Text className="text-base font-medium text-gray-400 mb-0.5">{site.code}</Text>
|
|
<Text className="font-bold text-gray-800 text-lg mb-1">{site.name}</Text>
|
|
<View className="flex-row items-center mt-1">
|
|
<MapPin size={16} color="#9ca3af" />
|
|
<Text className="text-sm text-gray-400 ml-1 font-medium">
|
|
{site.attachments_count} Documenti disponibili
|
|
</Text>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
|
|
{/* Freccia al posto del download */}
|
|
<ChevronRight size={24} color="#9ca3af" />
|
|
</TouchableOpacity>
|
|
))}
|
|
|
|
{filteredSites.length === 0 && (
|
|
<Text className="text-center text-gray-400 mt-10">Nessun cantiere trovato</Text>
|
|
)}
|
|
</ScrollView>
|
|
</View>
|
|
</View>
|
|
);
|
|
} |