import React, { useState, useEffect, useMemo, useCallback } from "react"; import './style/FinanceiroDashboard.css'; const CONVENIOS_LIST = [ "Particular", "Amil", "Bradesco Saúde", "SulAmérica", "Unimed", "Cassio", "Outro" ]; function CurrencyInput({ value, onChange, label, id }) { const formattedValue = useMemo(() => { let numericValue = Number(value) || 0; let stringValue = String(numericValue); while (stringValue.length < 3) { stringValue = '0' + stringValue; } const integerPart = stringValue.slice(0, -2); const decimalPart = stringValue.slice(-2); const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, '.'); return `R$ ${formattedInteger},${decimalPart}`; }, [value]); const handleKeyDown = useCallback((e) => { const key = e.key; if (['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab'].includes(key)) { if (key === 'Backspace' || key === 'Delete') { e.preventDefault(); const numericValue = value || 0; let newValueString = String(numericValue); if (newValueString.length <= 1) { onChange(0); } else { const newNumericValue = parseInt(newValueString.slice(0, -1)) || 0; onChange(newNumericValue); } } return; } if (!/^\d$/.test(key)) { e.preventDefault(); return; } e.preventDefault(); const digit = key; const numericValue = value || 0; let newValueString = String(numericValue) + digit; if (newValueString.length > 10) return; const newNumericValue = parseInt(newValueString); onChange(newNumericValue); }, [value, onChange]); return (
{}} onKeyDown={handleKeyDown} placeholder="R$ 0,00" />
); } function mockFetchPagamentos() { return [ { id: "PAY-001", paciente: { nome: "Sarah Oliveira", convenio: "Unimed" }, valor: 20000, forma_pagamento: "Cartão", data_vencimento: "2025-09-30", status: "pendente", desconto: 0, observacoes: "Pagamento parcelado em 2x" }, { id: "PAY-002", paciente: { nome: "Laissa Marquetti", convenio: "Bradesco Saúde" }, valor: 15000, forma_pagamento: "Dinheiro", data_vencimento: "2025-09-15", status: "pago", desconto: 1000, observacoes: "" }, { id: "PAY-003", paciente: { nome: "Vera Santos", convenio: "Particular" }, valor: 30000, forma_pagamento: "Pix", data_vencimento: "2025-09-20", status: "vencido", desconto: 0, observacoes: "Não respondeu ao contato" }, { id: "PAY-004", paciente: { nome: "Carlos Almeida", convenio: "Particular" }, valor: 10000, forma_pagamento: "Transferência", data_vencimento: "2025-09-29", status: "pago", desconto: 500, observacoes: "Desconto por pagamento adiantado" } ]; } export default function FinanceiroDashboard() { const [pagamentos, setPagamentos] = useState([]); const [modalPagamento, setModalPagamento] = useState(null); const [query, setQuery] = useState(""); const [filtroStatus, setFiltroStatus] = useState("Todos"); const [novoPagamento, setNovoPagamento] = useState(false); const [summary, setSummary] = useState({ totalRecebido: 0, totalAReceber: 0, totalDescontos: 0 }); useEffect(() => { const data = mockFetchPagamentos(); setPagamentos(data); }, []); function formatCurrency(centavos) { const valorEmReais = centavos / 100; return "R$ " + valorEmReais.toFixed(2).replace(".", ",").replace(/\B(?=(\d{3})+(?!\d))/g, '.'); } function getValorLiquido(valor, desconto) { return valor - desconto; } const filteredPagamentos = useMemo(() => { return pagamentos.filter(p => { const q = query.toLowerCase(); const statusOk = filtroStatus === "Todos" || p.status === filtroStatus; const buscaOk = p.paciente.nome.toLowerCase().includes(q) || p.id.toLowerCase().includes(q); return statusOk && buscaOk; }); }, [pagamentos, query, filtroStatus]); useEffect(() => { let recebido = 0; let aReceber = 0; let descontos = 0; filteredPagamentos.forEach(p => { const valorLiquido = getValorLiquido(p.valor, p.desconto); if (p.status === 'pago') { recebido += valorLiquido; descontos += p.desconto; } else { aReceber += p.valor; } }); setSummary({ totalRecebido: recebido, totalAReceber: aReceber, totalDescontos: descontos }); }, [filteredPagamentos]); function handleDelete(id) { if (window.confirm("Tem certeza que deseja excluir este pagamento?")) { setPagamentos(prev => prev.filter(p => p.id !== id)); setModalPagamento(null); } } function handleSave(pagamento) { if (!pagamento.paciente.nome || !pagamento.valor || !pagamento.data_vencimento || !pagamento.paciente.convenio) { alert("Preencha Paciente, Convênio, Valor e Data de Vencimento."); return; } if (novoPagamento) { const newId = "PAY-" + (pagamentos.length + 1).toString().padStart(3, "0"); pagamento.id = newId; setPagamentos(prev => [...prev, pagamento]); } else { setPagamentos(prev => prev.map(p => p.id === pagamento.id ? pagamento : p)); } setModalPagamento(null); setNovoPagamento(false); } const closeModal = () => { setModalPagamento(null); setNovoPagamento(false); }; return (

Controle Financeiro

Total Recebido (Filtrado)

{formatCurrency(summary.totalRecebido)}

Total a Receber (Filtrado)

{formatCurrency(summary.totalAReceber)}

Descontos Aplicados

{formatCurrency(summary.totalDescontos)}

setQuery(e.target.value)} style={{ flexGrow: 1 }} />
{filteredPagamentos.length === 0 ? (
Nenhum pagamento encontrado.
) : (
{filteredPagamentos.map(p => ( ))}
Paciente Convênio Valor Total (R$) Desconto (R$) Valor Líquido (R$) Forma Vencimento Status Ações
{p.paciente.nome} {p.paciente.convenio} {formatCurrency(p.valor)} {formatCurrency(p.desconto)} {formatCurrency(getValorLiquido(p.valor, p.desconto))} {p.forma_pagamento} {p.data_vencimento.split('-').reverse().join('/')} {p.status.toUpperCase()}
)}
{modalPagamento && (
e.target.classList.contains('modal') && closeModal()}>

{novoPagamento ? "Adicionar Pagamento" : `Editar Pagamento - ${modalPagamento.paciente.nome}`}

setModalPagamento({...modalPagamento, paciente:{...modalPagamento.paciente, nome:e.target.value}})} />
setModalPagamento({...modalPagamento, valor: newValue})} /> setModalPagamento({...modalPagamento, desconto: newValue})} />
setModalPagamento({...modalPagamento, data_vencimento:e.target.value})} />