Commit 30b8d87d9dd317af4aa4c2f04bfd3cd1c422eedc

Authored by Willen Borges Coelho
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,12 +5,18 @@ declare(strict_types=1);
5 require __DIR__ . '/../src/bootstrap.php'; 5 require __DIR__ . '/../src/bootstrap.php';
6 Auth::requireAdmin(); 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 $page = max(1, (int) ($_GET['p'] ?? 1)); 16 $page = max(1, (int) ($_GET['p'] ?? 1));
  17 +$page = min($page, $totalPages);
10 $offset = ($page - 1) * $perPage; 18 $offset = ($page - 1) * $perPage;
11 19
12 -$total = (int) Database::pdo()->query('SELECT COUNT(*) FROM audit_log')->fetchColumn();  
13 -  
14 $stmt = Database::pdo()->prepare( 20 $stmt = Database::pdo()->prepare(
15 'SELECT * FROM audit_log ORDER BY criado_em DESC, id DESC LIMIT :limit OFFSET :offset' 21 'SELECT * FROM audit_log ORDER BY criado_em DESC, id DESC LIMIT :limit OFFSET :offset'
16 ); 22 );
@@ -19,8 +25,6 @@ $stmt-&gt;bindValue(&#39;offset&#39;, $offset, PDO::PARAM_INT); @@ -19,8 +25,6 @@ $stmt-&gt;bindValue(&#39;offset&#39;, $offset, PDO::PARAM_INT);
19 $stmt->execute(); 25 $stmt->execute();
20 $logs = $stmt->fetchAll(); 26 $logs = $stmt->fetchAll();
21 27
22 -$totalPages = max(1, (int) ceil($total / $perPage));  
23 -  
24 $acaoLabels = [ 28 $acaoLabels = [
25 'login' => 'Login', 29 'login' => 'Login',
26 'login_negado' => 'Login negado (sem permissão)', 30 'login_negado' => 'Login negado (sem permissão)',
@@ -42,9 +46,23 @@ View::header(&#39;Auditoria&#39;); @@ -42,9 +46,23 @@ View::header(&#39;Auditoria&#39;);
42 <h1>Auditoria</h1> 46 <h1>Auditoria</h1>
43 <p class="hint"> 47 <p class="hint">
44 Histórico de logins (inclusive tentativas com senha incorreta), alterações em 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 </p> 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 <table> 66 <table>
49 <tr> 67 <tr>
50 <th>Data/hora</th> 68 <th>Data/hora</th>
@@ -70,16 +88,29 @@ View::header(&#39;Auditoria&#39;); @@ -70,16 +88,29 @@ View::header(&#39;Auditoria&#39;);
70 </table> 88 </table>
71 89
72 <?php if ($totalPages > 1): ?> 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 ?>">&larr; Anterior</a>
  94 + <?php else: ?>
  95 + <span class="btn secondary" style="opacity:.4;pointer-events:none">&larr; 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 &rarr;</a>
  110 + <?php else: ?>
  111 + <span class="btn secondary" style="opacity:.4;pointer-events:none">Próxima &rarr;</span>
  112 + <?php endif; ?>
  113 + </div>
83 <?php endif; ?> 114 <?php endif; ?>
84 </div> 115 </div>
85 <?php 116 <?php