/** * app.js — Application Bootstrap * * This is the main entry point. All business logic has been moved to modules: * - js/views/quote-view.js → Quote list * - js/views/invoice-view.js → Invoice list (existing) * - js/views/settings-view.js → Logo, QBO import/test * - js/modals/quote-modal.js → Quote create/edit * - js/modals/invoice-modal.js → Invoice create/edit * - js/modals/payment-modal.js → Payment recording (existing) * - js/components/customer-search.js → Alpine dropdown * - js/utils/item-editor.js → Shared accordion item editor * - js/utils/helpers.js → formatDate, spinner * - js/utils/api.js → API wrapper (existing) */ // --- Imports --- import { loadQuotes } from './views/quote-view.js'; import { loadInvoices, injectToolbar as injectInvoiceToolbar, renderInvoiceView } from './views/invoice-view.js'; import { loadCustomers, renderCustomerView, injectToolbar as injectCustomerToolbar } from './views/customer-view.js'; import { checkCurrentLogo, initSettingsView } from './views/settings-view.js'; import { initQuoteModal } from './modals/quote-modal.js'; import { initInvoiceModal, loadLaborRate } from './modals/invoice-modal.js'; import './modals/payment-modal.js'; import './modals/email-modal.js'; import { setDefaultDate } from './utils/helpers.js'; // ============================================================ // Tab Management // ============================================================ function showTab(tabName) { document.querySelectorAll('.tab-content').forEach(tab => tab.classList.add('hidden')); document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('bg-blue-800')); document.getElementById(`${tabName}-tab`).classList.remove('hidden'); document.getElementById(`tab-${tabName}`).classList.add('bg-blue-800'); localStorage.setItem('activeTab', tabName); if (tabName === 'quotes') { loadQuotes(); } else if (tabName === 'invoices') { injectInvoiceToolbar(); loadInvoices(); } else if (tabName === 'customers') { injectCustomerToolbar(); renderCustomerView(); } else if (tabName === 'settings') { checkCurrentLogo(); } } // ============================================================ // Init // ============================================================ document.addEventListener('DOMContentLoaded', () => { // Load shared data loadCustomers(); loadLaborRate(); setDefaultDate(); // Init modals (wire up form handlers) initQuoteModal(); initInvoiceModal(); initSettingsView(); // Restore saved tab (or default to quotes) const savedTab = localStorage.getItem('activeTab') || 'quotes'; showTab(savedTab); // Hash-based navigation (e.g. after OAuth redirect /#settings) if (window.location.hash) { const hashTab = window.location.hash.replace('#', ''); if (['quotes', 'invoices', 'customers', 'settings'].includes(hashTab)) { showTab(hashTab); } } }); // ============================================================ // Expose to HTML onclick handlers // ============================================================ window.showTab = showTab;