labs / static /js /layout.js
3v324v23's picture
deploy: unified router + dreamy website (2026-06-16T09:46:52Z)
c1a683f
Raw
History Blame Contribute Delete
4.1 kB
/* =========================================================================
layout.js — shared header (nav) + footer across every page
Injects a single source of truth into <div data-site-nav></div> and
<div data-site-footer></div> placeholders. Marks the current page link
with aria-current. No fetch / no FOUC risk — pure inline strings.
========================================================================= */
(function () {
'use strict';
// pages are relative to site root; each page passes its key via <body data-page>
const LINKS = [
{ key: 'home', href: 'index.html', label: 'Home' },
{ key: 'models', href: 'models.html', label: 'Models' },
{ key: 'pricing', href: 'pricing.html', label: 'Pricing' },
{ key: 'docs', href: 'docs.html', label: 'Docs' },
{ key: 'faq', href: 'faq.html', label: 'FAQ' },
{ key: 'dashboard', href: 'dashboard.html', label: 'Dashboard' },
];
const ENDPOINT = 'https://apiarium-labs.hf.space/v1/chat/completions';
const PROVIDERS = ['Claude', 'DeepSeek', 'MiniMax', 'MiMo', 'Gemini', 'GLM',
'Qwen', 'NVIDIA', 'Kimi', 'Grok', 'Ollama', 'OpenRouter'];
function navHtml(current) {
const items = LINKS.map(l =>
`<li><a href="${l.href}"${l.key === current ? ' aria-current="page"' : ''}>${l.label}</a></li>`
).join('');
return `
<a class="skip-link" href="#main">Skip to content</a>
<nav class="site-nav" aria-label="Primary">
<span class="nav-brand" data-page-root>
<img class="nav-logo" src="assets/svg/logo.svg?v=2" alt="" />
<span class="nav-brand-text">
<span class="brand-name">DreamRouter</span>
<span class="brand-sub">by Apiarium labs</span>
</span>
</span>
<ul class="nav-links">${items}</ul>
<a class="nav-cta" href="login.html" id="nav-auth">Sign in</a>
</nav>`;
}
function footerHtml() {
const provs = PROVIDERS.map(p => `<span>${p}</span>`).join('');
const year = new Date().getFullYear();
return `
<footer class="footer">
<div class="container">
<p class="made">DreamRouter · one endpoint, every model</p>
<p class="byline">by Apiarium labs</p>
<div class="providers">${provs}</div>
<nav class="footer-links" aria-label="Footer">
<a href="index.html">Home</a>
<a href="models.html">Models</a>
<a href="pricing.html">Pricing</a>
<a href="docs.html">Docs</a>
<a href="faq.html">FAQ</a>
</nav>
<p class="copyright">© ${year} Apiarium labs · endpoint
<code>${ENDPOINT.replace('https://', '')}</code></p>
</div>
</footer>`;
}
// inject + hydrate
function build() {
const current = document.body.dataset.page || '';
const navHost = document.querySelector('[data-site-nav]');
const footHost = document.querySelector('[data-site-footer]');
if (navHost) {
navHost.innerHTML = navHtml(current);
// scroll-shrink toggle
const nav = navHost.querySelector('.site-nav');
if (nav) {
const onScroll = () => {
nav.classList.toggle('is-scrolled', window.scrollY > 40);
};
window.addEventListener('scroll', onScroll, { passive: true });
onScroll();
}
// swap "Sign in" → "Dashboard" if a Google session cookie exists
const authLink = navHost.querySelector('#nav-auth');
if (authLink) {
fetch('/auth/me').then(r => r.ok ? r.json() : null).then(me => {
if (me) { // logged in
authLink.textContent = 'Dashboard';
authLink.setAttribute('href', 'dashboard.html');
}
}).catch(() => { /* not logged in — leave as Sign in */ });
}
}
if (footHost) footHost.innerHTML = footerHtml();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', build);
} else {
build();
}
})();