feat(backoffice,site): Sistema consistente com a frota; horário como acordeão

- Sidebar do backoffice: Backups/Auditoria/IP bans/Geo/Origem das visitas/
  Atualizações deixam de ser um link cada (enumerados à mão) e passam a um
  só link "Sistema" para o índice partilhado do platform-tools
  (platform.php?tool=index), como a fotografia/design/dance já fazem — uma
  ferramenta nova no platform-tools passa a aparecer sozinha, sem link novo
  a escrever aqui. Definições, Mensagens e Comunicações continuam com link
  próprio (são páginas do fitme, não do router).
- Horário de Aulas (home e CrossFit, mesmo componente partilhado): a grelha
  fica fechada por omissão atrás de um botão "Ver Horário das aulas"
  (Bootstrap collapse); clicar em "Horário" na navbar (ou abrir a página já
  com #horario no URL) abre-a de imediato em vez de só rolar até uma secção
  fechada.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
andreandClaude Sonnet 5 committed 2026-09-26 10:14:46 +01:00
1 parent b5bbbd3b5f
commit 4222b8f2e0
4 files changed
+41 -29

No files matched your search

+6 -22
View File
@@ -197,37 +197,21 @@ $app_name = defined('APP_NAME') ? APP_NAME : 'FitMe 3070';
<a class="nav-link<?= ($_SERVER['SCRIPT_NAME'] ?? '') === '/views/sysadmin/system_settings.php' ? ' active' : '' ?>" <a class="nav-link<?= ($_SERVER['SCRIPT_NAME'] ?? '') === '/views/sysadmin/system_settings.php' ? ' active' : '' ?>"
href="<?= base_url('views/sysadmin/system_settings.php') ?>"><i class="bi bi-sliders"></i>Definições</a> href="<?= base_url('views/sysadmin/system_settings.php') ?>"><i class="bi bi-sliders"></i>Definições</a>
</li> </li>
<li class="nav-item">
<a class="nav-link<?= (($_GET['tool'] ?? '') === 'backups') ? ' active' : '' ?>"
href="<?= base_url('platform.php?tool=backups') ?>"><i class="bi bi-database-fill-gear"></i>Backups</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link<?= ($_SERVER['SCRIPT_NAME'] ?? '') === '/views/sysadmin/messages.php' ? ' active' : '' ?>" <a class="nav-link<?= ($_SERVER['SCRIPT_NAME'] ?? '') === '/views/sysadmin/messages.php' ? ' active' : '' ?>"
href="<?= base_url('views/sysadmin/messages.php') ?>"><i class="bi bi-envelope-paper"></i>Mensagens</a> href="<?= base_url('views/sysadmin/messages.php') ?>"><i class="bi bi-envelope-paper"></i>Mensagens</a>
</li> </li>
<li class="nav-item">
<a class="nav-link<?= (($_GET['tool'] ?? '') === 'audit') ? ' active' : '' ?>"
href="<?= base_url('platform.php?tool=audit') ?>"><i class="bi bi-journal-text"></i>Auditoria</a>
</li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link<?= ($_SERVER['SCRIPT_NAME'] ?? '') === '/views/sysadmin/comms.php' ? ' active' : '' ?>" <a class="nav-link<?= ($_SERVER['SCRIPT_NAME'] ?? '') === '/views/sysadmin/comms.php' ? ' active' : '' ?>"
href="<?= base_url('views/sysadmin/comms.php') ?>"><i class="bi bi-send"></i>Comunicações</a> href="<?= base_url('views/sysadmin/comms.php') ?>"><i class="bi bi-send"></i>Comunicações</a>
</li> </li>
<?php // Backups/Auditoria/IP bans/Geo/Origem das visitas/Atualizações/Hub: um só
// link para o índice partilhado do platform-tools (como a fotografia/design/
// dance fazem), em vez de um por ferramenta — uma ferramenta nova no
// platform-tools passa a aparecer sozinha, sem precisar de link novo aqui. ?>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link<?= (($_GET['tool'] ?? '') === 'ip_bans') ? ' active' : '' ?>" <a class="nav-link<?= (($_GET['tool'] ?? 'index') === 'index' && str_contains($_SERVER['REQUEST_URI'] ?? '', 'platform.php')) ? ' active' : '' ?>"
href="<?= base_url('platform.php?tool=ip_bans') ?>"><i class="bi bi-shield-lock"></i>IP bans</a> href="<?= base_url('platform.php?tool=index') ?>"><i class="bi bi-shield-lock"></i>Sistema</a>
</li>
<li class="nav-item">
<a class="nav-link<?= (($_GET['tool'] ?? '') === 'geo') ? ' active' : '' ?>"
href="<?= base_url('platform.php?tool=geo') ?>"><i class="bi bi-globe-europe-africa"></i>Geo</a>
</li>
<li class="nav-item">
<a class="nav-link<?= (($_GET['tool'] ?? '') === 'tracking') ? ' active' : '' ?>"
href="<?= base_url('platform.php?tool=tracking') ?>"><i class="bi bi-graph-up"></i>Origem das visitas</a>
</li>
<li class="nav-item">
<a class="nav-link<?= (($_GET['tool'] ?? '') === 'platform_update') ? ' active' : '' ?>"
href="<?= base_url('platform.php?tool=platform_update') ?>"><i class="bi bi-arrow-repeat"></i>Actualizações</a>
</li> </li>
</ul> </ul>
<?php endif; ?> <?php endif; ?>
+10 -3
View File
@@ -35,14 +35,20 @@ foreach ($rows as $d) { $grid[$d['dia_semana']][$d['hora_inicio']][] = $d; }
<div class="section-title text-center deco"> <div class="section-title text-center deco">
<h2><?= htmlspecialchars($schedule_h2) ?></h2> <h2><?= htmlspecialchars($schedule_h2) ?></h2>
</div> </div>
<div class="text-center mb-2"> <div class="text-center">
<button type="button" class="schedule-dl-btn" id="scheduleDownloadCf"> <button type="button" class="site-btn" data-bs-toggle="collapse" data-bs-target="#horarioCollapseCf" aria-expanded="false" aria-controls="horarioCollapseCf">
<i class="fas fa-download" aria-hidden="true"></i> Guardar horário Ver Horário das aulas
</button> </button>
</div> </div>
</div> </div>
</div> </div>
<?php endif; ?> <?php endif; ?>
<div class="collapse" id="horarioCollapseCf">
<div class="text-center mb-4">
<button type="button" class="schedule-dl-btn" id="scheduleDownloadCf">
<i class="fas fa-download" aria-hidden="true"></i> Guardar horário
</button>
</div>
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="schedule_container"> <div class="schedule_container">
@@ -82,6 +88,7 @@ foreach ($rows as $d) { $grid[$d['dia_semana']][$d['hora_inicio']][] = $d; }
</div> </div>
</div> </div>
</div> </div>
</div>
</div> </div>
</div> </div>
<script> <script>
+14
View File
@@ -111,6 +111,7 @@ $logo_dims = svg_img_dims_attr(dirname(__DIR__, 2) . '/' . $logo_rel);
sections.push({ link: link, target: target, id: url.hash }); sections.push({ link: link, target: target, id: url.hash });
link.addEventListener('click', function(e) { link.addEventListener('click', function(e) {
e.preventDefault(); e.preventDefault();
openHorarioIfNeeded(url.hash);
smoothScrollTo(target, 600); smoothScrollTo(target, 600);
history.pushState(null, null, url.hash); history.pushState(null, null, url.hash);
var navCollapse = document.getElementById('navbarSupportedContent'); var navCollapse = document.getElementById('navbarSupportedContent');
@@ -120,6 +121,19 @@ $logo_dims = svg_img_dims_attr(dirname(__DIR__, 2) . '/' . $logo_rel);
}); });
}); });
/* Horário de Aulas is a closed accordion (button "Ver Horário das aulas") —
clicking the navbar link (or landing on #horario directly) should open
it right away instead of scrolling to a section that still needs an
extra click. */
function openHorarioIfNeeded(hash) {
if (hash !== '#horario') return;
var el = document.getElementById('horarioCollapse');
if (el && window.bootstrap) {
bootstrap.Collapse.getOrCreateInstance(el, { toggle: false }).show();
}
}
openHorarioIfNeeded(window.location.hash);
/* ── Scroll-spy: highlight current section ──────────────────────────── */ /* ── Scroll-spy: highlight current section ──────────────────────────── */
// Measure each section against the viewport with getBoundingClientRect: // Measure each section against the viewport with getBoundingClientRect:
// a link is "current" only while the line just below the navbar sits // a link is "current" only while the line just below the navbar sits
+11 -4
View File
@@ -265,13 +265,19 @@ if (!in_array($default_day, $week_values, true)) { $default_day = $week_values[0
<h2 id="horario-title">Horário de Aulas</h2> <h2 id="horario-title">Horário de Aulas</h2>
<p class="section-subtitle">Planeia a tua semana de treinos connosco.</p> <p class="section-subtitle">Planeia a tua semana de treinos connosco.</p>
</div> </div>
<div class="text-center mb-2"> <div class="text-center">
<button type="button" class="schedule-dl-btn" id="scheduleDownload"> <button type="button" class="site-btn" data-bs-toggle="collapse" data-bs-target="#horarioCollapse" aria-expanded="false" aria-controls="horarioCollapse">
<i class="fas fa-download" aria-hidden="true"></i> Guardar horário Ver Horário das aulas
</button> </button>
</div> </div>
</div> </div>
</div> </div>
<div class="collapse" id="horarioCollapse">
<div class="text-center mb-4">
<button type="button" class="schedule-dl-btn" id="scheduleDownload">
<i class="fas fa-download" aria-hidden="true"></i> Guardar horário
</button>
</div>
<?php <?php
// ── Build a time-aligned grid ────────────────────────────────────────── // ── Build a time-aligned grid ──────────────────────────────────────────
// Distinct start times become CSS-grid rows and days become columns, so // Distinct start times become CSS-grid rows and days become columns, so
@@ -348,9 +354,10 @@ if (!in_array($default_day, $week_values, true)) { $default_day = $week_values[0
</div> </div>
</div> </div>
</div> </div>
<p class="schedule-scroll-hint">&larr; Deslize para ver todos os dias &rarr;</p>
</div>
</div> </div>
</div> </div>
<p class="schedule-scroll-hint">&larr; Deslize para ver todos os dias &rarr;</p>
</section> </section>
<script> <script>
/* Quick "save the weekly schedule as JPG". html2canvas (1.4.1, loaded lazily /* Quick "save the weekly schedule as JPG". html2canvas (1.4.1, loaded lazily