// events.js - Manages all event listeners import { appState } from './state.js'; import { handleUpdateStock, handleRestock, handleSetStock } from './services.js'; import { refreshUI, showToast, renderReport, renderCustomPOModal } from './ui.js'; import { generatePurchaseOrder } from './purchaseOrderService.js'; import { supabase } from './supabaseClient.js'; export function attachAllListeners() { attachProductInputListeners(); attachCurrentStockEditListeners(); attachRestockListeners(); attachPurchaseOrderListener(); } export function attachOneTimeListeners() { attachAuthListeners(); attachModalListeners(); } function attachProductInputListeners() { document.querySelectorAll('.update-btn').forEach(btn => { if (btn.dataset.listenerAttached) return; btn.dataset.listenerAttached = 'true'; btn.addEventListener('click', (e) => { const card = e.target.closest('.dashboard-card'); const productName = e.target.dataset.productName; const quantity = parseInt(card.querySelector('input').value, 10); handleUpdateStock(productName, quantity); }); }); } function attachCurrentStockEditListeners() { document.querySelectorAll('.edit-current-stock').forEach(icon => { if (icon.dataset.listenerAttached) return; icon.dataset.listenerAttached = 'true'; icon.addEventListener('click', (e) => { const card = e.target.closest('.dashboard-card'); const valueDiv = card.querySelector('.current-stock-value'); const materialName = card.dataset.materialName; const input = document.createElement('input'); input.type = 'number'; input.value = valueDiv.textContent; input.className = 'input-field w-24 text-2xl font-bold'; valueDiv.replaceWith(input); input.focus(); input.select(); const saveChange = () => { const newValue = parseInt(input.value, 10); handleSetStock(materialName, newValue); }; input.addEventListener('blur', saveChange); input.addEventListener('keydown', (event) => { if (event.key === 'Enter') input.blur(); }); }); }); } function attachRestockListeners() { document.querySelectorAll('.restock-icon').forEach(btn => { if (btn.dataset.listenerAttached) return; btn.dataset.listenerAttached = 'true'; btn.addEventListener('click', (e) => { const parentEl = e.target.closest('[data-material-name]'); const materialName = parentEl.dataset.materialName; const formContainer = parentEl.querySelector('.restock-form'); if (formContainer.classList.contains('hidden')) { document.querySelectorAll('.restock-form').forEach(f => { f.classList.add('hidden'); f.innerHTML = ''; }); formContainer.classList.remove('hidden'); formContainer.innerHTML = `
`; const input = formContainer.querySelector('input'); input.focus(); formContainer.querySelector('.confirm-restock-btn').addEventListener('click', () => { handleRestock(materialName, parseInt(input.value, 10)); }); input.addEventListener('keydown', (event) => { if (event.key === 'Enter') handleRestock(materialName, parseInt(input.value, 10)); if (event.key === 'Escape') formContainer.classList.add('hidden'); }); } else { formContainer.classList.add('hidden'); formContainer.innerHTML = ''; } }); }); } function attachPurchaseOrderListener() { // This listener is now attached dynamically in renderReorderList in ui.js // We can use event delegation on the header to make it more robust. const reorderHeader = document.getElementById('reorder-header'); if (reorderHeader && !reorderHeader.dataset.listenerAttached) { reorderHeader.dataset.listenerAttached = 'true'; reorderHeader.addEventListener('click', (e) => { if (e.target.id === 'open-po-modal-btn') { const materialsToOrder = appState.materials.filter(m => m.currentStock <= m.reorderPoint * 1.5); if (materialsToOrder.length > 0) { renderCustomPOModal(materialsToOrder); } else { showToast('No items need reordering.', 'info'); } } }); } } function attachAuthListeners() { const loginForm = document.getElementById('login-form'); const logoutBtn = document.getElementById('logout-btn'); if (loginForm) { loginForm.addEventListener('submit', async (e) => { e.preventDefault(); const email = document.getElementById('email').value; const password = document.getElementById('password').value; const { error } = await supabase.auth.signInWithPassword({ email, password }); if (error) { showToast(`Login failed: ${error.message}`, 'error'); } // onAuthStateChange in main.js will handle success }); } if (logoutBtn) { logoutBtn.addEventListener('click', async () => { await supabase.auth.signOut(); // onAuthStateChange in main.js will handle UI changes }); } } function attachModalListeners() { const resetModal = document.getElementById('reset-modal'); const reportsModal = document.getElementById('reports-modal'); const customPOModal = document.getElementById('custom-po-modal'); document.getElementById('show-reset-modal-btn')?.addEventListener('click', () => resetModal.classList.remove('hidden')); resetModal.addEventListener('click', async (e) => { const target = e.target.closest('button'); if ((target && target.id === 'cancel-reset-btn') || e.target === resetModal) { resetModal.classList.add('hidden'); } if (target && target.id === 'confirm-reset-btn') { showToast('Resetting data... please wait.', 'info'); await supabase.from('production_log').delete().neq('id', '00000000-0000-0000-0000-000000000000'); await supabase.from('materials').delete().neq('id', '00000000-0000-0000-0000-000000000000'); window.location.reload(); } }); document.getElementById('show-reports-modal-btn')?.addEventListener('click', () => reportsModal.classList.remove('hidden')); reportsModal.addEventListener('click', (e) => { const target = e.target.closest('button'); if ((target && target.id === 'close-reports-modal-btn') || e.target === reportsModal) { reportsModal.classList.add('hidden'); } if (target && target.id === 'report-prod-summary') renderReport('production'); if (target && target.id === 'report-mat-usage') renderReport('material'); }); customPOModal.addEventListener('click', e => { const target = e.target; if (target.id === 'custom-po-modal' || target.closest('#cancel-po-btn') || target.id === 'cancel-po-btn-footer') { customPOModal.classList.add('hidden'); } if (target.id === 'confirm-po-generation-btn') { const supplierName = document.getElementById('supplier-name').value.trim(); const selectedItems = []; document.querySelectorAll('.po-item-select:checked').forEach(checkbox => { const row = checkbox.closest('.po-item-row'); const materialName = row.dataset.materialName; const material = appState.materials.find(m => m.name === materialName); const quantity = parseInt(row.querySelector('.po-item-qty').value, 10); if (material && !isNaN(quantity) && quantity > 0) { selectedItems.push({ material, quantity }); } }); if (selectedItems.length > 0) { generatePurchaseOrder(selectedItems, supplierName); showToast(`Generated PO for ${selectedItems.length} items.`, 'success'); customPOModal.classList.add('hidden'); } else { showToast('No items selected or quantities are invalid.', 'error'); } } }); }