Redesign BP tracker with lightweight views and unobtrusive save confirmations

This commit is contained in:
Peter Stockings
2026-09-08 15:07:57 +10:00
parent 25d1774e53
commit 87b60aac9b
40 changed files with 2693 additions and 2553 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+23 -68
View File
@@ -1,68 +1,23 @@
document.addEventListener('click', async (e) => {
const link = e.target.closest('a');
if (!link) return;
const url = link.getAttribute('href');
if (!url || url.startsWith('#') || url.startsWith('javascript:')) return;
// Only intercept same-origin links
if (link.origin !== window.location.origin) return;
// Ignore links that open in a new tab, download, or modifier keys
if (link.target === '_blank' || link.hasAttribute('download')) return;
if (e.ctrlKey || e.shiftKey || e.metaKey || e.altKey) return;
// Optional: add a "data-turbo='false'" attribute check to disable it on specific links
if (link.getAttribute('data-turbo') === 'false') return;
e.preventDefault();
document.body.style.cursor = 'wait';
try {
const response = await fetch(url);
if (!response.ok) throw new Error('Fetch failed');
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
document.title = doc.title;
document.body.innerHTML = doc.body.innerHTML;
// Carry over classes on the body if they changed
document.body.className = doc.body.className;
document.body.style.cursor = 'default';
window.history.pushState({}, '', url);
window.scrollTo(0, 0);
// Dispatch a custom event so other scripts can re-initialize if necessary
document.dispatchEvent(new Event('diy-turbo:load'));
} catch (error) {
console.error('DIY Turbo navigation error:', error);
window.location.href = url; // fallback
}
});
window.addEventListener('popstate', async () => {
document.body.style.cursor = 'wait';
try {
const response = await fetch(window.location.href);
if (!response.ok) throw new Error('Fetch failed');
const html = await response.text();
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
document.title = doc.title;
document.body.innerHTML = doc.body.innerHTML;
document.body.className = doc.body.className;
document.body.style.cursor = 'default';
document.dispatchEvent(new Event('diy-turbo:load'));
} catch (error) {
console.error('DIY Turbo popstate error:', error);
window.location.reload(); // fallback
}
});
// Core flows use native links and forms. These enhancements are optional.
document.addEventListener('click', (event) => {
const close = event.target.closest('[data-dismiss]');
if (close) {
const notice = close.closest('.notice');
const next = document.querySelector('.add-action, .entry-form input:not([type=hidden]), #main');
notice.remove();
next?.focus();
}
if (event.target.closest('[data-print]')) window.print();
document.querySelectorAll('.account-menu[open]').forEach((menu) => {
if (!menu.contains(event.target)) menu.open = false;
});
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') {
document.querySelectorAll('.account-menu[open]').forEach((menu) => {
menu.open = false;
menu.querySelector('summary').focus();
});
}
});
document.querySelectorAll('[data-print]').forEach((button) => { button.hidden = false; });
+1 -1
View File
@@ -1 +1 @@
document.addEventListener("click",async t=>{const e=t.target.closest("a");if(!e)return;const o=e.getAttribute("href");if(o&&!o.startsWith("#")&&!o.startsWith("javascript:")&&e.origin===window.location.origin&&!("_blank"===e.target||e.hasAttribute("download")||t.ctrlKey||t.shiftKey||t.metaKey||t.altKey||"false"===e.getAttribute("data-turbo"))){t.preventDefault(),document.body.style.cursor="wait";try{const t=await fetch(o);if(!t.ok)throw new Error("Fetch failed");const e=await t.text(),r=(new DOMParser).parseFromString(e,"text/html");document.title=r.title,document.body.innerHTML=r.body.innerHTML,document.body.className=r.body.className,document.body.style.cursor="default",window.history.pushState({},"",o),window.scrollTo(0,0),document.dispatchEvent(new Event("diy-turbo:load"))}catch(t){console.error("DIY Turbo navigation error:",t),window.location.href=o}}}),window.addEventListener("popstate",async()=>{document.body.style.cursor="wait";try{const t=await fetch(window.location.href);if(!t.ok)throw new Error("Fetch failed");const e=await t.text(),o=(new DOMParser).parseFromString(e,"text/html");document.title=o.title,document.body.innerHTML=o.body.innerHTML,document.body.className=o.body.className,document.body.style.cursor="default",document.dispatchEvent(new Event("diy-turbo:load"))}catch(t){console.error("DIY Turbo popstate error:",t),window.location.reload()}});
document.addEventListener("click",e=>{const t=e.target.closest("[data-dismiss]");if(t){const e=t.closest(".notice"),n=document.querySelector(".add-action, .entry-form input:not([type=hidden]), #main");e.remove(),n?.focus()}e.target.closest("[data-print]")&&window.print(),document.querySelectorAll(".account-menu[open]").forEach(t=>{t.contains(e.target)||(t.open=!1)})}),document.addEventListener("keydown",e=>{"Escape"===e.key&&document.querySelectorAll(".account-menu[open]").forEach(e=>{e.open=!1,e.querySelector("summary").focus()})}),document.querySelectorAll("[data-print]").forEach(e=>{e.hidden=!1});