From a8d0ff51d89e1035e3fb6e0f7e8ac4effbc0e451 Mon Sep 17 00:00:00 2001 From: thanhly-byte Date: Thu, 9 Jul 2026 11:46:25 -0700 Subject: [PATCH 1/2] Polish tracker metadata --- vault-tracker.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vault-tracker.html b/vault-tracker.html index 93e1a30..373341d 100644 --- a/vault-tracker.html +++ b/vault-tracker.html @@ -3,6 +3,7 @@ + Runway to 15' — Weekly Training Tracker @@ -114,7 +115,7 @@

Runway to 15'0"

- +
Not connected — checkbox data saves on this device only until you connect your sheet.
From d32ae07ea6878a01c1d43992de9c66b5154b12b6 Mon Sep 17 00:00:00 2001 From: thanhly-byte Date: Thu, 9 Jul 2026 11:51:36 -0700 Subject: [PATCH 2/2] Prevent duplicate sheet log entries --- vault-tracker.html | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/vault-tracker.html b/vault-tracker.html index 373341d..cc55dd4 100644 --- a/vault-tracker.html +++ b/vault-tracker.html @@ -195,8 +195,10 @@

Runway to 15'0"

const STORAGE_KEY = "vault-tracker-week"; const NOTES_KEY = "vault-tracker-notes"; const URL_KEY = "vault-sheet-webapp-url"; +const LOGGED_KEY = "vault-tracker-logged"; let state = {}; let notes = {}; +let loggedTasks = {}; let sheetUrl = ""; function totalTasks(){ return PROGRAM.reduce((sum,d)=>sum+d.tasks.length,0); } @@ -279,10 +281,15 @@

Runway to 15'0"

document.getElementById("goalReadout").innerHTML = pct + "%week done"; } +function buildLogKey(entry){ + return `${entry.date}:${entry.day}:${entry.exercise}`; +} + async function persistLocal(){ try{ localStorage.setItem(STORAGE_KEY, JSON.stringify(state)); localStorage.setItem(NOTES_KEY, JSON.stringify(notes)); + localStorage.setItem(LOGGED_KEY, JSON.stringify(loggedTasks)); }catch(err){ console.error("Local save failed:", err); } } @@ -300,6 +307,10 @@

Runway to 15'0"

sheetUrl = u || ""; if(sheetUrl){ document.getElementById("sheetUrl").value = sheetUrl; setStatus(true, "Connected — checkboxes log to your Sheet's Log tab."); loadPRs(); } }catch(err){ sheetUrl = ""; } + try{ + const l = localStorage.getItem(LOGGED_KEY); + loggedTasks = l ? JSON.parse(l) : {}; + }catch(err){ loggedTasks = {}; } } function setStatus(ok, msg){ @@ -311,6 +322,11 @@

Runway to 15'0"

async function logToSheet(entry, dayKey){ const tag = document.getElementById("sync-"+dayKey); if(!sheetUrl){ if(tag) tag.textContent = ""; return; } + if(!entry.completed){ if(tag) tag.textContent = ""; return; } + + const logKey = buildLogKey(entry); + if(loggedTasks[logKey]){ if(tag) tag.textContent = "Already synced for today"; return; } + if(tag) tag.textContent = "Syncing..."; try{ await fetch(sheetUrl, { @@ -319,6 +335,8 @@

Runway to 15'0"

headers: { "Content-Type": "text/plain;charset=utf-8" }, body: JSON.stringify(entry) }); + loggedTasks[logKey] = true; + await persistLocal(); if(tag) tag.textContent = "Sent to sheet ✓ " + new Date().toLocaleTimeString() + " — check Log tab to confirm"; }catch(err){ if(tag) tag.textContent = "Sync failed — saved locally only."; @@ -356,6 +374,7 @@

Runway to 15'0"

document.getElementById("resetBtn").addEventListener("click", async ()=>{ state = {}; + loggedTasks = {}; await persistLocal(); render(); updateGoal();