Autosave: 20260205-053735
@ -1,21 +1,65 @@
|
||||
<?php
|
||||
$pageTitle = "Añadir Nueva Columna al Kanban";
|
||||
require_once 'layout_header.php';
|
||||
require_once 'db/config.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$nombre = trim($_POST['nombre']);
|
||||
|
||||
if (!empty($nombre)) {
|
||||
$pdo = db();
|
||||
|
||||
// Find the current max order value
|
||||
$stmt_max_order = $pdo->query('SELECT MAX(orden) AS max_orden FROM kanban_columns');
|
||||
$max_orden = $stmt_max_order->fetchColumn();
|
||||
$new_orden = $max_orden + 1;
|
||||
|
||||
$stmt = $pdo->prepare('INSERT INTO kanban_columns (nombre, orden) VALUES (?, ?)');
|
||||
$stmt->execute([$nombre, $new_orden]);
|
||||
}
|
||||
// Asegurarse de que el usuario sea administrador
|
||||
if ($_SESSION['user_role'] !== 'Administrador' && $_SESSION['user_role'] !== 'admin') {
|
||||
echo "<div class='alert alert-danger'>Acceso denegado.</div>";
|
||||
require_once 'layout_footer.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
header('Location: kanban.php');
|
||||
exit;
|
||||
$message = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$nombre = trim($_POST['nombre'] ?? '');
|
||||
|
||||
if (!empty($nombre)) {
|
||||
try {
|
||||
$pdo = db();
|
||||
|
||||
// Find the current max order value
|
||||
$stmt_max_order = $pdo->query('SELECT MAX(orden) AS max_orden FROM kanban_columns');
|
||||
$max_orden = $stmt_max_order->fetchColumn();
|
||||
$new_orden = ($max_orden === null) ? 0 : $max_orden + 1;
|
||||
|
||||
$stmt = $pdo->prepare('INSERT INTO kanban_columns (nombre, orden) VALUES (?, ?)');
|
||||
|
||||
if ($stmt->execute([$nombre, $new_orden])) {
|
||||
// Usar una variable de sesión para mostrar el mensaje en la página de configuración
|
||||
$_SESSION['success_message'] = "Columna '" . htmlspecialchars($nombre) . "' añadida correctamente.";
|
||||
header('Location: configuracion.php');
|
||||
exit;
|
||||
} else {
|
||||
$message = "<div class='alert alert-danger'>Error al añadir la columna.</div>";
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
$message = "<div class='alert alert-danger'>Error de base de datos: " . $e->getMessage() . "</div>";
|
||||
}
|
||||
} else {
|
||||
$message = "<div class='alert alert-warning'>El nombre de la columna no puede estar vacío.</div>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2>Añadir Nueva Columna al Kanban</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php echo $message; ?>
|
||||
<form method="POST" action="add_column.php">
|
||||
<div class="mb-3">
|
||||
<label for="nombre" class="form-label">Nombre de la Nueva Columna</label>
|
||||
<input type="text" class="form-control" id="nombre" name="nombre" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Guardar Columna</button>
|
||||
<a href="configuracion.php" class="btn btn-secondary">Cancelar</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once 'layout_footer.php'; ?>
|
||||
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 144 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 119 KiB |
@ -12,63 +12,119 @@ if ($_SESSION['user_role'] !== 'Administrador' && $_SESSION['user_role'] !== 'ad
|
||||
|
||||
$conn = db();
|
||||
|
||||
// Obtener la configuración actual
|
||||
$query = "SELECT * FROM configuracion WHERE id = 1";
|
||||
$result = $conn->query($query);
|
||||
$config = $result->fetch(PDO::FETCH_ASSOC);
|
||||
// --- Gestión de Columnas ---
|
||||
|
||||
// Columnas disponibles
|
||||
$available_columns = [
|
||||
'new' => 'Nuevos',
|
||||
'reagendado' => 'Reagendado',
|
||||
'no_contactado' => 'No Contactado',
|
||||
'contactado' => 'Contactado',
|
||||
'agendado' => 'Agendado',
|
||||
'en_ruta' => 'En Ruta',
|
||||
'entregado' => 'Entregado',
|
||||
'no_entregado' => 'No Entregado',
|
||||
'reprogramado' => 'Reprogramado'
|
||||
];
|
||||
// Obtener todas las columnas del Kanban para la tabla de gestión
|
||||
$query_manage_columns = "SELECT * FROM kanban_columns ORDER BY orden ASC";
|
||||
$stmt_manage_columns = $conn->query($query_manage_columns);
|
||||
$management_columns = $stmt_manage_columns->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
|
||||
// --- Visibilidad de Columnas ---
|
||||
|
||||
// Obtener la configuración actual de visibilidad
|
||||
$query_config = "SELECT * FROM configuracion WHERE id = 1";
|
||||
$result_config = $conn->query($query_config);
|
||||
$config = $result_config->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$visible_columns = $config ? json_decode($config['kanban_columns'], true) : [];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_visibility'])) {
|
||||
$new_visible_columns = $_POST['columns'] ?? [];
|
||||
$json_columns = json_encode($new_visible_columns);
|
||||
|
||||
$update_query = "UPDATE configuracion SET kanban_columns = :kanban_columns WHERE id = 1";
|
||||
// Usar INSERT ... ON DUPLICATE KEY UPDATE para seguridad
|
||||
$update_query = "INSERT INTO configuracion (id, kanban_columns) VALUES (1, :kanban_columns)
|
||||
ON DUPLICATE KEY UPDATE kanban_columns = :kanban_columns";
|
||||
$stmt = $conn->prepare($update_query);
|
||||
$stmt->bindParam(':kanban_columns', $json_columns);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo "<div class='alert alert-success'>Configuración guardada correctamente.</div>";
|
||||
$visible_columns = $new_visible_columns;
|
||||
echo "<div class='alert alert-success'>Configuración de visibilidad guardada.</div>";
|
||||
$visible_columns = $new_visible_columns; // Actualizar para mostrar el cambio inmediatamente
|
||||
} else {
|
||||
echo "<div class='alert alert-danger'>Error al guardar la configuración.</div>";
|
||||
echo "<div class='alert alert-danger'>Error al guardar la configuración de visibilidad.</div>";
|
||||
}
|
||||
}
|
||||
|
||||
// Obtener todas las columnas de kanban_columns para el formulario de visibilidad
|
||||
$all_db_columns_query = "SELECT nombre FROM kanban_columns ORDER BY orden ASC";
|
||||
$stmt_all_db_columns = $conn->query($all_db_columns_query);
|
||||
$available_columns_for_visibility = $stmt_all_db_columns->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
?>
|
||||
|
||||
<div class="container mt-5">
|
||||
<h2>Configuración de Columnas del Kanban</h2>
|
||||
<p>Selecciona las columnas que deseas que sean visibles en el tablero Kanban.</p>
|
||||
|
||||
<form method="POST">
|
||||
<div class="row">
|
||||
<?php foreach ($available_columns as $key => $name): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="columns[]" value="<?php echo $key; ?>" id="col_<?php echo $key; ?>" <?php echo in_array($key, $visible_columns) ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="col_<?php echo $key; ?>">
|
||||
<?php echo htmlspecialchars($name); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<!-- Sección para Gestionar Columnas (Añadir, Editar, Eliminar) -->
|
||||
<div class="card mb-5">
|
||||
<div class="card-header">
|
||||
<h3>Gestionar Columnas del Kanban</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Aquí puedes añadir, editar y eliminar las columnas que se usarán en el tablero Kanban.</p>
|
||||
<a href="add_column.php" class="btn btn-success mb-3">
|
||||
<i class="fas fa-plus"></i> Añadir Nueva Columna
|
||||
</a>
|
||||
|
||||
<table class="table table-bordered table-striped">
|
||||
<thead class="table-dark">
|
||||
<tr>
|
||||
<th>Nombre de la Columna</th>
|
||||
<th style="width: 150px;">Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($management_columns)): ?>
|
||||
<tr>
|
||||
<td colspan="2" class="text-center">No hay columnas definidas.</td>
|
||||
</tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($management_columns as $column): ?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($column['nombre']); ?></td>
|
||||
<td>
|
||||
<a href="edit_column.php?id=<?php echo $column['id']; ?>" class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-edit"></i> Editar
|
||||
</a>
|
||||
<a href="delete_column.php?id=<?php echo $column['id']; ?>" class="btn btn-danger btn-sm" onclick="return confirm('¿Estás seguro de que quieres eliminar esta columna?');">
|
||||
<i class="fas fa-trash"></i> Eliminar
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary mt-3">Guardar Configuración</button>
|
||||
</form>
|
||||
<!-- Sección para Configurar Visibilidad de Columnas -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3>Configurar Visibilidad de Columnas</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Selecciona las columnas que deseas que sean visibles en el tablero Kanban.</p>
|
||||
<form method="POST">
|
||||
<input type="hidden" name="save_visibility" value="1">
|
||||
<div class="row">
|
||||
<?php foreach ($available_columns_for_visibility as $column_name): ?>
|
||||
<div class="col-md-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="columns[]" value="<?php echo htmlspecialchars($column_name); ?>" id="col_<?php echo htmlspecialchars($column_name); ?>" <?php echo in_array($column_name, $visible_columns) ? 'checked' : ''; ?>>
|
||||
<label class="form-check-label" for="col_<?php echo htmlspecialchars($column_name); ?>">
|
||||
<?php echo htmlspecialchars($column_name); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary mt-3">Guardar Visibilidad</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once 'layout_footer.php'; ?>
|
||||
<?php require_once 'layout_footer.php'; ?>
|
||||
|
||||
@ -1,21 +1,45 @@
|
||||
<?php
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$id = $_POST['id'];
|
||||
// Asegurarse de que el usuario sea administrador
|
||||
if ($_SESSION['user_role'] !== 'Administrador' && $_SESSION['user_role'] !== 'admin') {
|
||||
$_SESSION['error_message'] = "Acceso denegado.";
|
||||
header('Location: configuracion.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!empty($id)) {
|
||||
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
|
||||
$id = $_GET['id'];
|
||||
|
||||
try {
|
||||
$pdo = db();
|
||||
|
||||
// First, update info_productos to set column_id to NULL for the cards in the deleted column
|
||||
// Opcional: Obtener el nombre de la columna antes de eliminarla para el mensaje
|
||||
$stmt_name = $pdo->prepare("SELECT nombre FROM kanban_columns WHERE id = ?");
|
||||
$stmt_name->execute([$id]);
|
||||
$column_name = $stmt_name->fetchColumn();
|
||||
|
||||
// Primero, actualiza info_productos para desasociar las tarjetas de la columna
|
||||
$stmt_update = $pdo->prepare('UPDATE info_productos SET column_id = NULL WHERE column_id = ?');
|
||||
$stmt_update->execute([$id]);
|
||||
|
||||
// Then, delete the column
|
||||
// Luego, elimina la columna
|
||||
$stmt_delete = $pdo->prepare('DELETE FROM kanban_columns WHERE id = ?');
|
||||
$stmt_delete->execute([$id]);
|
||||
|
||||
if ($stmt_delete->execute([$id])) {
|
||||
$_SESSION['success_message'] = "Columna '" . htmlspecialchars($column_name) . "' eliminada correctamente.";
|
||||
} else {
|
||||
$_SESSION['error_message'] = "Error al eliminar la columna.";
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$_SESSION['error_message'] = "Error de base de datos: " . $e->getMessage();
|
||||
}
|
||||
} else {
|
||||
$_SESSION['error_message'] = "ID de columna no válido.";
|
||||
}
|
||||
|
||||
header('Location: kanban.php');
|
||||
header('Location: configuracion.php');
|
||||
exit;
|
||||
?>
|
||||
@ -1,18 +1,82 @@
|
||||
<?php
|
||||
session_start();
|
||||
$pageTitle = "Editar Columna del Kanban";
|
||||
require_once 'layout_header.php';
|
||||
require_once 'db/config.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['id'])) {
|
||||
$id = $_POST['id'];
|
||||
$nombre = $_POST['nombre'];
|
||||
// Asegurarse de que el usuario sea administrador
|
||||
if ($_SESSION['user_role'] !== 'Administrador' && $_SESSION['user_role'] !== 'admin') {
|
||||
echo "<div class='alert alert-danger'>Acceso denegado.</div>";
|
||||
require_once 'layout_footer.php';
|
||||
exit();
|
||||
}
|
||||
|
||||
$db = db();
|
||||
$stmt = $db->prepare("UPDATE kanban_columns SET name = ? WHERE id = ?");
|
||||
$stmt->bind_param('si', $nombre, $id);
|
||||
$stmt->execute();
|
||||
$message = '';
|
||||
$column = null;
|
||||
|
||||
$_SESSION['success_message'] = "Columna actualizada exitosamente.";
|
||||
header('Location: info_producto.php');
|
||||
if (!isset($_GET['id']) || !is_numeric($_GET['id'])) {
|
||||
header('Location: configuracion.php');
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
$column_id = $_GET['id'];
|
||||
|
||||
try {
|
||||
$pdo = db();
|
||||
|
||||
// Procesar el formulario cuando se envía
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$nombre = trim($_POST['nombre'] ?? '');
|
||||
|
||||
if (!empty($nombre)) {
|
||||
$stmt = $pdo->prepare('UPDATE kanban_columns SET nombre = ? WHERE id = ?');
|
||||
if ($stmt->execute([$nombre, $column_id])) {
|
||||
$_SESSION['success_message'] = "Columna actualizada a '" . htmlspecialchars($nombre) . "'.";
|
||||
header('Location: configuracion.php');
|
||||
exit;
|
||||
} else {
|
||||
$message = "<div class='alert alert-danger'>Error al actualizar la columna.</div>";
|
||||
}
|
||||
} else {
|
||||
$message = "<div class='alert alert-warning'>El nombre de la columna no puede estar vacío.</div>";
|
||||
}
|
||||
}
|
||||
|
||||
// Obtener los datos de la columna para mostrar en el formulario
|
||||
$stmt = $pdo->prepare('SELECT * FROM kanban_columns WHERE id = ?');
|
||||
$stmt->execute([$column_id]);
|
||||
$column = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$column) {
|
||||
echo "<div class='alert alert-danger'>La columna no existe.</div>";
|
||||
require_once 'layout_footer.php';
|
||||
exit;
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$message = "<div class='alert alert-danger'>Error de base de datos: " . $e->getMessage() . "</div>";
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h2>Editar Columna del Kanban</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php echo $message; ?>
|
||||
<?php if ($column): ?>
|
||||
<form method="POST" action="edit_column.php?id=<?php echo $column_id; ?>">
|
||||
<div class="mb-3">
|
||||
<label for="nombre" class="form-label">Nombre de la Columna</label>
|
||||
<input type="text" class="form-control" id="nombre" name="nombre" value="<?php echo htmlspecialchars($column['nombre']); ?>" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Actualizar Columna</button>
|
||||
<a href="configuracion.php" class="btn btn-secondary">Cancelar</a>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php require_once 'layout_footer.php'; ?>
|
||||
|
||||
160
kanban.php
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
session_start();
|
||||
require_once 'db/config.php';
|
||||
|
||||
@ -8,35 +9,44 @@ if (!isset($_SESSION['username'])) {
|
||||
}
|
||||
|
||||
$username = $_SESSION['username'];
|
||||
$role = $_SESSION['role'];
|
||||
$role = isset($_SESSION['role']) ? $_SESSION['role'] : '';
|
||||
|
||||
// Conectar a la base de datos
|
||||
$pdo = db();
|
||||
|
||||
// Obtener la configuración de las columnas del Kanban
|
||||
$stmt = $pdo->query("SELECT kanban_columns FROM configuracion WHERE id = 1");
|
||||
$config = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
// 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);
|
||||
|
||||
$columns_to_display = [];
|
||||
if ($config && !empty($config['kanban_columns'])) {
|
||||
$column_ids = json_decode($config['kanban_columns'], true);
|
||||
if (!empty($column_ids)) {
|
||||
$placeholders = implode(',', array_fill(0, count($column_ids), '?'));
|
||||
$stmt = $pdo->prepare("SELECT id, nombre FROM kanban_columns WHERE id IN ($placeholders)");
|
||||
$stmt->execute($column_ids);
|
||||
$columns_to_display = $stmt->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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($columns_to_display)) {
|
||||
$stmt = $pdo->query("SELECT id, nombre FROM kanban_columns");
|
||||
$columns_to_display = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
// Obtener todos los productos de información
|
||||
$stmt = $pdo->query("SELECT ip.*, p.nombre as producto_nombre FROM info_productos ip LEFT JOIN products p ON ip.product_id = p.id");
|
||||
$items = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$pageTitle = "Kanban de Productos";
|
||||
$pageDescription = "Tablero Kanban para visualizar la información de los productos.";
|
||||
|
||||
@ -58,26 +68,31 @@ include 'layout_header.php';
|
||||
<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['nombre']; ?>">
|
||||
<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 foreach ($items as $item): ?>
|
||||
<?php if ($item['estado_kanban'] == $column['nombre']): ?>
|
||||
<?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'])): ?>
|
||||
<img src="assets/uploads/info_images/<?php echo htmlspecialchars($item['imagen']); ?>" class="card-img-top mb-2" alt="Imagen del producto">
|
||||
<?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['titulo']); ?></h6>
|
||||
<p class="card-text small"><?php echo htmlspecialchars($item['producto_nombre']); ?></p>
|
||||
<button class="btn btn-sm btn-secondary" onclick="copiarTexto(this)">Copiar Texto</button>
|
||||
<div class="texto-a-copiar" style="display:none;"><?php echo htmlspecialchars($item['texto']); ?></div>
|
||||
|
||||
<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 endif; ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
@ -101,45 +116,80 @@ include 'layout_header.php';
|
||||
width: 300px;
|
||||
flex-shrink: 0;
|
||||
background-color: #f4f5f7;
|
||||
border-radius: 3px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
}
|
||||
.kanban-column-header {
|
||||
padding: 10px 15px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
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: 400px;
|
||||
overflow-y: auto;
|
||||
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: 3px;
|
||||
padding: 10px;
|
||||
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) {
|
||||
var cardBody = button.closest('.card-body');
|
||||
var texto = cardBody.querySelector('.texto-a-copiar').innerText;
|
||||
|
||||
var tempInput = document.createElement('textarea');
|
||||
tempInput.style.position = 'absolute';
|
||||
tempInput.style.left = '-9999px';
|
||||
tempInput.value = texto;
|
||||
document.body.appendChild(tempInput);
|
||||
tempInput.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(tempInput);
|
||||
|
||||
button.innerText = 'Copiado!';
|
||||
setTimeout(function() {
|
||||
button.innerText = 'Copiar Texto';
|
||||
}, 2000);
|
||||
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>
|
||||
|
||||
|
||||