500 lines
24 KiB
PHP
500 lines
24 KiB
PHP
<?php
|
|
if (session_status() === PHP_SESSION_NONE) {
|
|
session_start();
|
|
}
|
|
if (!isset($_SESSION['user_role']) || !in_array($_SESSION['user_role'], ['Administrador', 'admin'])) {
|
|
header('Location: dashboard.php');
|
|
exit();
|
|
}
|
|
$pageTitle = "Cálculo de Costos V3";
|
|
include 'db/config.php';
|
|
include 'layout_header.php';
|
|
|
|
$db = db();
|
|
|
|
// Obtener productos para el select del modal
|
|
$stmt_products = $db->query("SELECT id, nombre FROM products ORDER BY nombre ASC");
|
|
$productos_select = $stmt_products->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
// Obtener videos y sus costos asociados de las tablas V3
|
|
$stmt = $db->query("SELECT mv.id, mv.orden, mv.foto_producto, p.nombre as nombre_producto,
|
|
mc.costo_producto, mc.costo_fijo_film, mc.comision_asesora,
|
|
mc.delivery, mc.costo_publicitario, mc.inversion_total,
|
|
mc.promo_1, mc.promo_2, mc.promo_3,
|
|
mc.comision_asesora_provincia, mc.delivery_provincia
|
|
FROM marketing_videos_v3 mv
|
|
LEFT JOIN products p ON mv.producto_id = p.id
|
|
LEFT JOIN marketing_costos_v3 mc ON mv.id = mc.video_id
|
|
ORDER BY mv.orden ASC, mv.id DESC");
|
|
$costos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
?>
|
|
|
|
<style>
|
|
.table-v3 {
|
|
font-size: 0.8rem;
|
|
border-collapse: separate;
|
|
border-spacing: 0 5px;
|
|
}
|
|
.table-v3 th {
|
|
background-color: #f8f9fa;
|
|
border-bottom: 2px solid #dee2e6;
|
|
white-space: nowrap;
|
|
padding: 10px 5px;
|
|
position: sticky;
|
|
top: 0;
|
|
z-index: 10;
|
|
}
|
|
.table-v3 td {
|
|
vertical-align: middle;
|
|
padding: 6px 3px;
|
|
background-color: #fff;
|
|
}
|
|
.input-cell {
|
|
width: 100%;
|
|
min-width: 70px;
|
|
padding: 6px;
|
|
border: 2px solid #e9ecef;
|
|
border-radius: 6px;
|
|
text-align: center;
|
|
font-size: 0.85rem;
|
|
font-weight: 500;
|
|
transition: all 0.2s;
|
|
}
|
|
.input-cell:focus {
|
|
border-color: #0d6efd;
|
|
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.15);
|
|
outline: 0;
|
|
}
|
|
.input-cell.saving { background-color: #fff3cd !important; border-color: #ffc107 !important; }
|
|
.input-cell.saved { background-color: #d1e7dd !important; border-color: #198754 !important; }
|
|
|
|
.recaudo-v3 {
|
|
background-color: #f8f9fa;
|
|
font-weight: bold;
|
|
text-align: center;
|
|
padding: 6px 4px;
|
|
border-radius: 6px;
|
|
min-width: 85px;
|
|
border: 1px solid #dee2e6;
|
|
font-size: 0.8rem;
|
|
}
|
|
.recaudo-label {
|
|
font-size: 0.65rem;
|
|
display: block;
|
|
color: #6c757d;
|
|
margin-bottom: 2px;
|
|
}
|
|
.img-v3 {
|
|
width: 120px;
|
|
height: 120px;
|
|
object-fit: cover;
|
|
border-radius: 12px;
|
|
cursor: pointer;
|
|
transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
|
|
box-shadow: 0 4px 12px rgba(0,0,0,0.12);
|
|
}
|
|
.img-v3:hover {
|
|
transform: scale(2.2);
|
|
z-index: 100;
|
|
position: relative;
|
|
box-shadow: 0 15px 30px rgba(0,0,0,0.2);
|
|
}
|
|
.img-placeholder {
|
|
width: 120px;
|
|
height: 120px;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s;
|
|
border-radius: 12px;
|
|
}
|
|
.img-placeholder:hover {
|
|
background-color: #e2e6ea !important;
|
|
}
|
|
.btn-action {
|
|
width: 28px;
|
|
height: 28px;
|
|
padding: 0;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: 6px;
|
|
}
|
|
.bg-provincia {
|
|
background-color: #fff4e6 !important;
|
|
}
|
|
.header-provincia {
|
|
background-color: #ffe8cc !important;
|
|
color: #d9480f !important;
|
|
}
|
|
</style>
|
|
|
|
<div class="row align-items-center mb-4 mt-2">
|
|
<div class="col-md-6">
|
|
<p class="text-muted mb-0">Total de registros encontrados: <span class="fw-bold text-dark"><?php echo count($costos); ?></span></p>
|
|
</div>
|
|
<div class="col-md-6 text-end">
|
|
<button type="button" class="btn btn-outline-secondary me-2" onclick="location.reload()">
|
|
<i class="fas fa-sync-alt"></i> Actualizar
|
|
</button>
|
|
<button type="button" id="btnAbrirModalV3" class="btn btn-success btn-lg shadow-sm px-4">
|
|
<i class="fas fa-plus-circle me-2"></i> CREAR NUEVO PRODUCTO
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<?php if (isset($_GET['success'])): ?>
|
|
<div class="alert alert-success alert-dismissible fade show shadow-sm" role="alert">
|
|
<i class="fas fa-check-circle me-2"></i> ¡Operación realizada con éxito!
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if (isset($_GET['error'])): ?>
|
|
<div class="alert alert-danger alert-dismissible fade show shadow-sm" role="alert">
|
|
<i class="fas fa-exclamation-triangle me-2"></i> <?php echo htmlspecialchars($_GET['error']); ?>
|
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-body p-0">
|
|
<div class="table-responsive" style="max-height: 70vh;">
|
|
<table class="table table-v3 mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th class="text-center">Orden</th>
|
|
<th>Producto</th>
|
|
<th class="text-center">Imagen</th>
|
|
<th class="text-center">Costo Prod.</th>
|
|
<th class="text-center">Film</th>
|
|
<th class="text-center">Asesora (L)</th>
|
|
<th class="text-center header-provincia">Asesora (P)</th>
|
|
<th class="text-center">Delivery (L)</th>
|
|
<th class="text-center header-provincia">Delivery (P)</th>
|
|
<th class="text-center">Publicidad</th>
|
|
<th class="text-center">Promo 1</th>
|
|
<th class="text-center">Recaudo 1</th>
|
|
<th class="text-center">Promo 2</th>
|
|
<th class="text-center">Recaudo 2</th>
|
|
<th class="text-center">Promo 3</th>
|
|
<th class="text-center">Recaudo 3</th>
|
|
<th class="text-center">Acción</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($costos)): ?>
|
|
<tr>
|
|
<td colspan="17" class="text-center py-5 text-muted">
|
|
<i class="fas fa-info-circle me-2"></i> No hay productos en esta lista. Haz clic en "Nuevo Producto" para empezar.
|
|
</td>
|
|
</tr>
|
|
<?php endif; ?>
|
|
<?php
|
|
if (!function_exists('getValV3')) {
|
|
function getValV3($promo) {
|
|
if (empty($promo)) return 0;
|
|
preg_match('/[\d.]+/', $promo, $matches);
|
|
return isset($matches[0]) ? floatval($matches[0]) : 0;
|
|
}
|
|
}
|
|
?>
|
|
<?php foreach ($costos as $c): ?>
|
|
<?php
|
|
$costo_prod = ($c['costo_producto'] ?? 0);
|
|
$costo_film = ($c['costo_fijo_film'] ?? 0);
|
|
$costo_asesora = ($c['comision_asesora'] ?? 0);
|
|
$costo_asesora_p = ($c['comision_asesora_provincia'] ?? 0);
|
|
$costo_delivery = ($c['delivery'] ?? 0);
|
|
$costo_delivery_p = ($c['delivery_provincia'] ?? 0);
|
|
$costo_publicidad = ($c['costo_publicitario'] ?? 0);
|
|
|
|
$p1 = getValV3($c['promo_1']);
|
|
$p2 = getValV3($c['promo_2']);
|
|
$p3 = getValV3($c['promo_3']);
|
|
|
|
// Cálculos Local
|
|
$r1_l = $p1 > 0 ? $p1 - ($costo_prod + $costo_film + $costo_asesora + $costo_delivery + $costo_publicidad) : null;
|
|
$r2_l = $p2 > 0 ? $p2 - (($costo_prod + $costo_film) * 2 + $costo_asesora + $costo_delivery + $costo_publicidad) : null;
|
|
$r3_l = $p3 > 0 ? $p3 - (($costo_prod + $costo_film) * 3 + $costo_asesora + $costo_delivery + $costo_publicidad) : null;
|
|
|
|
// Cálculos Provincia
|
|
$r1_p = $p1 > 0 ? $p1 - ($costo_prod + $costo_film + $costo_asesora_p + $costo_delivery_p + $costo_publicidad) : null;
|
|
$r2_p = $p2 > 0 ? $p2 - (($costo_prod + $costo_film) * 2 + $costo_asesora_p + $costo_delivery_p + $costo_publicidad) : null;
|
|
$r3_p = $p3 > 0 ? $p3 - (($costo_prod + $costo_film) * 3 + $costo_asesora_p + $costo_delivery_p + $costo_publicidad) : null;
|
|
?>
|
|
<tr id="row-<?php echo $c['id']; ?>" data-id="<?php echo $c['id']; ?>">
|
|
<td class="text-center fw-bold text-primary"><?php echo $c['orden']; ?></td>
|
|
<td style="max-width: 120px;">
|
|
<div class="text-truncate fw-bold" title="<?php echo htmlspecialchars($c['nombre_producto']); ?>">
|
|
<?php echo htmlspecialchars($c['nombre_producto'] ?: 'General'); ?>
|
|
</div>
|
|
</td>
|
|
<td class="text-center">
|
|
<div class="position-relative d-inline-block">
|
|
<?php if ($c['foto_producto']): ?>
|
|
<img src="<?php echo $c['foto_producto']; ?>" class="img-v3" onclick="triggerImageUpload(<?php echo $c['id']; ?>)">
|
|
<?php else: ?>
|
|
<div class="bg-light rounded d-flex align-items-center justify-content-center img-placeholder" onclick="triggerImageUpload(<?php echo $c['id']; ?>)">
|
|
<i class="fas fa-camera text-muted"></i>
|
|
</div>
|
|
<?php endif; ?>
|
|
<input type="file" id="file-input-<?php echo $c['id']; ?>" class="d-none" accept="image/*" onchange="uploadImage(<?php echo $c['id']; ?>)">
|
|
</div>
|
|
</td>
|
|
<td><input type="number" step="0.01" class="input-cell cost-input" data-field="costo_producto" value="<?php echo $c['costo_producto']; ?>"></td>
|
|
<td><input type="number" step="0.01" class="input-cell cost-input" data-field="costo_fijo_film" value="<?php echo $c['costo_fijo_film']; ?>"></td>
|
|
<td><input type="number" step="0.01" class="input-cell cost-input" data-field="comision_asesora" value="<?php echo $c['comision_asesora']; ?>"></td>
|
|
<td><input type="number" step="0.01" class="input-cell cost-input bg-provincia" data-field="comision_asesora_provincia" value="<?php echo $c['comision_asesora_provincia']; ?>"></td>
|
|
<td><input type="number" step="0.01" class="input-cell cost-input" data-field="delivery" value="<?php echo $c['delivery']; ?>"></td>
|
|
<td><input type="number" step="0.01" class="input-cell cost-input bg-provincia" data-field="delivery_provincia" value="<?php echo $c['delivery_provincia']; ?>"></td>
|
|
<td><input type="number" step="0.01" class="input-cell cost-input" data-field="costo_publicitario" value="<?php echo $c['costo_publicitario']; ?>"></td>
|
|
|
|
<td><input type="text" class="input-cell promo-input" data-field="promo_1" value="<?php echo htmlspecialchars($c['promo_1']); ?>"></td>
|
|
<td>
|
|
<div class="recaudo-v3 mb-1 <?php echo $r1_l >= 0 ? 'text-success' : 'text-danger'; ?>" id="r1l-<?php echo $c['id']; ?>">
|
|
<span class="recaudo-label">LOCAL</span>
|
|
<?php echo $r1_l !== null ? 'S/ '.number_format($r1_l, 2) : '-'; ?>
|
|
</div>
|
|
<div class="recaudo-v3 bg-provincia <?php echo $r1_p >= 0 ? 'text-success' : 'text-danger'; ?>" id="r1p-<?php echo $c['id']; ?>">
|
|
<span class="recaudo-label">PROVINCIA</span>
|
|
<?php echo $r1_p !== null ? 'S/ '.number_format($r1_p, 2) : '-'; ?>
|
|
</div>
|
|
</td>
|
|
|
|
<td><input type="text" class="input-cell promo-input" data-field="promo_2" value="<?php echo htmlspecialchars($c['promo_2']); ?>"></td>
|
|
<td>
|
|
<div class="recaudo-v3 mb-1 <?php echo $r2_l >= 0 ? 'text-success' : 'text-danger'; ?>" id="r2l-<?php echo $c['id']; ?>">
|
|
<span class="recaudo-label">LOCAL</span>
|
|
<?php echo $r2_l !== null ? 'S/ '.number_format($r2_l, 2) : '-'; ?>
|
|
</div>
|
|
<div class="recaudo-v3 bg-provincia <?php echo $r2_p >= 0 ? 'text-success' : 'text-danger'; ?>" id="r2p-<?php echo $c['id']; ?>">
|
|
<span class="recaudo-label">PROVINCIA</span>
|
|
<?php echo $r2_p !== null ? 'S/ '.number_format($r2_p, 2) : '-'; ?>
|
|
</div>
|
|
</td>
|
|
|
|
<td><input type="text" class="input-cell promo-input" data-field="promo_3" value="<?php echo htmlspecialchars($c['promo_3']); ?>"></td>
|
|
<td>
|
|
<div class="recaudo-v3 mb-1 <?php echo $r3_l >= 0 ? 'text-success' : 'text-danger'; ?>" id="r3l-<?php echo $c['id']; ?>">
|
|
<span class="recaudo-label">LOCAL</span>
|
|
<?php echo $r3_l !== null ? 'S/ '.number_format($r3_l, 2) : '-'; ?>
|
|
</div>
|
|
<div class="recaudo-v3 bg-provincia <?php echo $r3_p >= 0 ? 'text-success' : 'text-danger'; ?>" id="r3p-<?php echo $c['id']; ?>">
|
|
<span class="recaudo-label">PROVINCIA</span>
|
|
<?php echo $r3_p !== null ? 'S/ '.number_format($r3_p, 2) : '-'; ?>
|
|
</div>
|
|
</td>
|
|
|
|
<td class="text-center">
|
|
<button class="btn btn-danger btn-action" onclick="eliminarRow(<?php echo $c['id']; ?>)" title="Eliminar">
|
|
<i class="fas fa-trash-alt"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Nuevo -->
|
|
<div class="modal fade" id="modalNuevoV3" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-dialog-centered">
|
|
<div class="modal-content border-0 shadow">
|
|
<form action="save_marketing_video_v3.php" method="POST" enctype="multipart/form-data">
|
|
<input type="hidden" name="redirect" value="calculo_costos_v3.php?success=1">
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title"><i class="fas fa-plus-circle me-2"></i> Nuevo Producto (V3)</h5>
|
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body p-4">
|
|
<div class="mb-3">
|
|
<label class="form-label fw-bold">Seleccionar Producto</label>
|
|
<select name="producto_id" class="form-select form-select-lg" onchange="fetchProductCost(this.value)">
|
|
<option value="">General / Sin producto específico</option>
|
|
<?php foreach ($productos_select as $p): ?>
|
|
<option value="<?php echo $p['id']; ?>"><?php echo htmlspecialchars($p['nombre']); ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<small class="text-muted">Si no seleccionas uno, se marcará como "General".</small>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-bold">Costo Base (S/)</label>
|
|
<input type="number" name="costo_producto" id="costo_producto_nuevo_v3" class="form-control" step="0.01" placeholder="0.00">
|
|
</div>
|
|
<div class="col-md-6 mb-3">
|
|
<label class="form-label fw-bold">Orden de Lista</label>
|
|
<input type="number" name="orden" class="form-control" value="1">
|
|
</div>
|
|
</div>
|
|
<div class="mb-0">
|
|
<label class="form-label fw-bold">Imagen del Producto</label>
|
|
<input type="file" name="foto_producto" class="form-control">
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer bg-light">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
|
|
<button type="submit" class="btn btn-primary px-4">Crear Registro</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
function fetchProductCost(productId) {
|
|
if (!productId) return;
|
|
fetch(`get_product_details.php?id=${productId}`)
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success && data.product.costo) {
|
|
document.getElementById('costo_producto_nuevo_v3').value = data.product.costo;
|
|
}
|
|
});
|
|
}
|
|
|
|
document.querySelectorAll('.input-cell').forEach(input => {
|
|
// Actualización instantánea visual
|
|
input.addEventListener('input', function() {
|
|
const row = this.closest('tr');
|
|
recalculateRowVisual(row);
|
|
});
|
|
|
|
// Guardado real al salir del cuadro
|
|
input.addEventListener('change', function() {
|
|
const row = this.closest('tr');
|
|
const id = row.dataset.id;
|
|
const field = this.dataset.field;
|
|
const value = this.value;
|
|
|
|
this.classList.add('saving');
|
|
|
|
fetch('update_marketing_costos_field_v3.php', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ id, field, value })
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
this.classList.remove('saving');
|
|
if (data.success) {
|
|
this.classList.add('saved');
|
|
setTimeout(() => this.classList.remove('saved'), 1000);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
function recalculateRowVisual(row) {
|
|
const id = row.dataset.id;
|
|
const costProd = parseFloat(row.querySelector('[data-field="costo_producto"]').value) || 0;
|
|
const costFilm = parseFloat(row.querySelector('[data-field="costo_fijo_film"]').value) || 0;
|
|
const costAsesora = parseFloat(row.querySelector('[data-field="comision_asesora"]').value) || 0;
|
|
const costAsesoraP = parseFloat(row.querySelector('[data-field="comision_asesora_provincia"]').value) || 0;
|
|
const costDelivery = parseFloat(row.querySelector('[data-field="delivery"]').value) || 0;
|
|
const costDeliveryP = parseFloat(row.querySelector('[data-field="delivery_provincia"]').value) || 0;
|
|
const costPublicidad = parseFloat(row.querySelector('[data-field="costo_publicitario"]').value) || 0;
|
|
|
|
for (let i = 1; i <= 3; i++) {
|
|
const promoVal = row.querySelector(`[data-field="promo_${i}"]`).value;
|
|
const match = promoVal.match(/[\d.]+/);
|
|
const pVal = match ? parseFloat(match[0]) : 0;
|
|
|
|
const recaudoElL = row.querySelector(`#r${i}l-${id}`);
|
|
const recaudoElP = row.querySelector(`#r${i}p-${id}`);
|
|
|
|
if (pVal > 0) {
|
|
// Local
|
|
const recaudoL = pVal - ((costProd + costFilm) * i + costAsesora + costDelivery + costPublicidad);
|
|
recaudoElL.innerHTML = `<span class="recaudo-label">LOCAL</span>S/ ${recaudoL.toFixed(2)}`;
|
|
recaudoElL.className = 'recaudo-v3 mb-1 ' + (recaudoL >= 0 ? 'text-success' : 'text-danger');
|
|
|
|
// Provincia
|
|
const recaudoP = pVal - ((costProd + costFilm) * i + costAsesoraP + costDeliveryP + costPublicidad);
|
|
recaudoElP.innerHTML = `<span class="recaudo-label">PROVINCIA</span>S/ ${recaudoP.toFixed(2)}`;
|
|
recaudoElP.className = 'recaudo-v3 bg-provincia ' + (recaudoP >= 0 ? 'text-success' : 'text-danger');
|
|
} else {
|
|
recaudoElL.innerHTML = `<span class="recaudo-label">LOCAL</span>-`;
|
|
recaudoElP.innerHTML = `<span class="recaudo-label">PROVINCIA</span>-`;
|
|
}
|
|
}
|
|
}
|
|
|
|
function eliminarRow(id) {
|
|
if (confirm("¿Eliminar este registro de la V3?")) {
|
|
window.location.href = "delete_marketing_video_v3.php?id=" + id;
|
|
}
|
|
}
|
|
|
|
function triggerImageUpload(id) {
|
|
document.getElementById(`file-input-${id}`).click();
|
|
}
|
|
|
|
function uploadImage(id) {
|
|
const fileInput = document.getElementById(`file-input-${id}`);
|
|
if (!fileInput.files || !fileInput.files[0]) return;
|
|
|
|
const formData = new FormData();
|
|
formData.append('id', id);
|
|
formData.append('foto_producto', fileInput.files[0]);
|
|
|
|
const cell = fileInput.closest('td');
|
|
const originalContent = cell.innerHTML;
|
|
cell.innerHTML = '<div class="spinner-border spinner-border-sm text-primary" role="status"></div>';
|
|
|
|
fetch('update_marketing_video_image_v3.php', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
location.reload(); // Recargamos para ver la nueva imagen
|
|
} else {
|
|
alert('Error al subir imagen: ' + data.error);
|
|
cell.innerHTML = originalContent;
|
|
}
|
|
})
|
|
.catch(err => {
|
|
console.error(err);
|
|
alert('Error técnico al subir imagen');
|
|
cell.innerHTML = originalContent;
|
|
});
|
|
}
|
|
|
|
// Script de apertura forzada y diagnóstico
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const btn = document.getElementById('btnAbrirModalV3');
|
|
const modalEl = document.getElementById('modalNuevoV3');
|
|
|
|
if (btn && modalEl) {
|
|
btn.addEventListener('click', function() {
|
|
console.log('Intento de apertura manual del modal...');
|
|
try {
|
|
// Intento 1: Usando la API de Bootstrap 5
|
|
if (typeof bootstrap !== 'undefined') {
|
|
const modalInstance = new bootstrap.Modal(modalEl);
|
|
modalInstance.show();
|
|
console.log('Modal abierto con bootstrap.Modal');
|
|
} else {
|
|
// Intento 2: Si bootstrap no está definido, intentar vía jQuery si existe
|
|
if (typeof $ !== 'undefined' && typeof $.fn.modal !== 'undefined') {
|
|
$(modalEl).modal('show');
|
|
console.log('Modal abierto con jQuery');
|
|
} else {
|
|
alert('Error: No se encontró la librería de Bootstrap. Por favor, recarga la página.');
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error('Error al abrir modal:', err);
|
|
alert('Hubo un problema técnico al abrir la ventana. Error: ' + err.message);
|
|
}
|
|
});
|
|
} else {
|
|
console.error('No se encontró el botón o el modal en el DOM');
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<?php include 'layout_footer.php'; ?>
|