import { useAlert } from '@/components/AlertComponent'; import LoadingScreen from '@/components/LoadingScreen'; import SetDescriptionModal from '@/components/SetDescriptionModal'; import api from '@/utils/api'; import { Image } from 'expo-image'; import { downloadAndShareDocument } from '@/utils/documentUtils'; import ImageView from "react-native-image-viewing"; import { useLocalSearchParams, useRouter } from 'expo-router'; import { ChevronLeft, ImageIcon, Share2, Trash2, Pencil } from 'lucide-react-native'; import React, { useCallback, useEffect, useState } from 'react'; import { Dimensions, RefreshControl, ScrollView, Text, TouchableOpacity, View } from 'react-native'; import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context'; export default function JournalDetailScreen() { const router = useRouter(); const alert = useAlert(); const params = useLocalSearchParams(); const insets = useSafeAreaInsets(); const [placeName, setPlaceName] = useState(''); const [photos, setPhotos] = useState([]); const [isLoading, setIsLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const [isVisible, setIsVisible] = useState(false); const [currentIndex, setCurrentIndex] = useState(0); const [descModalVisible, setDescModalVisible] = useState(false); const [editIndex, setEditIndex] = useState(null); const handleDescription = async (desc: string) => { if (editIndex === null) return; const photo = photos[editIndex]; if (!photo) return; setDescModalVisible(false); try { const response = await api.post('/journal/save-description', { id: photo.id, description: desc, }); if (response.data?.success) { fetchDetails(true); alert.showAlert('success', 'Salvato', 'Descrizione aggiornata con successo.'); } else { alert.showAlert('error', 'Errore', response.data?.message || 'Impossibile salvare la descrizione.'); } } catch (error) { console.error(error); alert.showAlert('error', 'Errore', 'Si è verificato un errore durante il salvataggio.'); } }; const [isSharing, setIsSharing] = useState(false); const handleShare = async (uri: string) => { if (isSharing) return; // Prevent multiple share actions setIsSharing(true); try { const fileName = uri.split('/').pop() || 'immagine.jpg'; await downloadAndShareDocument('image/jpeg', fileName, uri); } catch (error) { console.error('Error sharing image:', error); alert.showAlert('error', 'Errore', 'Si è verificato un errore durante la condivisione.'); } finally { setIsSharing(false); } }; const handleDelete = (id: string) => { alert.showConfirm( 'Sei sicuro?', 'Vuoi davvero eliminare questa foto?', [ { text: 'Annulla', style: 'cancel', onPress: () => {} }, { text: 'Elimina', style: 'destructive', onPress: async () => { try { const response = await api.post('/journal/delete-attachment', { id }); if (response.data?.success) { setIsVisible(false); fetchDetails(true); alert.showAlert('success', 'Eliminata', 'La foto è stata rimossa con successo.'); } else { alert.showAlert('error', 'Errore', response.data?.message || 'Impossibile eliminare la foto.'); } } catch (error) { console.error(error); alert.showAlert('error', 'Errore', 'Impossibile eliminare la foto.'); } } } ] ); }; const fetchDetails = useCallback(async (isRefreshing = false) => { try { if (!isRefreshing) setIsLoading(true); const response = await api.get(`/journal/get-journal-items?id=${params.id}`); if (response.data?.success) { setPlaceName(response.data.result?.place_name || ''); setPhotos(response.data.result?.photos || []); } else { alert.showAlert('error', 'Errore', 'Impossibile caricare i dettagli.'); } } catch (error) { console.error('Errore nel recupero del dettaglio giornale:', error); alert.showAlert('error', 'Errore', 'Si è verificato un errore di rete.'); } finally { setIsLoading(false); setRefreshing(false); } }, [params.id]); useEffect(() => { if (params.id) { fetchDetails(); } }, [params.id, fetchDetails]); const onRefresh = () => { setRefreshing(true); fetchDetails(true); }; if (isLoading && !refreshing) { return ; } // Calculate dimensions for the grid layout of photos const windowWidth = Dimensions.get('window').width; const padding = 40; const gap = 8; const itemSize = (windowWidth - padding - (gap * 2)) / 3; const imageSource = photos.map(photo => ({ uri: photo.uri })); // Custom Header for the ImageView const CustomHeader = ({ imageIndex }: { imageIndex: number }) => { const currentPhoto = photos[imageIndex]; if (!currentPhoto) return null; return ( setIsVisible(false)} className="p-2 -ml-2 active:opacity-70"> {currentPhoto.date || 'Dettaglio'} { setEditIndex(imageIndex); setDescModalVisible(true); }} className="p-2 active:opacity-70"> handleShare(currentPhoto.uri)} disabled={isSharing} className={`p-2 active:opacity-70 ${isSharing ? 'opacity-50' : ''}`}> handleDelete(currentPhoto.id)} className="p-2 active:opacity-70"> ); }; // Custom Footer for the ImageView const CustomFooter = ({ imageIndex }: { imageIndex: number }) => { const currentPhoto = photos[imageIndex]; if (!currentPhoto || !currentPhoto.description) return null; return ( {currentPhoto.description} ); }; return ( {/* Header */} router.back()} className="p-2 -ml-2 rounded-full active:bg-gray-100"> {placeName || 'Dettaglio Giornale'} } > {photos.length === 0 ? ( Nessuna foto presente per questo giornale. ) : ( {photos.map((item, index) => ( { setCurrentIndex(index); setIsVisible(true); }} style={{ width: itemSize }} className="mb-2" > {item.description && ( {item.description} )} ))} )} {/* Lightbox / Fullscreen viewer */} setIsVisible(false)} HeaderComponent={CustomHeader} FooterComponent={CustomFooter} backgroundColor={"#EDF1F7"} presentationStyle={'fullScreen'} /> setDescModalVisible(false)} onSave={handleDescription} /> ); }