๐Ÿ’Ž
Loading...
๐Ÿ’Ž
Smart Sheet Studio
๐Ÿ”„
Your net worth
$0
Loading...
Overview
๐Ÿ’ฐ
Total Assets
$0
๐Ÿ’ณ
Total Debt
$0
๐Ÿ“ˆ
Avg Growth
โ€”
๐ŸŽฏ
Freedom Score
0%
12-month growth
Net worth chart0 months
JanFebMarAprMayJunJulAugSepOctNovDec
Debt payoff
๐Ÿ† Debt Payoff Progress0%
Enter original debt in Settings to track progress
Recent monthsView all โ†’
MonthNet WorthChange
Log your first month โ†’
โš™๏ธ
Assets & Liabilities
Update balances. Saves to your Google Sheet.
Assets
๐ŸฆBank / CashSavings & checking
๐Ÿ Home / Real EstateEstimated value
๐Ÿ“ˆInvestmentsStocks, ETFs, 401k
โ‚ฟCrypto
๐Ÿš—VehiclesMarket value
๐Ÿ’ŽOther Assets
Total Assets$0
Liabilities
Current = today ยท Original = starting amount (once)
๐Ÿ  Mortgage
๐Ÿš— Car Loan
๐Ÿ’ณ Credit Cards
๐ŸŽ“ Student Loans
Total Debt$0

Saves directly to your private Google Sheet

๐Ÿ“…
Monthly Log
๏ผ‹
Tap + to log this month. Update once a month.
MonthNet WorthChange
Tap + to log your first month
โœ…
Monthly Checklist
0 of 5 tasks done
This month
Year tracker
๐Ÿ’ก Set a reminder on the 1st โ€” "Wealth Check-in"
๐Ÿ’ŽDashboard
โš™๏ธSettings
๐Ÿ“…Log
โœ…Checklist
try{ const[a,l,log]=await Promise.all([sheetsRead(SHEET_ID,'Settings!C4:C9'),sheetsRead(SHEET_ID,'Settings!C14:D18'),sheetsRead(SHEET_ID,'Monthly Log!C4:D15')]); const g=(arr,r,c)=>parseFloat(arr[r]?.[c])||0; D={assets:{bank:g(a,0,0),home:g(a,1,0),investments:g(a,2,0),crypto:g(a,3,0),vehicles:g(a,4,0),other:g(a,5,0)},liab:{mortgage:{cur:g(l,0,0),orig:g(l,0,1)},car:{cur:g(l,1,0),orig:g(l,1,1)},cc:{cur:g(l,2,0),orig:g(l,2,1)},student:{cur:g(l,3,0),orig:g(l,3,1)},other:{cur:g(l,4,0),orig:g(l,4,1)}},log:MOS.map((m,i)=>({month:m,assets:g(log,i,0),liab:g(log,i,1)}))}; localStorage.setItem('wd_data_'+SHEET_ID,JSON.stringify(D)); bootApp(); }catch(e){TOKEN=null;document.getElementById('loading').style.display='none';document.getElementById('signin-screen').style.display='flex';toast('Session expired โ€” sign in again');} } async function syncData(){if(!TOKEN)await reAuth();toast('Syncing...');await loadData();renderAll();fillForm();toast('โœ“ Synced');} async function reAuth(){ return new Promise(res=>{ const c=google.accounts.oauth2.initTokenClient({client_id:CLIENT_ID,scope:SCOPES,prompt:'',callback:async r=>{if(!r.error){TOKEN=r.access_token;}res();}}); c.requestAccessToken(); }); } function getEmpty(){return{assets:{bank:0,home:0,investments:0,crypto:0,vehicles:0,other:0},liab:{mortgage:{cur:0,orig:0},car:{cur:0,orig:0},cc:{cur:0,orig:0},student:{cur:0,orig:0},other:{cur:0,orig:0}},log:MOS.map(m=>({month:m,assets:0,liab:0}))};} function bootApp(){document.getElementById('loading').style.display='none';document.getElementById('setup-screen').style.display='none';document.getElementById('signin-screen').style.display='none';document.getElementById('tbar').style.display='flex';renderAll();fillForm();go('dashboard');} function renderAll(){if(!D)return;renderDash();renderLog();renderChecklist();} function renderDash(){ const ta=Object.values(D.assets).reduce((a,b)=>a+b,0); const td=Object.values(D.liab).reduce((a,b)=>a+(b.cur||0),0); const to=Object.values(D.liab).reduce((a,b)=>a+(b.orig||0),0); const nw=ta-td,fr=to>0?Math.max(0,Math.min(1,(to-td)/to)):0; const fil=D.log.filter(e=>e.assets>0||e.liab>0); const nwArr=fil.map(e=>e.assets-e.liab); let avg=0;if(nwArr.length>1){const ch=nwArr.slice(1).map((v,i)=>v-nwArr[i]);avg=ch.reduce((a,b)=>a+b,0)/ch.length;} const el=document.getElementById('d-nw');el.textContent=fmt(nw);el.className='hdr-nw'+(nw<0?' neg':''); document.getElementById('d-badge').textContent=avg?fmtC(avg)+' avg/month':'Log months to see growth'; document.getElementById('d-assets').textContent=fmt(ta);document.getElementById('d-debt').textContent=fmt(td); document.getElementById('d-freedom').textContent=Math.round(fr*1000)/10+'%';document.getElementById('d-growth').textContent=avg?fmtC(Math.round(avg)):'โ€”'; const pct=Math.round(fr*1000)/10;document.getElementById('d-pct').textContent=pct+'%'; setTimeout(()=>{document.getElementById('d-pfill').style.width=pct+'%';},300); if(to>0)document.getElementById('d-psub').textContent=fmt(to-td)+' paid off ยท '+fmt(td)+' remaining of '+fmt(to); renderChart(D.log);document.getElementById('d-chart-badge').textContent=fil.length+' month'+(fil.length!==1?'s':''); const rec=fil.slice(-5).reverse();const logEl=document.getElementById('d-log'); if(!rec.length){logEl.innerHTML='
Log your first month โ†’
';return;} logEl.innerHTML=rec.map((e,i)=>{const nwv=e.assets-e.liab,chg=i'+e.month.slice(0,3)+''+fmt(nwv)+''+(chg!==null?fmtC(chg):'โ€”')+'โœ๏ธ';}).join(''); logEl.addEventListener('click',ev=>{const t=ev.target.closest('.log-edit');if(t&&t.dataset.month)editLog(t.dataset.month);}); } function renderChart(log){ const svg=document.getElementById('d-chart'),f=log.filter(e=>e.assets>0||e.liab>0); if(f.length<2){svg.innerHTML='Log 2+ months to see chart';return;} const v=f.map(e=>e.assets-e.liab),mn=Math.min(...v),mx=Math.max(...v),rng=mx-mn||1,W=340,H=100,P=6; const pts=v.map((val,i)=>[P+(i/(v.length-1))*(W-P*2),H-P-((val-mn)/rng)*(H-P*2)]); const path='M '+pts.map(p=>p[0]+','+p[1]).join(' L ');const last=pts[pts.length-1];const color=v[v.length-1]>=v[0]?'#10B981':'#EF4444'; svg.innerHTML=``; } function renderLog(){ if(!D)return;const f=D.log.filter(e=>e.assets>0||e.liab>0),el=document.getElementById('log-rows'); if(!f.length){el.innerHTML='
Tap + to log your first month
';return;} el.innerHTML=f.map((e,i)=>{const nwv=e.assets-e.liab,chg=i>0?nwv-(f[i-1].assets-f[i-1].liab):null;return'
'+e.month+''+fmt(nwv)+''+(chg!==null?fmtC(chg):'โ€”')+'โœ๏ธ
';}).join(''); el.addEventListener('click',ev=>{const t=ev.target.closest('.log-edit');if(t&&t.dataset.month)editLog(t.dataset.month);}); } function fillForm(){ if(!D)return;const a=D.assets,l=D.liab,s=(id,v)=>{const e=document.getElementById(id);if(e)e.value=v||'';}; s('f-bank',a.bank);s('f-home',a.home);s('f-invest',a.investments);s('f-crypto',a.crypto);s('f-vehicles',a.vehicles);s('f-other',a.other); s('f-mc',l.mortgage.cur);s('f-mo',l.mortgage.orig);s('f-cc2',l.car.cur);s('f-co',l.car.orig);s('f-ccc',l.cc.cur);s('f-cco',l.cc.orig);s('f-sc',l.student.cur);s('f-so',l.student.orig); calcTotals(); } function calcTotals(){ const ta=['f-bank','f-home','f-invest','f-crypto','f-vehicles','f-other'].reduce((s,id)=>s+num(id),0); const td=['f-mc','f-cc2','f-ccc','f-sc'].reduce((s,id)=>s+num(id),0); document.getElementById('f-ta').textContent=fmt(ta);document.getElementById('f-td').textContent=fmt(td); } async function saveSettings(){ if(!TOKEN)await reAuth(); const btn=document.getElementById('save-btn');btn.textContent='Saving...';btn.disabled=true; const a={bank:num('f-bank'),home:num('f-home'),investments:num('f-invest'),crypto:num('f-crypto'),vehicles:num('f-vehicles'),other:num('f-other')}; const l={mortgage:{cur:num('f-mc'),orig:num('f-mo')},car:{cur:num('f-cc2'),orig:num('f-co')},cc:{cur:num('f-ccc'),orig:num('f-cco')},student:{cur:num('f-sc'),orig:num('f-so')},other:{cur:0,orig:0}}; D.assets=a;D.liab=l;localStorage.setItem('wd_data_'+SHEET_ID,JSON.stringify(D)); try{ await sheetsWrite(SHEET_ID,'Settings!C4:C9',[[a.bank],[a.home],[a.investments],[a.crypto],[a.vehicles],[a.other]]); await sheetsWrite(SHEET_ID,'Settings!C14:D18',[[l.mortgage.cur,l.mortgage.orig],[l.car.cur,l.car.orig],[l.cc.cur,l.cc.orig],[l.student.cur,l.student.orig],[0,0]]); renderDash();btn.textContent='โœ“ Saved!';btn.style.background='var(--green2)'; setTimeout(()=>{btn.textContent='๐Ÿ’พ Save to My Google Sheet';btn.disabled=false;btn.style.background='';},2200); toast('โœ“ Saved to your Google Sheet'); }catch(e){btn.textContent='๐Ÿ’พ Save to My Google Sheet';btn.disabled=false;toast('Save failed');} } function openModal(){ const sel=document.getElementById('m-month');sel.innerHTML=MOS.map(m=>``).join(''); sel.selectedIndex=new Date().getMonth();document.getElementById('m-a').value='';document.getElementById('m-l').value=''; document.getElementById('m-nw').textContent='$0';setupPrefill();document.getElementById('modal').style.display='block'; } function editLog(month){ const e=D.log.find(x=>x.month===month);if(!e)return; const sel=document.getElementById('m-month');sel.innerHTML=MOS.map(m=>``).join(''); sel.value=month;document.getElementById('m-a').value=e.assets||'';document.getElementById('m-l').value=e.liab||'';calcM();setupPrefill();document.getElementById('modal').style.display='block'; } function setupPrefill(){ if(!D)return;const ta=Object.values(D.assets).reduce((a,b)=>a+b,0),td=Object.values(D.liab).reduce((a,b)=>a+(b.cur||0),0); const bar=document.getElementById('prefill-bar'),btn=document.getElementById('btn-use'); bar.style.display='block';btn.textContent=`Use current โ†’ Assets ${fmt(ta)} ยท Debt ${fmt(td)}`; btn.onclick=()=>{document.getElementById('m-a').value=ta;document.getElementById('m-l').value=td;calcM();hidePrefill();}; } function hidePrefill(){document.getElementById('prefill-bar').style.display='none';} function closeModal(){document.getElementById('modal').style.display='none';} function calcM(){const nw=(parseFloat(document.getElementById('m-a').value)||0)-(parseFloat(document.getElementById('m-l').value)||0);const el=document.getElementById('m-nw');el.textContent=fmt(nw);el.style.color=nw>=0?'var(--green)':'var(--red)';} async function saveLog(){ if(!TOKEN)await reAuth(); const month=document.getElementById('m-month').value; const assets=parseFloat(document.getElementById('m-a').value)||0; const liab=parseFloat(document.getElementById('m-l').value)||0; const idx=D.log.findIndex(e=>e.month===month); if(idx>=0){D.log[idx].assets=assets;D.log[idx].liab=liab;} localStorage.setItem('wd_data_'+SHEET_ID,JSON.stringify(D)); try{ const row=MOS.indexOf(month)+4; await sheetsWrite(SHEET_ID,`Monthly Log!C${row}:D${row}`,[[assets,liab]]); renderLog();renderDash();closeModal();toast('โœ“ '+month+' logged'); }catch(e){closeModal();toast('Save failed');} } function renderChecklist(){ const mo=MOS[new Date().getMonth()];document.getElementById('chk-mo-lbl').textContent=mo+"'s tasks"; document.getElementById('chk-prog').textContent=CHK.filter(Boolean).length+' of 5 tasks done'; const tasks=[['Check bank balance','Banking app'],['Check credit card','CC app'],['Update Settings','Settings'],['Log this month','Log tab'],['Review Dashboard','Dashboard']]; document.getElementById('chk-items').innerHTML=tasks.map((t,i)=>`
${t[0]}${t[1]}
`).join(''); document.getElementById('mon-grid').innerHTML=MOS.map((m,i)=>`
${m.slice(0,3)}
${MDONE.includes(i)?'โœ“':''}
`).join(''); } function toggleChk(i){CHK[i]=!CHK[i];localStorage.setItem('wd_chk_'+SHEET_ID,JSON.stringify(CHK));renderChecklist();} function toggleMonth(i){const idx=MDONE.indexOf(i);if(idx>=0)MDONE.splice(idx,1);else MDONE.push(i);localStorage.setItem('wd_md_'+SHEET_ID,JSON.stringify(MDONE));renderChecklist();} function go(tab){['dashboard','settings','log','checklist'].forEach(t=>{document.getElementById('screen-'+t).classList.remove('active');document.getElementById('tab-'+t).classList.remove('active');});document.getElementById('screen-'+tab).classList.add('active');document.getElementById('tab-'+tab).classList.add('active');if(tab==='settings')calcTotals();if(tab==='checklist')renderChecklist();} function toast(msg){const t=document.getElementById('toast');t.textContent=msg;t.classList.add('show');setTimeout(()=>t.classList.remove('show'),2800);} ['f-bank','f-home','f-invest','f-crypto','f-vehicles','f-other','f-mc','f-cc2','f-ccc','f-sc'].forEach(id=>{ window.addEventListener('DOMContentLoaded',()=>{const e=document.getElementById(id);if(e)e.addEventListener('input',calcTotals);}); }); // Make sign in button show loading state until GIS is ready function waitForGoogle(cb, tries=0){ if(typeof google!=='undefined'&&google.accounts){cb();} else if(tries<20){setTimeout(()=>waitForGoogle(cb,tries+1),300);} } window.addEventListener('DOMContentLoaded',()=>{ document.getElementById('tbar').style.display='none'; document.getElementById('loading').style.display='none'; if(SHEET_ID&&D){ bootApp(); }else{ document.getElementById('signin-screen').style.display='flex'; } });