diff --git a/susconecta/app/agenda/page.tsx b/susconecta/app/(main-routes)/agenda/page.tsx similarity index 94% rename from susconecta/app/agenda/page.tsx rename to susconecta/app/(main-routes)/agenda/page.tsx index 5a7630d..a292cf2 100644 --- a/susconecta/app/agenda/page.tsx +++ b/susconecta/app/(main-routes)/agenda/page.tsx @@ -99,16 +99,16 @@ export default function NovoAgendamentoPage() { }; return ( -
+
-
- +
+
); -} \ No newline at end of file +} diff --git a/susconecta/app/(main-routes)/consultas/page.tsx b/susconecta/app/(main-routes)/consultas/page.tsx index 339467d..f351ff5 100644 --- a/susconecta/app/(main-routes)/consultas/page.tsx +++ b/susconecta/app/(main-routes)/consultas/page.tsx @@ -1,7 +1,7 @@ "use client"; import Link from "next/link"; -import { useEffect, useState, useCallback } from "react"; +import { useEffect, useState, useCallback, useMemo } from "react"; import { MoreHorizontal, PlusCircle, @@ -87,6 +87,10 @@ export default function ConsultasPage() { // Local form state used when editing. Keep hook at top-level to avoid Hooks order changes. const [localForm, setLocalForm] = useState(null); + // Paginação + const [currentPage, setCurrentPage] = useState(1); + const [itemsPerPage, setItemsPerPage] = useState(10); + const mapAppointmentToFormData = (appointment: any) => { // prefer scheduled_at (ISO) if available const scheduledBase = appointment.scheduled_at || appointment.time || appointment.created_at || null; @@ -177,8 +181,8 @@ export default function ConsultasPage() { let duration_minutes = 30; try { if (formData.startTime && formData.endTime) { - const [sh, sm] = String(formData.startTime).split(":").map((n: string) => Number(n)); - const [eh, em] = String(formData.endTime).split(":").map((n: string) => Number(n)); + const [sh, sm] = String(formData.startTime).split(":").map(Number); + const [eh, em] = String(formData.endTime).split(":").map(Number); const start = (sh || 0) * 60 + (sm || 0); const end = (eh || 0) * 60 + (em || 0); if (!Number.isNaN(start) && !Number.isNaN(end) && end > start) duration_minutes = end - start; @@ -404,12 +408,28 @@ export default function ConsultasPage() { performSearch(searchValue); }, 250); return () => clearTimeout(t); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [searchValue, originalAppointments]); useEffect(() => { applyFilters(); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedStatus, filterDate, originalAppointments]); + // Dados paginados + const paginatedAppointments = useMemo(() => { + const startIndex = (currentPage - 1) * itemsPerPage; + const endIndex = startIndex + itemsPerPage; + return appointments.slice(startIndex, endIndex); + }, [appointments, currentPage, itemsPerPage]); + + const totalPages = Math.ceil(appointments.length / itemsPerPage); + + // Reset para página 1 quando mudar a busca ou itens por página + useEffect(() => { + setCurrentPage(1); + }, [searchValue, selectedStatus, filterDate, itemsPerPage]); + // Keep localForm synchronized with editingAppointment useEffect(() => { if (showForm && editingAppointment) { @@ -437,7 +457,7 @@ export default function ConsultasPage() {
- @@ -515,7 +535,7 @@ export default function ConsultasPage() { - {appointments.map((appointment) => { + {paginatedAppointments.map((appointment) => { // appointment.professional may now contain the doctor's name (resolved) const professionalLookup = mockProfessionals.find((p) => p.id === appointment.professional); const professionalName = typeof appointment.professional === "string" && appointment.professional && !professionalLookup @@ -574,6 +594,64 @@ export default function ConsultasPage() { + {/* Controles de paginação */} +
+
+ Itens por página: + + + Mostrando {paginatedAppointments.length > 0 ? (currentPage - 1) * itemsPerPage + 1 : 0} a{" "} + {Math.min(currentPage * itemsPerPage, appointments.length)} de {appointments.length} + +
+ +
+ + + + Página {currentPage} de {totalPages || 1} + + + +
+
+ {viewingAppointment && ( setViewingAppointment(null)}> diff --git a/susconecta/app/(main-routes)/dashboard/page.tsx b/susconecta/app/(main-routes)/dashboard/page.tsx index 9d9c5c0..1ec2c13 100644 --- a/susconecta/app/(main-routes)/dashboard/page.tsx +++ b/susconecta/app/(main-routes)/dashboard/page.tsx @@ -283,15 +283,15 @@ export default function DashboardPage() { Novo Paciente - - - diff --git a/susconecta/app/(main-routes)/dashboard/relatorios/page.tsx b/susconecta/app/(main-routes)/dashboard/relatorios/page.tsx index 473cbde..65bdcaf 100644 --- a/susconecta/app/(main-routes)/dashboard/relatorios/page.tsx +++ b/susconecta/app/(main-routes)/dashboard/relatorios/page.tsx @@ -102,7 +102,7 @@ export default function RelatoriosPage() {

Consultas por Período

- +
@@ -119,7 +119,7 @@ export default function RelatoriosPage() {

Faturamento Mensal

- +
@@ -138,7 +138,7 @@ export default function RelatoriosPage() {

Taxa de No-show

- +
@@ -155,7 +155,7 @@ export default function RelatoriosPage() {

Satisfação dos Pacientes

- +
92% @@ -169,7 +169,7 @@ export default function RelatoriosPage() {

Pacientes Mais Atendidos

- +
@@ -193,7 +193,7 @@ export default function RelatoriosPage() {

Médicos Mais Produtivos

- +
@@ -219,7 +219,7 @@ export default function RelatoriosPage() {

Análise de Convênios

- +
@@ -238,7 +238,7 @@ export default function RelatoriosPage() {

Performance por Médico

- +
diff --git a/susconecta/app/(main-routes)/doutores/page.tsx b/susconecta/app/(main-routes)/doutores/page.tsx index 1acbb83..85a795e 100644 --- a/susconecta/app/(main-routes)/doutores/page.tsx +++ b/susconecta/app/(main-routes)/doutores/page.tsx @@ -141,6 +141,10 @@ export default function DoutoresPage() { const [searchMode, setSearchMode] = useState(false); const [searchTimeout, setSearchTimeout] = useState(null); + // Paginação + const [currentPage, setCurrentPage] = useState(1); + const [itemsPerPage, setItemsPerPage] = useState(10); + async function load() { setLoading(true); @@ -310,6 +314,20 @@ export default function DoutoresPage() { return filtered; }, [doctors, search, searchMode, searchResults]); + // Dados paginados + const paginatedDoctors = useMemo(() => { + const startIndex = (currentPage - 1) * itemsPerPage; + const endIndex = startIndex + itemsPerPage; + return displayedDoctors.slice(startIndex, endIndex); + }, [displayedDoctors, currentPage, itemsPerPage]); + + const totalPages = Math.ceil(displayedDoctors.length / itemsPerPage); + + // Reset para página 1 quando mudar a busca ou itens por página + useEffect(() => { + setCurrentPage(1); + }, [search, itemsPerPage, searchMode]); + function handleAdd() { setEditingId(null); setShowForm(true); @@ -480,8 +498,8 @@ export default function DoutoresPage() { Carregando… - ) : displayedDoctors.length > 0 ? ( - displayedDoctors.map((doctor) => ( + ) : paginatedDoctors.length > 0 ? ( + paginatedDoctors.map((doctor) => ( {doctor.full_name} @@ -580,6 +598,64 @@ export default function DoutoresPage() {
+ {/* Controles de paginação */} +
+
+ Itens por página: + + + Mostrando {paginatedDoctors.length > 0 ? (currentPage - 1) * itemsPerPage + 1 : 0} a{" "} + {Math.min(currentPage * itemsPerPage, displayedDoctors.length)} de {displayedDoctors.length} + +
+ +
+ + + + Página {currentPage} de {totalPages || 1} + + + +
+
+ {viewingDoctor && ( setViewingDoctor(null)}> @@ -753,7 +829,7 @@ export default function DoutoresPage() { )}
- Mostrando {displayedDoctors.length} {searchMode ? 'resultado(s) da busca' : `de ${doctors.length}`} + {searchMode ? 'Resultado(s) da busca' : `Total de ${doctors.length} médico(s)`}
{/* Dialog para pacientes atribuídos */} { if (!open) { setAssignedDialogOpen(false); setAssignedPatients([]); setAssignedDoctor(null); } }}> diff --git a/susconecta/app/financeiro/page.tsx b/susconecta/app/(main-routes)/financeiro/page.tsx similarity index 87% rename from susconecta/app/financeiro/page.tsx rename to susconecta/app/(main-routes)/financeiro/page.tsx index 3861848..acab08f 100644 --- a/susconecta/app/financeiro/page.tsx +++ b/susconecta/app/(main-routes)/financeiro/page.tsx @@ -1,27 +1,16 @@ "use client"; -import Link from "next/link"; -import { usePathname, useRouter } from "next/navigation"; +import { useRouter } from "next/navigation"; import { useState } from "react"; -import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; -import { Switch } from "@/components/ui/switch"; -import { Search, ChevronDown, Calculator, DollarSign } from "lucide-react"; -import { Plus } from "lucide-react"; +import { Calculator, DollarSign } from "lucide-react"; import HeaderAgenda from "@/components/agenda/HeaderAgenda"; import FooterAgenda from "@/components/agenda/FooterAgenda"; export default function FinanceiroPage() { - const pathname = usePathname(); const router = useRouter(); - const [bloqueio, setBloqueio] = useState(false); const [formaTipo, setFormaTipo] = useState(""); - const [parcelas, setParcelas] = useState("1"); - - const isAg = pathname?.startsWith("/agendamento"); - const isPr = pathname?.startsWith("/procedimento"); - const isFi = pathname?.startsWith("/financeiro"); const handleSave = () => { // Lógica de salvar será implementada @@ -33,12 +22,11 @@ export default function FinanceiroPage() { }; return ( -
- {/* HEADER */} +
{/* CORPO */} -
+
{/* INFORMAÇÕES FINANCEIRAS */}
{/* Selo Financeiro */} @@ -58,7 +46,7 @@ export default function FinanceiroPage() { Valor do Atendimento
-
+
@@ -68,7 +56,7 @@ export default function FinanceiroPage() { />
-
+
@@ -90,7 +78,7 @@ export default function FinanceiroPage() { Forma de Pagamento
-
+
-
+
-
+
@@ -156,4 +144,4 @@ export default function FinanceiroPage() {
); -} \ No newline at end of file +} diff --git a/susconecta/app/(main-routes)/pacientes/page.tsx b/susconecta/app/(main-routes)/pacientes/page.tsx index c09855e..fe592e9 100644 --- a/susconecta/app/(main-routes)/pacientes/page.tsx +++ b/susconecta/app/(main-routes)/pacientes/page.tsx @@ -49,6 +49,10 @@ export default function PacientesPage() { const [viewingPatient, setViewingPatient] = useState(null); const [assignDialogOpen, setAssignDialogOpen] = useState(false); const [assignPatientId, setAssignPatientId] = useState(null); + + // Paginação + const [currentPage, setCurrentPage] = useState(1); + const [itemsPerPage, setItemsPerPage] = useState(10); async function loadAll() { try { @@ -95,6 +99,20 @@ export default function PacientesPage() { }); }, [patients, search]); + // Dados paginados + const paginatedData = useMemo(() => { + const startIndex = (currentPage - 1) * itemsPerPage; + const endIndex = startIndex + itemsPerPage; + return filtered.slice(startIndex, endIndex); + }, [filtered, currentPage, itemsPerPage]); + + const totalPages = Math.ceil(filtered.length / itemsPerPage); + + // Reset para página 1 quando mudar a busca ou itens por página + useEffect(() => { + setCurrentPage(1); + }, [search, itemsPerPage]); + function handleAdd() { setEditingId(null); setShowForm(true); @@ -228,8 +246,8 @@ export default function PacientesPage() { - {filtered.length > 0 ? ( - filtered.map((p) => ( + {paginatedData.length > 0 ? ( + paginatedData.map((p) => ( {p.full_name || "(sem nome)"} {p.cpf || "-"} @@ -277,6 +295,64 @@ export default function PacientesPage() {
+ {/* Controles de paginação */} +
+
+ Itens por página: + + + Mostrando {paginatedData.length > 0 ? (currentPage - 1) * itemsPerPage + 1 : 0} a{" "} + {Math.min(currentPage * itemsPerPage, filtered.length)} de {filtered.length} + +
+ +
+ + + + Página {currentPage} de {totalPages || 1} + + + +
+
+ {viewingPatient && ( setViewingPatient(null)}> @@ -326,8 +402,6 @@ export default function PacientesPage() { onSaved={() => { setAssignDialogOpen(false); setAssignPatientId(null); loadAll(); }} /> )} - -
Mostrando {filtered.length} de {patients.length}
); } diff --git a/susconecta/app/(main-routes)/perfil/page.tsx b/susconecta/app/(main-routes)/perfil/page.tsx index 2db4cf9..0308815 100644 --- a/susconecta/app/(main-routes)/perfil/page.tsx +++ b/susconecta/app/(main-routes)/perfil/page.tsx @@ -115,7 +115,7 @@ export default function PerfilPage() { - -
+ {/* Remover campos de especialidade e localização, deixar só o botão centralizado */} +
+
- -
-
- - -
- -
- -
- - setLocalizacao(event.target.value)} - placeholder="Cidade ou estado" - className="pl-9" - /> -
-
-
- - {/* Botão agora redireciona direto para /resultados */} -
- +
@@ -940,9 +889,15 @@ export default function PacientePage() { Editar Perfil ) : ( -
+
- +
)}
@@ -1042,11 +997,39 @@ export default function PacientePage() {
{/* Sidebar vertical */} {/* Conteúdo principal */}
diff --git a/susconecta/app/profissional/page.tsx b/susconecta/app/profissional/page.tsx index ddcf693..5efa5be 100644 --- a/susconecta/app/profissional/page.tsx +++ b/susconecta/app/profissional/page.tsx @@ -900,7 +900,7 @@ const ProfissionalPage = () => { variant={selectedRange === 'todos' ? 'default' : 'outline'} size="sm" onClick={() => setSelectedRange('todos')} - className="hover:bg-blue-50" + className="hover:bg-primary/10 hover:text-primary" > Todos @@ -908,7 +908,7 @@ const ProfissionalPage = () => { variant={selectedRange === 'semana' ? 'default' : 'outline'} size="sm" onClick={() => setSelectedRange('semana')} - className="hover:bg-blue-50" + className="hover:bg-primary/10 hover:text-primary" > Semana @@ -916,7 +916,7 @@ const ProfissionalPage = () => { variant={selectedRange === 'mes' ? 'default' : 'outline'} size="sm" onClick={() => setSelectedRange('mes')} - className="hover:bg-blue-50" + className="hover:bg-primary/10 hover:text-primary" > Mês @@ -2191,25 +2191,25 @@ const ProfissionalPage = () => { title="Cor da fonte" /> {/* Alinhamento */} - - - - + + + + {/* Listas */} - - + + {/* Recuo */} - - + + {/* Desfazer/Refazer */} - +
{templates.map((template, idx) => (

diff --git a/susconecta/app/resultados/ResultadosClient.tsx b/susconecta/app/resultados/ResultadosClient.tsx index e9ef340..485a7e1 100644 --- a/susconecta/app/resultados/ResultadosClient.tsx +++ b/susconecta/app/resultados/ResultadosClient.tsx @@ -617,7 +617,7 @@ export default function ResultadosClient() {

-
-
+
+
-
+
-
+
-
+