diff --git a/public/app.js b/public/app.js index 8097309..7014739 100644 --- a/public/app.js +++ b/public/app.js @@ -1,5 +1,5 @@ // Global state -let customers = []; // shared, updated by customer-view.js +let customers = window.customers || []; let quotes = []; let invoices = []; let currentQuoteId = null; @@ -20,14 +20,14 @@ function customerSearch(type) { get filteredCustomers() { // Wenn Suche leer ist: ALLE Kunden zurückgeben (kein .slice mehr!) if (!this.search) { - return customers; + return (window.getCustomers ? window.getCustomers() : customers); } const searchLower = this.search.toLowerCase(); // Filtern: Sucht im Namen, Line1, Stadt oder Account Nummer // Auch hier: Kein .slice mehr, damit alle Ergebnisse (z.B. alle mit 'C') angezeigt werden - return customers.filter(c => + return (window.getCustomers ? window.getCustomers() : customers).filter(c => (c.name || '').toLowerCase().includes(searchLower) || (c.line1 || '').toLowerCase().includes(searchLower) || (c.city || '').toLowerCase().includes(searchLower) || @@ -76,9 +76,7 @@ window.customerSearch = customerSearch; // Initialize app document.addEventListener('DOMContentLoaded', () => { - loadCustomers(); loadQuotes(); - //loadInvoices(); setDefaultDate(); checkCurrentLogo(); loadLaborRate(); @@ -95,7 +93,6 @@ document.addEventListener('DOMContentLoaded', () => { } // Setup form handlers - document.getElementById('customer-form').addEventListener('submit', handleCustomerSubmit); document.getElementById('quote-form').addEventListener('submit', handleQuoteSubmit); document.getElementById('invoice-form').addEventListener('submit', handleInvoiceSubmit); document.getElementById('quote-tax-exempt').addEventListener('change', updateQuoteTotals); @@ -128,7 +125,9 @@ function showTab(tabName) { } else if (tabName === 'invoices') { loadInvoices(); } else if (tabName === 'customers') { - loadCustomers(); + if (window.customerView) { + window.customerView.loadCustomers(); + } } else if (tabName === 'settings') { checkCurrentLogo(); } @@ -204,167 +203,6 @@ async function uploadLogo() { } } - - - -// --- 2. Credits async laden --- -async function loadCustomerCredits() { - const qboCustomers = customers.filter(c => c.qbo_id); - for (const cust of qboCustomers) { - const span = document.getElementById(`customer-credit-${cust.id}`); - if (!span) continue; - try { - const res = await fetch(`/api/qbo/customer-credit/${cust.qbo_id}`); - const data = await res.json(); - if (data.credit > 0) { - span.innerHTML = `Credit: $${data.credit.toFixed(2)}`; - } else { - span.textContent = ''; - } - } catch (e) { - span.textContent = ''; - } - } -} -// --- 3. Downpayment Dialog --- -async function openDownpaymentModal(customerId, customerQboId, customerName) { - // Load QBO data if needed - let bankAccounts = []; - let paymentMethods = []; - try { - const [accRes, pmRes] = await Promise.all([ - fetch('/api/qbo/accounts'), - fetch('/api/qbo/payment-methods') - ]); - if (accRes.ok) bankAccounts = await accRes.json(); - if (pmRes.ok) paymentMethods = await pmRes.json(); - } catch (e) { console.error('Error loading QBO data:', e); } - - const accountOptions = bankAccounts.map(a => ``).join(''); - const filtered = paymentMethods.filter(p => /check|ach/i.test(p.name)); - const methods = filtered.length > 0 ? filtered : paymentMethods; - const methodOptions = methods.map(p => ``).join(''); - const today = new Date().toISOString().split('T')[0]; - - let modal = document.getElementById('downpayment-modal'); - if (!modal) { - modal = document.createElement('div'); - modal.id = 'downpayment-modal'; - modal.className = 'modal fixed inset-0 bg-black bg-opacity-50 z-50 justify-center items-start pt-10 overflow-y-auto'; - document.body.appendChild(modal); - } - - modal.innerHTML = ` -
- Customer: ${customerName}
- This will record an unapplied payment (credit) on the customer's QBO account.
-