PASSWORD
Incorrect Password
Connecting...
Tasks

Schedule

Coming soon...

INVOICES
CONTRACTS
โ˜€๏ธ SUNSHINE COFFEE
7838 Atlantic Way ยท Miami Beach

Add Task

Add Goal

Task Notes

Add Invoice

Add Contract

Add Lead

Add Project

Add Pipeline Item

function updateConnectionStatus(status, message) { const statusEl = document.getElementById('connectionStatus'); statusEl.className = `connection-status ${status}`; statusEl.textContent = message; if (status === 'connected') { setTimeout(() => statusEl.style.opacity = '0.7', 3000); } } // โ”€โ”€ GLOBAL STATE โ”€โ”€ let tasks = []; let invoices = []; let leads = []; let goals = []; let contracts = []; let pipeline = []; let projects = []; let socPlats = []; let nextIds = {}; let tonightTasks = JSON.parse(localStorage.getItem('alan-tonight') || '[]'); let currentEditingTaskId = null; let currentEditingGoalId = null; let currentNotesTaskId = null; let currentEditingInvoiceId = null; let currentEditingContractId = null; let currentEditingLeadId = null; // โ”€โ”€ INIT CHECK โ”€โ”€ if (localStorage.getItem(PW_KEY)) { document.getElementById('pwGate').style.display = 'none'; } else { setTimeout(() => document.getElementById('pwInput').focus(), 500); } // โ”€โ”€ NAV โ”€โ”€ const PTITLES = { todo:'Tasks', goals:'Goals', schedule:'Schedule', money:'Finance', bd:'Business Dev', pipeline:'Editing Pipeline', projects:'Projects', social:'Social', sunshine:'Sunshine' }; function toggleNav() { document.getElementById('sidenav').classList.toggle('open'); document.getElementById('navOverlay').classList.toggle('open'); } function closeNav() { document.getElementById('sidenav').classList.remove('open'); document.getElementById('navOverlay').classList.remove('open'); } function showPage(id,btn) { document.querySelectorAll('.page').forEach(p=>p.classList.remove('active')); document.querySelectorAll('.nav-link').forEach(n=>n.classList.remove('active')); document.getElementById('page-'+id).classList.add('active'); btn?.classList.add('active'); document.getElementById('pageTitle').textContent=PTITLES[id]||id; closeNav(); var gdBtn=document.getElementById('gdocsBtn'); if(gdBtn) { gdBtn.style.display=['todo','money','bd'].includes(id)?'block':'none'; } var tonightBanner = document.getElementById('tonightBanner'); if (tonightBanner) { tonightBanner.style.display = id === 'todo' ? 'block' : 'none'; } if(id==='todo') renderTasks(); if(id==='goals') renderGoals(); } // โ”€โ”€ DATA FUNCTIONS โ”€โ”€ async function loadData() { console.log('๐Ÿš€ Loading data...'); const result = await findWorkingTable(); if (result && result.config) { console.log(`โœ… Using table: ${result.config.table}`); WORKING_CONFIG = result.config; // Load existing data if any if (result.data && result.data.length > 0) { try { const row = result.data[0]; const rawTasks = JSON.parse(row.tasks || '[]'); tasks = rawTasks.map(t => ({ ...t, id: t.id || t.row_id || Date.now(), row_id: t.row_id || t.id, text: t.text || t.txt || '', priority: t.priority || t.pri || 'soon', bucket: t.bucket || 'personal', done: t.done || false, notes: t.notes || '' })); invoices = JSON.parse(row.invoices || '[]'); leads = JSON.parse(row.leads || '[]'); goals = JSON.parse(row.goals || '[]'); contracts = JSON.parse(row.contracts || '[]'); pipeline = JSON.parse(row.pipeline || '[]'); projects = JSON.parse(row.projects || '[]'); socPlats = JSON.parse(row.soc_plats || '[]'); nextIds = JSON.parse(row.next_ids || '{}'); populateClientSelects(); console.log(`๐Ÿ“Š Loaded: ${tasks.length}T ${goals.length}G`); updateConnectionStatus('connected', `${tasks.length}T ${goals.length}G loaded`); return; } catch (error) { console.error('Data parsing error:', error); } } else { console.log('Database connected but empty'); updateConnectionStatus('connected', 'Database ready'); } } else { console.log('Using localStorage fallback'); } // Load from localStorage tasks = JSON.parse(localStorage.getItem('alan-tasks') || '[]'); goals = JSON.parse(localStorage.getItem('alan-goals') || '[]'); invoices = JSON.parse(localStorage.getItem('alan-invoices') || '[]'); leads = JSON.parse(localStorage.getItem('alan-leads') || '[]'); console.log(`๐Ÿ“ฑ Local: ${tasks.length}T ${goals.length}G`); updateConnectionStatus(WORKING_CONFIG ? 'connected' : 'error', `Local: ${tasks.length}T ${goals.length}G`); } async function saveAll() { // Always save to localStorage localStorage.setItem('alan-tasks', JSON.stringify(tasks)); localStorage.setItem('alan-goals', JSON.stringify(goals)); localStorage.setItem('alan-invoices', JSON.stringify(invoices)); localStorage.setItem('alan-leads', JSON.stringify(leads)); localStorage.setItem('alan-tonight', JSON.stringify(tonightTasks)); if (!WORKING_CONFIG) return; try { const payload = { id: 'alan', tasks: JSON.stringify(tasks), invoices: JSON.stringify(invoices), leads: JSON.stringify(leads), goals: JSON.stringify(goals), contracts: JSON.stringify(contracts), pipeline: JSON.stringify(pipeline), projects: JSON.stringify(projects), soc_plats: JSON.stringify(socPlats), next_ids: JSON.stringify(nextIds), updated_at: new Date().toISOString() }; const response = await fetch(`${WORKING_CONFIG.url}/rest/v1/${WORKING_CONFIG.table}`, { method: 'POST', headers: { 'apikey': WORKING_CONFIG.key, 'Authorization': `Bearer ${WORKING_CONFIG.key}`, 'Content-Type': 'application/json', 'Prefer': 'resolution=merge-duplicates' }, body: JSON.stringify(payload) }); if (response.ok) { console.log('โœ… Saved to database'); } else { console.error('โŒ Save failed:', response.status); } } catch (error) { console.error('โŒ Save error:', error); } } // โ”€โ”€ TASKS โ”€โ”€ function renderTasks() { const todoStats = document.getElementById('todoStats'); const todoContent = document.getElementById('todoContent'); const total = tasks.length; const done = tasks.filter(t => t.done).length; const open = total - done; todoStats.innerHTML = `
${open}
Open
${done}
Done
${total}
Total
`; const BUCKETS = [ {id: 'personal', name: 'Personal'}, {id: 'family', name: 'Family'}, {id: 'wgm', name: "What's Good Miami"}, {id: 'tmd', name: 'TMD'}, {id: 'sunshine', name: 'Sunshine Coffee'}, {id: 'lucky', name: 'Lucky'} ]; let html = ''; BUCKETS.forEach(bucket => { const bucketTasks = tasks.filter(t => t.bucket === bucket.id); if (bucketTasks.length === 0) return; html += `
${bucket.name.toUpperCase()}
`; ['now', 'soon', 'later'].forEach(pri => { const priTasks = bucketTasks.filter(t => t.priority === pri); if (priTasks.length === 0) return; priTasks.forEach(task => { const taskId = task.row_id || task.id || Date.now(); const isTonight = tonightTasks.includes(taskId); html += `
${task.done ? 'โœ“' : ''}
${task.text}
${task.notes ? `
${task.notes}
` : ''}
`; }); }); }); if (!html) { html = '
No tasks yet. Add your first task!
'; } todoContent.innerHTML = html; renderTonightBanner(); } function renderTonightBanner() { const tonightList = document.getElementById('tonightList'); const tonightCount = document.getElementById('tonightCount'); const tonightTasksData = tasks.filter(t => { const taskId = t.row_id || t.id; return tonightTasks.includes(taskId); }); tonightCount.textContent = tonightTasksData.length; const banner = document.getElementById('tonightBanner'); if (document.getElementById('page-todo').classList.contains('active')) { banner.style.display = tonightTasksData.length > 0 ? 'block' : 'none'; } let html = ''; tonightTasksData.forEach(task => { const taskId = task.row_id || task.id; html += `
${task.done ? 'โœ“' : ''}
${task.text}
`; }); tonightList.innerHTML = html; } function toggleTask(taskId) { const task = tasks.find(t => (t.row_id || t.id) == taskId); if (task) { task.done = !task.done; saveAll(); renderTasks(); } } function toggleTonight(taskId) { const index = tonightTasks.indexOf(taskId); if (index > -1) { tonightTasks.splice(index, 1); } else { tonightTasks.push(taskId); } localStorage.setItem('alan-tonight', JSON.stringify(tonightTasks)); renderTasks(); } function openTaskNotes(taskId) { const task = tasks.find(t => (t.row_id || t.id) == taskId); if (task) { currentNotesTaskId = taskId; document.getElementById('nm-notes').value = task.notes || ''; openModal('notesModal'); } } function saveTaskNotes() { if (currentNotesTaskId) { const task = tasks.find(t => (t.row_id || t.id) == currentNotesTaskId); if (task) { task.notes = document.getElementById('nm-notes').value.trim(); saveAll(); closeModals(); renderTasks(); } } } function editTask(taskId) { const task = tasks.find(t => (t.row_id || t.id) == taskId); if (task) { currentEditingTaskId = taskId; document.getElementById('taskModalTitle').textContent = 'Edit Task'; document.getElementById('taskSaveBtn').textContent = 'Save'; document.getElementById('tm-txt').value = task.text; document.getElementById('tm-pri').value = task.priority; document.getElementById('tm-bucket').value = task.bucket; openModal('taskModal'); } } function saveTask() { const text = document.getElementById('tm-txt').value.trim(); const priority = document.getElementById('tm-pri').value; const bucket = document.getElementById('tm-bucket').value; if (!text) return; if (currentEditingTaskId) { const task = tasks.find(t => (t.row_id || t.id) == currentEditingTaskId); if (task) { task.text = text; task.priority = priority; task.bucket = bucket; } currentEditingTaskId = null; } else { const newTask = { row_id: Date.now(), id: Date.now(), text: text, priority: priority, bucket: bucket, done: false, created: new Date().toISOString(), notes: '' }; tasks.push(newTask); } saveAll(); closeModals(); renderTasks(); document.getElementById('taskModalTitle').textContent = 'Add Task'; document.getElementById('taskSaveBtn').textContent = 'Add'; document.getElementById('tm-txt').value = ''; document.getElementById('tm-pri').value = 'soon'; document.getElementById('tm-bucket').value = 'personal'; } function deleteTask(taskId) { if (confirm('Delete this task?')) { tasks = tasks.filter(t => (t.row_id || t.id) != taskId); tonightTasks = tonightTasks.filter(tid => tid != taskId); localStorage.setItem('alan-tonight', JSON.stringify(tonightTasks)); saveAll(); renderTasks(); } } // โ”€โ”€ GOALS โ”€โ”€ function renderGoals() { const goalsStats = document.getElementById('goalsStats'); const goalsContent = document.getElementById('goalsContent'); const total = goals.length; const completed = goals.filter(g => g.completed).length; const overdue = goals.filter(g => !g.completed && new Date(g.targetDate) < new Date()).length; goalsStats.innerHTML = `
${total}
Total
${completed}
Done
${overdue}
Overdue
`; let html = ''; goals.forEach((goal, index) => { const targetDate = new Date(goal.targetDate); const today = new Date(); const daysUntil = Math.ceil((targetDate - today) / (1000 * 60 * 60 * 24)); let statusClass = 'ontrack'; let statusText = 'On Track'; if (goal.completed) { statusClass = 'complete'; statusText = 'Complete'; } else if (daysUntil < 0) { statusClass = 'overdue'; statusText = `${Math.abs(daysUntil)} days overdue`; } else if (daysUntil <= 7) { statusClass = 'urgent'; statusText = `${daysUntil} days left`; } else { statusText = `${daysUntil} days left`; } html += `
${statusText}
${goal.title}
${goal.description ? `
${goal.description}
` : ''}
Target: ${targetDate.toLocaleDateString()}
`; }); if (!html) { html = '
No goals yet. Add your first goal!
'; } goalsContent.innerHTML = html; } function editGoal(index) { const goal = goals[index]; if (goal) { currentEditingGoalId = index; document.getElementById('goalModalTitle').textContent = 'Edit Goal'; document.getElementById('goalSaveBtn').textContent = 'Save'; document.getElementById('gm-title').value = goal.title; document.getElementById('gm-desc').value = goal.description || ''; document.getElementById('gm-date').value = goal.targetDate; openModal('goalModal'); } } function saveGoal() { const title = document.getElementById('gm-title').value.trim(); const description = document.getElementById('gm-desc').value.trim(); const targetDate = document.getElementById('gm-date').value; if (!title || !targetDate) return; if (currentEditingGoalId !== null) { goals[currentEditingGoalId].title = title; goals[currentEditingGoalId].description = description; goals[currentEditingGoalId].targetDate = targetDate; currentEditingGoalId = null; } else { goals.push({ gid: Date.now(), title: title, description: description, targetDate: targetDate, completed: false, created: new Date().toISOString() }); } saveAll(); closeModals(); renderGoals(); document.getElementById('goalModalTitle').textContent = 'Add Goal'; document.getElementById('goalSaveBtn').textContent = 'Add'; document.getElementById('gm-title').value = ''; document.getElementById('gm-desc').value = ''; document.getElementById('gm-date').value = ''; } function toggleGoal(index) { goals[index].completed = !goals[index].completed; if (goals[index].completed) { goals[index].completedDate = new Date().toISOString(); } else { delete goals[index].completedDate; } saveAll(); renderGoals(); } function deleteGoal(index) { if (confirm('Delete this goal?')) { goals.splice(index, 1); saveAll(); renderGoals(); } } // โ”€โ”€ FINANCE โ”€โ”€ function renderMoney() { const inv = invoices; const con = contracts; const paid = inv.filter(i=>i.sts==='paid').reduce((s,i)=>s+i.amt,0); const sent = inv.filter(i=>i.sts==='sent').reduce((s,i)=>s+i.amt,0); const draft = inv.filter(i=>i.sts==='draft').reduce((s,i)=>s+i.amt,0); document.getElementById('moneyStats').innerHTML = `
$${(paid/1000).toFixed(0)}k
Collected
$${(sent/1000).toFixed(0)}k
Sent
$${(draft/1000).toFixed(0)}k
Draft
`; const STS_INV = {paid:'#1db954',sent:'#f5a623',draft:'#888',overdue:'#e63329'}; document.getElementById('invoicesContent').innerHTML = inv.length ? inv.map((i,idx)=>`
${i.cli}
${i.dsc||''} ยท ${i.dt||''}
$${i.amt?.toLocaleString()}
${i.sts}
`).join('') : '
No invoices yet
'; const STS_CON = {signed:'#1db954',sent:'#f5a623',draft:'#888'}; document.getElementById('contractsContent').innerHTML = con.length ? con.map((c,idx)=>`
${c.cli} โ€” ${c.ttl}
${c.nts||''}
$${c.val?.toLocaleString()}
${c.sts}
`).join('') : '
No contracts yet
'; } function editInvoice(idx) { const i = invoices[idx]; currentEditingInvoiceId = idx; populateClientSelects(); document.getElementById('invoiceModalTitle').textContent = 'Edit Invoice'; document.getElementById('invoiceSaveBtn').textContent = 'Save'; document.getElementById('im-cli').value = i.cli; document.getElementById('im-dsc').value = i.dsc||''; document.getElementById('im-amt').value = i.amt||''; document.getElementById('im-ent').value = i.ent||'Breakthrough Brands LLC'; document.getElementById('im-dt').value = i.dt||''; document.getElementById('im-due').value = i.due||''; document.getElementById('im-sts').value = i.sts||'draft'; openModal('invoiceModal'); } function saveInvoice() { const obj = { id: currentEditingInvoiceId !== null ? invoices[currentEditingInvoiceId].id : (nextIds.nextIId++), cli: document.getElementById('im-cli').value, dsc: document.getElementById('im-dsc').value, amt: parseFloat(document.getElementById('im-amt').value)||0, ent: document.getElementById('im-ent').value, dt: document.getElementById('im-dt').value, due: document.getElementById('im-due').value, sts: document.getElementById('im-sts').value }; if (currentEditingInvoiceId !== null) { invoices[currentEditingInvoiceId] = obj; currentEditingInvoiceId = null; } else invoices.push(obj); saveAll(); closeModals(); renderMoney(); document.getElementById('invoiceModalTitle').textContent = 'Add Invoice'; document.getElementById('invoiceSaveBtn').textContent = 'Add'; } function deleteInvoice(idx) { if(confirm('Delete invoice?')) { invoices.splice(idx,1); saveAll(); renderMoney(); } } function saveContract() { const obj = { id: currentEditingContractId !== null ? contracts[currentEditingContractId].id : (nextIds.nextCId++), cli: document.getElementById('cm-cli').value, ttl: document.getElementById('cm-ttl').value, val: parseFloat(document.getElementById('cm-val').value)||0, ent: document.getElementById('cm-ent').value, sent: document.getElementById('cm-sent').value, sts: document.getElementById('cm-sts').value, nts: document.getElementById('cm-nts').value, sgn: '' }; if (currentEditingContractId !== null) { contracts[currentEditingContractId] = obj; currentEditingContractId = null; } else contracts.push(obj); saveAll(); closeModals(); renderMoney(); } function deleteContract(idx) { if(confirm('Delete contract?')) { contracts.splice(idx,1); saveAll(); renderMoney(); } } // โ”€โ”€ BUSINESS DEV โ”€โ”€ const STAGE_ORDER = ['new','contacted','proposal','closing','won','lost']; const STAGE_COLOR = {new:'#888',contacted:'#3a00f4',proposal:'#f5a623',closing:'#1db954',won:'#1db954',lost:'#e63329'}; function renderBD() { const total = leads.length; const pipeline = leads.filter(l=>!['won','lost'].includes(l.stg)).reduce((s,l)=>s+(l.val||0),0); const won = leads.filter(l=>l.stg==='won').reduce((s,l)=>s+(l.val||0),0); document.getElementById('bdStats').innerHTML = `
${total}
Leads
$${(pipeline/1000).toFixed(0)}k
Pipeline
$${(won/1000).toFixed(0)}k
Won
`; document.getElementById('leadsContent').innerHTML = leads.length ? leads.map((l,idx)=>`
${l.nm}
${l.co||''}
$${(l.val||0).toLocaleString()}
${l.stg}
${l.act ? `
โ†’ ${l.act}
` : ''}
`).join('') : '
No leads yet
'; } function editLead(idx) { const l = leads[idx]; currentEditingLeadId = idx; document.getElementById('leadModalTitle').textContent = 'Edit Lead'; document.getElementById('leadSaveBtn').textContent = 'Save'; document.getElementById('lm-nm').value = l.nm||''; document.getElementById('lm-co').value = l.co||''; document.getElementById('lm-stg').value = l.stg||'new'; document.getElementById('lm-val').value = l.val||''; document.getElementById('lm-act').value = l.act||''; openModal('leadModal'); } function saveLead() { const obj = { id: currentEditingLeadId !== null ? leads[currentEditingLeadId].id : (nextIds.nextLId++), nm: document.getElementById('lm-nm').value, co: document.getElementById('lm-co').value, stg: document.getElementById('lm-stg').value, val: parseFloat(document.getElementById('lm-val').value)||0, act: document.getElementById('lm-act').value, tags: [] }; if (currentEditingLeadId !== null) { leads[currentEditingLeadId] = obj; currentEditingLeadId = null; } else leads.push(obj); saveAll(); closeModals(); renderBD(); document.getElementById('leadModalTitle').textContent = 'Add Lead'; document.getElementById('leadSaveBtn').textContent = 'Add'; } function deleteLead(idx) { if(confirm('Delete lead?')) { leads.splice(idx,1); saveAll(); renderBD(); } } // โ”€โ”€ PIPELINE โ”€โ”€ const PL_STATUS = {brief:'#888',scripting:'#3a00f4',filming:'#f5a623',editing:'#f5a623',review:'#cfc0ff',done:'#1db954'}; function renderPipeline() { const total = pipeline.length; const inprog = pipeline.filter(p=>!['done'].includes(p.sts)).length; const done = pipeline.filter(p=>p.sts==='done').length; document.getElementById('pipelineStats').innerHTML = `
${total}
Total
${inprog}
In Progress
${done}
Done
`; document.getElementById('pipelineContent').innerHTML = pipeline.length ? pipeline.map((p,idx)=>`
${p.ttl||p.title||''}
${p.cli||''}
${p.sts}
`).join('') : '
No pipeline items yet
'; } function savePipelineItem() { pipeline.push({ id: nextIds.nextPId++, ttl: document.getElementById('plm-ttl').value, cli: document.getElementById('plm-cli').value, sts: document.getElementById('plm-sts').value }); saveAll(); closeModals(); renderPipeline(); } function deletePipelineItem(idx) { if(confirm('Delete?')) { pipeline.splice(idx,1); saveAll(); renderPipeline(); } } // โ”€โ”€ PROJECTS โ”€โ”€ const BKT_LABEL = {tmd:'TMD',wgm:"What's Good Miami",sunshine:'Sunshine Coffee',personal:'Personal',lucky:'Lucky'}; const BKT_COLOR = {tmd:'pu',wgm:'gr',sunshine:'or',personal:'bl',lucky:'ye'}; function renderProjects() { document.getElementById('projectsContent').innerHTML = projects.length ? projects.map((p,idx)=>`
${p.nm}
${BKT_LABEL[p.bkt]||p.bkt}
${p.notes ? `
${p.notes}
` : ''}
${p.canva && p.canva !== 'https://canva.com' ? `๐Ÿ“ Canva` : ''} ${p.claude && p.claude !== 'https://claude.ai' ? `๐Ÿค– Claude` : ''}
`).join('') : '
No projects yet
'; } function saveProject() { projects.push({ id: nextIds.nextProjId++, nm: document.getElementById('pm-nm').value, bkt: document.getElementById('pm-bkt').value, notes: document.getElementById('pm-notes').value, canva: document.getElementById('pm-canva').value, claude: document.getElementById('pm-claude').value }); saveAll(); closeModals(); renderProjects(); } function deleteProject(idx) { if(confirm('Delete project?')) { projects.splice(idx,1); saveAll(); renderProjects(); } } // โ”€โ”€ SOCIAL โ”€โ”€ const POST_STS = {live:'#1db954',scheduled:'#3a00f4',draft:'#888'}; function renderSocial() { document.getElementById('socialContent').innerHTML = socPlats.map(plat=>`
${plat.nm} ยท ${plat.hdl}
${(plat.posts||[]).map(p=>`
${p.txt}
${p.dt||''}
${p.sts}
`).join('')} ${!(plat.posts||[]).length ? '
No posts yet
' : ''}
`).join(''); } // โ”€โ”€ SUNSHINE โ”€โ”€ function renderSunshine() { const sunTasks = tasks.filter(t=>t.bucket==='sunshine'); const sunLeads = leads.filter(l=>(l.tags||[]).includes('Sunshine') || (l.co||'').toLowerCase().includes('sunshine')); document.getElementById('sunshineContent').innerHTML = `
TASKS (${sunTasks.length})
${sunTasks.length ? sunTasks.map(t=>`
${t.done?'โœ“':''}
${t.text}
`).join('') : '
No Sunshine tasks
'}
SOCIAL POSTS
${socPlats.filter(p=>p.hdl.includes('sunshine')).map(plat=>`
${plat.nm} ยท ${plat.hdl}
${(plat.posts||[]).map(p=>`
${p.txt}
${p.sts}
`).join('')}
`).join('')} `; } // โ”€โ”€ POPULATE CLIENT SELECTS โ”€โ”€ function populateClientSelects() { const clients = nextIds.clients || []; ['im-cli','cm-cli','plm-cli'].forEach(id => { const el = document.getElementById(id); if (el) el.innerHTML = clients.map(c=>``).join(''); }); } // โ”€โ”€ SHOW PAGE OVERRIDE โ”€โ”€ const _origShowPage = showPage; function showPage(id, btn) { _origShowPage(id, btn); if (id==='money') renderMoney(); if (id==='bd') renderBD(); if (id==='pipeline') renderPipeline(); if (id==='projects') renderProjects(); if (id==='social') renderSocial(); if (id==='sunshine') renderSunshine(); } function exportToGoogleDocs() { alert('Google Docs export coming soon!'); } // โ”€โ”€ MODALS โ”€โ”€ function openModal(id) { document.getElementById(id).classList.add('open'); setTimeout(() => { const firstInput = document.querySelector(`#${id} input, #${id} textarea`); if (firstInput) firstInput.focus(); }, 100); } function closeModals() { document.querySelectorAll('.mo').forEach(m => m.classList.remove('open')); currentEditingTaskId = null; currentEditingGoalId = null; currentNotesTaskId = null; } document.addEventListener('click', (e) => { if (e.target.classList.contains('mo')) closeModals(); }); document.addEventListener('keydown', (e) => { if (e.key === 'Escape') closeModals(); }); // โ”€โ”€ BOOT โ”€โ”€ async function boot() { console.log('๐Ÿš€ Alan OS starting...'); document.getElementById('topDate').textContent = new Date().toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' }); await loadData(); renderTasks(); console.log('โœ… Alan OS loaded'); } if (localStorage.getItem(PW_KEY)) { boot(); }