customer-presentation/protected/mobile/mobile.js
Arlind Ukshini cd9bd71f4b mobile: drop the masthead logout button
Masthead is now the Fenja wordmark on its own, centred. The logout
handler and the .m-logout CSS are gone; mobile.js header comment
updated to reflect "two behaviours" (session check + join CTA).
Users who need to log out can do so from a desktop session or by
clearing cookies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 10:34:37 +02:00

70 lines
2.7 KiB
JavaScript

// ─────────────────────────────────────────────────────────────
// protected/mobile/mobile.js — minimal client for the mobile view.
//
// Two behaviours, nothing else:
// 1. Confirm the session is still valid on page load. If the
// session expired since the server rendered the HTML, bounce
// to "/" so the user doesn't read gated content without a
// session cookie (defensive — requireAuth already gates the
// page request itself).
// 2. POST /api/bifrost-join on CTA click; swap CTA panel →
// confirmation panel on success.
//
// There is no logout button on the mobile view; the masthead is
// logo-only by design. Users who want to log out can do so from a
// desktop session, or by clearing cookies.
//
// No GSAP, no Lenis, no d3. No sharing of globals with the desktop
// timeline/bifrost scripts — this file is only loaded by
// protected/mobile/index.html and never by the desktop view.
// ─────────────────────────────────────────────────────────────
(async function checkSession() {
try {
const res = await fetch('/auth/me', { credentials: 'same-origin' });
if (!res.ok) {
window.location.href = '/';
}
} catch {
// Network error — do not boot the user out; desktop behaviour is
// the same. If the next action actually needs the server, we'll
// surface the error there.
}
})();
const joinBtn = document.getElementById('m-join-btn');
const joinCta = document.getElementById('m-join-cta');
const joinConfirm = document.getElementById('m-join-confirm');
if (joinBtn && joinCta && joinConfirm) {
joinBtn.addEventListener('click', async () => {
joinBtn.disabled = true;
try {
const res = await fetch('/api/bifrost-join', {
method: 'POST',
credentials: 'same-origin',
headers: { 'content-type': 'application/json' },
// Server reads email + sessionId from the session cookie, body
// just needs to be parseable JSON for express.json() to keep
// its rhythm.
body: '{}',
});
if (res.status === 401) {
window.location.href = '/';
return;
}
if (!res.ok) {
joinBtn.disabled = false;
joinBtn.textContent = 'Try again';
return;
}
joinCta.hidden = true;
joinConfirm.hidden = false;
joinConfirm.scrollIntoView({ behavior: 'smooth', block: 'start' });
} catch {
joinBtn.disabled = false;
joinBtn.textContent = 'Try again';
}
});
}