34786-vm/index.php
2025-12-12 16:33:10 +00:00

259 lines
11 KiB
PHP

<?php
$page_title = 'Panel de Control';
require_once __DIR__ . '/includes/header.php';
require_once __DIR__ . '/db/config.php';
// Proteger la página: si el usuario no ha iniciado sesión, redirigir a login
if (!is_logged_in()) {
header('Location: /auth/login.php');
exit();
}
// Obtener el número total de productos
$pdo = db();
$stmt = $pdo->query("SELECT COUNT(*) FROM productos");
$total_products = $stmt->fetchColumn();
// Obtener stock por ciudad y producto, ordenando las ciudades por stock total
$stock_stmt = $pdo->query("
SELECT
c.nombre AS ciudad,
p.nombre AS producto,
s.stock_actual
FROM
stock_por_ciudad s
JOIN
ciudades c ON s.ciudad_id = c.id
JOIN
productos p ON s.producto_id = p.id
JOIN
(SELECT ciudad_id, SUM(stock_actual) as total_stock FROM stock_por_ciudad GROUP BY ciudad_id) as stock_totales
ON c.id = stock_totales.ciudad_id
WHERE
s.stock_actual > 0
ORDER BY
stock_totales.total_stock DESC, p.nombre;
");
$stock_data = $stock_stmt->fetchAll(PDO::FETCH_ASSOC);
// Agrupar por ciudad
$stock_por_ciudad = [];
foreach ($stock_data as $row) {
$stock_por_ciudad[$row['ciudad']][] = [
'producto' => $row['producto'],
'stock' => $row['stock_actual']
];
}
?>
<div class="container-fluid">
<!-- Mensaje de Bienvenida -->
<div class="row mb-4">
<div class="col-12 text-center">
<h1 class="welcome-title">Bienvenido a tu Panel de Control</h1>
<p class="welcome-subtitle">Aquí tienes un resumen de tu aplicación.</p>
</div>
</div>
<div class="row justify-content-center">
<!-- Tarjeta de Total de Productos -->
<div class="col-md-6 col-lg-4 mb-4">
<div class="card info-card h-100">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="icon-circle">
<!-- Icono de Caja (Productos) -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-box"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path><polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline><line x1="12" y1="22.08" x2="12" y2="12"></line></svg>
</div>
<div class="ms-3">
<h5 class="card-title">Total de Productos</h5>
<p class="card-text"><?php echo $total_products; ?></p>
</div>
</div>
</div>
</div>
</div>
<!-- Tarjeta de Acceso a Productos -->
<div class="col-md-6 col-lg-4 mb-4">
<a href="productos.php" class="card-link">
<div class="card info-card h-100">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="icon-circle">
<!-- Icono de Tareas (Administrar) -->
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-settings"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
</div>
<div class="ms-3">
<h5 class="card-title">Administrar Productos</h5>
<p class="card-text">Ir a la lista de productos</p>
</div>
</div>
</div>
</div>
</a>
</div>
<!-- Tarjeta de Gráfico de Stock -->
<div class="col-md-12 col-lg-4 mb-4">
<div class="card info-card h-100">
<div class="card-body">
<h5 class="card-title text-center">Distribución de Stock</h5>
<div style="height: 300px;">
<canvas id="stockChart"></canvas>
</div>
</div>
</div>
</div>
</div>
<div class="row justify-content-center">
<!-- Tarjeta de Stock por Ciudad y Producto -->
<div class="col-md-12 col-lg-8 mb-4">
<div class="card info-card h-100">
<div class="card-body">
<h5 class="card-title">Stock por Ciudad y Producto</h5>
<div class="accordion" id="stockAccordion">
<?php if (empty($stock_por_ciudad)): ?>
<p class="text-center mt-3">No hay datos de stock disponibles.</p>
<?php else: ?>
<?php
$i = 0;
foreach ($stock_por_ciudad as $ciudad => $productos):
$ciudad_id = 'ciudad_' . $i++;
?>
<div class="accordion-item">
<h2 class="accordion-header" id="heading-<?php echo $ciudad_id; ?>">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapse-<?php echo $ciudad_id; ?>" aria-expanded="false" aria-controls="collapse-<?php echo $ciudad_id; ?>">
<?php echo htmlspecialchars($ciudad); ?>
</button>
</h2>
<div id="collapse-<?php echo $ciudad_id; ?>" class="accordion-collapse collapse" aria-labelledby="heading-<?php echo $ciudad_id; ?>" data-bs-parent="#stockAccordion">
<div class="accordion-body">
<div class="table-responsive">
<table class="table table-sm table-hover">
<thead>
<tr>
<th>Producto</th>
<th>Stock</th>
</tr>
</thead>
<tbody>
<?php foreach ($productos as $producto): ?>
<tr>
<td><?php echo htmlspecialchars($producto['producto']); ?></td>
<td><?php echo htmlspecialchars($producto['stock']); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php
// Preparar datos para el gráfico
$chart_labels = [];
$chart_data = [];
$chart_bg_colors = []; // Array para los colores de fondo
$chart_border_colors = []; // Array para los colores de borde
// Paleta de colores (puedes añadir más si tienes muchas ciudades)
$color_palette_bg = [
'rgba(54, 162, 235, 0.8)', // Azul
'rgba(255, 206, 86, 0.8)', // Amarillo
'rgba(75, 192, 192, 0.8)', // Turquesa
'rgba(153, 102, 255, 0.8)',// Morado
'rgba(255, 99, 132, 0.8)', // Rojo
'rgba(255, 159, 64, 0.8)' // Naranja
];
$color_palette_border = [
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 99, 132, 1)',
'rgba(255, 159, 64, 1)'
];
// Asignar verde a Lima
$city_color_map = [
'Lima' => [
'bg' => 'rgba(40, 167, 69, 0.8)', // Verde fondo
'border' => 'rgba(40, 167, 69, 1)' // Verde borde
]
];
if (!empty($stock_por_ciudad)) {
$color_index = 0;
foreach ($stock_por_ciudad as $ciudad => $productos) {
$chart_labels[] = $ciudad;
// Asignar color
if (isset($city_color_map[$ciudad])) {
$chart_bg_colors[] = $city_color_map[$ciudad]['bg'];
$chart_border_colors[] = $city_color_map[$ciudad]['border'];
} else {
// Asignar un color de la paleta
$chart_bg_colors[] = $color_palette_bg[$color_index % count($color_palette_bg)];
$chart_border_colors[] = $color_palette_border[$color_index % count($color_palette_border)];
$color_index++;
}
$total_stock = 0;
foreach ($productos as $producto) {
$total_stock += $producto['stock'];
}
$chart_data[] = $total_stock;
}
}
?>
<script>
document.addEventListener('DOMContentLoaded', function () {
const ctx = document.getElementById('stockChart');
if (ctx && <?php echo json_encode(!empty($chart_data)); ?>) {
new Chart(ctx, {
type: 'pie',
data: {
labels: <?php echo json_encode($chart_labels); ?>,
datasets: [{
label: 'Stock Total',
data: <?php echo json_encode($chart_data); ?>,
backgroundColor: <?php echo json_encode($chart_bg_colors); ?>,
borderColor: <?php echo json_encode($chart_border_colors); ?>,
borderWidth: 1
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom',
},
title: {
display: false,
}
}
}
});
} else if (ctx) {
ctx.getContext('2d').fillText("No hay datos de stock para mostrar.", ctx.width / 2 - 50, ctx.height / 2);
}
});
</script>
<?php
require_once __DIR__ . '/includes/footer.php';
?>