Primer version funcional
This commit is contained in:
263
views/dashboard/index.php
Executable file
263
views/dashboard/index.php
Executable file
@@ -0,0 +1,263 @@
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<h2>Dashboard</h2>
|
||||
<p class="text-muted">Vista general del sistema</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4 d-flex justify-content-between align-items-center flex-wrap gap-2">
|
||||
<div>
|
||||
<label for="yearSelect" class="form-label me-2">Año:</label>
|
||||
<select id="yearSelect" class="form-select d-inline-block" style="width: auto;">
|
||||
<?php for ($y = 2024; $y <= 2030; $y++): ?>
|
||||
<option value="<?= $y ?>" <?= $y == $year ? 'selected' : '' ?>><?= $y ?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group" style="width: 300px;">
|
||||
<input type="text" class="form-control" id="globalSearch" placeholder="Buscar casa o propietario...">
|
||||
<button class="btn btn-outline-secondary" onclick="globalSearch()">
|
||||
<i class="bi bi-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-2">
|
||||
<div class="card stat-card border-primary">
|
||||
<div class="card-body text-center">
|
||||
<h6 class="text-muted small">Casas</h6>
|
||||
<h4 class="text-primary mb-0"><?= $stats['total_houses'] ?></h4>
|
||||
<small class="text-muted">Total</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="card stat-card border-success">
|
||||
<div class="card-body text-center">
|
||||
<h6 class="text-muted small">Activas</h6>
|
||||
<h4 class="text-success mb-0"><?= $stats['active_houses'] ?></h4>
|
||||
<small class="text-muted">Operativas</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="card stat-card border-info">
|
||||
<div class="card-body text-center">
|
||||
<h6 class="text-muted small">Ingresos</h6>
|
||||
<h4 class="text-info mb-0">$<?= number_format($stats['total_payments'], 0) ?></h4>
|
||||
<small class="text-muted">Año <?= $year ?></small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (!Auth::isLector()): ?>
|
||||
<div class="col-md-2">
|
||||
<div class="card stat-card border-danger">
|
||||
<div class="card-body text-center">
|
||||
<h6 class="text-muted small">Gastos</h6>
|
||||
<h4 class="text-danger mb-0">$<?= number_format($stats['total_expenses'], 0) ?></h4>
|
||||
<small class="text-muted">Año <?= $year ?></small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<div class="card stat-card border-warning">
|
||||
<div class="card-body text-center">
|
||||
<h6 class="text-muted small">Balance</h6>
|
||||
<h4 class="<?= $stats['balance'] >= 0 ? 'text-success' : 'text-danger' ?> mb-0">
|
||||
$<?= number_format($stats['balance'], 0) ?>
|
||||
</h4>
|
||||
<small class="text-muted">Neto</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="col-md-2">
|
||||
<div class="card stat-card border-secondary">
|
||||
<div class="card-body text-center">
|
||||
<h6 class="text-muted small">Conceptos</h6>
|
||||
<h4 class="text-secondary mb-0"><?= $stats['active_concepts'] ?></h4>
|
||||
<small class="text-muted">Activos</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<?php if (Auth::isAdmin() || Auth::isCapturist()): ?>
|
||||
<div class="col-lg-<?= Auth::isCapturist() && !Auth::isAdmin() ? '8' : '12' ?>">
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h5 class="card-title mb-0"><i class="bi bi-activity"></i> Actividad Reciente</h5>
|
||||
<?php if (Auth::isAdmin()): ?>
|
||||
<div>
|
||||
<select id="userActivityFilter" class="form-select form-select-sm d-inline-block" style="width: 200px;">
|
||||
<option value="">Todos los usuarios</option>
|
||||
<?php foreach ($distinctUsers as $user): ?>
|
||||
<option value="<?= $user['id'] ?>" <?= ($_GET['user'] ?? '') == $user['id'] ? 'selected' : '' ?>>
|
||||
<?= htmlspecialchars($user['first_name'] . ' ' . $user['last_name']) ?> (<?= htmlspecialchars($user['username']) ?>)
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<button onclick="clearActivityHistory()" class="btn btn-sm btn-outline-danger ms-2">
|
||||
<i class="bi bi-trash"></i> Limpiar Historial
|
||||
</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Fecha</th>
|
||||
<th>Usuario</th>
|
||||
<th>Acción</th>
|
||||
<th>Detalles</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($recentActivity as $log): ?>
|
||||
<tr>
|
||||
<td><small><?= date('d/m/Y H:i', strtotime($log['created_at'])) ?></small></td>
|
||||
<td><?= htmlspecialchars($log['username'] ?? '-') ?></td>
|
||||
<td>
|
||||
<span class="badge bg-secondary"><?= htmlspecialchars($log['action']) ?></span>
|
||||
</td>
|
||||
<td><small><?= htmlspecialchars($log['details'] ?? '-') ?></small></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (Auth::isCapturist() && !Auth::isAdmin()): ?>
|
||||
<div class="col-lg-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title mb-0"><i class="bi bi-grid"></i> Acciones Rápidas</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-2">
|
||||
<div class="col-6">
|
||||
<a href="/dashboard.php?page=pagos" class="btn btn-outline-primary w-100">
|
||||
<i class="bi bi-droplet-fill d-block mb-1"></i>
|
||||
<small>Pagos</small>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<a href="/dashboard.php?page=finanzas" class="btn btn-outline-danger w-100">
|
||||
<i class="bi bi-receipt d-block mb-1"></i>
|
||||
<small>Gastos</small>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<a href="/dashboard.php?page=casas" class="btn btn-outline-info w-100">
|
||||
<i class="bi bi-building d-block mb-1"></i>
|
||||
<small>Casas</small>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<a href="/dashboard.php?page=reportes" class="btn btn-outline-secondary w-100">
|
||||
<i class="bi bi-file-earmark-bar-graph d-block mb-1"></i>
|
||||
<small>Reportes</small>
|
||||
</a>
|
||||
</div>
|
||||
<?php if (Auth::isAdmin()): ?>
|
||||
<div class="col-6">
|
||||
<a href="/dashboard.php?page=configurar" class="btn btn-outline-warning w-100">
|
||||
<i class="bi bi-gear d-block mb-1"></i>
|
||||
<small>Configurar</small>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<a href="/dashboard.php?page=importar" class="btn btn-outline-success w-100">
|
||||
<i class="bi bi-file-earmark-arrow-up d-block mb-1"></i>
|
||||
<small>Importar</small>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5 class="card-title mb-0"><i class="bi bi-info-circle"></i> Información</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="mb-1"><small><strong>Usuario:</strong> <?= htmlspecialchars((Auth::user()['first_name'] ?? '') . ' ' . (Auth::user()['last_name'] ?? '')) ?></small></p>
|
||||
<p class="mb-1"><small><strong>Rol:</strong> <?= htmlspecialchars(Auth::role()) ?></small></p>
|
||||
<p class="mb-0"><small><strong>Año Fiscal:</strong> <?= $year ?></small></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.getElementById('yearSelect').addEventListener('change', function() {
|
||||
window.location.href = '/dashboard.php?page=dashboard&year=' + this.value;
|
||||
});
|
||||
|
||||
function globalSearch() {
|
||||
const query = document.getElementById('globalSearch').value.trim();
|
||||
if (query) {
|
||||
fetch(`/dashboard.php?page=search_global&q=${encodeURIComponent(query)}`)
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
if (data.success && data.results.length > 0) {
|
||||
const results = data.results.map(r =>
|
||||
`<a href="/dashboard.php?page=house_view&id=${r.id}" class="dropdown-item">
|
||||
Casa ${r.number} - ${r.owner_name || 'Sin propietario'}
|
||||
</a>`
|
||||
).join('');
|
||||
Swal.fire({
|
||||
title: 'Resultados',
|
||||
html: `<div style="max-height:300px;overflow-y:auto">${results}</div>`,
|
||||
showConfirmButton: false
|
||||
});
|
||||
} else {
|
||||
Swal.fire('Sin resultados', 'No se encontraron casas', 'info');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('userActivityFilter')?.addEventListener('change', function() {
|
||||
const userId = this.value;
|
||||
if (userId) {
|
||||
window.location.href = '/dashboard.php?page=dashboard&user=' + userId;
|
||||
} else {
|
||||
window.location.href = '/dashboard.php?page=dashboard';
|
||||
}
|
||||
});
|
||||
|
||||
function clearActivityHistory() {
|
||||
Swal.fire({
|
||||
title: '¿Limpiar historial?',
|
||||
text: 'Esta acción eliminará TODO el historial de actividad y no se puede deshacer.',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#d33',
|
||||
confirmButtonText: 'Sí, eliminar todo'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
fetch('/dashboard.php?page=activity_logs&action=clear', {
|
||||
method: 'DELETE'
|
||||
}).then(r => r.json()).then(data => {
|
||||
if (data.success) {
|
||||
Swal.fire('Eliminado', data.message, 'success').then(() => location.reload());
|
||||
} else {
|
||||
Swal.fire('Error', data.message, 'error');
|
||||
}
|
||||
}).catch(() => {
|
||||
Swal.fire('Error', 'Error de conexión', 'error');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user