import React, { useEffect, useState, useMemo } from 'react'; import { CondoService } from '../services/mockDb'; import { Payment, Family, Condo } from '../types'; import { PieChart, Download, Calendar, Search, CreditCard, Banknote, Filter, ArrowUpRight } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; const MONTH_NAMES = [ "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre" ]; export const ReportsPage: React.FC = () => { const navigate = useNavigate(); const [loading, setLoading] = useState(true); const [payments, setPayments] = useState([]); const [families, setFamilies] = useState([]); const [activeCondo, setActiveCondo] = useState(undefined); const [availableYears, setAvailableYears] = useState([]); // Filters const [selectedYear, setSelectedYear] = useState(new Date().getFullYear()); const [selectedMonth, setSelectedMonth] = useState('ALL'); const [searchTerm, setSearchTerm] = useState(''); useEffect(() => { const fetchData = async () => { setLoading(true); try { const settings = await CondoService.getSettings(); if (!settings.features.reports) { navigate('/'); return; } const condo = await CondoService.getActiveCondo(); setActiveCondo(condo); if (condo) { const [payList, famList, years] = await Promise.all([ CondoService.getCondoPayments(condo.id), CondoService.getFamilies(condo.id), CondoService.getAvailableYears() ]); setPayments(payList); setFamilies(famList); setAvailableYears(years); if (years.length > 0 && !years.includes(selectedYear)) { setSelectedYear(years[0]); } } } catch (e) { console.error("Error loading reports", e); } finally { setLoading(false); } }; fetchData(); }, [navigate]); // Filter Logic const filteredData = useMemo(() => { return payments.filter(p => { const matchesYear = p.forYear === selectedYear; const matchesMonth = selectedMonth === 'ALL' || p.forMonth === selectedMonth; const familyName = families.find(f => f.id === p.familyId)?.name.toLowerCase() || ''; const matchesSearch = searchTerm === '' || familyName.includes(searchTerm.toLowerCase()) || (p.notes && p.notes.toLowerCase().includes(searchTerm.toLowerCase())); return matchesYear && matchesMonth && matchesSearch; }).map(p => { const isPayPal = p.notes && p.notes.includes("PayPal"); const family = families.find(f => f.id === p.familyId); return { ...p, familyName: family ? family.name : 'Sconosciuto', familyUnit: family ? family.unitNumber : '-', method: isPayPal ? 'PayPal' : 'Manuale' }; }); }, [payments, families, selectedYear, selectedMonth, searchTerm]); // Statistics const stats = useMemo(() => { const totalAmount = filteredData.reduce((acc, curr) => acc + curr.amount, 0); const paypalAmount = filteredData.filter(p => p.method === 'PayPal').reduce((acc, curr) => acc + curr.amount, 0); const manualAmount = filteredData.filter(p => p.method === 'Manuale').reduce((acc, curr) => acc + curr.amount, 0); const count = filteredData.length; return { totalAmount, paypalAmount, manualAmount, count }; }, [filteredData]); const handleExportCSV = () => { if (!activeCondo) return; const headers = ["Data Pagamento", "Famiglia", "Interno", "Mese Rif.", "Anno Rif.", "Importo", "Metodo", "Note"]; const rows = filteredData.map(p => [ new Date(p.datePaid).toLocaleDateString(), p.familyName, p.familyUnit, MONTH_NAMES[p.forMonth - 1], p.forYear, p.amount.toFixed(2), p.method, p.notes ? `"${p.notes.replace(/"/g, '""')}"` : "" ]); const csvContent = "data:text/csv;charset=utf-8," + headers.join(",") + "\n" + rows.map(e => e.join(",")).join("\n"); const encodedUri = encodeURI(csvContent); const link = document.createElement("a"); link.setAttribute("href", encodedUri); link.setAttribute("download", `Report_Pagamenti_${activeCondo.name}_${selectedYear}.csv`); document.body.appendChild(link); link.click(); document.body.removeChild(link); }; if (loading) return
Caricamento report...
; return (

Reportistica & Transazioni

Analisi incassi per {activeCondo?.name}

{/* Filters Bar */}
setSearchTerm(e.target.value)} className="w-full border p-2 pl-9 rounded-lg text-slate-700 bg-slate-50" />
{/* Stats Cards */}

Incasso Totale

€ {stats.totalAmount.toLocaleString('it-IT', { minimumFractionDigits: 2 })}

su {stats.count} transazioni

PayPal / Online

€ {stats.paypalAmount.toLocaleString('it-IT', { minimumFractionDigits: 2 })}

{stats.count > 0 ? Math.round((stats.paypalAmount / stats.totalAmount) * 100) : 0}%

Manuale / Bonifico

€ {stats.manualAmount.toLocaleString('it-IT', { minimumFractionDigits: 2 })}

{stats.count > 0 ? Math.round((stats.manualAmount / stats.totalAmount) * 100) : 0}%
{/* Transactions Table */}

Dettaglio Transazioni

{filteredData.length} risultati
{filteredData.length === 0 ? ( ) : ( filteredData.map((t) => ( )) )}
Data Famiglia Riferimento Metodo Note / ID Transazione Importo
Nessuna transazione trovata con i filtri attuali.
{new Date(t.datePaid).toLocaleDateString()}
{t.familyName}
Int. {t.familyUnit}
{MONTH_NAMES[t.forMonth - 1].substring(0, 3)} {t.forYear} {t.method === 'PayPal' ? : } {t.method} {t.notes || '-'} € {t.amount.toFixed(2)}
); };