Initial commit
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
import DocumentListCard from '@/components/DocumentListCard';
|
||||
import LoadingScreen from '@/components/LoadingScreen';
|
||||
import { DocumentItem } from '@/types/types';
|
||||
import api from '@/utils/api';
|
||||
import * as DocumentPicker from 'expo-document-picker';
|
||||
import { useLocalSearchParams, useRouter } from 'expo-router';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { ChevronLeft, AlertCircle } from 'lucide-react-native';
|
||||
import { useAlert } from '@/components/AlertComponent';
|
||||
import { uploadDocument } from '@/utils/documentUtils';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { ActivityIndicator, RefreshControl, ScrollView, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
|
||||
export default function ConstructionSiteDocumentsScreen() {
|
||||
const { id, name } = useLocalSearchParams();
|
||||
const router = useRouter();
|
||||
const alert = useAlert();
|
||||
const [documents, setDocuments] = useState<DocumentItem[]>([]);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
|
||||
const fetchDocuments = useCallback(async () => {
|
||||
try {
|
||||
const response = await api.get(`/construction-site/get-attachments?id=${id}`);
|
||||
if (response.data?.success) {
|
||||
setDocuments(response.data.result || []);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Errore nel recupero dei documenti:', error);
|
||||
alert.showAlert('error', 'Errore', 'Impossibile recuperare la lista dei documenti.');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
setIsRefreshing(false);
|
||||
}
|
||||
}, [id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (id) {
|
||||
fetchDocuments();
|
||||
}
|
||||
}, [id, fetchDocuments]);
|
||||
|
||||
const onRefresh = () => {
|
||||
setIsRefreshing(true);
|
||||
fetchDocuments();
|
||||
};
|
||||
|
||||
const handleUpload = async () => {
|
||||
try {
|
||||
const result = await DocumentPicker.getDocumentAsync({
|
||||
type: '*/*',
|
||||
copyToCacheDirectory: true,
|
||||
multiple: false,
|
||||
});
|
||||
|
||||
if (result.canceled || !result.assets || result.assets.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const file = result.assets[0];
|
||||
setIsUploading(true);
|
||||
|
||||
await uploadDocument(file, {
|
||||
endpoint: '/construction-site/upload-attachment',
|
||||
fileKey: 'files',
|
||||
extraData: {
|
||||
model_classname: 'ConstructionSite',
|
||||
model_id: id as string,
|
||||
method: 'put',
|
||||
name: file.name,
|
||||
type: file.mimeType || 'application/octet-stream'
|
||||
}
|
||||
});
|
||||
|
||||
alert.showAlert('success', 'Successo', 'Documento caricato con successo.');
|
||||
onRefresh(); // reload list
|
||||
} catch (error: any) {
|
||||
console.error('Errore durante l\'upload:', error);
|
||||
alert.showAlert('error', 'Errore', error.message || 'Si è verificato un errore durante l\'upload del documento.');
|
||||
} finally {
|
||||
setIsUploading(false);
|
||||
}
|
||||
};
|
||||
|
||||
if (isLoading && !isRefreshing) {
|
||||
return <LoadingScreen />;
|
||||
}
|
||||
|
||||
return (
|
||||
<View className="flex-1 bg-primary-dark">
|
||||
<StatusBar style="light" />
|
||||
<SafeAreaView edges={['top']} className="pt-5">
|
||||
{/* Header */}
|
||||
<View className="pb-6 px-6 z-10 flex-row items-center justify-between">
|
||||
<TouchableOpacity
|
||||
onPress={() => router.back()}
|
||||
className="p-2 -ml-2 rounded-full active:bg-white/20 w-12 items-center justify-center"
|
||||
>
|
||||
<ChevronLeft size={28} color="white" pointerEvents="none" />
|
||||
</TouchableOpacity>
|
||||
|
||||
<View className="flex-1 px-2">
|
||||
<Text className="text-white text-xl font-bold text-center leading-tight uppercase" numberOfLines={1}>
|
||||
{name || 'Allegati Cantiere'}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View className="w-10" />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
|
||||
{/* Content */}
|
||||
<View className="flex-1 bg-slate-50 rounded-t-[2.5rem] overflow-hidden">
|
||||
{isUploading && (
|
||||
<View className="absolute z-10 top-0 left-0 right-0 bottom-0 bg-white/50 justify-center items-center">
|
||||
<ActivityIndicator size="large" color="#1071C2" />
|
||||
<Text className="text-primary-dark font-bold mt-2">Caricamento in corso...</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<ScrollView
|
||||
className="flex-1 px-6 pt-6"
|
||||
contentContainerStyle={{ paddingBottom: 100 }}
|
||||
showsVerticalScrollIndicator={false}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={isRefreshing} onRefresh={onRefresh} colors={['#1071C2']} />
|
||||
}
|
||||
>
|
||||
<View className="flex-row justify-between items-center mb-6 px-1">
|
||||
<Text className="text-slate-800 text-xl font-bold">Documenti</Text>
|
||||
<TouchableOpacity onPress={handleUpload} disabled={isUploading}>
|
||||
{isUploading ? (
|
||||
<ActivityIndicator size="small" color="#1071C2" />
|
||||
) : (
|
||||
<Text className="text-[#1071C2] text-lg font-semibold">Aggiungi</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{documents.length > 0 ? (
|
||||
<View className="gap-4">
|
||||
{documents.map((item, index) => (
|
||||
<DocumentListCard key={item.id || index} item={item} />
|
||||
))}
|
||||
</View>
|
||||
) : (
|
||||
<View className="bg-white p-8 rounded-3xl border border-slate-200 items-center justify-center border-dashed mt-4">
|
||||
<View className="bg-slate-50 p-4 rounded-full mb-3">
|
||||
<AlertCircle size={32} color="#94a3b8" />
|
||||
</View>
|
||||
<Text className="text-slate-500 font-medium text-center">
|
||||
Nessun documento caricato per questo cantiere.
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</ScrollView>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user