diff --git a/frontend/dashboard.css b/frontend/dashboard.css index b013d2f..761e1d9 100644 --- a/frontend/dashboard.css +++ b/frontend/dashboard.css @@ -273,6 +273,15 @@ textarea { resize: vertical; min-height: 120px; } .week-conflict-day strong { display:block; color:#bfdbfe; } .week-conflict-actions { display:flex; gap:8px; margin-top:14px; } .week-conflict-actions button { min-height:44px; flex:1 1 0; } +.week-conflict-days { display:grid; gap:12px; } +.week-conflict-date { min-width:0; padding:12px; border:1px solid #31577f; border-radius:12px; background:#10233a; } +.week-conflict-date h4 { margin:0 0 8px; color:#bfdbfe; } +.week-conflict-choice { min-height:44px; display:flex; align-items:center; gap:10px; padding:8px; border-radius:8px; } +.week-conflict-choice:has(input:checked) { background:#17365a; outline:1px solid #60a5fa; } +.week-conflict-choice input { min-width:20px; min-height:20px; } +.week-conflict-choice span { display:grid; min-width:0; } +.week-conflict-choice small { color:#a9bdd3; } +#save-merged-week { width:100%; min-height:44px; margin-top:14px; } .week-conflict-status { min-height:1.4em; margin-top:8px; } .plan-today-sheet.week-conflict-mode .week-plan-dates, .plan-today-sheet.week-conflict-mode .mobile-plan-today-nav, diff --git a/frontend/dashboard.js b/frontend/dashboard.js index a409577..141e45b 100644 --- a/frontend/dashboard.js +++ b/frontend/dashboard.js @@ -3063,30 +3063,15 @@ requestAnimationFrame(() => keep.focus()); } - function weekConflictMarkup(value) { - const days=value?.days||[]; - if(!days.length)return '

Nothing planned.

'; - return days.map(day=>{ - const estimates=day.estimates||{}; - const minutes=(day.ids||[]).reduce((total,id)=>total+(Number(estimates[id])||0),0); - const capacity=Number(day.capacity_minutes)||0; - const detail=(day.ids||[]).length+' item'+((day.ids||[]).length===1?'':'s')+ - (minutes&&capacity?' · '+minutes+' of '+capacity+' min':''); - return '

'+escapeHtml(day.plan_date)+''+escapeHtml(detail)+'

'; - }).join(''); - } - function showWeekConflict(conflict) { qs('#plan-today-title').textContent='Resolve Week Ahead conflict'; - qs('#week-conflict-phone-plan').innerHTML=weekConflictMarkup(conflict.local); - qs('#week-conflict-server-plan').innerHTML=weekConflictMarkup(conflict.remote); + const focus=weekWorkflow.renderConflict(conflict); qs('#week-conflict-status').textContent=''; qs('#week-conflict-review').hidden=false; qs('#plan-today-sheet').classList.add('week-conflict-mode'); qs('#plan-today-sheet').hidden=false; document.body.classList.add('task-overlay-open'); - const keep=qs('#keep-phone-week'); - keep.focus();requestAnimationFrame(()=>keep.focus()); + focus.focus();requestAnimationFrame(()=>focus.focus()); } function openPlanToday(trigger, navigate = true, actualMinutes = null) { @@ -7890,6 +7875,26 @@ qs('#my-work-action-status').textContent='Saved account Week Ahead plan selected. Today was not changed.'; closePlanToday(); }); + qs('#save-merged-week').addEventListener('click', async () => { + const save=qs('#save-merged-week'); + save.disabled=true; + qs('#week-conflict-status').textContent='Saving combined Week Ahead plan…'; + try { + await weekPlan.saveMerged(); + qs('#mobile-week-summary').textContent=weekPlan.summary(); + qs('#my-work-action-status').textContent='Combined Week Ahead changes are saved. Today was not changed.'; + closePlanToday(); + } catch(error) { + const conflict=weekPlan.conflict(); + if(conflict)showWeekConflict(conflict); + qs('#week-conflict-status').textContent=error?.status===409? + 'Week Ahead changed again. The latest days are preserved; review the remaining choices.': + `${error.message||'The combined week could not be saved.'} Your phone plan is still preserved.`; + } finally { + const conflict=weekPlan.conflict(); + save.disabled=Boolean(conflict?.conflicts?.some(item=>!item.choice)); + } + }); qs('#cancel-plan-today').addEventListener('click', closePlanToday); 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 4aa15d7..85cd60b 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -483,9 +483,11 @@