Schedule
Click to select · shift-click or lasso to multi-select · drag blank area to lasso · drop on left half to swap · drop on right half to stack
let HS=7,HE=21; const HPX=80,SNAP=15,SHORT_DUR=35; const COLORS=[ // row 1 — blues & teals {name:'sky', fill:'#C8E6FA',text:'#09527A',border:'#7DC4EE',dot:'#2490C8',print:'#2490C8'}, {name:'blue', fill:'#B5D4F4',text:'#0C447C',border:'#85B7EB',dot:'#378ADD',print:'#2E7CC4'}, {name:'navy', fill:'#B8C8E8',text:'#1A2F6A',border:'#7A97D4',print:'#1A2F6A',dot:'#3A5FB0'}, {name:'teal', fill:'#9FE1CB',text:'#085041',border:'#5DCAA5',dot:'#1D9E75',print:'#1D9E75'}, {name:'mint', fill:'#B8EDDF',text:'#0A5E48',border:'#6BD4B8',dot:'#18A87C',print:'#18A87C'}, // row 2 — purples & pinks {name:'purple', fill:'#CECBF6',text:'#3C3489',border:'#AFA9EC',dot:'#7F77DD',print:'#7F77DD'}, {name:'violet', fill:'#DCC8F4',text:'#4A2080',border:'#BB96E8',dot:'#9060D0',print:'#9060D0'}, {name:'pink', fill:'#F4C0D1',text:'#72243E',border:'#ED93B1',dot:'#D4537E',print:'#C94070'}, {name:'rose', fill:'#F9C8C8',text:'#7A1A1A',border:'#F09090',dot:'#D84848',print:'#C83030'}, {name:'lilac', fill:'#E8D0F0',text:'#5A2A70',border:'#CC99E0',dot:'#A060C8',print:'#8040A8'}, // row 3 — greens & earthy {name:'green', fill:'#C0DD97',text:'#27500A',border:'#97C459',dot:'#639922',print:'#5A8C1A'}, {name:'sage', fill:'#C8DCC0',text:'#2A4A20',border:'#90C080',dot:'#508040',print:'#406830'}, {name:'amber', fill:'#FAC775',text:'#633806',border:'#EF9F27',dot:'#BA7517',print:'#BA7517'}, {name:'coral', fill:'#F5C4B3',text:'#712B13',border:'#F0997B',dot:'#D85A30',print:'#D85A30'}, {name:'peach', fill:'#FAD8B8',text:'#6B3A10',border:'#F0B070',dot:'#D08030',print:'#B86020'}, // row 4 — neutrals & dark {name:'slate', fill:'#C8D4DC',text:'#283848',border:'#8AACBE',dot:'#4A7890',print:'#2C5870'}, {name:'stone', fill:'#D8D0C4',text:'#3A3020',border:'#B0A090',dot:'#786050',print:'#584030'}, {name:'lemon', fill:'#F0ECA0',text:'#4A4800',border:'#D8D040',dot:'#A0A000',print:'#787800'}, {name:'gold', fill:'#F8DCA0',text:'#5A3A00',border:'#E8B840',dot:'#C09010',print:'#906800'}, {name:'ash', fill:'#D0D0D8',text:'#303048',border:'#9090A8',dot:'#505070',print:'#303050'}, ]; let state={title:'',events:[]}; let nid=1,editId=null,selColor='blue',selectedId=null,use24h=false; let equipDragSrc=null; const ICON_PIN=``; const ICON_USER=``; function t2m(t){const[h,m]=t.split(':').map(Number);return h*60+m;} function m2t(m){const h=Math.floor(m/60),mn=m%60;return(h<10?'0':'')+h+':'+(mn<10?'0':'')+mn;} function m2y(m){return((m-HS*60)/60)*HPX;} function dl(d){if(d<60)return d+'m';if(d%60===0)return(d/60)+'h';return Math.floor(d/60)+'h '+(d%60)+'m';} function ft(t){ const[h,m]=t.split(':').map(Number); if(use24h){return(h<10?'0':'')+h+':'+(m<10?'0':'')+m;} const ap=h<12?'am':'pm';const h12=h%12||12; return h12+(m?':'+String(m).padStart(2,'0'):'')+ap; } function toggleClock(){ use24h=!use24h; document.getElementById('clockToggle').classList.toggle('on',use24h); buildTimeline();renderSidebar();if(selectedId)renderDetails(selectedId); } function showToast(msg){ const t=document.getElementById('toast');t.textContent=msg;t.classList.add('show'); setTimeout(()=>t.classList.remove('show'),2800); } /* ── History / Undo ── */ const MAX_HISTORY=40; let history=[]; let redoStack=[]; function snapshot(){ history.push(JSON.stringify({state:JSON.parse(JSON.stringify(state)),nid,HS,HE})); if(history.length>MAX_HISTORY)history.shift(); redoStack=[]; updateUndoBtn(); } function doUndo(){ if(!history.length)return; redoStack.push(JSON.stringify({state:JSON.parse(JSON.stringify(state)),nid,HS,HE})); const prev=JSON.parse(history.pop()); state=prev.state;nid=prev.nid; if(prev.HS!=null)HS=prev.HS; if(prev.HE!=null)HE=prev.HE; document.getElementById('eventTitle').value=state.title; onTitleInput();buildTimeline();renderSidebar(); if(selectedId&&!state.events.find(e=>e.id===selectedId)){ selectedId=null; document.getElementById('detailsEmpty').style.display='flex'; document.getElementById('detailsContent').classList.remove('visible'); } else if(selectedId){renderDetails(selectedId);} saveToLocalStorage();updateUndoBtn(); } function doRedo(){ if(!redoStack.length)return; history.push(JSON.stringify({state:JSON.parse(JSON.stringify(state)),nid,HS,HE})); const next=JSON.parse(redoStack.pop()); state=next.state;nid=next.nid; if(next.HS!=null)HS=next.HS; if(next.HE!=null)HE=next.HE; document.getElementById('eventTitle').value=state.title; onTitleInput();buildTimeline();renderSidebar(); if(selectedId&&!state.events.find(e=>e.id===selectedId)){ selectedId=null; document.getElementById('detailsEmpty').style.display='flex'; document.getElementById('detailsContent').classList.remove('visible'); } else if(selectedId){renderDetails(selectedId);} saveToLocalStorage();updateUndoBtn(); }> Event Schedule Planner
Schedule
Click to select · shift-click or lasso to multi-select · drag blank area to lasso · drop on left half to swap · drop on right half to stack