import { useAlert } from '@/components/AlertComponent'; import CalendarWidget from '@/components/CalendarWidget'; import LoadingScreen from '@/components/LoadingScreen'; import RequestPermitModal from '@/components/RequestPermitModal'; import { TimeOffRequest, TimeOffRequestType } from '@/types/types'; import api from '@/utils/api'; import { formatDate, formatTime } from '@/utils/dateTime'; import { Calendar as CalendarIcon, CalendarX, Clock, Plus, Thermometer, Trash2 } from 'lucide-react-native'; import React, { JSX, useEffect, useMemo, useState } from 'react'; import { RefreshControl, ScrollView, Text, TouchableOpacity, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import Swipeable from 'react-native-gesture-handler/ReanimatedSwipeable'; // Icon Mapping const typeIcons: Record JSX.Element> = { Ferie: (color) => , Permesso: (color) => , Malattia: (color) => , Assenza: (color) => , }; export default function PermitsScreen() { const [showModal, setShowModal] = useState(false); const alert = useAlert(); const [permits, setPermits] = useState([]); const [types, setTypes] = useState([]); const [currentMonthDate, setCurrentMonthDate] = useState(new Date()); const [isLoading, setIsLoading] = useState(true); const [refreshing, setRefreshing] = useState(false); const fetchPermits = async () => { try { if (!refreshing) setIsLoading(true); // Fetch Permits const response = await api.get('/time-off-request/list'); setPermits(response.data); // Fetch Types const typesResponse = await api.get('/time-off-request/get-types'); setTypes(typesResponse.data); } catch (error) { console.error('Errore nel recupero dei permessi:', error); alert.showAlert('error', 'Errore', 'Impossibile recuperare i permessi. Riprova più tardi.'); } finally { setIsLoading(false); setRefreshing(false); } }; const filteredPermits = useMemo(() => { if (!permits.length) return []; // Calculate start and end of the current month const year = currentMonthDate.getFullYear(); const month = currentMonthDate.getMonth(); const startOfMonth = new Date(year, month, 1); // Day 0 of the next month = last day of the current month const endOfMonth = new Date(year, month + 1, 0, 23, 59, 59); return permits.filter(item => { const itemStart = new Date(item.start_date?.toString() ?? ''); // If there's no end_date, assume it's a single day (so end = start) const itemEnd = item.end_date ? new Date(item.end_date?.toString() ?? '') : new Date(item.start_date?.toString() ?? ''); // The permit is visible if it starts before the end of the month // And ends after the start of the month. return itemStart <= endOfMonth && itemEnd >= startOfMonth; }); }, [permits, currentMonthDate]); useEffect(() => { fetchPermits(); }, []); const onRefresh = () => { setRefreshing(true); fetchPermits(); }; // Funzione per eliminare una richiesta const deletePermitRequest = async (id: number, itemRef?: React.ElementRef | null) => { try { itemRef?.close(); await api.post(`/time-off-request/delete-request`, { id: id }); // Optimistic update setPermits(prevPermits => prevPermits.filter(p => p.id !== id)); alert.showAlert('success', 'Richiesta eliminata', 'La richiesta è stata eliminata con successo.'); // Refresh fetchPermits(); } catch (error: any) { console.error('Errore eliminazione richiesta:', error); const errorMessage = error?.response?.data?.message || 'Impossibile eliminare la richiesta.'; alert.showAlert('error', 'Errore', errorMessage); fetchPermits(); // Ripristina stato corretto } }; // Dialogo di conferma const confirmDelete = (item: TimeOffRequest, itemRef?: React.ElementRef | null) => { const requestType = item.timeOffRequestType.name; const dateRange = item.end_date ? `${formatDate(item.start_date?.toLocaleString())} - ${formatDate(item.end_date.toLocaleString())}` : formatDate(item.start_date?.toLocaleString()); alert.showConfirm( 'Conferma eliminazione', `Sei sicuro di voler eliminare questa richiesta?\n\n${requestType}\n${dateRange}`, [ { text: 'Annulla', style: 'cancel', onPress: () => itemRef?.close() }, { text: 'Elimina', style: 'destructive', onPress: () => deletePermitRequest(item.id, itemRef) } ] ); }; // Renderizza pulsante DELETE al swipe const renderRightActions = ( progress: any, dragX: any, item: TimeOffRequest, swipeableRef: React.RefObject | null> ) => { return ( confirmDelete(item, swipeableRef.current)} className="bg-red-500 justify-center items-center px-6 rounded-3xl ml-3" activeOpacity={0.7} style={{ margin: 2 }} > Elimina ); }; if (isLoading && !refreshing) { return ; } return ( setShowModal(false)} onSubmit={(data) => { console.log('Richiesta:', data); fetchPermits(); }} /> {/* Header */} Ferie e Permessi Gestisci le tue assenze } > {/* Calendar Widget */} setCurrentMonthDate(date)} /> {/* Recent Requests List */} {filteredPermits.length === 0 ? ( Nessuna richiesta di permesso questo mese ) : ( Le tue richieste {filteredPermits.map((item) => { const swipeableRef = React.createRef>(); const canDelete = item.status === null; // Solo "In Attesa" const cardContent = ( {typeIcons[item.timeOffRequestType.name]?.(item.timeOffRequestType.color)} {item.timeOffRequestType.name} {item.status === 1 ? 'Approvata' : item.status === 0 ? 'Rifiutata' : 'In Attesa'} {item.message} {formatDate(item.start_date?.toLocaleString())} {item.end_date ? `- ${formatDate(item.end_date.toLocaleString())}` : ''} {item.timeOffRequestType.name === 'Permesso' && ( {formatTime(item.start_time)} - {formatTime(item.end_time)} )} ); // Wrappa solo richieste "In Attesa" con Swipeable if (canDelete) { return ( renderRightActions(progress, dragX, item, swipeableRef) } rightThreshold={40} friction={2} overshootFriction={8} containerStyle={{ padding: 2 }} > {cardContent} ); } // Richieste approvate senza swipe return {cardContent}; })} )} {/* FAB */} setShowModal(true)} className="absolute bottom-8 right-6 w-16 h-16 bg-[#099499] rounded-full shadow-lg items-center justify-center active:scale-90" > ); }