Modulos Pacientes Listo

This commit is contained in:
2026-08-11 23:21:29 -03:00
parent b4b25e49e0
commit 7c04a64269
164 changed files with 1717 additions and 5643 deletions
+646 -76
View File
@@ -1,88 +1,658 @@
@model List<vita_asistente.Data.Models.Paciente>
@model List<vita_asistente.Models.Pacientes>
@{
ViewData["Title"] = "Pacientes";
Layout = "_Layout";
}
<div class="container mt-4">
<h2>Lista de Pacientes</h2>
@if (User.IsInRole("Admin"))
{
<a asp-action="Create" class="btn btn-success mb-3">Nuevo Paciente</a>
}
<div class="card">
<div class="container mt-4 pb-5">
<!-- Encabezado + Botón Agregar -->
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-4">
<h2 class="mb-0">Lista de Pacientes</h2>
@if (User.IsInRole("Admin"))
{
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#createModal">
<i class="bi bi-person-plus-fill me-1"></i> Agregar Paciente
</button>
}
</div>
<!-- Buscador -->
<div class="card shadow-sm mb-4">
<div class="card-body">
<form asp-action="Index" method="get" class="row g-3 mb-4">
<div class="col-md-5">
<form asp-action="Index" method="get" class="row g-3 align-items-end">
<div class="col-md-8 col-lg-6">
<label for="nombreBusqueda" class="form-label">Nombre o Documento</label>
<input type="text" class="form-control" id="nombreBusqueda" name="nombreBusqueda"
placeholder="Buscar por nombre o documento..." value="@ViewBag.NombreBusqueda">
</div>
<div class="col-md-2 d-flex align-items-end">
<button type="submit" class="btn btn-primary me-3">Buscar</button>
@if (!string.IsNullOrEmpty(ViewBag.NombreBusqueda))
{
<a asp-action="Index" class="btn btn-outline-secondary">Limpiar</a>
}
<div class="input-group">
<input type="text" class="form-control" id="nombreBusqueda" name="nombreBusqueda"
placeholder="Buscar por nombre o documento..." value="@ViewBag.NombreBusqueda">
<button type="submit" class="btn btn-primary">Buscar</button>
@if (!string.IsNullOrEmpty(ViewBag.NombreBusqueda))
{
<a asp-action="Index" class="btn btn-outline-secondary">Limpiar</a>
}
</div>
</div>
</form>
<table class="table table-striped">
<thead class="table-dark">
<tr>
<th>Documento</th>
<th>Nombre Completo</th>
<th>Email</th>
<th>Fecha Registro</th>
<th>Estado</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
@foreach (var paciente in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => paciente.Documento)</td>
<td>@Html.DisplayFor(modelItem => paciente.Nombre) @Html.DisplayFor(modelItem => paciente.Apellido)</td>
<td>@Html.DisplayFor(modelItem => paciente.Email)</td>
<td>@Html.DisplayFor(modelItem => paciente.FechaRegistro.ToShortDateString())</td>
<td>
@if (paciente.IsActive)
{
<span class="badge bg-success">Activo</span>
}
else
{
<span class="badge bg-danger">Inactivo</span>
}
</td>
<td>
@if (User.IsInRole("Admin") || (User.Identity != null && User.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier")?.Value == paciente.Id))
{
<a asp-action="Details" asp-route-id="@paciente.Id" class="btn btn-sm btn-info">Ver</a>
@if (User.IsInRole("Admin"))
{
<a asp-action="Edit" asp-route-id="@paciente.Id" class="btn btn-sm btn-warning ms-1">Editar</a>
@if (!paciente.IsActive)
{
<form asp-action="Activate" asp-route-id="@paciente.Id" class="d-inline">
<button type="submit" class="btn btn-sm btn-success ms-1" onclick="return confirm('¿Activar este paciente?');">Activar</button>
</form>
}
else
{
<a asp-action="Delete" asp-route-id="@paciente.Id" class="btn btn-sm btn-danger ms-1">Desactivar</a>
}
}
}
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
<!-- Tabla -->
<div class="table-responsive">
<table class="table table-hover align-middle" id="pacientesTable">
<thead class="table-dark">
<tr>
<th>Documento</th>
<th>Nombre Completo</th>
<th>Email</th>
<th>Fecha Registro</th>
<th>Estado</th>
<th class="text-end">Acciones</th>
</tr>
</thead>
<tbody>
@foreach (var paciente in Model)
{
<tr data-id="@paciente.Id">
<td>@paciente.DocumentNumber</td>
<td>@paciente.FirstName @paciente.LastName</td>
<td>@paciente.Email</td>
<td>@paciente.CreatedAt.ToShortDateString()</td>
<td>
<span class="badge @(paciente.IsActive ? "bg-success" : "bg-danger")">
@(paciente.IsActive ? "Activo" : "Inactivo")
</span>
</td>
<td class="text-end">
<a asp-action="Details" asp-route-id="@paciente.Id" class="btn btn-sm btn-outline-info">
<i class="bi bi-eye"></i> Ver
</a>
@if (User.IsInRole("Admin"))
{
<button type="button" class="btn btn-sm btn-outline-warning edit-btn"
data-id="@paciente.Id"
data-documenttype="@paciente.DocumentType"
data-documentnumber="@paciente.DocumentNumber"
data-firstname="@paciente.FirstName"
data-lastname="@paciente.LastName"
data-email="@paciente.Email"
data-birthdate="@(paciente.BirthDate?.ToString("yyyy-MM-dd"))"
data-address="@paciente.Address"
data-phone="@paciente.Phone"
data-emergencycontactname="@paciente.EmergencyContactName"
data-emergencycontactphone="@paciente.EmergencyContactPhone"
data-bloodtype="@paciente.BloodType"
data-allergiesdescription="@paciente.AllergiesDescription"
data-hasmedicationallergies="@paciente.HasMedicationAllergies.ToString().ToLower()"
data-isactive="@paciente.IsActive.ToString().ToLower()"
data-bs-toggle="modal" data-bs-target="#editModal">
<i class="bi bi-pencil"></i> Editar
</button>
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
data-id="@paciente.Id"
data-name="@($"{paciente.FirstName} {paciente.LastName}")"
data-bs-toggle="modal" data-bs-target="#deleteModal">
<i class="bi bi-trash"></i> Eliminar
</button>
}
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<!-- =============== MODAL CREAR =============== -->
<div class="modal fade" id="createModal" tabindex="-1" aria-labelledby="createModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-success text-white">
<h5 class="modal-title" id="createModalLabel"><i class="bi bi-person-plus-fill me-2"></i>Nuevo Paciente</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<form id="createForm" asp-action="Create" method="post">
<div class="modal-body">
@Html.AntiForgeryToken()
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Nombre</label>
<input type="text" class="form-control" id="createFirstName" name="FirstName" />
<span class="text-danger" id="createFirstNameError"></span>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Apellido</label>
<input type="text" class="form-control" id="createLastName" name="LastName" />
<span class="text-danger" id="createLastNameError"></span>
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label class="form-label">Tipo Documento</label>
<input type="text" class="form-control" id="createDocumentType" name="DocumentType" />
<span class="text-danger" id="createDocumentTypeError"></span>
</div>
<div class="col-md-4 mb-3">
<label class="form-label">Número Documento</label>
<input type="text" class="form-control" id="createDocumentNumber" name="DocumentNumber" />
<span class="text-danger" id="createDocumentNumberError"></span>
</div>
<div class="col-md-4 mb-3">
<label class="form-label">Email</label>
<input type="email" class="form-control" id="createEmail" name="Email" />
<span class="text-danger" id="createEmailError"></span>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Fecha Nacimiento</label>
<input type="date" class="form-control" id="createBirthDate" name="BirthDate" />
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Teléfono</label>
<input type="text" class="form-control" id="createPhone" name="Phone" />
</div>
</div>
<div class="mb-3">
<label class="form-label">Dirección</label>
<input type="text" class="form-control" id="createAddress" name="Address" />
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Contacto Emergencia</label>
<input type="text" class="form-control" id="createEmergencyContactName" name="EmergencyContactName" />
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Teléfono Emergencia</label>
<input type="text" class="form-control" id="createEmergencyContactPhone" name="EmergencyContactPhone" />
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label class="form-label">Tipo Sangre</label>
<input type="text" class="form-control" id="createBloodType" name="BloodType" />
</div>
<div class="col-md-8 mb-3">
<label class="form-label">Alergias</label>
<input type="text" class="form-control" id="createAllergiesDescription" name="AllergiesDescription" />
</div>
</div>
<div class="form-check mb-3">
<input type="checkbox" class="form-check-input" id="createHasMedicationAllergies" name="HasMedicationAllergies" value="true" />
<label class="form-check-label" for="createHasMedicationAllergies">¿Tiene alergias a medicamentos?</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
<button type="submit" class="btn btn-success">Guardar</button>
</div>
</form>
</div>
</div>
</div>
<!-- =============== MODAL EDITAR =============== -->
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="editModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-warning text-dark">
<h5 class="modal-title" id="editModalLabel"><i class="bi bi-pencil me-2"></i>Editar Paciente</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="editForm" method="post">
<div class="modal-body">
@Html.AntiForgeryToken()
<input type="hidden" id="editId" name="Id" />
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Nombre</label>
<input type="text" class="form-control" id="editFirstName" name="FirstName" />
<span class="text-danger" id="editFirstNameError"></span>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Apellido</label>
<input type="text" class="form-control" id="editLastName" name="LastName" />
<span class="text-danger" id="editLastNameError"></span>
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label class="form-label">Tipo Documento</label>
<input type="text" class="form-control" id="editDocumentType" name="DocumentType" />
<span class="text-danger" id="editDocumentTypeError"></span>
</div>
<div class="col-md-4 mb-3">
<label class="form-label">Número Documento</label>
<input type="text" class="form-control" id="editDocumentNumber" name="DocumentNumber" />
<span class="text-danger" id="editDocumentNumberError"></span>
</div>
<div class="col-md-4 mb-3">
<label class="form-label">Email</label>
<input type="email" class="form-control" id="editEmail" name="Email" />
<span class="text-danger" id="editEmailError"></span>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Fecha Nacimiento</label>
<input type="date" class="form-control" id="editBirthDate" name="BirthDate" />
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Teléfono</label>
<input type="text" class="form-control" id="editPhone" name="Phone" />
</div>
</div>
<div class="mb-3">
<label class="form-label">Dirección</label>
<input type="text" class="form-control" id="editAddress" name="Address" />
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Contacto Emergencia</label>
<input type="text" class="form-control" id="editEmergencyContactName" name="EmergencyContactName" />
</div>
<div class="col-md-6 mb-3">
<label class="form-label">Teléfono Emergencia</label>
<input type="text" class="form-control" id="editEmergencyContactPhone" name="EmergencyContactPhone" />
</div>
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label class="form-label">Tipo Sangre</label>
<input type="text" class="form-control" id="editBloodType" name="BloodType" />
</div>
<div class="col-md-8 mb-3">
<label class="form-label">Alergias</label>
<input type="text" class="form-control" id="editAllergiesDescription" name="AllergiesDescription" />
</div>
</div>
<div class="form-check mb-3">
<input type="checkbox" class="form-check-input" id="editHasMedicationAllergies" name="HasMedicationAllergies" value="true" />
<label class="form-check-label" for="editHasMedicationAllergies">¿Tiene alergias a medicamentos?</label>
</div>
<div class="form-check mb-3">
<input type="checkbox" class="form-check-input" id="editIsActive" name="IsActive" value="true" />
<label class="form-check-label" for="editIsActive">Activo</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
<button type="submit" class="btn btn-warning">Actualizar</button>
</div>
</form>
</div>
</div>
</div>
<!-- =============== MODAL ELIMINAR =============== -->
<div class="modal fade" id="deleteModal" tabindex="-1" aria-labelledby="deleteModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-danger text-white">
<h5 class="modal-title" id="deleteModalLabel"><i class="bi bi-exclamation-triangle me-2"></i>Eliminar Paciente</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>¿Estás seguro de que deseas eliminar al paciente <strong id="deletePatientName"></strong>?</p>
<p class="text-danger">Esta acción no se puede deshacer.</p>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="confirmDeleteCheck">
<label class="form-check-label" for="confirmDeleteCheck">
Confirmo que deseo eliminar este paciente.
</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
<form id="deleteForm" asp-action="Delete" method="post" class="d-inline">
@Html.AntiForgeryToken()
<input type="hidden" name="id" id="deleteId" />
<button type="submit" class="btn btn-danger" id="deleteConfirmBtn" disabled>Eliminar</button>
</form>
</div>
</div>
</div>
</div>
<!-- Toast container -->
<div id="toastContainer" class="position-fixed bottom-0 end-0 p-3" style="z-index: 1200;"></div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
document.addEventListener('DOMContentLoaded', function () {
// ---------- UTILIDADES ----------
function showToast(message, isSuccess = true) {
const container = document.getElementById('toastContainer');
const toast = document.createElement('div');
toast.className = `toast align-items-center text-white ${isSuccess ? 'bg-success' : 'bg-danger'} border-0`;
toast.role = 'alert';
toast.setAttribute('aria-live', 'assertive');
toast.setAttribute('aria-atomic', 'true');
const body = document.createElement('div');
body.className = 'toast-body';
body.textContent = message;
toast.appendChild(body);
container.appendChild(toast);
const bsToast = new bootstrap.Toast(toast, { delay: 4000 });
bsToast.show();
toast.addEventListener('hidden.bs.toast', () => toast.remove());
}
function getAntiForgeryToken(form) {
return form.querySelector('input[name="__RequestVerificationToken"]')?.value || '';
}
function clearValidationErrors(form) {
form.querySelectorAll('.text-danger').forEach(el => el.textContent = '');
}
function displayValidationErrors(form, errors) {
clearValidationErrors(form);
for (const [key, messages] of Object.entries(errors)) {
// Buscar el span de error correspondiente: id="[formId][PropertyName]Error"
const prefix = form.id === 'createForm' ? 'create' : 'edit';
const span = document.getElementById(`${prefix}${key}Error`);
if (span) {
span.textContent = Array.isArray(messages) ? messages.join(' ') : messages;
}
}
}
// ---------- CREAR PACIENTE ----------
const createForm = document.getElementById('createForm');
const createModalEl = document.getElementById('createModal');
const createModal = new bootstrap.Modal(createModalEl);
createForm.addEventListener('submit', async function (e) {
e.preventDefault();
clearValidationErrors(createForm);
const formData = new FormData(createForm);
const token = getAntiForgeryToken(createForm);
try {
const response = await fetch(createForm.action, {
method: 'POST',
headers: {
'Accept': 'application/json',
'RequestVerificationToken': token
},
body: new URLSearchParams(formData)
});
if (!response.ok) {
const errorData = await response.json();
if (errorData.errors) {
displayValidationErrors(createForm, errorData.errors);
showToast('Por favor corrige los errores.', false);
} else {
showToast('Error al guardar.', false);
}
return;
}
const result = await response.json();
if (result.success) {
const patient = result.data;
addRowToTable(patient);
createModal.hide();
showToast('Paciente creado exitosamente.');
createForm.reset();
} else {
showToast('Error al crear el paciente.', false);
}
} catch (error) {
console.error(error);
showToast('Ocurrió un error inesperado.', false);
}
});
// ---------- EDITAR PACIENTE ----------
const editModalEl = document.getElementById('editModal');
const editModal = new bootstrap.Modal(editModalEl);
const editForm = document.getElementById('editForm');
function loadEditData(btn) {
document.getElementById('editId').value = btn.dataset.id;
document.getElementById('editFirstName').value = btn.dataset.firstname || '';
document.getElementById('editLastName').value = btn.dataset.lastname || '';
document.getElementById('editDocumentType').value = btn.dataset.documenttype || '';
document.getElementById('editDocumentNumber').value = btn.dataset.documentnumber || '';
document.getElementById('editEmail').value = btn.dataset.email || '';
document.getElementById('editBirthDate').value = btn.dataset.birthdate || '';
document.getElementById('editAddress').value = btn.dataset.address || '';
document.getElementById('editPhone').value = btn.dataset.phone || '';
document.getElementById('editEmergencyContactName').value = btn.dataset.emergencycontactname || '';
document.getElementById('editEmergencyContactPhone').value = btn.dataset.emergencycontactphone || '';
document.getElementById('editBloodType').value = btn.dataset.bloodtype || '';
document.getElementById('editAllergiesDescription').value = btn.dataset.allergiesdescription || '';
document.getElementById('editHasMedicationAllergies').checked = btn.dataset.hasmedicationallergies === 'true';
document.getElementById('editIsActive').checked = btn.dataset.isactive === 'true';
editForm.action = `/Pacientes/Edit/${btn.dataset.id}`;
clearValidationErrors(editForm);
}
// Asignar evento a botones de edición (incluyendo los dinámicos)
document.addEventListener('click', function (e) {
const btn = e.target.closest('.edit-btn');
if (btn) {
loadEditData(btn);
}
});
editForm.addEventListener('submit', async function (e) {
e.preventDefault();
clearValidationErrors(editForm);
const formData = new FormData(editForm);
const token = getAntiForgeryToken(editForm);
try {
const response = await fetch(editForm.action, {
method: 'POST',
headers: {
'Accept': 'application/json',
'RequestVerificationToken': token
},
body: new URLSearchParams(formData)
});
if (!response.ok) {
const errorData = await response.json();
if (errorData.errors) {
displayValidationErrors(editForm, errorData.errors);
showToast('Por favor corrige los errores.', false);
} else {
showToast('Error al actualizar.', false);
}
return;
}
const result = await response.json();
if (result.success) {
const patient = result.data;
updateRowInTable(patient);
editModal.hide();
showToast('Paciente actualizado exitosamente.');
} else {
showToast('Error al actualizar.', false);
}
} catch (error) {
console.error(error);
showToast('Ocurrió un error inesperado.', false);
}
});
// ---------- ELIMINAR PACIENTE ----------
const deleteModalEl = document.getElementById('deleteModal');
const deleteModal = new bootstrap.Modal(deleteModalEl);
const deleteForm = document.getElementById('deleteForm');
const confirmCheck = document.getElementById('confirmDeleteCheck');
const deleteBtn = document.getElementById('deleteConfirmBtn');
const deletePatientName = document.getElementById('deletePatientName');
document.addEventListener('click', function (e) {
const btn = e.target.closest('.delete-btn');
if (btn) {
const id = btn.dataset.id;
const name = btn.dataset.name;
deletePatientName.textContent = name;
document.getElementById('deleteId').value = id;
confirmCheck.checked = false;
deleteBtn.disabled = true;
deleteForm.action = `/Pacientes/Delete/${id}`;
}
});
confirmCheck.addEventListener('change', function () {
deleteBtn.disabled = !this.checked;
});
deleteForm.addEventListener('submit', async function (e) {
e.preventDefault();
const token = getAntiForgeryToken(deleteForm);
const id = document.getElementById('deleteId').value;
try {
const response = await fetch(deleteForm.action, {
method: 'POST',
headers: {
'Accept': 'application/json',
'RequestVerificationToken': token
},
body: new URLSearchParams(new FormData(deleteForm))
});
if (!response.ok) {
showToast('Error al eliminar.', false);
return;
}
const result = await response.json();
if (result.success) {
removeRowFromTable(id);
deleteModal.hide();
showToast('Paciente eliminado correctamente.');
} else {
showToast('Error al eliminar.', false);
}
} catch (error) {
console.error(error);
showToast('Ocurrió un error inesperado.', false);
}
});
// ---------- FUNCIONES DE ACTUALIZACIÓN DE TABLA ----------
function addRowToTable(patient) {
const tbody = document.querySelector('#pacientesTable tbody');
const row = document.createElement('tr');
row.dataset.id = patient.id;
const statusBadge = patient.isActive
? '<span class="badge bg-success">Activo</span>'
: '<span class="badge bg-danger">Inactivo</span>';
const adminActions = `
<button type="button" class="btn btn-sm btn-outline-warning edit-btn"
data-id="${patient.id}"
data-documenttype="${patient.documentType || ''}"
data-documentnumber="${patient.documentNumber || ''}"
data-firstname="${patient.firstName || ''}"
data-lastname="${patient.lastName || ''}"
data-email="${patient.email || ''}"
data-birthdate="${patient.birthDate || ''}"
data-address="${patient.address || ''}"
data-phone="${patient.phone || ''}"
data-emergencycontactname="${patient.emergencyContactName || ''}"
data-emergencycontactphone="${patient.emergencyContactPhone || ''}"
data-bloodtype="${patient.bloodType || ''}"
data-allergiesdescription="${patient.allergiesDescription || ''}"
data-hasmedicationallergies="${patient.hasMedicationAllergies || false}"
data-isactive="${patient.isActive || false}"
data-bs-toggle="modal" data-bs-target="#editModal">
<i class="bi bi-pencil"></i> Editar
</button>
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
data-id="${patient.id}"
data-name="${patient.firstName || ''} ${patient.lastName || ''}"
data-bs-toggle="modal" data-bs-target="#deleteModal">
<i class="bi bi-trash"></i> Eliminar
</button>
`;
row.innerHTML = `
<td>${patient.documentNumber || ''}</td>
<td>${patient.firstName || ''} ${patient.lastName || ''}</td>
<td>${patient.email || ''}</td>
<td>${patient.createdAt ? new Date(patient.createdAt).toLocaleDateString() : 'N/A'}</td>
<td>${statusBadge}</td>
<td class="text-end">
<a href="/Pacientes/Details/${encodeURIComponent(patient.id)}" class="btn btn-sm btn-outline-info">
<i class="bi bi-eye"></i> Ver
</a>
${patient.id ? adminActions : ''}
</td>
`;
tbody.prepend(row);
}
function updateRowInTable(patient) {
const row = document.querySelector(`#pacientesTable tbody tr[data-id="${patient.id}"]`);
if (row) {
const newRow = document.createElement('tr');
newRow.dataset.id = patient.id;
const statusBadge = patient.isActive
? '<span class="badge bg-success">Activo</span>'
: '<span class="badge bg-danger">Inactivo</span>';
const adminActions = `
<button type="button" class="btn btn-sm btn-outline-warning edit-btn"
data-id="${patient.id}"
data-documenttype="${patient.documentType || ''}"
data-documentnumber="${patient.documentNumber || ''}"
data-firstname="${patient.firstName || ''}"
data-lastname="${patient.lastName || ''}"
data-email="${patient.email || ''}"
data-birthdate="${patient.birthDate || ''}"
data-address="${patient.address || ''}"
data-phone="${patient.phone || ''}"
data-emergencycontactname="${patient.emergencyContactName || ''}"
data-emergencycontactphone="${patient.emergencyContactPhone || ''}"
data-bloodtype="${patient.bloodType || ''}"
data-allergiesdescription="${patient.allergiesDescription || ''}"
data-hasmedicationallergies="${patient.hasMedicationAllergies || false}"
data-isactive="${patient.isActive || false}"
data-bs-toggle="modal" data-bs-target="#editModal">
<i class="bi bi-pencil"></i> Editar
</button>
<button type="button" class="btn btn-sm btn-outline-danger delete-btn"
data-id="${patient.id}"
data-name="${patient.firstName || ''} ${patient.lastName || ''}"
data-bs-toggle="modal" data-bs-target="#deleteModal">
<i class="bi bi-trash"></i> Eliminar
</button>
`;
newRow.innerHTML = `
<td>${patient.documentNumber || ''}</td>
<td>${patient.firstName || ''} ${patient.lastName || ''}</td>
<td>${patient.email || ''}</td>
<td>${patient.createdAt ? new Date(patient.createdAt).toLocaleDateString() : 'N/A'}</td>
<td>${statusBadge}</td>
<td class="text-end">
<a href="/Pacientes/Details/${encodeURIComponent(patient.id)}" class="btn btn-sm btn-outline-info">
<i class="bi bi-eye"></i> Ver
</a>
${patient.id ? adminActions : ''}
</td>
`;
row.replaceWith(newRow);
}
}
function removeRowFromTable(id) {
const row = document.querySelector(`#pacientesTable tbody tr[data-id="${id}"]`);
if (row) row.remove();
}
});
</script>
}