Initial import of fitme3070.pt platform
Plain-PHP fleet platform with id.andmore.pt SSO. Wires shared/platform-tools as a submodule (platform_update, backups, git/migration tools) like the other platforms. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
commit
e68d357177
2330 files changed
+215968
No files matched your search
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
if($current_uri_2 == 'crossfit'){
|
||||
$logo = base_url('site/assets/img/logos/logo_crossfit.svg');
|
||||
}
|
||||
else
|
||||
{
|
||||
$logo = base_url('site/assets/img/logos/logo_black.svg');
|
||||
}
|
||||
?>
|
||||
<header class="header-section lazy">
|
||||
<nav class="navbar navbar-expand-lg navbar-light" style="padding-left:1rem; padding-top: 0; padding-bottom: 0;padding-right: 0; ">
|
||||
<a class="navbar-brand" href="<?= base_url('home') ?>">
|
||||
<img loading="eager" alt="Logo FitMe3070" src="<?= $logo ?>" style="width: 150px;">
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mx-auto ">
|
||||
<?php foreach($navbar as $key => $n):
|
||||
$is_crossfit = ($key === 'CrossFit');
|
||||
$is_active = false;
|
||||
if ($is_crossfit) {
|
||||
$is_active = ($current_uri_2 === 'crossfit');
|
||||
} elseif ($n === '#home') {
|
||||
// Only the Home link is active by default on the homepage
|
||||
$is_active = ($current_uri_2 === '');
|
||||
}
|
||||
// Other anchor links activate via JS scroll spy, not PHP
|
||||
?>
|
||||
<li class="nav-item <?= $is_active ? 'active' : '' ?> main-menu-li" >
|
||||
<?php if ($is_crossfit): ?>
|
||||
<a class="nav-link crossfit-nav-link" href="<?= base_url($n) ?>"<?= $is_active ? ' aria-current="page"' : '' ?>>
|
||||
<?= $key ?>
|
||||
</a>
|
||||
<?php elseif (isset($n[0]) && $n[0] === '#'): ?>
|
||||
<?php $href = ($current_uri_2 === 'crossfit') ? base_url('home' . $n) : base_url($n); ?>
|
||||
<a class="nav-link smooth-scroll" href="<?= $href ?>"<?= $is_active ? ' aria-current="page"' : '' ?>>
|
||||
<?= $key ?>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<a class="nav-link" href="<?= base_url($n) ?>">
|
||||
<?= $key ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<div class="clearfix"></div>
|
||||
<!-- Header section end -->
|
||||
|
||||
<!-- Smooth scroll + scroll-spy for one-page layout -->
|
||||
<script>
|
||||
(function() {
|
||||
/* ── Eased smooth-scroll helper ──────────────────────────────────────── */
|
||||
function smoothScrollTo(targetEl, duration) {
|
||||
var start = window.scrollY;
|
||||
var navbar = document.querySelector('.header-section');
|
||||
var offset = navbar ? navbar.offsetHeight : 60;
|
||||
var startTime = null;
|
||||
duration = duration || 500;
|
||||
|
||||
function easeInOutCubic(t) {
|
||||
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
|
||||
}
|
||||
|
||||
function step(currentTime) {
|
||||
if (!startTime) startTime = currentTime;
|
||||
var elapsed = currentTime - startTime;
|
||||
var progress = Math.min(elapsed / duration, 1);
|
||||
// Recompute the destination every frame. These sections use
|
||||
// content-visibility:auto, so off-screen ones report a placeholder
|
||||
// height until rendered; a target computed once on click lands short
|
||||
// (e.g. Contactos → Horário on the first click). The live absolute
|
||||
// top (rect.top + scrollY) updates as sections render, so the scroll
|
||||
// converges on the real position.
|
||||
var end = targetEl.getBoundingClientRect().top + window.scrollY - offset;
|
||||
window.scrollTo(0, start + (end - start) * easeInOutCubic(progress));
|
||||
if (progress < 1) requestAnimationFrame(step);
|
||||
}
|
||||
requestAnimationFrame(step);
|
||||
}
|
||||
|
||||
/* ── Bind all smooth-scroll links ───────────────────────────────────── */
|
||||
// Hrefs come from base_url() as absolute URLs (https://…/#equipa), so
|
||||
// resolve them and only bind the ones whose hash targets THIS page.
|
||||
// "/", "/home" and "/index.php" are all the same route.
|
||||
function normPath(p) {
|
||||
p = p.replace(/\/+$/, '');
|
||||
if (p.slice(-10) === '/index.php') p = p.slice(0, -10);
|
||||
if (p.slice(-5) === '/home') p = p.slice(0, -5);
|
||||
return p;
|
||||
}
|
||||
var navLinks = document.querySelectorAll('a.smooth-scroll');
|
||||
var sections = [];
|
||||
navLinks.forEach(function(link) {
|
||||
var url;
|
||||
try { url = new URL(link.getAttribute('href'), window.location.href); } catch (e) { return; }
|
||||
if (!url.hash || normPath(url.pathname) !== normPath(window.location.pathname)) return;
|
||||
var target = document.querySelector(url.hash);
|
||||
if (!target) return;
|
||||
sections.push({ link: link, target: target, id: url.hash });
|
||||
link.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
smoothScrollTo(target, 600);
|
||||
history.pushState(null, null, url.hash);
|
||||
var navCollapse = document.getElementById('navbarSupportedContent');
|
||||
if (navCollapse && navCollapse.classList.contains('show')) {
|
||||
document.querySelector('.navbar-toggler').click();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/* ── Scroll-spy: highlight current section ──────────────────────────── */
|
||||
// Measure each section against the viewport with getBoundingClientRect:
|
||||
// a link is "current" only while the line just below the navbar sits
|
||||
// *inside* its section (top at/above the line, bottom below it). We use the
|
||||
// live rect rather than offsetTop/offsetHeight because these sections use
|
||||
// `content-visibility:auto`, which makes those offset metrics unreliable.
|
||||
// Bounds (not "top has passed") also means the offer + gallery gap above
|
||||
// #equipa highlights nothing, so Home stops underlining past the header.
|
||||
function updateActive() {
|
||||
var navbarH = (document.querySelector('.header-section') || {}).offsetHeight || 60;
|
||||
var line = navbarH + 12;
|
||||
var current = null;
|
||||
sections.forEach(function(s) {
|
||||
var r = s.target.getBoundingClientRect();
|
||||
if (r.top <= line && r.bottom > line) current = s;
|
||||
});
|
||||
document.querySelectorAll('.main-menu-li').forEach(function(li) {
|
||||
li.classList.remove('active');
|
||||
});
|
||||
sections.forEach(function(s) {
|
||||
s.link.removeAttribute('aria-current');
|
||||
});
|
||||
if (current) {
|
||||
// Several links can point at the same section (nav item + mobile
|
||||
// CTA); highlight every one that has a surrounding nav item.
|
||||
sections.forEach(function(s) {
|
||||
if (s.target !== current.target) return;
|
||||
var li = s.link.closest('.nav-item');
|
||||
if (li) li.classList.add('active');
|
||||
s.link.setAttribute('aria-current', 'page');
|
||||
});
|
||||
}
|
||||
}
|
||||
// Only run the spy when this page actually has bound sections — on the
|
||||
// CrossFit page the list is empty and the PHP-set active pill must stay.
|
||||
if (sections.length > 0) {
|
||||
window.addEventListener('scroll', updateActive, { passive: true });
|
||||
updateActive();
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
Reference in new issue
Block a user