34849-vm/kanban.php
2026-02-05 05:37:35 +00:00

197 lines
7.0 KiB
PHP

<?php
session_start();
require_once 'db/config.php';
if (!isset($_SESSION['username'])) {
header("Location: login.php");
exit();
}
$username = $_SESSION['username'];
$role = isset($_SESSION['role']) ? $_SESSION['role'] : '';
// Conectar a la base de datos
$pdo = db();
// 1. Obtener todas las columnas del Kanban
$stmt_cols = $pdo->query("SELECT id, nombre FROM kanban_columns ORDER BY orden, id");
$columns_to_display = $stmt_cols->fetchAll(PDO::FETCH_ASSOC);
// 2. Obtener todos los productos de información, uniéndolos con productos y columnas
$stmt_items = $pdo->query("
SELECT
ip.id,
ip.texto_informativo,
ip.imagen_url,
p.nombre as producto_nombre,
kc.nombre as estado_kanban
FROM
info_productos ip
LEFT JOIN
products p ON ip.producto_id = p.id
LEFT JOIN
kanban_columns kc ON ip.column_id = kc.id
ORDER BY
ip.orden, ip.id
");
$items = $stmt_items->fetchAll(PDO::FETCH_ASSOC);
// 3. Agrupar items por el nombre de la columna (estado_kanban)
$items_by_column = [];
if ($items) {
foreach ($items as $item) {
if (!empty($item['estado_kanban'])) {
$items_by_column[$item['estado_kanban']][] = $item;
}
}
}
$pageTitle = "Kanban de Productos";
$pageDescription = "Tablero Kanban para visualizar la información de los productos.";
include 'layout_header.php';
?>
<div class="container-fluid mt-4">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-3">
<h1><?php echo $pageTitle; ?></h1>
</div>
<p><?php echo $pageDescription; ?></p>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="kanban-board-container">
<div class="kanban-board">
<?php foreach ($columns_to_display as $column): ?>
<div class="kanban-column" data-column-id="<?php echo $column['id']; ?>">
<div class="kanban-column-header">
<h5><?php echo htmlspecialchars($column['nombre']); ?></h5>
</div>
<div class="kanban-column-body">
<?php if (isset($items_by_column[$column['nombre']])): ?>
<?php foreach ($items_by_column[$column['nombre']] as $item): ?>
<div class="kanban-card" data-item-id="<?php echo $item['id']; ?>">
<div class="card-body">
<?php if (!empty($item['imagen_url']) && file_exists($item['imagen_url'])): ?>
<img src="<?php echo htmlspecialchars($item['imagen_url']); ?>" class="card-img-top mb-2" alt="Imagen del producto">
<?php endif; ?>
<h6 class="card-title"><?php echo htmlspecialchars($item['producto_nombre'] ?? 'Producto sin nombre'); ?></h6>
<p class="card-text fs-sm text-muted"><?php echo nl2br(htmlspecialchars($item['texto_informativo'])); ?></p>
<button class="btn btn-sm btn-outline-secondary w-100 mt-2" onclick="copiarTexto(this)">
Copiar Texto
</button>
<div class="texto-a-copiar" style="display:none;"><?php echo htmlspecialchars($item['texto_informativo']); ?></div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
</div>
<style>
.kanban-board-container {
overflow-x: auto;
padding-bottom: 15px;
}
.kanban-board {
display: flex;
gap: 15px;
min-width: max-content;
}
.kanban-column {
width: 300px;
flex-shrink: 0;
background-color: #f4f5f7;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.kanban-column-header {
padding: 12px 15px;
border-bottom: 1px solid #e0e0e0;
background-color: #fff;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
.kanban-column-body {
padding: 10px;
min-height: 200px; /* Altura mínima por si la columna está vacía */
max-height: 70vh; /* Altura máxima del 70% de la pantalla */
overflow-y: auto; /* Scroll vertical si el contenido excede la altura */
}
.kanban-card {
background-color: #fff;
border: 1px solid #ddd;
border-radius: 6px;
padding: 15px;
margin-bottom: 10px;
cursor: grab;
transition: box-shadow 0.2s ease;
}
.kanban-card:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
.card-title {
font-weight: 600;
margin-bottom: 0; /* Ajustado para dar espacio al botón */
}
</style>
<script>
function copiarTexto(button) {
const cardBody = button.closest('.card-body');
const texto = cardBody.querySelector('.texto-a-copiar').innerText;
const originalText = button.innerHTML;
navigator.clipboard.writeText(texto).then(() => {
button.innerHTML = '<i class="fas fa-check"></i> Copiado!';
button.classList.remove('btn-outline-secondary');
button.classList.add('btn-success');
setTimeout(() => {
button.innerHTML = originalText;
button.classList.remove('btn-success');
button.classList.add('btn-outline-secondary');
}, 2000);
}).catch(err => {
console.error('Error al copiar texto: ', err);
const tempInput = document.createElement('textarea');
tempInput.style.position = 'absolute';
tempInput.style.left = '-9999px';
tempInput.value = texto;
document.body.appendChild(tempInput);
tempInput.select();
try {
document.execCommand('copy');
button.innerHTML = '<i class="fas fa-check"></i> Copiado!';
button.classList.remove('btn-outline-secondary');
button.classList.add('btn-success');
setTimeout(() => {
button.innerHTML = originalText;
button.classList.remove('btn-success');
button.classList.add('btn-outline-secondary');
}, 2000);
} catch (e) {
alert('No se pudo copiar el texto.');
}
document.body.removeChild(tempInput);
});
}
</script>
<?php include 'layout_footer.php'; ?>