Init: MVP de Gestión de Pagos (Stitch UI + SQLite/PHP)
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
let currentMonto = "0";
|
||||
let selectedTipo = "gasto"; // default
|
||||
|
||||
const montoEl = document.getElementById('ui-monto');
|
||||
const btnGasto = document.getElementById('btn-gasto');
|
||||
const btnIngreso = document.getElementById('btn-ingreso');
|
||||
const numpad = document.getElementById('ui-numpad');
|
||||
const btnSave = document.getElementById('btn-save');
|
||||
const iptFecha = document.getElementById('ui-fecha');
|
||||
|
||||
// Default a hoy
|
||||
iptFecha.valueAsDate = new Date();
|
||||
|
||||
// Tipo selector
|
||||
const updateTipoUI = () => {
|
||||
if (selectedTipo === 'gasto') {
|
||||
btnGasto.classList.replace('text-on-surface-variant', 'text-primary');
|
||||
btnGasto.classList.add('bg-surface-container-lowest');
|
||||
btnIngreso.classList.replace('bg-surface-container-lowest', 'bg-transparent');
|
||||
btnIngreso.classList.replace('text-primary', 'text-on-surface-variant');
|
||||
} else {
|
||||
btnIngreso.classList.replace('text-on-surface-variant', 'text-primary');
|
||||
btnIngreso.classList.add('bg-surface-container-lowest');
|
||||
btnGasto.classList.replace('bg-surface-container-lowest', 'bg-transparent');
|
||||
btnGasto.classList.replace('text-primary', 'text-on-surface-variant');
|
||||
}
|
||||
};
|
||||
|
||||
btnGasto.addEventListener('click', () => { selectedTipo = 'gasto'; updateTipoUI(); });
|
||||
btnIngreso.addEventListener('click', () => { selectedTipo = 'ingreso'; updateTipoUI(); });
|
||||
|
||||
// Numpad logic
|
||||
numpad.addEventListener('click', (e) => {
|
||||
const btn = e.target.closest('button');
|
||||
if (!btn) return;
|
||||
|
||||
const val = btn.textContent.trim() || btn.innerText.trim();
|
||||
|
||||
if (val === 'backspace' || btn.querySelector('[data-icon="backspace"]')) {
|
||||
currentMonto = currentMonto.slice(0, -1);
|
||||
if (currentMonto === '') currentMonto = "0";
|
||||
} else {
|
||||
if (currentMonto === "0" && val !== ".") {
|
||||
currentMonto = val;
|
||||
} else {
|
||||
if (val === "." && currentMonto.includes(".")) return;
|
||||
currentMonto += val;
|
||||
}
|
||||
}
|
||||
montoEl.textContent = currentMonto;
|
||||
});
|
||||
|
||||
// Guardar Movimiento
|
||||
btnSave.addEventListener('click', async () => {
|
||||
const payload = {
|
||||
tipo: selectedTipo,
|
||||
monto: parseFloat(currentMonto),
|
||||
fecha: document.getElementById('ui-fecha').value,
|
||||
notas: document.getElementById('ui-notas').value,
|
||||
id_categoria: document.getElementById('ui-categoria').value
|
||||
};
|
||||
|
||||
if (isNaN(payload.monto) || payload.monto <= 0) {
|
||||
alert('Por favor ingrese un monto mayor a 0');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const btnOriginal = btnSave.innerHTML;
|
||||
btnSave.innerHTML = 'Guardando...';
|
||||
btnSave.disabled = true;
|
||||
|
||||
const r = await fetch('api/movimientos.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
const data = await r.json();
|
||||
|
||||
if (data.status === 'success') {
|
||||
window.location.href = 'index.html'; // Redirige al inicio tras guardar
|
||||
} else {
|
||||
alert('Error al guardar: ' + data.message);
|
||||
btnSave.innerHTML = btnOriginal;
|
||||
btnSave.disabled = false;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
alert('Fallo en la comunicación');
|
||||
btnSave.disabled = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user