Mis Finanzas V4 — Código completo
Copiar desde hasta y reemplazar todo el contenido de index.html.
Mis Finanzas
MI CONTROL
Mis Finanzas
Disponible$0
Ingresos$0
Últimos movimientos
Movimientos
■ Tarjetas
■ Cuotas
Total comprometido$0
<
■ Presupuesto
Ingr
■ Recurrentes
■ Recordatorios
Próximos 30 días:
■ Mi Auto
Ve
■ Precios
■ Resumen
Movimientos0
■■ Ajustes
Los datos se guardan automáticamente en este dispositivo.
({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m]));
let db=load(), movementType='expense';
function load(){try{let x=JSON.parse(localStorage.getItem(K));return x?{...empty,...x,car:{...empty.car,...x.car},budget:{...empty.budget,...x.budget}}:structuredCl
function save(){try{localStorage.setItem(K,JSON.stringify(db));return true}catch{toast('No hay espacio para guardar');return false}}
function toast(t){$('toast').textContent=t;$('toast').classList.add('show');clearTimeout(window.tt);window.tt=setTimeout(()=>$('toast').classList.remove('show'),180
function val(i){return $(i)?.value?.trim()||''}function num(i){return Number(val(i))||0}
function totals(){return db.movements.reduce((r,x)=>(r[x.type]+=Number(x.amount)||0,r),{income:0,expense:0})}
function go(s){if(s==='more'){more();return}document.querySelectorAll('.section').forEach(x=>x.classList.toggle('active',x.id===s));document.querySelectorAll('nav b
function more(){document.querySelectorAll('.section').forEach(x=>x.classList.remove('active'));let old=$('more');if(old)old.remove();let s=document.createElement('s
function modal(title,body){$('modalBody').innerHTML='
'+title+'
'+body;$('modal').classList.remove('hidden')}
function close(){ $('modal').classList.add('hidden');$('modalBody').innerHTML=''}
const sub=t=>'Guardar';
function form(t){
let h='';
if(t==='movement')h='ProductoProductoNombreLímite mensual'+sub(t);
if(t==='fixed')h='DescripciónVehículoConcepto
')}
function render(){
let t=totals();$('balance').textContent=money(t.income-t.expense);$('incomeTotal').textContent=money(t.income);$('expenseTotal').textContent=money(t.expense);$('mov
let ms=[...db.movements].sort((a,b)=>b.date.localeCompare(a.date));list('recent',ms.slice(0,5),'Todavía no hay movimientos.',movement);list('allMovements',ms,'No ha
list('cardsList',db.cards,'No hay tarjetas.',x=>'