Commit 30b8d87d9dd317af4aa4c2f04bfd3cd1c422eedc
1 parent
72556b0d
Exists in
main
Auditoria: paginação com escolha de registros por página
Adiciona seletor de 10/25/50/100 registros por página e navegação por Anterior/Próxima + select de página, em vez de listar todos os números de página de uma vez (inviável com muitos registros). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Showing
1 changed file
with
47 additions
and
16 deletions
Show diff stats
public_html/auditoria.php
| ... | ... | @@ -5,12 +5,18 @@ declare(strict_types=1); |
| 5 | 5 | require __DIR__ . '/../src/bootstrap.php'; |
| 6 | 6 | Auth::requireAdmin(); |
| 7 | 7 | |
| 8 | -$perPage = 50; | |
| 8 | +$perPageOptions = [10, 25, 50, 100]; | |
| 9 | +$perPage = (int) ($_GET['per'] ?? 50); | |
| 10 | +if (!in_array($perPage, $perPageOptions, true)) { | |
| 11 | + $perPage = 50; | |
| 12 | +} | |
| 13 | +$total = (int) Database::pdo()->query('SELECT COUNT(*) FROM audit_log')->fetchColumn(); | |
| 14 | +$totalPages = max(1, (int) ceil($total / $perPage)); | |
| 15 | + | |
| 9 | 16 | $page = max(1, (int) ($_GET['p'] ?? 1)); |
| 17 | +$page = min($page, $totalPages); | |
| 10 | 18 | $offset = ($page - 1) * $perPage; |
| 11 | 19 | |
| 12 | -$total = (int) Database::pdo()->query('SELECT COUNT(*) FROM audit_log')->fetchColumn(); | |
| 13 | - | |
| 14 | 20 | $stmt = Database::pdo()->prepare( |
| 15 | 21 | 'SELECT * FROM audit_log ORDER BY criado_em DESC, id DESC LIMIT :limit OFFSET :offset' |
| 16 | 22 | ); |
| ... | ... | @@ -19,8 +25,6 @@ $stmt->bindValue('offset', $offset, PDO::PARAM_INT); |
| 19 | 25 | $stmt->execute(); |
| 20 | 26 | $logs = $stmt->fetchAll(); |
| 21 | 27 | |
| 22 | -$totalPages = max(1, (int) ceil($total / $perPage)); | |
| 23 | - | |
| 24 | 28 | $acaoLabels = [ |
| 25 | 29 | 'login' => 'Login', |
| 26 | 30 | 'login_negado' => 'Login negado (sem permissão)', |
| ... | ... | @@ -42,9 +46,23 @@ View::header('Auditoria'); |
| 42 | 46 | <h1>Auditoria</h1> |
| 43 | 47 | <p class="hint"> |
| 44 | 48 | Histórico de logins (inclusive tentativas com senha incorreta), alterações em |
| 45 | - alunos, administradores e configurações. Mostrando <?= count($logs) ?> de <?= $total ?> registros. | |
| 49 | + alunos, administradores e configurações. | |
| 46 | 50 | </p> |
| 47 | 51 | |
| 52 | + <div style="display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:12px;margin-bottom:4px"> | |
| 53 | + <span class="hint"> | |
| 54 | + Mostrando <?= count($logs) ?> de <?= $total ?> registros — página <?= $page ?> de <?= $totalPages ?> | |
| 55 | + </span> | |
| 56 | + <form method="get" action="auditoria" style="display:flex;align-items:center;gap:8px;margin:0"> | |
| 57 | + <label for="per" style="margin:0;white-space:nowrap">Por página</label> | |
| 58 | + <select id="per" name="per" onchange="this.form.submit()" style="margin:0;width:auto"> | |
| 59 | + <?php foreach ($perPageOptions as $opt): ?> | |
| 60 | + <option value="<?= $opt ?>" <?= $opt === $perPage ? 'selected' : '' ?>><?= $opt ?></option> | |
| 61 | + <?php endforeach; ?> | |
| 62 | + </select> | |
| 63 | + </form> | |
| 64 | + </div> | |
| 65 | + | |
| 48 | 66 | <table> |
| 49 | 67 | <tr> |
| 50 | 68 | <th>Data/hora</th> |
| ... | ... | @@ -70,16 +88,29 @@ View::header('Auditoria'); |
| 70 | 88 | </table> |
| 71 | 89 | |
| 72 | 90 | <?php if ($totalPages > 1): ?> |
| 73 | - <p style="margin-top:12px"> | |
| 74 | - <?php for ($p = 1; $p <= $totalPages; $p++): ?> | |
| 75 | - <?php if ($p === $page): ?> | |
| 76 | - <strong><?= $p ?></strong> | |
| 77 | - <?php else: ?> | |
| 78 | - <a href="auditoria?p=<?= $p ?>"><?= $p ?></a> | |
| 79 | - <?php endif; ?> | |
| 80 | - <?php if ($p < $totalPages): ?> | <?php endif; ?> | |
| 81 | - <?php endfor; ?> | |
| 82 | - </p> | |
| 91 | + <div style="display:flex;align-items:center;gap:10px;margin-top:16px;flex-wrap:wrap"> | |
| 92 | + <?php if ($page > 1): ?> | |
| 93 | + <a class="btn secondary" href="auditoria?per=<?= $perPage ?>&p=<?= $page - 1 ?>">← Anterior</a> | |
| 94 | + <?php else: ?> | |
| 95 | + <span class="btn secondary" style="opacity:.4;pointer-events:none">← Anterior</span> | |
| 96 | + <?php endif; ?> | |
| 97 | + | |
| 98 | + <form method="get" action="auditoria" style="display:flex;align-items:center;gap:8px;margin:0"> | |
| 99 | + <input type="hidden" name="per" value="<?= $perPage ?>"> | |
| 100 | + <label for="p" style="margin:0;white-space:nowrap">Página</label> | |
| 101 | + <select id="p" name="p" onchange="this.form.submit()" style="margin:0;width:auto"> | |
| 102 | + <?php for ($p = 1; $p <= $totalPages; $p++): ?> | |
| 103 | + <option value="<?= $p ?>" <?= $p === $page ? 'selected' : '' ?>><?= $p ?> de <?= $totalPages ?></option> | |
| 104 | + <?php endfor; ?> | |
| 105 | + </select> | |
| 106 | + </form> | |
| 107 | + | |
| 108 | + <?php if ($page < $totalPages): ?> | |
| 109 | + <a class="btn secondary" href="auditoria?per=<?= $perPage ?>&p=<?= $page + 1 ?>">Próxima →</a> | |
| 110 | + <?php else: ?> | |
| 111 | + <span class="btn secondary" style="opacity:.4;pointer-events:none">Próxima →</span> | |
| 112 | + <?php endif; ?> | |
| 113 | + </div> | |
| 83 | 114 | <?php endif; ?> |
| 84 | 115 | </div> |
| 85 | 116 | <?php | ... | ... |