riseup-squad18/src/components/secretaria/SecretaryPatientList.tsx

805 lines
31 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, useEffect } from "react";
import toast from "react-hot-toast";
import { Search, Plus, Eye, Calendar, Edit, Trash2, X } from "lucide-react";
import { patientService, type Patient } from "../../services";
import PacienteForm, { type PacienteFormData } from "../pacientes/PacienteForm";
import { Avatar } from "../ui/Avatar";
import { useAuth } from "../../hooks/useAuth";
const BLOOD_TYPES = ["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"];
const CONVENIOS = [
"Particular",
"Unimed",
"Amil",
"Bradesco Saúde",
"SulAmérica",
"Golden Cross",
];
const COUNTRY_OPTIONS = [
{ value: "55", label: "+55 🇧🇷 Brasil" },
{ value: "1", label: "+1 🇺🇸 EUA/Canadá" },
];
// Função para buscar endereço via CEP
const buscarEnderecoViaCEP = async (cep: string) => {
try {
const response = await fetch(`https://viacep.com.br/ws/${cep}/json/`);
const data = await response.json();
if (data.erro) return null;
return {
rua: data.logradouro,
bairro: data.bairro,
cidade: data.localidade,
estado: data.uf,
cep: data.cep,
};
} catch {
return null;
}
};
export function SecretaryPatientList({
onOpenAppointment,
}: {
onOpenAppointment?: (patientId: string) => void;
}) {
const { user } = useAuth();
const [patients, setPatients] = useState<Patient[]>([]);
const [loading, setLoading] = useState(false);
const [searchTerm, setSearchTerm] = useState("");
const [insuranceFilter, setInsuranceFilter] = useState("Todos");
const [showBirthdays, setShowBirthdays] = useState(false);
const [showVIP, setShowVIP] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage] = useState(10);
// Modal states
const [showModal, setShowModal] = useState(false);
const [modalMode, setModalMode] = useState<"create" | "edit">("create");
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [patientToDelete, setPatientToDelete] = useState<Patient | null>(null);
const [showViewModal, setShowViewModal] = useState(false);
const [selectedPatient, setSelectedPatient] = useState<Patient | null>(null);
const [formData, setFormData] = useState<PacienteFormData>({
nome: "",
social_name: "",
cpf: "",
sexo: "",
dataNascimento: "",
email: "",
codigoPais: "55",
ddd: "",
numeroTelefone: "",
tipo_sanguineo: "",
altura: "",
peso: "",
convenio: "Particular",
numeroCarteirinha: "",
observacoes: "",
endereco: {
cep: "",
rua: "",
numero: "",
bairro: "",
cidade: "",
estado: "",
},
});
const [cpfError, setCpfError] = useState<string | null>(null);
const [cpfValidationMessage, setCpfValidationMessage] = useState<
string | null
>(null);
const loadPatients = async () => {
setLoading(true);
try {
const data = await patientService.list();
console.log("✅ Pacientes carregados:", data);
// Log para verificar se temos user_id
if (Array.isArray(data) && data.length > 0) {
console.log("📋 Primeiro paciente (verificar user_id):", {
full_name: data[0].full_name,
user_id: data[0].user_id,
avatar_url: data[0].avatar_url,
email: data[0].email,
});
}
setPatients(Array.isArray(data) ? data : []);
if (Array.isArray(data) && data.length === 0) {
console.warn("⚠️ Nenhum paciente encontrado na API");
}
} catch (error) {
console.error("❌ Erro ao carregar pacientes:", error);
toast.error("Erro ao carregar pacientes");
setPatients([]);
} finally {
setLoading(false);
}
};
useEffect(() => {
loadPatients();
}, []);
// Função de filtro
const filteredPatients = patients.filter((patient) => {
// Filtro de busca por nome, CPF ou email
const searchLower = searchTerm.toLowerCase();
const matchesSearch =
!searchTerm ||
patient.full_name?.toLowerCase().includes(searchLower) ||
patient.cpf?.includes(searchTerm) ||
patient.email?.toLowerCase().includes(searchLower);
// Filtro de aniversariantes do mês
const matchesBirthday =
!showBirthdays ||
(() => {
if (!patient.birth_date) return false;
const birthDate = new Date(patient.birth_date);
const currentMonth = new Date().getMonth();
const birthMonth = birthDate.getMonth();
return currentMonth === birthMonth;
})();
// Filtro de convênio
const matchesInsurance =
insuranceFilter === "Todos" ||
((patient as any).convenio || "Particular") === insuranceFilter;
// Filtro VIP (se o backend fornecer uma flag 'is_vip' ou 'vip')
const matchesVIP = !showVIP || ((patient as any).is_vip === true || (patient as any).vip === true);
return matchesSearch && matchesBirthday && matchesInsurance && matchesVIP;
});
// Cálculos de paginação
const totalPages = Math.ceil(filteredPatients.length / itemsPerPage);
const startIndex = (currentPage - 1) * itemsPerPage;
const endIndex = startIndex + itemsPerPage;
const paginatedPatients = filteredPatients.slice(startIndex, endIndex);
const handleSearch = () => {
loadPatients();
};
const handleClear = () => {
setSearchTerm("");
setInsuranceFilter("Todos");
setShowBirthdays(false);
setShowVIP(false);
setCurrentPage(1);
loadPatients();
};
// Reset página quando filtros mudarem
useEffect(() => {
setCurrentPage(1);
}, [searchTerm, insuranceFilter, showBirthdays, showVIP]);
const handleNewPatient = () => {
setModalMode("create");
setFormData({
nome: "",
social_name: "",
cpf: "",
sexo: "",
dataNascimento: "",
email: "",
codigoPais: "55",
ddd: "",
numeroTelefone: "",
tipo_sanguineo: "",
altura: "",
peso: "",
convenio: "Particular",
numeroCarteirinha: "",
observacoes: "",
endereco: {
cep: "",
rua: "",
numero: "",
bairro: "",
cidade: "",
estado: "",
},
});
setCpfError(null);
setCpfValidationMessage(null);
setShowModal(true);
};
const handleEditPatient = (patient: Patient) => {
setModalMode("edit");
setFormData({
id: patient.id,
user_id: patient.user_id,
nome: patient.full_name || "",
social_name: patient.social_name || "",
cpf: patient.cpf || "",
sexo: patient.sex || "",
dataNascimento: patient.birth_date || "",
email: patient.email || "",
codigoPais: "55",
ddd: "",
numeroTelefone: patient.phone_mobile || "",
tipo_sanguineo: patient.blood_type || "",
altura: patient.height_m?.toString() || "",
peso: patient.weight_kg?.toString() || "",
convenio: "Particular",
numeroCarteirinha: "",
observacoes: "",
avatar_url: patient.avatar_url || undefined,
endereco: {
cep: patient.cep || "",
rua: patient.street || "",
numero: patient.number || "",
complemento: patient.complement || "",
bairro: patient.neighborhood || "",
cidade: patient.city || "",
estado: patient.state || "",
},
});
setCpfError(null);
setCpfValidationMessage(null);
setShowModal(true);
};
const handleFormChange = (patch: Partial<PacienteFormData>) => {
setFormData((prev) => ({ ...prev, ...patch }));
};
const handleCpfChange = (value: string) => {
setFormData((prev) => ({ ...prev, cpf: value }));
setCpfError(null);
setCpfValidationMessage(null);
};
const handleCepLookup = async (cep: string) => {
const endereco = await buscarEnderecoViaCEP(cep);
if (endereco) {
setFormData((prev) => ({
...prev,
endereco: {
...prev.endereco,
...endereco,
},
}));
toast.success("Endereço encontrado!");
} else {
toast.error("CEP não encontrado");
}
};
const handleFormSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
setLoading(true);
try {
if (modalMode === "edit" && formData.id) {
// Para edição, usa o endpoint antigo (PATCH /patients/:id)
// Remove formatação de telefone, CPF e CEP
const cleanPhone = formData.numeroTelefone.replace(/\D/g, "");
const cleanCpf = formData.cpf.replace(/\D/g, "");
const cleanCep = formData.endereco.cep
? formData.endereco.cep.replace(/\D/g, "")
: null;
const patientData = {
full_name: formData.nome,
social_name: formData.social_name || null,
cpf: cleanCpf,
sex: formData.sexo || null,
birth_date: formData.dataNascimento || null,
email: formData.email,
phone_mobile: cleanPhone,
blood_type: formData.tipo_sanguineo || null,
height_m: formData.altura ? parseFloat(formData.altura) : null,
weight_kg: formData.peso ? parseFloat(formData.peso) : null,
cep: cleanCep,
street: formData.endereco.rua || null,
number: formData.endereco.numero || null,
complement: formData.endereco.complemento || null,
neighborhood: formData.endereco.bairro || null,
city: formData.endereco.cidade || null,
state: formData.endereco.estado || null,
};
await patientService.update(formData.id, patientData);
toast.success("Paciente atualizado com sucesso!");
} else {
// Criar novo paciente usando a API REST direta
// Remove formatação de telefone e CPF
const cleanPhone = formData.numeroTelefone.replace(/\D/g, "");
const cleanCpf = formData.cpf.replace(/\D/g, "");
const cleanCep = formData.endereco.cep
? formData.endereco.cep.replace(/\D/g, "")
: null;
const createData = {
full_name: formData.nome,
cpf: cleanCpf,
email: formData.email,
phone_mobile: cleanPhone,
birth_date: formData.dataNascimento || null,
social_name: formData.social_name || null,
sex: formData.sexo || null,
blood_type: formData.tipo_sanguineo || null,
weight_kg: formData.peso ? parseFloat(formData.peso) : null,
height_m: formData.altura ? parseFloat(formData.altura) : null,
street: formData.endereco.rua || null,
number: formData.endereco.numero || null,
complement: formData.endereco.complemento || null,
neighborhood: formData.endereco.bairro || null,
city: formData.endereco.cidade || null,
state: formData.endereco.estado || null,
cep: cleanCep,
created_by: user?.id || undefined,
};
await patientService.create(createData);
toast.success("Paciente cadastrado com sucesso!");
}
setShowModal(false);
loadPatients();
} catch (error) {
console.error("Erro ao salvar paciente:", error);
toast.error("Erro ao salvar paciente");
} finally {
setLoading(false);
}
};
const handleCancelForm = () => {
setShowModal(false);
};
const handleDeleteClick = (patient: Patient) => {
setPatientToDelete(patient);
setShowDeleteDialog(true);
};
const handleViewPatient = (patient: Patient) => {
setSelectedPatient(patient);
setShowViewModal(true);
};
const handleSchedulePatient = (patient: Patient) => {
if (onOpenAppointment) {
onOpenAppointment(patient.id as string);
} else {
// fallback: store in sessionStorage and dispatch event
sessionStorage.setItem("selectedPatientForAppointment", patient.id as string);
window.dispatchEvent(new CustomEvent("open-create-appointment"));
}
};
const handleConfirmDelete = async () => {
if (!patientToDelete?.id) return;
setLoading(true);
try {
await patientService.delete(patientToDelete.id);
toast.success("Paciente deletado com sucesso!");
setShowDeleteDialog(false);
setPatientToDelete(null);
loadPatients();
} catch (error) {
console.error("Erro ao deletar paciente:", error);
toast.error("Erro ao deletar paciente");
} finally {
setLoading(false);
}
};
const handleCancelDelete = () => {
setShowDeleteDialog(false);
setPatientToDelete(null);
};
const getPatientColor = (
index: number
): "blue" | "green" | "purple" | "orange" | "pink" | "teal" => {
const colors: Array<
"blue" | "green" | "purple" | "orange" | "pink" | "teal"
> = ["blue", "green", "purple", "orange", "pink", "teal"];
return colors[index % colors.length];
};
return (
<div className="space-y-6">
{/* Header */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-3xl font-bold text-gray-900 dark:text-gray-100">Pacientes</h1>
<p className="text-gray-600 dark:text-gray-400 mt-1">
Gerencie os pacientes cadastrados
</p>
</div>
<button
onClick={handleNewPatient}
className="flex items-center gap-2 px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors"
>
<Plus className="h-4 w-4" />
Novo Paciente
</button>
</div>
{/* Search and Filters */}
<div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 p-6 space-y-4">
<div className="flex gap-3">
<div className="flex-1 relative">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-5 w-5 text-gray-400 dark:text-gray-500" />
<input
type="text"
placeholder="Buscar pacientes por nome ou email..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="w-full pl-10 pr-4 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg focus:ring-2 focus:ring-green-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400"
/>
</div>
<button
onClick={handleSearch}
className="px-6 py-2.5 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors"
>
Buscar
</button>
<button
onClick={handleClear}
className="px-6 py-2.5 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
>
Limpar
</button>
</div>
<div className="flex items-center gap-6">
<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
checked={showBirthdays}
onChange={(e) => setShowBirthdays(e.target.checked)}
className="h-4 w-4 text-green-600 border-gray-300 rounded focus:ring-green-500"
/>
<span className="text-sm text-gray-700 dark:text-gray-300">
Aniversariantes do mês
</span>
</label>
<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
checked={showVIP}
onChange={(e) => setShowVIP(e.target.checked)}
className="h-4 w-4 text-green-600 border-gray-300 rounded focus:ring-green-500"
/>
<span className="text-sm text-gray-700 dark:text-gray-300">Somente VIP</span>
</label>
<div className="flex items-center gap-2 ml-auto">
<span className="text-sm text-gray-600 dark:text-gray-400">Convênio:</span>
<select
value={insuranceFilter}
onChange={(e) => setInsuranceFilter(e.target.value)}
className="px-3 py-1.5 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:ring-2 focus:ring-green-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100"
>
<option>Todos</option>
<option>Particular</option>
<option>Unimed</option>
<option>Amil</option>
<option>Bradesco Saúde</option>
</select>
</div>
</div>
</div>
{/* Table */}
<div className="bg-white dark:bg-gray-800 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden">
<table className="w-full">
<thead className="bg-gray-50 dark:bg-gray-700 border-b border-gray-200 dark:border-gray-600">
<tr>
<th className="px-6 py-4 text-left text-sm font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wider">
Paciente
</th>
<th className="px-6 py-4 text-left text-sm font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wider">
Próximo Atendimento
</th>
<th className="px-6 py-4 text-left text-sm font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wider">
Convênio
</th>
<th className="px-6 py-4 text-left text-sm font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wider">
Ações
</th>
</tr>
</thead>
<tbody className="divide-y divide-gray-200 dark:divide-gray-700">
{loading ? (
<tr>
<td
colSpan={4}
className="px-6 py-12 text-center text-gray-500 dark:text-gray-400"
>
Carregando pacientes...
</td>
</tr>
) : filteredPatients.length === 0 ? (
<tr>
<td
colSpan={4}
className="px-6 py-12 text-center text-gray-500 dark:text-gray-400"
>
{searchTerm
? "Nenhum paciente encontrado com esse termo"
: "Nenhum paciente encontrado"}
</td>
</tr>
) : (
paginatedPatients.map((patient, index) => (
<tr
key={patient.id}
className="hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
>
<td className="px-6 py-4">
<div className="flex items-center gap-3">
<Avatar
src={patient}
name={patient.full_name || ""}
size="md"
color={getPatientColor(index)}
/>
<div>
<p className="text-sm font-medium text-gray-900 dark:text-gray-100">
{patient.full_name}
</p>
<p className="text-sm text-gray-500 dark:text-gray-400">{patient.email}</p>
<p className="text-sm text-gray-500 dark:text-gray-400">
{patient.phone_mobile}
</p>
</div>
</div>
</td>
<td className="px-6 py-4 text-sm text-gray-700 dark:text-gray-300">
{/* TODO: Buscar próximo agendamento */}
</td>
<td className="px-6 py-4 text-sm text-gray-700 dark:text-gray-300">
{(patient as any).convenio || "Particular"}
</td>
<td className="px-6 py-4">
<div className="flex items-center gap-2">
<button
onClick={() => handleViewPatient(patient)}
title="Visualizar"
className="p-2 text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
>
<Eye className="h-4 w-4" />
</button>
<button
onClick={() => handleSchedulePatient(patient)}
title="Agendar consulta"
className="p-2 text-green-600 hover:bg-green-50 rounded-lg transition-colors"
>
<Calendar className="h-4 w-4" />
</button>
<button
onClick={() => handleEditPatient(patient)}
title="Editar"
className="p-2 text-orange-600 hover:bg-orange-50 rounded-lg transition-colors"
>
<Edit className="h-4 w-4" />
</button>
<button
onClick={() => handleDeleteClick(patient)}
title="Deletar"
className="p-2 text-red-600 hover:bg-red-50 rounded-lg transition-colors"
>
<Trash2 className="h-4 w-4" />
</button>
</div>
</td>
</tr>
))
)}
</tbody>
</table>
</div>
{/* Paginação */}
{filteredPatients.length > 0 && (
<div className="flex items-center justify-between bg-white dark:bg-gray-800 px-6 py-4 rounded-xl shadow-sm border border-gray-200 dark:border-gray-700">
<div className="text-sm text-gray-700 dark:text-gray-300">
Mostrando {startIndex + 1} até {Math.min(endIndex, filteredPatients.length)} de {filteredPatients.length} pacientes
</div>
<div className="flex items-center gap-2">
<button
onClick={() => setCurrentPage((prev) => Math.max(prev - 1, 1))}
disabled={currentPage === 1}
className="px-4 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed text-gray-700 dark:text-gray-300"
>
Anterior
</button>
<div className="flex items-center gap-1">
{(() => {
const maxPagesToShow = 4;
let startPage = Math.max(1, currentPage - Math.floor(maxPagesToShow / 2));
let endPage = Math.min(totalPages, startPage + maxPagesToShow - 1);
if (endPage - startPage < maxPagesToShow - 1) {
startPage = Math.max(1, endPage - maxPagesToShow + 1);
}
const pages = [];
for (let i = startPage; i <= endPage; i++) {
pages.push(i);
}
return pages.map((page) => (
<button
key={page}
onClick={() => setCurrentPage(page)}
className={`px-3 py-2 text-sm rounded-lg transition-colors ${
currentPage === page
? "bg-green-600 text-white"
: "border border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700 text-gray-700 dark:text-gray-300"
}`}
>
{page}
</button>
));
})()}
</div>
<button
onClick={() => setCurrentPage((prev) => Math.min(prev + 1, totalPages))}
disabled={currentPage === totalPages}
className="px-4 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed text-gray-700 dark:text-gray-300"
>
Próxima
</button>
</div>
</div>
)}
{/* Modal de Formulário */}
{showModal && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-xl shadow-xl max-w-4xl w-full max-h-[90vh] overflow-hidden flex flex-col">
{/* Header */}
<div className="flex items-center justify-between p-6 border-b border-gray-200">
<h2 className="text-xl font-semibold text-gray-900">
{modalMode === "create" ? "Novo Paciente" : "Editar Paciente"}
</h2>
<button
onClick={handleCancelForm}
className="p-2 text-gray-400 hover:text-gray-600 rounded-lg transition-colors"
>
<X className="h-5 w-5" />
</button>
</div>
{/* Form Content */}
<div className="flex-1 overflow-y-auto p-6">
<PacienteForm
mode={modalMode}
loading={loading}
data={formData}
bloodTypes={BLOOD_TYPES}
convenios={CONVENIOS}
countryOptions={COUNTRY_OPTIONS}
cpfError={cpfError}
cpfValidationMessage={cpfValidationMessage}
onChange={handleFormChange}
onCpfChange={handleCpfChange}
onCepLookup={handleCepLookup}
onCancel={handleCancelForm}
onSubmit={handleFormSubmit}
/>
</div>
</div>
</div>
)}
{/* Modal de Visualizar Paciente */}
{showViewModal && selectedPatient && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-xl shadow-xl max-w-3xl w-full max-h-[90vh] overflow-y-auto">
<div className="p-6 border-b border-gray-200 flex items-center justify-between">
<h2 className="text-xl font-semibold text-gray-900">Visualizar Paciente</h2>
<button
onClick={() => setShowViewModal(false)}
className="p-2 text-gray-400 hover:text-gray-600 rounded-lg transition-colors"
>
<X className="h-5 w-5" />
</button>
</div>
<div className="p-6 space-y-4">
<div>
<p className="text-sm text-gray-500">Nome</p>
<p className="text-gray-900 font-medium">{selectedPatient.full_name}</p>
</div>
<div>
<p className="text-sm text-gray-500">Email</p>
<p className="text-gray-900">{selectedPatient.email || '—'}</p>
</div>
<div>
<p className="text-sm text-gray-500">Telefone</p>
<p className="text-gray-900">{selectedPatient.phone_mobile || '—'}</p>
</div>
<div>
<p className="text-sm text-gray-500">Convênio</p>
<p className="text-gray-900">{(selectedPatient as any).convenio || 'Particular'}</p>
</div>
<div className="flex justify-end">
<button
onClick={() => setShowViewModal(false)}
className="px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors"
>
Fechar
</button>
</div>
</div>
</div>
</div>
)}
{/* Delete Confirmation Dialog */}
{showDeleteDialog && patientToDelete && (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
<div className="bg-white rounded-xl shadow-xl max-w-md w-full p-6">
<div className="flex items-start gap-4">
<div className="flex-shrink-0 w-12 h-12 rounded-full bg-red-100 flex items-center justify-center">
<Trash2 className="h-6 w-6 text-red-600" />
</div>
<div className="flex-1">
<h3 className="text-lg font-semibold text-gray-900 mb-2">
Confirmar Exclusão
</h3>
<p className="text-sm text-gray-600 mb-4">
Tem certeza que deseja deletar o paciente{" "}
<span className="font-semibold">
{patientToDelete.full_name}
</span>
?
</p>
<div className="bg-red-50 border border-red-200 rounded-lg p-4 mb-4">
<h4 className="text-sm font-semibold text-red-900 mb-2">
Atenção: Esta ação é irreversível
</h4>
<ul className="text-sm text-red-800 space-y-1">
<li> Todos os dados do paciente serão perdidos</li>
<li>
Histórico de consultas será mantido (por auditoria)
</li>
<li>
Prontuários médicos serão mantidos (por legislação)
</li>
<li> O paciente precisará se cadastrar novamente</li>
</ul>
</div>
<div className="flex gap-3">
<button
onClick={handleCancelDelete}
disabled={loading}
className="flex-1 px-4 py-2.5 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors disabled:opacity-50"
>
Cancelar
</button>
<button
onClick={handleConfirmDelete}
disabled={loading}
className="flex-1 px-4 py-2.5 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors disabled:opacity-50"
>
{loading ? "Deletando..." : "Sim, Deletar"}
</button>
</div>
</div>
</div>
</div>
</div>
)}
</div>
);
}