File size: 8,669 Bytes
5a5996a
8b41798
 
2313378
572e913
8b41798
5a5996a
 
 
2313378
5a5996a
76c2b27
933a12f
 
 
8b41798
5a5996a
 
 
5676853
f080a44
5676853
933a12f
5676853
f080a44
22f1d46
5676853
 
 
 
 
 
3f496fe
 
 
 
 
 
 
 
 
 
 
8b41798
2313378
3f496fe
 
 
 
 
 
 
8b41798
3f496fe
 
 
 
 
 
 
 
5676853
572e913
 
933a12f
572e913
 
 
 
5676853
572e913
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
933a12f
8b41798
 
 
 
 
 
 
 
 
 
 
 
 
572e913
 
933a12f
5676853
5a5996a
8b41798
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5a5996a
 
5a50dfa
8b41798
 
 
5a5996a
8b41798
933a12f
 
 
 
 
8b41798
 
 
933a12f
 
 
5a50dfa
8b41798
933a12f
 
 
 
 
 
 
 
8b41798
2313378
 
8b41798
2313378
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5a5996a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// 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');
            }
        }
    });
}