feat: Implement document management features
- 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.
This commit is contained in:
@ -1,12 +1,41 @@
|
||||
import React, { useState } from 'react';
|
||||
import { View, Text, TouchableOpacity, ScrollView } from 'react-native';
|
||||
import React, { use, useEffect, useState } from 'react';
|
||||
import { View, Text, TouchableOpacity, ScrollView, Alert, RefreshControl } from 'react-native';
|
||||
import { QrCode, CheckCircle2 } from 'lucide-react-native';
|
||||
import { ATTENDANCE_DATA } from '@/data/data';
|
||||
import QrScanModal from '@/components/QrScanModal';
|
||||
import LoadingScreen from '@/components/LoadingScreen';
|
||||
import api from '@/utils/api';
|
||||
|
||||
export default function AttendanceScreen() {
|
||||
const [showScanner, setShowScanner] = useState(false);
|
||||
const [lastScan, setLastScan] = useState<{ type: string; time: string; site: string } | null>(null);
|
||||
const [attendances, setAttendances] = useState(ATTENDANCE_DATA);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
|
||||
const fetchAttendances = async () => {
|
||||
try {
|
||||
if (!refreshing) setIsLoading(true);
|
||||
// Fetch today's attendance data from API
|
||||
const response = await api.get('/attendance/list');
|
||||
// setAttendances(response.data);
|
||||
} catch (error) {
|
||||
console.error('Errore nel recupero delle presenze:', error);
|
||||
Alert.alert('Errore', 'Impossibile recuperare le presenze. Riprova più tardi.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
setRefreshing(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchAttendances();
|
||||
}, []);
|
||||
|
||||
const onRefresh = () => {
|
||||
setRefreshing(true);
|
||||
fetchAttendances();
|
||||
};
|
||||
|
||||
const handleQRScan = () => {
|
||||
setShowScanner(true);
|
||||
@ -22,6 +51,10 @@ export default function AttendanceScreen() {
|
||||
}, 3000);
|
||||
};
|
||||
|
||||
if (isLoading && !refreshing) {
|
||||
return <LoadingScreen />;
|
||||
}
|
||||
|
||||
return (
|
||||
<View className="flex-1 bg-gray-50">
|
||||
{/* Header */}
|
||||
@ -30,7 +63,13 @@ export default function AttendanceScreen() {
|
||||
<Text className="text-base text-gray-500">Registra i tuoi movimenti</Text>
|
||||
</View>
|
||||
|
||||
<ScrollView contentContainerStyle={{ paddingBottom: 40 }}>
|
||||
<ScrollView
|
||||
contentContainerStyle={{ paddingBottom: 40 }}
|
||||
showsVerticalScrollIndicator={false}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} colors={['#099499']} />
|
||||
}
|
||||
>
|
||||
<View className="flex-1 p-5 items-center">
|
||||
|
||||
{/* Feedback Card - OPZIONALE */}
|
||||
@ -69,7 +108,7 @@ export default function AttendanceScreen() {
|
||||
|
||||
{/* Mini History */}
|
||||
<View className="w-full mt-4">
|
||||
<Text className="text-gray-500 font-bold text-base mb-4 uppercase tracking-wider px-2">Oggi</Text>
|
||||
<Text className="text-gray-500 font-bold text-base mb-4 uppercase tracking-wider px-2">Ultime Presenze</Text>
|
||||
<View className="bg-white rounded-3xl shadow-sm overflow-hidden border border-gray-100">
|
||||
{ATTENDANCE_DATA.map((item, index) => (
|
||||
<View key={item.id} className={`p-6 flex-row justify-between items-center ${index !== 0 ? 'border-t border-gray-100' : ''}`}>
|
||||
@ -81,9 +120,9 @@ export default function AttendanceScreen() {
|
||||
</View>
|
||||
</View>
|
||||
{item.status === 'complete' && (
|
||||
<View className="bg-gray-100 px-3 py-1.5 rounded-lg">
|
||||
<Text className="text-base font-mono text-gray-600 font-bold">8h</Text>
|
||||
</View>
|
||||
<View className="bg-gray-100 px-3 py-1.5 rounded-lg">
|
||||
<Text className="text-base font-mono text-gray-600 font-bold">8h</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
))}
|
||||
@ -94,9 +133,9 @@ export default function AttendanceScreen() {
|
||||
</ScrollView>
|
||||
|
||||
{/* Scanner Modal */}
|
||||
<QrScanModal
|
||||
visible={showScanner}
|
||||
onClose={() => setShowScanner(false)}
|
||||
<QrScanModal
|
||||
visible={showScanner}
|
||||
onClose={() => setShowScanner(false)}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user