Autosave: 20260212-035552
This commit is contained in:
parent
184bb26fca
commit
697dbbf92b
@ -4,6 +4,7 @@ body {
|
||||
font-family: 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif;
|
||||
display: flex;
|
||||
color: #333;
|
||||
transition: margin-left 0.3s;
|
||||
}
|
||||
|
||||
/* Sidebar Styles */
|
||||
@ -17,6 +18,8 @@ body {
|
||||
color: #ecf0f1;
|
||||
padding-top: 20px;
|
||||
box-shadow: 2px 0 15px rgba(0,0,0,0.1);
|
||||
transition: transform 0.3s ease;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.sidebar .navbar-brand {
|
||||
@ -61,8 +64,49 @@ body {
|
||||
padding: 30px;
|
||||
width: calc(100% - 260px);
|
||||
overflow-y: auto;
|
||||
transition: margin-left 0.3s ease;
|
||||
}
|
||||
|
||||
/* Hamburger Menu Button */
|
||||
.sidebar-toggle {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 15px;
|
||||
left: 15px;
|
||||
z-index: 1001;
|
||||
background: #34495e;
|
||||
color: #fff;
|
||||
border: none;
|
||||
padding: 10px 15px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Responsive Styles */
|
||||
@media (max-width: 992px) {
|
||||
.sidebar {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
.sidebar.active {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sidebar-toggle {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body.sidebar-active .content {
|
||||
margin-left: 260px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
h1, .h1 {
|
||||
color: #333 !important; /* Color oscuro para los títulos */
|
||||
}
|
||||
@ -109,8 +153,12 @@ h1, .h1 {
|
||||
}
|
||||
|
||||
/* Table Styles */
|
||||
.table-responsive {
|
||||
overflow-x: auto;
|
||||
}
|
||||
.table {
|
||||
margin-bottom: 0;
|
||||
min-width: 600px; /* Prevent table from collapsing too much */
|
||||
}
|
||||
|
||||
.table thead th {
|
||||
@ -245,4 +293,4 @@ h1, .h1 {
|
||||
.sidebar .submenu .nav-link.active {
|
||||
color: #fff; /* White color for active sub-item */
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
@ -1,21 +1,31 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
require_once 'db/config.php';
|
||||
|
||||
if (isset($_GET['id'])) {
|
||||
$id = $_GET['id'];
|
||||
$stmt = $db->prepare("SELECT id, nombre, provincia FROM products WHERE id = ?");
|
||||
$stmt->execute([$id]);
|
||||
$product = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$response = ['success' => false, 'message' => 'ID de producto no proporcionado.'];
|
||||
|
||||
if ($product) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($product);
|
||||
if (isset($_GET['id'])) {
|
||||
$product_id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
|
||||
|
||||
if ($product_id) {
|
||||
try {
|
||||
$pdo = db();
|
||||
$stmt = $pdo->prepare("SELECT id, nombre, sku FROM products WHERE id = :id");
|
||||
$stmt->execute(['id' => $product_id]);
|
||||
$product = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($product) {
|
||||
$response = ['success' => true, 'product' => $product];
|
||||
} else {
|
||||
$response['message'] = 'Producto no encontrado.';
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$response['message'] = 'Error en la base de datos: ' . $e->getMessage();
|
||||
}
|
||||
} else {
|
||||
http_response_code(404);
|
||||
echo json_encode(['error' => 'Producto no encontrado']);
|
||||
$response['message'] = 'ID de producto inválido.';
|
||||
}
|
||||
} else {
|
||||
http_response_code(400);
|
||||
echo json_encode(['error' => 'ID de producto no proporcionado']);
|
||||
}
|
||||
|
||||
echo json_encode($response);
|
||||
?>
|
||||
86
imprimir_etiquetas.php
Normal file
86
imprimir_etiquetas.php
Normal file
@ -0,0 +1,86 @@
|
||||
<?php
|
||||
session_start();
|
||||
if (!isset($_SESSION['user_id'])) {
|
||||
header("Location: login.php");
|
||||
exit;
|
||||
}
|
||||
require_once 'db/config.php';
|
||||
|
||||
$product_ids = isset($_POST['product_ids']) ? $_POST['product_ids'] : [];
|
||||
|
||||
if (empty($product_ids)) {
|
||||
echo "No se han seleccionado productos para imprimir.";
|
||||
exit;
|
||||
}
|
||||
|
||||
// Sanitize input
|
||||
$placeholders = implode(',', array_fill(0, count($product_ids), '?'));
|
||||
$stmt = db()->prepare("SELECT id, nombre FROM products WHERE id IN ($placeholders)");
|
||||
foreach ($product_ids as $k => $id) {
|
||||
$stmt->bindValue(($k + 1), $id, PDO::PARAM_INT);
|
||||
}
|
||||
$stmt->execute();
|
||||
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Imprimir Etiquetas de Códigos de Barras</title>
|
||||
<style>
|
||||
@media print {
|
||||
body {
|
||||
-webkit-print-color-adjust: exact;
|
||||
}
|
||||
.no-print {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
.label-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
}
|
||||
.label {
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
.label img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.label .product-name {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.print-button-container {
|
||||
text-align: center;
|
||||
margin: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="print-button-container no-print">
|
||||
<button onclick="window.print();">Imprimir</button>
|
||||
</div>
|
||||
|
||||
<div class="label-grid">
|
||||
<?php foreach ($products as $product): ?>
|
||||
<div class="label">
|
||||
<div class="product-name"><?php echo htmlspecialchars($product['nombre']); ?></div>
|
||||
<img src="https://barcode.tec-it.com/barcode.ashx?data=<?php echo $product['id']; ?>&code=Code128" alt="Barcode for product ID <?php echo $product['id']; ?>">
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -26,5 +26,19 @@
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
const sidebarToggle = document.querySelector('.sidebar-toggle');
|
||||
const sidebar = document.querySelector('.sidebar');
|
||||
const body = document.querySelector('body');
|
||||
|
||||
if (sidebarToggle && sidebar) {
|
||||
sidebarToggle.addEventListener('click', function() {
|
||||
sidebar.classList.toggle('active');
|
||||
body.classList.toggle('sidebar-active');
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -126,6 +126,12 @@ $navItems = [
|
||||
'icon' => 'fa-plus',
|
||||
'text' => 'Agregar Producto',
|
||||
'roles' => ['Administrador', 'admin', 'Control Logistico']
|
||||
],
|
||||
'productos' => [
|
||||
'url' => 'productos.php',
|
||||
'icon' => 'fa-box',
|
||||
'text' => 'Productos',
|
||||
'roles' => ['Administrador', 'admin', 'Control Logistico']
|
||||
]
|
||||
]
|
||||
],
|
||||
@ -202,7 +208,9 @@ $navItems = [
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<button class="sidebar-toggle">
|
||||
<i class="fas fa-bars"></i>
|
||||
</button>
|
||||
<div class="sidebar">
|
||||
<a href="pedidos.php" class="navbar-brand"><h3>FLOOWER CRM</h3></a>
|
||||
<ul class="nav flex-column">
|
||||
|
||||
108
productos.php
108
productos.php
@ -41,48 +41,65 @@ $products = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table id="products-table" class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Nombre</th>
|
||||
<th>SKU</th>
|
||||
<th>Costo</th>
|
||||
<th>Precio Venta</th>
|
||||
<th>Unidades Vendidas</th>
|
||||
<th>Ganancia/Unidad</th>
|
||||
<th>Ingreso Total</th>
|
||||
<th>Ganancia Total</th>
|
||||
<th>Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($products as $product): ?>
|
||||
<tr>
|
||||
<td><?php echo $product['id']; ?></td>
|
||||
<td><?php echo htmlspecialchars($product['nombre']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['sku']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['costo']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['precio_venta']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['unidades_vendidas']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['ganancia_unidad']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['ingreso_total']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['ganancia_total']); ?></td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-info btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Acciones
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="edit_product.php?id=<?php echo $product['id']; ?>">Editar</a>
|
||||
<a class="dropdown-item" href="delete_product.php?id=<?php echo $product['id']; ?>" onclick="return confirm('¿Estás seguro de que quieres eliminar este producto?');">Eliminar</a>
|
||||
<form action="imprimir_etiquetas.php" method="post" target="_blank">
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-success">Imprimir Etiquetas Seleccionadas</button>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table id="products-table" class="table table-bordered table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" id="select-all"></th>
|
||||
<th>ID</th>
|
||||
<th>Código de Barras</th>
|
||||
<th>Nombre</th>
|
||||
<th>SKU</th>
|
||||
<th>Costo</th>
|
||||
<th>Precio Venta</th>
|
||||
<th>Unidades Vendidas</th>
|
||||
<th>Ganancia/Unidad</th>
|
||||
<th>Ingreso Total</th>
|
||||
<th>Ganancia Total</th>
|
||||
<th>Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($products as $product): ?>
|
||||
<tr>
|
||||
<td><input type="checkbox" name="product_ids[]" value="<?php echo $product['id']; ?>"></td>
|
||||
<td><?php echo $product['id']; ?></td>
|
||||
<td>
|
||||
<?php if (!empty($product['id'])): ?>
|
||||
<img src="https://barcode.tec-it.com/barcode.ashx?data=<?php echo $product['id']; ?>&code=Code128" alt="Barcode for product ID <?php echo $product['id']; ?>" style="max-height: 40px;">
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($product['nombre']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['sku']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['costo']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['precio_venta']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['unidades_vendidas']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['ganancia_unidad']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['ingreso_total']); ?></td>
|
||||
<td><?php echo htmlspecialchars($product['ganancia_total']); ?></td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-info btn-sm dropdown-toggle" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
Acciones
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="edit_product.php?id=<?php echo $product['id']; ?>">Editar</a>
|
||||
<a class="dropdown-item" href="delete_product.php?id=<?php echo $product['id']; ?>" onclick="return confirm('¿Estás seguro de que quieres eliminar este producto?');">Eliminar</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -93,6 +110,15 @@ $products = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
<?php require_once 'layout_footer.php'; ?>
|
||||
|
||||
<script>
|
||||
document.getElementById('select-all').addEventListener('click', function(event) {
|
||||
var checkboxes = document.getElementsByName('product_ids[]');
|
||||
for (var checkbox of checkboxes) {
|
||||
checkbox.checked = event.target.checked;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script src="https://cdn.datatables.net/1.11.3/js/jquery.dataTables.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/1.11.3/js/dataTables.bootstrap4.min.js"></script>
|
||||
|
||||
|
||||
@ -98,6 +98,9 @@ try {
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="producto" class="form-label">Producto</label>
|
||||
<button type="button" class="btn btn-info btn-sm float-end" data-bs-toggle="modal" data-bs-target="#scannerModal">
|
||||
<i class="fa fa-camera"></i> Escanear
|
||||
</button>
|
||||
<select class="form-select" id="producto" name="product_id" required>
|
||||
<option value="">Seleccione un producto</option>
|
||||
<?php foreach ($products as $product): ?>
|
||||
@ -130,4 +133,97 @@ try {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once 'layout_footer.php'; ?>
|
||||
<!-- Modal para el Escáner -->
|
||||
<div class="modal fade" id="scannerModal" tabindex="-1" aria-labelledby="scannerModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="scannerModalLabel">Escanear Código de Barras</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="reader" style="width: 100%;"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://unpkg.com/html5-qrcode" type="text/javascript"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
if (typeof bootstrap === 'undefined') {
|
||||
console.error('Bootstrap no está cargado. El modal del escáner no funcionará.');
|
||||
return;
|
||||
}
|
||||
|
||||
const scannerModalElement = document.getElementById('scannerModal');
|
||||
if (!scannerModalElement) {
|
||||
console.error('El elemento del modal del escáner no se encontró.');
|
||||
return;
|
||||
}
|
||||
|
||||
const scannerModal = new bootstrap.Modal(scannerModalElement);
|
||||
const html5QrCode = new Html5Qrcode("reader");
|
||||
|
||||
const qrCodeSuccessCallback = (decodedText, decodedResult) => {
|
||||
html5QrCode.stop().then((ignore) => {
|
||||
console.log("QR Code scanning stopped.");
|
||||
}).catch((err) => {
|
||||
console.error("Failed to stop QR Code scanning.", err);
|
||||
});
|
||||
|
||||
scannerModal.hide();
|
||||
|
||||
fetch(`get_product_details.php?id=${decodedText}`)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success && data.product) {
|
||||
const productSelect = document.getElementById('producto');
|
||||
productSelect.value = data.product.id;
|
||||
|
||||
const productName = data.product.nombre || 'desconocido';
|
||||
alert(`Producto seleccionado: ${productName}`);
|
||||
|
||||
} else {
|
||||
alert('Error: ' + (data.message || 'Producto no encontrado.'));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error al buscar los detalles del producto:', error);
|
||||
alert('Hubo un error al procesar el código de barras. Verifique la consola para más detalles.');
|
||||
});
|
||||
};
|
||||
|
||||
const config = { fps: 10, qrbox: { width: 250, height: 250 } };
|
||||
|
||||
scannerModalElement.addEventListener('shown.bs.modal', function () {
|
||||
html5QrCode.start(
|
||||
{ facingMode: "environment" },
|
||||
config,
|
||||
qrCodeSuccessCallback,
|
||||
(errorMessage) => {
|
||||
// console.log("QR Code no match.", errorMessage);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("No se pudo iniciar el escáner de QR.", err);
|
||||
alert("Error al iniciar la cámara. Asegúrese de dar permisos.");
|
||||
});
|
||||
});
|
||||
|
||||
scannerModalElement.addEventListener('hidden.bs.modal', function () {
|
||||
html5QrCode.stop().catch(err => {
|
||||
// Ignorar error si el escáner ya estaba detenido
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once 'layout_footer.php'; ?>
|
||||
@ -105,6 +105,9 @@ try {
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="producto" class="form-label">Producto</label>
|
||||
<button type="button" class="btn btn-info btn-sm float-end" data-bs-toggle="modal" data-bs-target="#scannerModal">
|
||||
<i class="fa fa-camera"></i> Escanear
|
||||
</button>
|
||||
<select class="form-select" id="producto" name="product_id" required>
|
||||
<option value="">Seleccione un producto</option>
|
||||
<?php foreach ($products as $product): ?>
|
||||
@ -137,4 +140,97 @@ try {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once 'layout_footer.php'; ?>
|
||||
<!-- Modal para el Escáner -->
|
||||
<div class="modal fade" id="scannerModal" tabindex="-1" aria-labelledby="scannerModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="scannerModalLabel">Escanear Código de Barras</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="reader" style="width: 100%;"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cerrar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="https://unpkg.com/html5-qrcode" type="text/javascript"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', (event) => {
|
||||
if (typeof bootstrap === 'undefined') {
|
||||
console.error('Bootstrap no está cargado. El modal del escáner no funcionará.');
|
||||
return;
|
||||
}
|
||||
|
||||
const scannerModalElement = document.getElementById('scannerModal');
|
||||
if (!scannerModalElement) {
|
||||
console.error('El elemento del modal del escáner no se encontró.');
|
||||
return;
|
||||
}
|
||||
|
||||
const scannerModal = new bootstrap.Modal(scannerModalElement);
|
||||
const html5QrCode = new Html5Qrcode("reader");
|
||||
|
||||
const qrCodeSuccessCallback = (decodedText, decodedResult) => {
|
||||
html5QrCode.stop().then((ignore) => {
|
||||
console.log("QR Code scanning stopped.");
|
||||
}).catch((err) => {
|
||||
console.error("Failed to stop QR Code scanning.", err);
|
||||
});
|
||||
|
||||
scannerModal.hide();
|
||||
|
||||
fetch(`get_product_details.php?id=${decodedText}`)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
if (data.success && data.product) {
|
||||
const productSelect = document.getElementById('producto');
|
||||
productSelect.value = data.product.id;
|
||||
|
||||
const productName = data.product.nombre || 'desconocido';
|
||||
alert(`Producto seleccionado: ${productName}`);
|
||||
|
||||
} else {
|
||||
alert('Error: ' + (data.message || 'Producto no encontrado.'));
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error al buscar los detalles del producto:', error);
|
||||
alert('Hubo un error al procesar el código de barras. Verifique la consola para más detalles.');
|
||||
});
|
||||
};
|
||||
|
||||
const config = { fps: 10, qrbox: { width: 250, height: 250 } };
|
||||
|
||||
scannerModalElement.addEventListener('shown.bs.modal', function () {
|
||||
html5QrCode.start(
|
||||
{ facingMode: "environment" },
|
||||
config,
|
||||
qrCodeSuccessCallback,
|
||||
(errorMessage) => {
|
||||
// console.log("QR Code no match.", errorMessage);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error("No se pudo iniciar el escáner de QR.", err);
|
||||
alert("Error al iniciar la cámara. Asegúrese de dar permisos.");
|
||||
});
|
||||
});
|
||||
|
||||
scannerModalElement.addEventListener('hidden.bs.modal', function () {
|
||||
html5QrCode.stop().catch(err => {
|
||||
// Ignorar error si el escáner ya estaba detenido
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php require_once 'layout_footer.php'; ?>
|
||||
Loading…
x
Reference in New Issue
Block a user