From d67f4d6db440f8d61ecd225f760b61bc283bd6b7 Mon Sep 17 00:00:00 2001 From: pedrofedericoo Date: Thu, 27 Nov 2025 12:05:41 -0300 Subject: [PATCH] =?UTF-8?q?Ultimas=20corre=C3=A7=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/PagesMedico/DoctorAgendamentoManager.jsx | 1090 +++++++++++------- src/PagesMedico/styleMedico/Agendamento.css | 1 + src/pages/FinanceiroDashboard.jsx | 379 +++--- src/pages/style/FinanceiroDashboard.css | 7 +- src/pages/style/inicioPaciente.css | 22 +- 5 files changed, 942 insertions(+), 557 deletions(-) diff --git a/src/PagesMedico/DoctorAgendamentoManager.jsx b/src/PagesMedico/DoctorAgendamentoManager.jsx index d89a68f..567646c 100644 --- a/src/PagesMedico/DoctorAgendamentoManager.jsx +++ b/src/PagesMedico/DoctorAgendamentoManager.jsx @@ -1,14 +1,21 @@ -import React, { useState, useMemo, useEffect, useCallback } from 'react'; -import { useNavigate } from 'react-router-dom'; -import API_KEY from '../components/utils/apiKeys.js'; -import AgendamentoCadastroManager from '../pages/AgendamentoCadastroManager.jsx'; -import { GetAllDoctors } from '../components/utils/Functions-Endpoints/Doctor.js'; -import { useAuth } from '../components/utils/AuthProvider.js'; -import dayjs from 'dayjs'; -import 'dayjs/locale/pt-br'; -import isBetween from 'dayjs/plugin/isBetween'; -import localeData from 'dayjs/plugin/localeData'; -import { Search, ChevronLeft, ChevronRight, Edit, Trash2, CheckCircle } from 'lucide-react'; +import React, { useState, useMemo, useEffect, useCallback } from "react"; +import { useNavigate } from "react-router-dom"; +import API_KEY from "../components/utils/apiKeys.js"; +import AgendamentoCadastroManager from "../pages/AgendamentoCadastroManager.jsx"; +import { GetAllDoctors } from "../components/utils/Functions-Endpoints/Doctor.js"; +import { useAuth } from "../components/utils/AuthProvider.js"; +import dayjs from "dayjs"; +import "dayjs/locale/pt-br"; +import isBetween from "dayjs/plugin/isBetween"; +import localeData from "dayjs/plugin/localeData"; +import { + Search, + ChevronLeft, + ChevronRight, + Edit, + Trash2, + CheckCircle, +} from "lucide-react"; import "../pages/style/Agendamento.css"; import "../pages/style/FilaEspera.css"; import Spinner from "../components/Spinner.jsx"; @@ -22,8 +29,7 @@ const Agendamento = () => { const { getAuthorizationHeader, user } = useAuth(); const authHeader = getAuthorizationHeader(); - - const ID_MEDICO_ESPECIFICO = "078d2a67-b4c1-43c8-ae32-c1e75bb5b3df"; + const ID_MEDICO_ESPECIFICO = "078d2a67-b4c1-43c8-ae32-c1e75bb5b3df"; const [listaTodosAgendamentos, setListaTodosAgendamentos] = useState([]); const [selectedID, setSelectedId] = useState("0"); @@ -55,17 +61,19 @@ const Agendamento = () => { year: currentDate.year(), }); + const fetchAppointments = useCallback(async () => { + if (!authHeader) return; + setShowSpinner(true); + const myHeaders = new Headers(); + myHeaders.append("Authorization", authHeader); + myHeaders.append("apikey", API_KEY); + const requestOptions = { + method: "GET", + headers: myHeaders, + redirect: "follow", + }; - const fetchAppointments = useCallback(async () => { - if (!authHeader) return; - setShowSpinner(true); - const myHeaders = new Headers(); - myHeaders.append("Authorization", authHeader); - myHeaders.append("apikey", API_KEY); - const requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' }; - - - const apiUrl = `https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?doctor_id=eq.${ID_MEDICO_ESPECIFICO}&select=*`; + const apiUrl = `https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/appointments?doctor_id=eq.${ID_MEDICO_ESPECIFICO}&select=*`; try { const res = await fetch(apiUrl, requestOptions); @@ -151,33 +159,33 @@ const Agendamento = () => { [updateAppointmentStatus] ); - useEffect(() => { - if(authHeader) { - fetchAppointments(); - - if (user?.role !== 'doctor') { - GetAllDoctors(authHeader).then(docs => { - if (docs) { - setListaDeMedicos(docs.map(d => ({ nomeMedico: d.full_name, idMedico: d.id }))); - } - }); - } - } - }, [authHeader, fetchAppointments, user?.role]); + useEffect(() => { + if (authHeader) { + fetchAppointments(); - useEffect(() => { - const processData = async () => { - - if (!listaTodosAgendamentos.length) { - setAgendamentosOrganizados({}); - setFilaEsperaData([]); - return; - } + if (user?.role !== "doctor") { + GetAllDoctors(authHeader).then((docs) => { + if (docs) { + setListaDeMedicos( + docs.map((d) => ({ nomeMedico: d.full_name, idMedico: d.id })) + ); + } + }); + } + } + }, [authHeader, fetchAppointments, user?.role]); + + useEffect(() => { + const processData = async () => { + if (!listaTodosAgendamentos.length) { + setAgendamentosOrganizados({}); + setFilaEsperaData([]); + return; + } setShowSpinner(true); - - const appointmentsToShow = listaTodosAgendamentos; + const appointmentsToShow = listaTodosAgendamentos; const patientIdsToFetch = new Set(); const doctorIdsToFetch = new Set(); @@ -193,16 +201,19 @@ const Agendamento = () => { const fetchPromises = []; - if (patientIdsToFetch.size > 0) { - const query = `id=in.(${Array.from(patientIdsToFetch).join(',')})`; - fetchPromises.push( - fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients?${query}&select=*`, { - headers: { apikey: API_KEY, Authorization: authHeader } - }).then(res => res.json()) - ); - } else { - fetchPromises.push(Promise.resolve(null)); + if (patientIdsToFetch.size > 0) { + const query = `id=in.(${Array.from(patientIdsToFetch).join(",")})`; + fetchPromises.push( + fetch( + `https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients?${query}&select=*`, + { + headers: { apikey: API_KEY, Authorization: authHeader }, } + ).then((res) => res.json()) + ); + } else { + fetchPromises.push(Promise.resolve(null)); + } if (doctorIdsToFetch.size > 0) { const query = `id=in.(${Array.from(doctorIdsToFetch).join(",")})`; @@ -271,10 +282,8 @@ const Agendamento = () => { setShowSpinner(false); }; - processData(); - }, [listaTodosAgendamentos, authHeader]); - - + processData(); + }, [listaTodosAgendamentos, authHeader]); const handleEditConsulta = (agendamento) => { setAgendamentoParaEdicao(agendamento); @@ -305,28 +314,54 @@ const Agendamento = () => { return grid; }; - const dateGrid = useMemo(() => generateDateGrid(), [currentDate]); - const weekDays = ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sáb']; - const handleDateClick = (day) => setSelectedDay(day); -const DeleteModal = () => ( -
-
-
-
-
Confirmação de Cancelamento
-
-
-

Qual o motivo do cancelamento?

- -
-
- - -
-
+ const dateGrid = useMemo(() => generateDateGrid(), [currentDate]); + const weekDays = ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"]; + const handleDateClick = (day) => setSelectedDay(day); + const DeleteModal = () => ( +
+
+
+
+
Confirmação de Cancelamento
+
+
+

Qual o motivo do cancelamento?

+ +
+
+ + +
+
); @@ -409,320 +444,591 @@ const DeleteModal = () => ( setSelectedDay(newDate); }; - return ( -
-

Agendar nova consulta

-
- - - -
- {!PageNovaConsulta ? ( -
- {user?.role !== 'doctor' && ( -
-
- - Filtrar por Médico -
-
- handleSearchMedicos(e.target.value)} - /> - Buscar médico para filtrar consultas - - {searchTermDoctor && FiltredTodosMedicos.length > 0 && ( -
- {FiltredTodosMedicos.map((medico) => ( - - ))} -
- )} -
- - {MedicoFiltrado.id !== "vazio" && ( -
- - - {searchTermDoctor} - - -
- )} -
- )} -
- - -
-
- {!FiladeEspera ? ( -
-
-
{selectedDay.format('MMM')}{selectedDay.format('DD')}
-

{selectedDay.format('dddd')}

{selectedDay.format('D [de] MMMM [de] YYYY')}

-
-

Consultas para {selectedDay.format('DD/MM')}

- {showSpinner ? : (DictAgendamentosOrganizados[selectedDay.format('YYYY-MM-DD')]?.filter(app => MedicoFiltrado.id === "vazio" || app.doctor_id === MedicoFiltrado.id).length > 0) ? ( - DictAgendamentosOrganizados[selectedDay.format('YYYY-MM-DD')] - .filter(app => MedicoFiltrado.id === "vazio" || app.doctor_id === MedicoFiltrado.id) - .map(app => ( -
-
{dayjs(app.scheduled_at).format('HH:mm')}
-
{app.paciente_nome}Dr(a). {app.medico_nome}
-
- {app.status === 'cancelled' ? ( - - ) : ( - - )} - {app.status !== 'cancelled' && ( - - )} -
-
- )) - ) : (

Nenhuma consulta agendada.

)} -
-
-
-
-
Realizado
-
Confirmado
-
Agendado
-
Cancelado
-
-
-
-

{currentDate.format('MMMM [de] YYYY')}

-
- - - -
-
-
- - - -
-
-
- {weekDays.map(day =>
{day}
)} - {dateGrid.map((day, index) => { - const dayString = day.format('YYYY-MM-DD'); - const appointmentsOnDay = DictAgendamentosOrganizados[dayString] || []; - const filteredAppointments = appointmentsOnDay.filter(app => MedicoFiltrado.id === "vazio" || app.doctor_id === MedicoFiltrado.id); - const cellClasses = `day-cell ${day.isSame(currentDate, 'month') ? 'current-month' : 'other-month'} ${day.isSame(dayjs(), 'day') ? 'today' : ''} ${day.isSame(selectedDay, 'day') ? 'selected' : ''}`; - return ( -
handleDateClick(day)}> - {day.format('D')} - {filteredAppointments.length > 0 &&
{filteredAppointments.length}
} -
- ); - })} -
-
-
- ) : ( -
-
-
-
-

Fila de Espera

-
-
-
Filtros
-
setWaitlistSearch(e.target.value)} />Digite o nome do paciente, CPF ou nome do médico
-
-
- Ordenar por: - -
-
-
-
{filaEsperaFiltrada.length} DE {filaEsperaData.length} SOLICITAÇÕES ENCONTRADAS
-
-
-
- - - - - - - - - - - - {filaEsperaPaginada.length > 0 ? ( - filaEsperaPaginada.map((item, index) => ( - - - - - - - - )) - ) : ( - - - - )} - -
Nome do PacienteCPFMédico SolicitadoData da SolicitaçãoAções
{item?.Infos?.paciente_nome}{item?.Infos?.paciente_cpf}{item?.Infos?.medico_nome}{dayjs(item.agendamento.scheduled_at).format('DD/MM/YYYY')} - -
-
- {showSpinner ? : (<>

Nenhuma solicitação encontrada.

)} -
-
- {filaEsperaFiltrada.length > 0 && ( -
-
- Itens por página: - -
-
- Página {waitPage} de {waitTotalPages} • Mostrando {waitIndiceInicial + 1}-{Math.min(waitIndiceFinal, filaEsperaFiltrada.length)} de {filaEsperaFiltrada.length} - -
-
- )} -
-
-
-
-
-
- )} -
-
- ) : ( - { - setPageConsulta(false); - fetchAppointments(); - }} + return ( +
+

Agendar nova consulta

+ {!PageNovaConsulta ? ( +
+ {user?.role !== "doctor" && ( +
+
+ + Filtrar por Médico +
+
+ handleSearchMedicos(e.target.value)} /> + + Buscar médico para filtrar consultas + + + {searchTermDoctor && FiltredTodosMedicos.length > 0 && ( +
+ {FiltredTodosMedicos.map((medico) => ( + + ))} +
+ )} +
+ + {MedicoFiltrado.id !== "vazio" && ( +
+ + + {searchTermDoctor} + + +
+ )} +
+ )} +
+
+ + +
+
+ + + +
+
+ +
+ {!FiladeEspera ? ( +
+
+
+ {selectedDay.format("MMM")} + {selectedDay.format("DD")} +
+
+

{selectedDay.format("dddd")}

+

{selectedDay.format("D [de] MMMM [de] YYYY")}

+
+
+

Consultas para {selectedDay.format("DD/MM")}

+ {showSpinner ? ( + + ) : DictAgendamentosOrganizados[ + selectedDay.format("YYYY-MM-DD") + ]?.filter( + (app) => + MedicoFiltrado.id === "vazio" || + app.doctor_id === MedicoFiltrado.id + ).length > 0 ? ( + DictAgendamentosOrganizados[ + selectedDay.format("YYYY-MM-DD") + ] + .filter( + (app) => + MedicoFiltrado.id === "vazio" || + app.doctor_id === MedicoFiltrado.id + ) + .map((app) => ( +
+
+ {dayjs(app.scheduled_at).format("HH:mm")} +
+
+ {app.paciente_nome} + Dr(a). {app.medico_nome} +
+
+ {app.status === "cancelled" ? ( + + ) : ( + + )} + {app.status !== "cancelled" && ( + + )} +
+
+ )) + ) : ( +
+

Nenhuma consulta agendada.

+
+ )} +
+
+
+
+
+ Realizado +
+
+ Confirmado +
+
+ Agendado +
+
+ Cancelado +
+
+
+
+

{currentDate.format("MMMM [de] YYYY")}

+
+ + + +
+
+
+ + + +
+
+
+ {weekDays.map((day) => ( +
+ {day} +
+ ))} + {dateGrid.map((day, index) => { + const dayString = day.format("YYYY-MM-DD"); + const appointmentsOnDay = + DictAgendamentosOrganizados[dayString] || []; + const filteredAppointments = appointmentsOnDay.filter( + (app) => + MedicoFiltrado.id === "vazio" || + app.doctor_id === MedicoFiltrado.id + ); + const cellClasses = `day-cell ${ + day.isSame(currentDate, "month") + ? "current-month" + : "other-month" + } ${day.isSame(dayjs(), "day") ? "today" : ""} ${ + day.isSame(selectedDay, "day") ? "selected" : "" + }`; + return ( +
handleDateClick(day)} + > + {day.format("D")} + {filteredAppointments.length > 0 && ( +
+ {filteredAppointments.length} +
+ )} +
+ ); + })} +
+
+
+ ) : ( +
+
+
+
+
+

Fila de Espera

+
+
+
+
+ {" "} + Filtros +
+
+ + setWaitlistSearch(e.target.value) + } + /> + + Digite o nome do paciente, CPF ou nome do médico + +
+
+
+ + Ordenar por: + + +
+
+
+
+ {filaEsperaFiltrada.length} DE{" "} + {filaEsperaData.length} SOLICITAÇÕES ENCONTRADAS +
+
+
+
+ + + + + + + + + + + + {filaEsperaPaginada.length > 0 ? ( + filaEsperaPaginada.map((item, index) => ( + + + + + + + + )) + ) : ( + + + + )} + +
Nome do PacienteCPFMédico SolicitadoData da SolicitaçãoAções
{item?.Infos?.paciente_nome}{item?.Infos?.paciente_cpf}{item?.Infos?.medico_nome} + {dayjs( + item.agendamento.scheduled_at + ).format("DD/MM/YYYY")} + + +
+
+ {showSpinner ? ( + + ) : ( + <> + +

+ Nenhuma solicitação encontrada. +

+ + )} +
+
+ {filaEsperaFiltrada.length > 0 && ( +
+
+ + Itens por página: + + +
+
+ + Página {waitPage} de {waitTotalPages} • + Mostrando {waitIndiceInicial + 1}- + {Math.min( + waitIndiceFinal, + filaEsperaFiltrada.length + )}{" "} + de {filaEsperaFiltrada.length} + + +
+
+ )} +
+
+
+
+
+
)} - {showDeleteModal && } +
- ); -} + ) : ( + { + setPageConsulta(false); + fetchAppointments(); + }} + /> + )} + {showDeleteModal && } +
+ ); +}; export default Agendamento; diff --git a/src/PagesMedico/styleMedico/Agendamento.css b/src/PagesMedico/styleMedico/Agendamento.css index ffa5552..09cde6f 100644 --- a/src/PagesMedico/styleMedico/Agendamento.css +++ b/src/PagesMedico/styleMedico/Agendamento.css @@ -140,6 +140,7 @@ border-bottom: 3px solid transparent; padding: 8px; border-radius: 10px 10px 0px 0px; + color: #fff; font-weight: bold; cursor: pointer; } diff --git a/src/pages/FinanceiroDashboard.jsx b/src/pages/FinanceiroDashboard.jsx index d2bf772..e41b321 100644 --- a/src/pages/FinanceiroDashboard.jsx +++ b/src/pages/FinanceiroDashboard.jsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useMemo, useCallback } from "react"; -import './style/FinanceiroDashboard.css'; +import "./style/FinanceiroDashboard.css"; const CONVENIOS_LIST = [ "Particular", @@ -8,72 +8,77 @@ const CONVENIOS_LIST = [ "SulAmérica", "Unimed", "Cassio", - "Outro" + "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; + stringValue = "0" + stringValue; } const integerPart = stringValue.slice(0, -2); const decimalPart = stringValue.slice(-2); - - const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, '.'); + + const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, "."); return `R$ ${formattedInteger},${decimalPart}`; }, [value]); - const handleKeyDown = useCallback((e) => { - const key = e.key; + const handleKeyDown = useCallback( + (e) => { + const key = e.key; - if (['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'Tab'].includes(key)) { - if (key === 'Backspace' || key === 'Delete') { + 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); + onChange(0); } else { - const newNumericValue = parseInt(newValueString.slice(0, -1)) || 0; - onChange(newNumericValue); + const newNumericValue = parseInt(newValueString.slice(0, -1)) || 0; + onChange(newNumericValue); } + } + return; + } + + if (!/^\d$/.test(key)) { + e.preventDefault(); + return; } - 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 digit = key; + const numericValue = value || 0; - const newNumericValue = parseInt(newValueString); + let newValueString = String(numericValue) + digit; - onChange(newNumericValue); - }, [value, onChange]); + if (newValueString.length > 10) return; + + const newNumericValue = parseInt(newValueString); + + onChange(newNumericValue); + }, + [value, onChange] + ); return (
- {}} + className="input-field currency-input" + type="text" + value={formattedValue} + onChange={() => {}} onKeyDown={handleKeyDown} placeholder="R$ 0,00" /> @@ -91,27 +96,27 @@ function mockFetchPagamentos() { data_vencimento: "2025-09-30", status: "pendente", desconto: 0, - observacoes: "Pagamento parcelado em 2x" + observacoes: "Pagamento parcelado em 2x", }, { id: "PAY-002", paciente: { nome: "Laissa Marquetti", convenio: "Bradesco Saúde" }, - valor: 15000, + valor: 15000, forma_pagamento: "Dinheiro", data_vencimento: "2025-09-15", status: "pago", - desconto: 1000, - observacoes: "" + desconto: 1000, + observacoes: "", }, { id: "PAY-003", paciente: { nome: "Vera Santos", convenio: "Particular" }, - valor: 30000, + valor: 30000, forma_pagamento: "Pix", data_vencimento: "2025-09-20", - status: "vencido", + status: "vencido", desconto: 0, - observacoes: "Não respondeu ao contato" + observacoes: "Não respondeu ao contato", }, { id: "PAY-004", @@ -120,9 +125,9 @@ function mockFetchPagamentos() { forma_pagamento: "Transferência", data_vencimento: "2025-09-29", status: "pago", - desconto: 500, - observacoes: "Desconto por pagamento adiantado" - } + desconto: 500, + observacoes: "Desconto por pagamento adiantado", + }, ]; } @@ -132,7 +137,11 @@ export default function FinanceiroDashboard() { const [query, setQuery] = useState(""); const [filtroStatus, setFiltroStatus] = useState("Todos"); const [novoPagamento, setNovoPagamento] = useState(false); - const [summary, setSummary] = useState({ totalRecebido: 0, totalAReceber: 0, totalDescontos: 0 }); + const [summary, setSummary] = useState({ + totalRecebido: 0, + totalAReceber: 0, + totalDescontos: 0, + }); useEffect(() => { const data = mockFetchPagamentos(); @@ -141,7 +150,13 @@ export default function FinanceiroDashboard() { function formatCurrency(centavos) { const valorEmReais = centavos / 100; - return "R$ " + valorEmReais.toFixed(2).replace(".", ",").replace(/\B(?=(\d{3})+(?!\d))/g, '.'); + return ( + "R$ " + + valorEmReais + .toFixed(2) + .replace(".", ",") + .replace(/\B(?=(\d{3})+(?!\d))/g, ".") + ); } function getValorLiquido(valor, desconto) { @@ -149,11 +164,12 @@ export default function FinanceiroDashboard() { } const filteredPagamentos = useMemo(() => { - return pagamentos.filter(p => { + 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); + const buscaOk = + p.paciente.nome.toLowerCase().includes(q) || + p.id.toLowerCase().includes(q); return statusOk && buscaOk; }); }, [pagamentos, query, filtroStatus]); @@ -163,47 +179,55 @@ export default function FinanceiroDashboard() { let aReceber = 0; let descontos = 0; - filteredPagamentos.forEach(p => { + filteredPagamentos.forEach((p) => { const valorLiquido = getValorLiquido(p.valor, p.desconto); - if (p.status === 'pago') { + if (p.status === "pago") { recebido += valorLiquido; descontos += p.desconto; } else { - aReceber += valorLiquido; + aReceber += valorLiquido; } }); setSummary({ totalRecebido: recebido, totalAReceber: aReceber, - totalDescontos: descontos + totalDescontos: descontos, }); }, [filteredPagamentos]); function handleDelete(id) { if (window.confirm("Tem certeza que deseja excluir este pagamento?")) { - setPagamentos(prev => prev.filter(p => p.id !== id)); + 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 ( + !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]); + 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)); + setPagamentos((prev) => + prev.map((p) => (p.id === pagamento.id ? pagamento : p)) + ); } setModalPagamento(null); setNovoPagamento(false); } - + const closeModal = () => { setModalPagamento(null); setNovoPagamento(false); @@ -212,50 +236,54 @@ export default function FinanceiroDashboard() { return (

Controle Financeiro

- +
-

Total Recebido (Filtrado)

-

{formatCurrency(summary.totalRecebido)}

+

Total Recebido (Filtrado)

+

{formatCurrency(summary.totalRecebido)}

-

Total a Receber (Filtrado)

-

{formatCurrency(summary.totalAReceber)}

+

Total a Receber (Filtrado)

+

{formatCurrency(summary.totalAReceber)}

-

Descontos Aplicados

-

{formatCurrency(summary.totalDescontos)}

+

Descontos Aplicados

+

{formatCurrency(summary.totalDescontos)}

-
-
- +
+ setQuery(e.target.value)} + placeholder="Buscar paciente" + value={query} + onChange={(e) => setQuery(e.target.value)} style={{ flexGrow: 1 }} /> - setFiltroStatus(e.target.value)} + > -