win-superpower2 / events.js
Ultronprime's picture
Update events.js
8b41798 verified
// 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 = `<div class="flex items-center gap-2"><input type="number" placeholder="Qty" class="input-field w-20"><button class="btn btn-primary text-xs confirm-restock-btn">Add</button></div>`;
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');
}
}
});
}