Autosave: 20260203-020543
This commit is contained in:
parent
bdc6e40a34
commit
6995544f62
@ -215,4 +215,34 @@ h1, .h1 {
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
overflow: hidden; /* This is important to make border-radius work on tables */
|
overflow: hidden; /* This is important to make border-radius work on tables */
|
||||||
border: 1px solid #dee2e6;
|
border: 1px solid #dee2e6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Submenu Styles */
|
||||||
|
.sidebar .submenu {
|
||||||
|
display: none;
|
||||||
|
list-style: none;
|
||||||
|
padding-left: 20px;
|
||||||
|
background-color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Show submenu when it has .show class or its parent .has-submenu is active */
|
||||||
|
.sidebar .submenu.show,
|
||||||
|
.sidebar .nav-item.has-submenu.active > .submenu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep the submenu open when the parent has the 'open' class (for JS toggle) */
|
||||||
|
.sidebar .nav-item.open > .submenu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .submenu .nav-link {
|
||||||
|
padding-left: 35px;
|
||||||
|
color: #bdc3c7; /* Match main link color */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Style for the active link within the submenu */
|
||||||
|
.sidebar .submenu .nav-link.active {
|
||||||
|
color: #fff; /* White color for active sub-item */
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,9 +1,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
|
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
|
||||||
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
|
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
|
||||||
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
|
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
var hasSubmenu = document.querySelectorAll(".has-submenu > a");
|
||||||
|
for (var i = 0; i < hasSubmenu.length; i++) {
|
||||||
|
hasSubmenu[i].addEventListener("click", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var parent = this.parentElement;
|
||||||
|
if (parent.classList.contains("open")) {
|
||||||
|
parent.classList.remove("open");
|
||||||
|
} else {
|
||||||
|
// Close other open submenus
|
||||||
|
var openSubmenus = document.querySelectorAll(".has-submenu.open");
|
||||||
|
for (var j = 0; j < openSubmenus.length; j++) {
|
||||||
|
openSubmenus[j].classList.remove("open");
|
||||||
|
}
|
||||||
|
parent.classList.add("open");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@ -80,23 +80,30 @@ $navItems = [
|
|||||||
'text' => 'Gestionar Productos',
|
'text' => 'Gestionar Productos',
|
||||||
'roles' => ['Administrador', 'admin']
|
'roles' => ['Administrador', 'admin']
|
||||||
],
|
],
|
||||||
'finanzas' => [
|
'finanzas_group' => [
|
||||||
'url' => 'finanzas.php',
|
|
||||||
'icon' => 'fa-dollar-sign',
|
'icon' => 'fa-dollar-sign',
|
||||||
'text' => 'Finanzas',
|
'text' => 'Finanzas',
|
||||||
'roles' => ['Administrador', 'admin']
|
'roles' => ['Administrador', 'admin'],
|
||||||
],
|
'submenu' => [
|
||||||
'recaudo_esperado' => [
|
'finanzas' => [
|
||||||
'url' => 'recaudo_esperado.php',
|
'url' => 'finanzas.php',
|
||||||
'icon' => 'fa-chart-line',
|
'icon' => 'fa-dollar-sign',
|
||||||
'text' => 'Recaudo Esperado',
|
'text' => 'Finanzas',
|
||||||
'roles' => ['Administrador', 'admin']
|
'roles' => ['Administrador', 'admin']
|
||||||
],
|
],
|
||||||
'rentabilidad' => [
|
'recaudo_esperado' => [
|
||||||
'url' => 'rentabilidad.php',
|
'url' => 'recaudo_esperado.php',
|
||||||
'icon' => 'fa-chart-pie',
|
'icon' => 'fa-chart-line',
|
||||||
'text' => 'Rentabilidad de Producto',
|
'text' => 'Recaudo Esperado',
|
||||||
'roles' => ['Administrador', 'admin']
|
'roles' => ['Administrador', 'admin']
|
||||||
|
],
|
||||||
|
'rentabilidad' => [
|
||||||
|
'url' => 'rentabilidad.php',
|
||||||
|
'icon' => 'fa-chart-pie',
|
||||||
|
'text' => 'Rentabilidad de Producto',
|
||||||
|
'roles' => ['Administrador', 'admin']
|
||||||
|
],
|
||||||
|
]
|
||||||
],
|
],
|
||||||
'info_producto' => [
|
'info_producto' => [
|
||||||
'url' => 'info_producto.php',
|
'url' => 'info_producto.php',
|
||||||
@ -150,13 +157,45 @@ $navItems = [
|
|||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<a href="pedidos.php" class="navbar-brand"><h3>FLOOWER CRM</h3></a>
|
<a href="pedidos.php" class="navbar-brand"><h3>FLOOWER CRM</h3></a>
|
||||||
<ul class="nav flex-column">
|
<ul class="nav flex-column">
|
||||||
<?php foreach ($navItems as $key => $item): ?>
|
<?php
|
||||||
<?php if (in_array($userRole, $item['roles'])): ?>
|
$currentPage = basename($_SERVER['PHP_SELF']);
|
||||||
<li class="nav-item">
|
|
||||||
<a href="<?php echo $item['url']; ?>" class="nav-link"><i class="fas <?php echo $item['icon']; ?>"></i> <?php echo $item['text']; ?></a>
|
foreach ($navItems as $key => $item):
|
||||||
</li>
|
if (in_array($userRole, $item['roles'])):
|
||||||
<?php endif; ?>
|
if (isset($item['submenu'])):
|
||||||
<?php endforeach; ?>
|
$isSubmenuActive = false;
|
||||||
|
foreach ($item['submenu'] as $sub_item) {
|
||||||
|
if ($currentPage == $sub_item['url']) {
|
||||||
|
$isSubmenuActive = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<li class="nav-item has-submenu <?php echo $isSubmenuActive ? 'active' : ''; ?>">
|
||||||
|
<a href="#" class="nav-link"><i class="fas <?php echo $item['icon']; ?>"></i> <?php echo $item['text']; ?></a>
|
||||||
|
<ul class="submenu <?php echo $isSubmenuActive ? 'show' : ''; ?>">
|
||||||
|
<?php foreach ($item['submenu'] as $sub_item):
|
||||||
|
if (in_array($userRole, $sub_item['roles'])):
|
||||||
|
$isActive = $currentPage == $sub_item['url'] ? 'active' : '';
|
||||||
|
?>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="<?php echo $sub_item['url']; ?>" class="nav-link <?php echo $isActive; ?>"><i class="fas <?php echo $sub_item['icon']; ?>"></i> <?php echo $sub_item['text']; ?></a>
|
||||||
|
</li>
|
||||||
|
<?php
|
||||||
|
endif;
|
||||||
|
endforeach; ?>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<?php else:
|
||||||
|
$isActive = $currentPage == $item['url'] ? 'active' : '';
|
||||||
|
?>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="<?php echo $item['url']; ?>" class="nav-link <?php echo $isActive; ?>"><i class="fas <?php echo $item['icon']; ?>"></i> <?php echo $item['text']; ?></a>
|
||||||
|
</li>
|
||||||
|
<?php endif;
|
||||||
|
endif;
|
||||||
|
endforeach;
|
||||||
|
?>
|
||||||
<li class="nav-item mt-auto">
|
<li class="nav-item mt-auto">
|
||||||
<a href="logout.php" class="nav-link"><i class="fas fa-sign-out-alt"></i> Cerrar Sesión</a>
|
<a href="logout.php" class="nav-link"><i class="fas fa-sign-out-alt"></i> Cerrar Sesión</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@ -28,7 +28,109 @@ $where_clause = '';
|
|||||||
$params = [];
|
$params = [];
|
||||||
|
|
||||||
if ($fecha_inicio_obj && $fecha_fin_obj) {
|
if ($fecha_inicio_obj && $fecha_fin_obj) {
|
||||||
$where_clause = ' WHERE p.created_at BETWEEN ? AND ?';
|
$where_conditions = ["p.estado = 'Completado'", "p.estado_pago = 'Pendiente'"];
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
if ($fecha_inicio_obj && $fecha_fin_obj) {
|
||||||
|
$where_conditions[] = 'p.created_at BETWEEN ? AND ?';
|
||||||
|
$params[] = $fecha_inicio_obj->format('Y-m-d 00:00:00');
|
||||||
|
$params[] = $fecha_fin_obj->format('Y-m-d 23:59:59');
|
||||||
|
}
|
||||||
|
|
||||||
|
$where_clause = ' WHERE ' . implode(' AND ', $where_conditions);
|
||||||
|
|
||||||
|
|
||||||
|
// --- RECAUDO ESPERADO POR ASESORA --
|
||||||
|
$asesoras_recuado = [];
|
||||||
|
try {
|
||||||
|
$sql_asesoras = "
|
||||||
|
SELECT
|
||||||
|
u.nombre_asesor AS asesora_nombre,
|
||||||
|
SUM(p.monto_total) AS monto_total,
|
||||||
|
COUNT(p.id) AS cantidad_pedidos
|
||||||
|
FROM users u
|
||||||
|
JOIN pedidos p ON u.id = p.asesor_id
|
||||||
|
{$where_clause}
|
||||||
|
GROUP BY u.id, u.nombre_asesor
|
||||||
|
ORDER BY monto_total DESC
|
||||||
|
";
|
||||||
|
|
||||||
|
$stmt_asesoras = $pdo->prepare($sql_asesoras);
|
||||||
|
$stmt_asesoras->execute($params);
|
||||||
|
$asesoras_recuado = $stmt_asesoras->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
error_log("Error en RECAUDO POR ASESORA: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- RESUMEN GENERAL Y POR ASESOR (VERSIÓN CORREGIDA) ---
|
||||||
|
$productos_resumen = [];
|
||||||
|
$resumen_por_asesor = [];
|
||||||
|
$pedidos = []; // Inicializar para que exista siempre
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. Obtener precios de productos
|
||||||
|
$precios_productos = $pdo->query("SELECT nombre, price FROM products")->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||||
|
|
||||||
|
// 2. Obtener todos los pedidos relevantes
|
||||||
|
$sql_pedidos = "
|
||||||
|
SELECT
|
||||||
|
p.producto,
|
||||||
|
p.cantidad,
|
||||||
|
COALESCE(u.nombre_asesor, u.username, 'Sin Asesor') AS asesor_nombre
|
||||||
|
FROM pedidos p
|
||||||
|
LEFT JOIN users u ON p.asesor_id = u.id
|
||||||
|
{$where_clause}
|
||||||
|
";
|
||||||
|
$stmt_pedidos = $pdo->prepare($sql_pedidos);
|
||||||
|
$stmt_pedidos->execute($params);
|
||||||
|
$pedidos = $stmt_pedidos->fetchAll(PDO::FETCH_ASSOC); // Traer todos los pedidos a un array
|
||||||
|
|
||||||
|
// 3. Procesar pedidos en PHP
|
||||||
|
foreach ($pedidos as $pedido) { // Iterar sobre el array
|
||||||
|
$asesor = $pedido['asesor_nombre'];
|
||||||
|
$nombres = explode(',', $pedido['producto']);
|
||||||
|
$cantidades = explode(',', $pedido['cantidad']);
|
||||||
|
|
||||||
|
foreach ($nombres as $index => $nombre) {
|
||||||
|
$nombre = trim($nombre);
|
||||||
|
if (empty($nombre)) continue;
|
||||||
|
|
||||||
|
$cantidad = isset($cantidades[$index]) ? (int)trim($cantidades[$index]) : 0;
|
||||||
|
$precio = isset($precios_productos[$nombre]) ? (float)$precios_productos[$nombre] : 0;
|
||||||
|
$monto = $cantidad * $precio;
|
||||||
|
|
||||||
|
// Acumular para Resumen General
|
||||||
|
if (!isset($productos_resumen[$nombre])) {
|
||||||
|
$productos_resumen[$nombre] = ['cantidad' => 0, 'monto' => 0, 'num_pedidos' => 0];
|
||||||
|
}
|
||||||
|
$productos_resumen[$nombre]['cantidad'] += $cantidad;
|
||||||
|
$productos_resumen[$nombre]['monto'] += $monto;
|
||||||
|
$productos_resumen[$nombre]['num_pedidos']++;
|
||||||
|
|
||||||
|
// Acumular para Desglose por Asesor
|
||||||
|
if (!isset($resumen_por_asesor[$asesor][$nombre])) {
|
||||||
|
$resumen_por_asesor[$asesor][$nombre] = ['cantidad' => 0, 'monto' => 0, 'num_pedidos' => 0];
|
||||||
|
}
|
||||||
|
$resumen_por_asesor[$asesor][$nombre]['cantidad'] += $cantidad;
|
||||||
|
$resumen_por_asesor[$asesor][$nombre]['monto'] += $monto;
|
||||||
|
$resumen_por_asesor[$asesor][$nombre]['num_pedidos']++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Ordenar resultados
|
||||||
|
uasort($productos_resumen, function($a, $b) { return $b['cantidad'] <=> $a['cantidad']; });
|
||||||
|
foreach ($resumen_por_asesor as &$productos) {
|
||||||
|
uasort($productos, function($a, $b) { return $b['cantidad'] <=> $a['cantidad']; });
|
||||||
|
}
|
||||||
|
unset($productos);
|
||||||
|
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
error_log("Error en RESUMEN GENERAL DE PRODUCTOS: " . $e->getMessage());
|
||||||
|
$productos_resumen = [];
|
||||||
|
$resumen_por_asesor = [];
|
||||||
|
$pedidos = []; // Asegurar que se reinicia en caso de error
|
||||||
|
}
|
||||||
$params[] = $fecha_inicio_obj->format('Y-m-d 00:00:00');
|
$params[] = $fecha_inicio_obj->format('Y-m-d 00:00:00');
|
||||||
$params[] = $fecha_fin_obj->format('Y-m-d 23:59:59');
|
$params[] = $fecha_fin_obj->format('Y-m-d 23:59:59');
|
||||||
}
|
}
|
||||||
@ -57,81 +159,80 @@ try {
|
|||||||
error_log("Error en RECAUDO POR ASESORA: " . $e->getMessage());
|
error_log("Error en RECAUDO POR ASESORA: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- RESUMEN GENERAL Y POR ASESOR ---
|
// --- RESUMEN GENERAL Y POR ASESOR (VERSIÓN CORREGIDA) ---
|
||||||
$productos_resumen = [];
|
$productos_resumen = [];
|
||||||
$resumen_por_asesor = [];
|
$resumen_por_asesor = [];
|
||||||
|
$pedidos = []; // Inicializar para que exista siempre
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Consulta para obtener el resumen de productos vendidos
|
// 1. Obtener precios de productos
|
||||||
$sql_resumen = "
|
$precios_productos = $pdo->query("SELECT nombre, price FROM products")->fetchAll(PDO::FETCH_KEY_PAIR);
|
||||||
|
|
||||||
|
// 2. Obtener todos los pedidos relevantes
|
||||||
|
$sql_pedidos = "
|
||||||
SELECT
|
SELECT
|
||||||
p.producto,
|
p.producto,
|
||||||
p.cantidad,
|
p.cantidad,
|
||||||
p.monto_total,
|
|
||||||
COALESCE(u.nombre_asesor, u.username, 'Sin Asesor') AS asesor_nombre
|
COALESCE(u.nombre_asesor, u.username, 'Sin Asesor') AS asesor_nombre
|
||||||
FROM pedidos p
|
FROM pedidos p
|
||||||
LEFT JOIN users u ON p.asesor_id = u.id
|
LEFT JOIN users u ON p.asesor_id = u.id
|
||||||
{$where_clause}
|
{$where_clause}
|
||||||
";
|
";
|
||||||
$stmt_resumen = $pdo->prepare($sql_resumen);
|
$stmt_pedidos = $pdo->prepare($sql_pedidos);
|
||||||
$stmt_resumen->execute($params);
|
$stmt_pedidos->execute($params);
|
||||||
$pedidos_resumen = $stmt_resumen->fetchAll(PDO::FETCH_ASSOC);
|
$pedidos = $stmt_pedidos->fetchAll(PDO::FETCH_ASSOC); // Traer todos los pedidos a un array
|
||||||
|
|
||||||
$temp_resumen = [];
|
// 3. Procesar pedidos en PHP
|
||||||
$temp_asesor = [];
|
foreach ($pedidos as $pedido) { // Iterar sobre el array
|
||||||
|
|
||||||
foreach ($pedidos_resumen as $pedido) {
|
|
||||||
$asesor = $pedido['asesor_nombre'];
|
$asesor = $pedido['asesor_nombre'];
|
||||||
$productos_pedido = explode(',', $pedido['producto']);
|
$nombres = explode(',', $pedido['producto']);
|
||||||
$cantidades_pedido = explode(',', $pedido['cantidad']);
|
$cantidades = explode(',', $pedido['cantidad']);
|
||||||
|
|
||||||
// Solo si el pedido tiene un único producto, asignamos el monto total.
|
foreach ($nombres as $index => $nombre) {
|
||||||
$monto_a_distribuir = (count($productos_pedido) == 1) ? $pedido['monto_total'] : 0;
|
$nombre = trim($nombre);
|
||||||
|
if (empty($nombre)) continue;
|
||||||
|
|
||||||
foreach ($productos_pedido as $index => $nombre_prod) {
|
$cantidad = isset($cantidades[$index]) ? (int)trim($cantidades[$index]) : 0;
|
||||||
$nombre_prod = trim($nombre_prod);
|
$precio = isset($precios_productos[$nombre]) ? (float)$precios_productos[$nombre] : 0;
|
||||||
if (empty($nombre_prod)) continue;
|
$monto = $cantidad * $precio;
|
||||||
|
|
||||||
$cantidad = isset($cantidades_pedido[$index]) ? (int)trim($cantidades_pedido[$index]) : 0;
|
// Acumular para Resumen General
|
||||||
|
if (!isset($productos_resumen[$nombre])) {
|
||||||
// Resumen general
|
$productos_resumen[$nombre] = ['cantidad' => 0, 'monto' => 0, 'num_pedidos' => 0];
|
||||||
if (!isset($temp_resumen[$nombre_prod])) {
|
|
||||||
$temp_resumen[$nombre_prod] = ['cantidad' => 0, 'monto' => 0, 'num_pedidos' => 0];
|
|
||||||
}
|
}
|
||||||
$temp_resumen[$nombre_prod]['cantidad'] += $cantidad;
|
$productos_resumen[$nombre]['cantidad'] += $cantidad;
|
||||||
$temp_resumen[$nombre_prod]['monto'] += $monto_a_distribuir;
|
$productos_resumen[$nombre]['monto'] += $monto;
|
||||||
$temp_resumen[$nombre_prod]['num_pedidos']++;
|
$productos_resumen[$nombre]['num_pedidos']++;
|
||||||
|
|
||||||
|
// Acumular para Desglose por Asesor
|
||||||
// Desglose por asesor
|
if (!isset($resumen_por_asesor[$asesor][$nombre])) {
|
||||||
if (!isset($temp_asesor[$asesor][$nombre_prod])) {
|
$resumen_por_asesor[$asesor][$nombre] = ['cantidad' => 0, 'monto' => 0, 'num_pedidos' => 0];
|
||||||
$temp_asesor[$asesor][$nombre_prod] = ['cantidad' => 0, 'monto' => 0, 'num_pedidos' => 0];
|
|
||||||
}
|
}
|
||||||
$temp_asesor[$asesor][$nombre_prod]['cantidad'] += $cantidad;
|
$resumen_por_asesor[$asesor][$nombre]['cantidad'] += $cantidad;
|
||||||
$temp_asesor[$asesor][$nombre_prod]['monto'] += $monto_a_distribuir;
|
$resumen_por_asesor[$asesor][$nombre]['monto'] += $monto;
|
||||||
$temp_asesor[$asesor][$nombre_prod]['num_pedidos']++;
|
$resumen_por_asesor[$asesor][$nombre]['num_pedidos']++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ordenar resultados
|
// 4. Ordenar resultados
|
||||||
uasort($temp_resumen, function($a, $b) { return $b['cantidad'] <=> $a['cantidad']; });
|
uasort($productos_resumen, function($a, $b) { return $b['cantidad'] <=> $a['cantidad']; });
|
||||||
foreach ($temp_asesor as &$prods) {
|
foreach ($resumen_por_asesor as &$productos) {
|
||||||
uasort($prods, function($a, $b) { return $b['cantidad'] <=> $a['cantidad']; });
|
uasort($productos, function($a, $b) { return $b['cantidad'] <=> $a['cantidad']; });
|
||||||
}
|
}
|
||||||
unset($prods);
|
unset($productos);
|
||||||
|
|
||||||
$productos_resumen = $temp_resumen;
|
|
||||||
$resumen_por_asesor = $temp_asesor;
|
|
||||||
|
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
error_log("Error en RESUMEN GENERAL DE PRODUCTOS: " . $e->getMessage());
|
error_log("Error en RESUMEN GENERAL DE PRODUCTOS: " . $e->getMessage());
|
||||||
// Dejar las variables vacías para que la UI muestre "No hay datos"
|
|
||||||
$productos_resumen = [];
|
$productos_resumen = [];
|
||||||
$resumen_por_asesor = [];
|
$resumen_por_asesor = [];
|
||||||
|
$pedidos = []; // Asegurar que se reinicia en caso de error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
include 'layout_header.php';
|
include 'layout_header.php';
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user