import { useState } from 'react'; import { useConfig } from '../hooks/useConfig'; import { DataProvider } from '../context/DataContext'; import { useDataContext } from '../hooks/useDataContext'; import { usePaginatedList } from '../hooks/usePaginatedList'; import CustomContainer from '../components/CustomContainer'; import ContentWrapper from '../components/ContentWrapper'; import LoadingIcon from '../components/LoadingIcon'; import SearchToolbar from '../components/SearchToolbar'; import PaginatedCardGrid from '../components/PaginatedCardGrid'; import PDFModal from '../components/PDFModal'; import IngresoCard from '../components/Ingresos/IngresoCard'; import IngresosFilter from '../components/Ingresos/IngresosFilter'; import { IngresosPDF } from '../components/Ingresos/IngresosPDF'; import { CONSTANTS } from '../util/constants'; import '../css/Ingresos.css'; import CustomModal from '../components/CustomModal'; import { Button } from 'react-bootstrap'; import { useError } from '../context/ErrorContext'; const PAGE_SIZE = 10; const Ingresos = () => { const { config, configLoading } = useConfig(); const { showError } = useError(); if (configLoading) return

; const reqConfig = { baseUrl: config.apiConfig.baseUrl + config.apiConfig.endpoints.incomes.withInfo, rawUrl: config.apiConfig.baseUrl + config.apiConfig.endpoints.incomes.all, usersUrl: config.apiConfig.baseUrl + config.apiConfig.endpoints.users.all, params: {} }; return ( ); }; const IngresosContent = ({ reqConfig }) => { const { data, dataLoading, postData, putData, deleteData } = useDataContext(); const [showPDFModal, setShowPDFModal] = useState(false); const [creatingIngreso, setCreatingIngreso] = useState(false); const [tempIngreso, setTempIngreso] = useState(null); const [deleteTargetId, setDeleteTargetId] = useState(null); const [fieldErrors, setFieldErrors] = useState(null); const members = data ? Array.from( new Map( data.map(i => [i.memberNumber, { memberNumber: i.memberNumber, displayName: i.displayName, userId: i.userId }]) ).values() ).sort((a, b) => a.memberNumber - b.memberNumber) : []; const { filtered, searchTerm, setSearchTerm, filters, setFilters } = usePaginatedList({ data, pageSize: PAGE_SIZE, initialFilters: { todos: true, banco: true, caja: true, semestral: true, anual: true }, filterFn: (ingreso, filters) => { if (filters.todos) return true; const { banco, caja, semestral, anual } = filters; const typeMatch = (banco && ingreso.type === CONSTANTS.PAYMENT_TYPE_BANK) || (caja && ingreso.type === CONSTANTS.PAYMENT_TYPE_CASH); const freqMatch = (semestral && ingreso.frequency === CONSTANTS.PAYMENT_FREQUENCY_BIYEARLY) || (anual && ingreso.frequency === CONSTANTS.PAYMENT_FREQUENCY_YEARLY); const typeFilters = [banco, caja].filter(Boolean).length; const freqFilters = [semestral, anual].filter(Boolean).length; if (typeFilters > 0 && freqFilters > 0) return typeMatch && freqMatch; if (typeFilters > 0) return typeMatch; if (freqFilters > 0) return freqMatch; return false; }, searchFn: (ingreso, term) => { const normalized = term.toLowerCase(); return ingreso.concept?.toLowerCase().includes(normalized) || String(ingreso.memberNumber).includes(normalized) || ingreso.displayName?.toLowerCase().includes(normalized); } }); const handleCreate = () => { const firstMember = members[0]; setCreatingIngreso(true); setTempIngreso({ incomeId: null, memberNumber: firstMember?.memberNumber ?? null, userId: firstMember?.userId ?? null, concept: '', amount: 0.0, frequency: CONSTANTS.PAYMENT_FREQUENCY_YEARLY, type: CONSTANTS.PAYMENT_TYPE_BANK }); }; const handleCancelCreate = () => { setCreatingIngreso(false); setTempIngreso(null); setFieldErrors(null); }; const handleCreateSubmit = async (nuevo) => { try { await postData(reqConfig.rawUrl, nuevo); setCreatingIngreso(false); setTempIngreso(null); setFieldErrors(null); } catch (err) { setTempIngreso({ ...nuevo }); if (err?.status === 422 && err?.errors) { setFieldErrors(err.errors); } } }; const handleEditSubmit = async (editado, id) => { try { await putData(`${reqConfig.rawUrl}/${id}`, editado); } catch (err) { if (err?.status === 422 && err?.errors) { setFieldErrors(err.errors); } } }; const handleDelete = async (id) => { setDeleteTargetId(id); }; if (dataLoading) return

; return (

Lista de Ingresos


} onCreate={handleCreate} onPDF={() => setShowPDFModal(true)} /> ( )} renderCard={(income) => ( handleEditSubmit(data, id)} onDelete={() => handleDelete(income.incomeId)} fieldErrors={fieldErrors} /> )} /> setShowPDFModal(false)} title="Vista previa del PDF"> setDeleteTargetId(null)} >

¿Estás seguro de que quieres eliminar el ingreso?

); }; export default Ingresos;