invoice-system/public/js/app.js

85 lines
3.2 KiB
JavaScript

/**
* 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 { 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;