197 lines
7.0 KiB
PHP
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'; ?>
|