Spaces:
Running
Running
Create events.js
Browse files
events.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// events.js - Manages all event listeners
|
| 2 |
+
|
| 3 |
+
import { appState, saveState } from './state.js';
|
| 4 |
+
import { handleUpdateStock, handleRestock } from './services.js';
|
| 5 |
+
import { refreshUI, showToast } from './ui.js';
|
| 6 |
+
|
| 7 |
+
export function attachAllListeners() {
|
| 8 |
+
attachProductInputListeners();
|
| 9 |
+
attachMaxStockEditListeners();
|
| 10 |
+
attachRestockListeners();
|
| 11 |
+
attachModalListeners();
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
function attachProductInputListeners() {
|
| 15 |
+
document.querySelectorAll('.product-card .update-btn').forEach(btn => {
|
| 16 |
+
if (btn.dataset.listenerAttached) return;
|
| 17 |
+
btn.dataset.listenerAttached = true;
|
| 18 |
+
btn.addEventListener('click', (e) => {
|
| 19 |
+
const card = e.target.closest('.product-card');
|
| 20 |
+
const productName = card.dataset.productName;
|
| 21 |
+
const quantity = parseInt(card.querySelector('input').value, 10);
|
| 22 |
+
handleUpdateStock(productName, quantity);
|
| 23 |
+
});
|
| 24 |
+
});
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
function attachMaxStockEditListeners() {
|
| 28 |
+
document.querySelectorAll('.edit-max-stock').forEach(icon => {
|
| 29 |
+
if (icon.dataset.listenerAttached) return;
|
| 30 |
+
icon.dataset.listenerAttached = true;
|
| 31 |
+
icon.addEventListener('click', (e) => {
|
| 32 |
+
const valueSpan = e.target.previousElementSibling;
|
| 33 |
+
const materialName = e.target.closest('.material-card').dataset.materialName;
|
| 34 |
+
const material = appState.materials.find(m => m.name === materialName);
|
| 35 |
+
const input = document.createElement('input');
|
| 36 |
+
input.type = 'number';
|
| 37 |
+
input.value = material.maxStock;
|
| 38 |
+
input.className = 'w-20 text-right font-semibold border rounded px-1';
|
| 39 |
+
valueSpan.replaceWith(input);
|
| 40 |
+
input.focus();
|
| 41 |
+
input.select();
|
| 42 |
+
const saveChange = () => {
|
| 43 |
+
const newValue = parseInt(input.value, 10);
|
| 44 |
+
if (!isNaN(newValue) && newValue >= material.currentStock) {
|
| 45 |
+
material.maxStock = newValue;
|
| 46 |
+
saveState();
|
| 47 |
+
refreshUI();
|
| 48 |
+
} else {
|
| 49 |
+
showToast('Max stock must be a number >= current stock.', 'error');
|
| 50 |
+
refreshUI();
|
| 51 |
+
}
|
| 52 |
+
};
|
| 53 |
+
input.addEventListener('blur', saveChange);
|
| 54 |
+
input.addEventListener('keydown', (event) => { if (event.key === 'Enter') input.blur(); });
|
| 55 |
+
});
|
| 56 |
+
});
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
function attachRestockListeners() {
|
| 60 |
+
const showRestockForm = (e) => {
|
| 61 |
+
const parentEl = e.target.closest('[data-material-name]');
|
| 62 |
+
const materialName = parentEl.dataset.materialName;
|
| 63 |
+
const formContainer = parentEl.querySelector('.restock-form');
|
| 64 |
+
|
| 65 |
+
if (formContainer.classList.contains('hidden')) {
|
| 66 |
+
document.querySelectorAll('.restock-form').forEach(f => { f.classList.add('hidden'); f.innerHTML = ''; });
|
| 67 |
+
formContainer.classList.remove('hidden');
|
| 68 |
+
formContainer.innerHTML = `<div class="flex items-center gap-2"><input type="number" placeholder="Qty" class="input-number w-20 px-2 py-1 border border-gray-300 rounded"><button class="confirm-restock-btn px-3 py-1 bg-green-500 text-white text-xs rounded hover:bg-green-600">Add</button></div>`;
|
| 69 |
+
const input = formContainer.querySelector('input');
|
| 70 |
+
input.focus();
|
| 71 |
+
formContainer.querySelector('.confirm-restock-btn').addEventListener('click', () => { handleRestock(materialName, parseInt(input.value, 10)); });
|
| 72 |
+
input.addEventListener('keydown', (event) => { if (event.key === 'Enter') handleRestock(materialName, parseInt(input.value, 10)); if (event.key === 'Escape') formContainer.classList.add('hidden'); });
|
| 73 |
+
} else {
|
| 74 |
+
formContainer.classList.add('hidden');
|
| 75 |
+
formContainer.innerHTML = '';
|
| 76 |
+
}
|
| 77 |
+
};
|
| 78 |
+
document.querySelectorAll('.restock-icon, .restock-btn-reorder').forEach(btn => {
|
| 79 |
+
if (btn.dataset.listenerAttached) return;
|
| 80 |
+
btn.dataset.listenerAttached = true;
|
| 81 |
+
btn.addEventListener('click', showRestockForm);
|
| 82 |
+
});
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
function attachModalListeners() {
|
| 86 |
+
const resetModal = document.getElementById('reset-modal');
|
| 87 |
+
const showResetModalBtn = document.getElementById('show-reset-modal-btn');
|
| 88 |
+
if (showResetModalBtn.dataset.listenerAttached) return;
|
| 89 |
+
|
| 90 |
+
const cancelResetBtn = document.getElementById('cancel-reset-btn');
|
| 91 |
+
const confirmResetBtn = document.getElementById('confirm-reset-btn');
|
| 92 |
+
|
| 93 |
+
showResetModalBtn.addEventListener('click', () => resetModal.classList.remove('hidden'));
|
| 94 |
+
cancelResetBtn.addEventListener('click', () => resetModal.classList.add('hidden'));
|
| 95 |
+
confirmResetBtn.addEventListener('click', () => {
|
| 96 |
+
localStorage.removeItem('antennaTrackerState');
|
| 97 |
+
loadState(); // This is a placeholder as loadState is not directly imported. A full reload is better.
|
| 98 |
+
window.location.reload(); // Simple and effective way to reset to config defaults.
|
| 99 |
+
});
|
| 100 |
+
|
| 101 |
+
showResetModalBtn.dataset.listenerAttached = true;
|
| 102 |
+
}
|