diff --git a/README.md b/README.md index 35166e4..f230cb3 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,13 @@ storage before closing on a phone. The Queues summary marks it **sync pending** foreground, and midnight lifecycle checks share one delivery flight. A successful account receipt removes the pending copy, while a revision conflict preserves both the phone plan and fresh server snapshot for review. Unsynced Tomorrow work is never promoted into Today. +**Plan Week Ahead** continues through seven local dates and now finishes on a mobile review step instead of +closing after the seventh save. The review shows planned minutes against each day’s capacity, marks overloads, +and flags work assigned to more than one date. Operators can move an item to another date without copying it; +the estimate follows the item and the server rejects duplicate cross-day assignments without advancing the +week revision. Confirmation remains disabled while duplicates exist or the account-bound week is still syncing. +Rapid saves and review moves use one network flight plus a coalesced latest-state delivery, so later staged days +are not stranded behind an earlier request. Planning edits can remain offline for up to 30 days. After that, the expired edit is discarded visibly and the account plan is kept rather than replaying stale intent. The server retains no more than 4,096 operation receipts per account and removes diff --git a/frontend/dashboard.css b/frontend/dashboard.css index 3dfb3fc..0594813 100644 --- a/frontend/dashboard.css +++ b/frontend/dashboard.css @@ -294,6 +294,30 @@ textarea { resize: vertical; min-height: 120px; } .week-conflict-plans { grid-template-columns:1fr; } .week-conflict-actions { flex-direction:column; } } +.week-review { margin-top:14px; } +.week-review h2 { margin-bottom:6px; } +.week-review-days { display:grid; gap:12px; } +.week-review-day { padding:12px; border:1px solid #31577f; border-radius:12px; background:#10233a; } +.week-review-day.is-overloaded { border-color:#f59e0b; background:#2a1c12; } +.week-review-day h3, .week-review-day p { margin:0 0 8px; } +.week-review-load { color:#bfdbfe; font-weight:700; } +.week-review-day ul { display:grid; gap:10px; margin:0; padding:0; list-style:none; } +.week-review-day li { display:grid; grid-template-columns:minmax(0,1fr) auto; gap:8px; align-items:end; padding-top:8px; border-top:1px solid #31577f; overflow-wrap:anywhere; } +.week-review-day label { display:grid; gap:4px; font-size:12px; } +.week-review-day select, .week-review-day button { min-height:44px; } +.week-review-day button { min-height:44px; } +.week-review-duplicates { margin:12px 0; padding:12px; border:1px solid #f59e0b; border-radius:10px; background:#2a1c12; } +.week-review-status { min-height:1.4em; margin:10px 0; } +#confirm-week-plan { width:100%; min-height:48px; position:sticky; bottom:0; } +.plan-today-sheet.week-review-mode .week-plan-dates, +.plan-today-sheet.week-review-mode .mobile-plan-today-nav, +.plan-today-sheet.week-review-mode #plan-today-fit, +.plan-today-sheet.week-review-mode #plan-today-selected, +.plan-today-sheet.week-review-mode #plan-today-available-work, +.plan-today-sheet.week-review-mode .plan-today-actions { display:none; } +@media (max-width:480px) { + .week-review-day li { grid-template-columns:1fr; } +} .mobile-plan-today-nav { position:sticky; top:0; z-index:5; display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:4px; margin:0 -18px 10px; padding:4px 18px; background:rgba(11,21,38,.98); border-block:1px solid #2a496e; } .mobile-plan-today-nav button { min-width:0; min-height:44px; padding:4px; border-color:transparent; font-size:12px; } .mobile-plan-today-nav button[aria-current="location"] { color:#bfdbfe; background:#17365a; border-color:#31577f; } diff --git a/frontend/dashboard.js b/frontend/dashboard.js index 507ce06..6715fe4 100644 --- a/frontend/dashboard.js +++ b/frontend/dashboard.js @@ -453,7 +453,8 @@ getLogin: () => planningOwnerLogin, }); const weekWorkflow=createWeekPlanWorkflow({controller:weekPlan,qs,getLogin:()=>planningOwnerLogin, - openPlanner:openPlanToday,escapeHtml,escapeAttribute:escAttr,todayWork, + openPlanner:openPlanToday,setReviewMode:value=>qs('#plan-today-sheet').classList.toggle('week-review-mode',value), + escapeHtml,escapeAttribute:escAttr,todayWork, refresh:refreshMyWorkView,warm:warmTodayOffline}); const todaySync = createTodaySync({ storage: localStorage, @@ -7896,6 +7897,15 @@ } }); qs('#cancel-plan-today').addEventListener('click', closePlanToday); + qs('#confirm-week-plan').addEventListener('click', () => { + if(!weekWorkflow.confirm()){ + qs('#week-review-status').textContent=weekPlan.pending()?'Wait for Week Ahead to finish syncing before confirming.':'Move duplicated work to one date before confirming.'; + return; + } + qs('#mobile-week-summary').textContent=weekPlan.summary(); + qs('#my-work-action-status').textContent='Week Ahead reviewed and confirmed.'; + taskOverlayHistory.leave(); + }); qs('#plan-today-sheet').addEventListener('click', event => { if (event.target === qs('#plan-today-sheet')) closePlanToday(); }); diff --git a/frontend/index.html b/frontend/index.html index 6bd717b..df8d2c5 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -504,6 +504,15 @@
+