85 lines
3.2 KiB
JavaScript
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; |