Añadir edición de presupuestos en la App (editar presupuesto + reenvío de enlace por WhatsApp)

This commit is contained in:
2026-09-13 17:03:18 +00:00
parent 92d360b407
commit 550ac1ed75

View File

@@ -57,7 +57,7 @@
<main id="viewCreate" class="hidden flex-1 overflow-y-auto px-5 pt-6 main-content z-20 fade-in bg-[var(--app-bg)] absolute inset-0 mt-[6rem] rounded-t-[2.5rem] shadow-[0_-10px_40px_rgba(0,0,0,0.1)]">
<div class="flex justify-between items-center mb-6">
<h2 class="text-lg font-black text-slate-800">Generar Nuevo</h2>
<h2 id="createViewTitle" class="text-lg font-black text-slate-800">Generar Nuevo</h2>
<button onclick="hideCreateView()" class="w-8 h-8 bg-slate-200 text-slate-600 rounded-full flex items-center justify-center active:scale-95"><i data-lucide="x" class="w-4 h-4"></i></button>
</div>
@@ -261,6 +261,7 @@
let catalog = [];
let currentItems = [];
let allBudgets = [];
let editingId = null; // null = modo crear, con valor = modo editar
// ------------------ INICIALIZACIÓN Y TEMA CORPORATIVO ------------------
async function applyTheme() {
@@ -295,6 +296,9 @@
// ------------------ NAVEGACIÓN Y TOASTS ------------------
function showCreateView() {
editingId = null;
document.getElementById('createViewTitle').textContent = 'Generar Nuevo';
document.getElementById('btnSave').innerHTML = '<i data-lucide="save" class="w-4 h-4"></i> Generar Presupuesto';
document.getElementById('viewList').classList.add('hidden');
document.getElementById('viewCreate').classList.remove('hidden');
currentItems = [];
@@ -307,6 +311,21 @@
document.getElementById('viewList').classList.remove('hidden');
}
function editBudget(id) {
const budget = allBudgets.find(b => b.id === id);
if (!budget) return showToast("Error: Presupuesto no encontrado");
editingId = id;
document.getElementById('c_name').value = budget.client_name || '';
document.getElementById('c_phone').value = budget.client_phone || '';
document.getElementById('c_address').value = budget.client_address || '';
currentItems = (budget.items || []).map(it => ({ concept: it.concept, qty: it.qty, price: it.price, total: (Number(it.qty) * Number(it.price)) }));
document.getElementById('createViewTitle').textContent = 'Editar Presupuesto #' + id;
document.getElementById('btnSave').innerHTML = '<i data-lucide="save" class="w-4 h-4"></i> Guardar Cambios';
document.getElementById('viewList').classList.add('hidden');
document.getElementById('viewCreate').classList.remove('hidden');
renderItems();
}
function showToast(msg) {
const toast = document.getElementById('toast');
document.getElementById('toastMsg').innerText = msg;
@@ -572,6 +591,7 @@
${actionBtns}
</div>
<div class="flex gap-2">
${(b.status !== 'converted' && b.status !== 'paid') ? `<button onclick="editBudget(${b.id})" class="w-9 h-9 bg-slate-50 border border-slate-200 text-blue-600 rounded-full flex items-center justify-center active:scale-95 transition-transform"><i data-lucide="pencil" class="w-4 h-4"></i></button>` : ''}
<button onclick="downloadPDF(${b.id})" class="w-9 h-9 bg-slate-50 border border-slate-200 text-slate-600 rounded-full flex items-center justify-center active:scale-95 transition-transform"><i data-lucide="download" class="w-4 h-4"></i></button>
<button onclick="deleteBudget(${b.id})" class="w-9 h-9 bg-slate-50 border border-slate-200 text-rose-500 rounded-full flex items-center justify-center active:scale-95 transition-transform"><i data-lucide="trash-2" class="w-4 h-4"></i></button>
</div>
@@ -669,18 +689,20 @@
btn.innerHTML = '<i data-lucide="loader-2" class="w-5 h-5 animate-spin"></i> Generando...';
lucide.createIcons();
const isEdit = !!editingId;
const totals = calcTotals();
const payload = { client_name: cName, client_phone: cPhone, client_address: cAddress, items: currentItems, subtotal: totals.sub, tax: totals.tax, total: totals.tot };
try {
const res = await fetch(`${API_URL}/budgets`, {
method: 'POST',
const res = await fetch(isEdit ? `${API_URL}/budgets/${editingId}` : `${API_URL}/budgets`, {
method: isEdit ? 'PUT' : 'POST',
headers: { 'Content-Type': 'application/json', "Authorization": `Bearer ${localStorage.getItem("token")}` },
body: JSON.stringify(payload)
});
const data = await res.json();
if(data.ok) {
showToast("¡Presupuesto Creado!");
showToast(isEdit ? "¡Presupuesto Actualizado!" : "¡Presupuesto Creado!");
editingId = null;
hideCreateView();
fetchBudgets();
} else { showToast("Error al guardar."); }