-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshell.js
More file actions
90 lines (83 loc) · 3.67 KB
/
Copy pathshell.js
File metadata and controls
90 lines (83 loc) · 3.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
* shell.js - injects a consistent mobile bottom-nav across every page.
*
* Why: the topbar nav works fine on desktop but on a 390px-wide phone the 5 nav
* items either wrap or require horizontal scroll. RBTs use this on their phones
* mid-day; the bottom-nav matches native iOS / Android conventions and keeps
* primary actions always reachable with thumb.
*
* Hides itself on viewports >= 720px (CSS-driven). Topbar nav hides on < 720px
* so the two don't compete.
*
* Auto-detects current page from URL, marks the matching item active.
*/
(function () {
const RBT_LINKS = [
{ href: "rbt-home.html", label: "Today", icon: "🏠" },
{ href: "rbt-session-entry.html", label: "Write", icon: "✍️" },
{ href: "rbt-quick-log.html", label: "Quick Log", icon: "⚡" },
{ href: "rbt-note-review.html", label: "Review", icon: "✓" },
{ href: "rbt-cancellation.html", label: "Cancel", icon: "✕" }
];
const ADMIN_LINKS = [
{ href: "admin-overview.html", label: "Overview", icon: "📊" },
{ href: "admin-review-queue.html", label: "Queue", icon: "📋" },
{ href: "admin-reference-library.html", label: "Library", icon: "📚" }
];
function currentPath() {
return (location.pathname.split("/").pop() || "rbt-home.html").replace(/\.html$/, "");
}
function isAdminPage() {
return /^admin-/.test(currentPath());
}
function build() {
const links = isAdminPage() ? ADMIN_LINKS : RBT_LINKS;
const cur = currentPath();
const nav = document.createElement("nav");
nav.className = "mobile-bottom-nav";
nav.setAttribute("aria-label", "Primary");
links.forEach(l => {
const a = document.createElement("a");
a.href = l.href;
const isActive = l.href.replace(/\.html$/, "") === cur;
a.className = "mbn-item" + (isActive ? " mbn-active" : "");
a.innerHTML = `<span class="mbn-icon" aria-hidden="true">${l.icon}</span><span class="mbn-label">${l.label}</span>`;
nav.appendChild(a);
});
return nav;
}
function inject() {
// Don't double-inject on pages that already include shell.js multiple times
if (document.querySelector(".mobile-bottom-nav")) return;
document.body.appendChild(build());
// Add bottom padding to body so content doesn't get hidden behind the nav on mobile
document.body.classList.add("has-mobile-bottom-nav");
collapseFooterOnMobile();
}
/*
* collapseFooterOnMobile - on mobile only, wrap the footer disclaimer in a
* <details><summary> so it reads as a single-line "Compliance details" tap
* target instead of three lines of dense legal copy on every short page.
* Desktop is unaffected. Media-query-keyed; a hard reload after rotating /
* widening past 720px restores the inline disclaimer.
*/
function collapseFooterOnMobile() {
if (!window.matchMedia || !window.matchMedia("(max-width: 720px)").matches) return;
const disclaimer = document.querySelector(".footer-disclaimer");
if (!disclaimer || disclaimer.closest(".footer-disclaimer-details")) return;
const details = document.createElement("details");
details.className = "footer-disclaimer-details";
const summary = document.createElement("summary");
summary.textContent = "Compliance details";
details.appendChild(summary);
// Insert the details right before the disclaimer, then move the disclaimer
// inside so existing content stays semantically intact.
disclaimer.parentNode.insertBefore(details, disclaimer);
details.appendChild(disclaimer);
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", inject);
} else {
inject();
}
})();