// Global variables let inventory = []; let currentEditId = null; let apiBaseUrl = 'http://localhost:11000/api'; // Replace with your actual API URL // DOM elements const inventoryTableBody = document.getElementById('inventoryTableBody'); const addBtn = document.getElementById('addBtn'); const refreshBtn = document.getElementById('refreshBtn'); const searchInput = document.getElementById('searchInput'); const modal = document.getElementById('modal'); const modalTitle = document.getElementById('modalTitle'); const itemForm = document.getElementById('itemForm'); const cancelBtn = document.getElementById('cancelBtn'); const closeBtn = document.querySelector('.close'); const loading = document.getElementById('loading'); const error = document.getElementById('error'); const errorMessage = document.getElementById('errorMessage'); // Stats elements const totalItems = document.getElementById('totalItems'); const totalValue = document.getElementById('totalValue'); const lowStock = document.getElementById('lowStock'); // API functions async function fetchInventory() { try { showLoading(true); hideError(); const response = await fetch(`${apiBaseUrl}/read`); const result = await response.json(); if (result.status === 'Berhasil') { inventory = result.data || []; renderInventoryTable(); updateStats(); } else { throw new Error(result.message || 'Failed to fetch inventory'); } } catch (err) { console.error('Error fetching inventory:', err); showError(`Failed to load inventory: ${err.message}`); inventory = []; renderInventoryTable(); } finally { showLoading(false); } } async function createItem(item) { try { const response = await fetch(`${apiBaseUrl}/create`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(item) }); const result = await response.json(); if (result.status === 'Berhasil') { await fetchInventory(); // Refresh the list return true; } else { throw new Error(result.message || 'Failed to create item'); } } catch (err) { console.error('Error creating item:', err); showError(`Failed to create item: ${err.message}`); return false; } } async function updateItem(id, item) { item.key = id; // Ensure the item has the ID for update try { const response = await fetch(`${apiBaseUrl}/update`, { method: 'PUT', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(item) }); const result = await response.json(); if (result.status === 'Berhasil') { await fetchInventory(); // Refresh the list return true; } else { throw new Error(result.message || 'Failed to update item'); } } catch (err) { console.error('Error updating item:', err); showError(`Failed to update item: ${err.message}`); return false; } } async function deleteItem(id) { try { const response = await fetch(`${apiBaseUrl}/delete`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ key: id }) }); const result = await response.json(); if (result.status === 'Berhasil') { await fetchInventory(); // Refresh the list return true; } else { throw new Error(result.message || 'Failed to delete item'); } } catch (err) { console.error('Error deleting item:', err); showError(`Failed to delete item: ${err.message}`); return false; } } // UI functions function renderInventoryTable(items = inventory) { inventoryTableBody.innerHTML = ''; if (items.length === 0) { const row = document.createElement('tr'); row.innerHTML = ` No items found `; inventoryTableBody.appendChild(row); return; } items.forEach(item => { const row = document.createElement('tr'); const totalItemValue = (item.price * item.qty).toFixed(2); const quantityClass = item.qty <= 10 ? 'low-stock' : ''; row.innerHTML = ` ${item.id} ${item.name} $${item.price.toFixed(2)} ${item.qty} $${totalItemValue} `; inventoryTableBody.appendChild(row); }); } function updateStats() { const total = inventory.length; const value = inventory.reduce((sum, item) => sum + (item.price * item.qty), 0); const lowStockCount = inventory.filter(item => item.qty <= 10).length; totalItems.textContent = total; totalValue.textContent = `$${value.toFixed(2)}`; lowStock.textContent = lowStockCount; } function showLoading(show) { loading.style.display = show ? 'block' : 'none'; } function showError(message) { errorMessage.textContent = message; error.style.display = 'block'; } function hideError() { error.style.display = 'none'; } function showModal(title = 'Add New Item') { modalTitle.textContent = title; modal.style.display = 'block'; } function hideModal() { modal.style.display = 'none'; itemForm.reset(); currentEditId = null; } function filterItems(searchTerm) { const filtered = inventory.filter(item => item.name.toLowerCase().includes(searchTerm.toLowerCase()) ); renderInventoryTable(filtered); } // Event handlers function editItem(id) { const item = inventory.find(item => item.id === id); if (item) { currentEditId = id; document.getElementById('itemName').value = item.name; document.getElementById('itemPrice').value = item.price; document.getElementById('itemQty').value = item.qty; showModal('Edit Item'); } } function deleteItemConfirm(id) { const item = inventory.find(item => item.id === id); if (item && confirm(`Are you sure you want to delete "${item.name}"?`)) { deleteItem(id); } } // Event listeners addBtn.addEventListener('click', () => { showModal('Add New Item'); }); refreshBtn.addEventListener('click', fetchInventory); searchInput.addEventListener('input', (e) => { filterItems(e.target.value); }); closeBtn.addEventListener('click', hideModal); cancelBtn.addEventListener('click', hideModal); // Close modal when clicking outside window.addEventListener('click', (e) => { if (e.target === modal) { hideModal(); } }); // Form submission itemForm.addEventListener('submit', async (e) => { e.preventDefault(); const name = document.getElementById('itemName').value.trim(); const price = parseFloat(document.getElementById('itemPrice').value); const qty = parseInt(document.getElementById('itemQty').value); if (!name || isNaN(price) || isNaN(qty)) { alert('Please fill in all fields correctly'); return; } const item = { name, price, qty }; let success = false; if (currentEditId) { success = await updateItem(currentEditId, item); } else { success = await createItem(item); } if (success) { hideModal(); } }); // Initialize the application document.addEventListener('DOMContentLoaded', () => { fetchInventory(); }); // For demo purposes - if API is not available, use mock data function loadMockData() { inventory = [ { id: 1, name: 'Laptop', price: 999.99, qty: 15 }, { id: 2, name: 'Mouse', price: 29.99, qty: 50 }, { id: 3, name: 'Keyboard', price: 79.99, qty: 8 }, { id: 4, name: 'Monitor', price: 299.99, qty: 12 }, { id: 5, name: 'Headphones', price: 149.99, qty: 3 } ]; renderInventoryTable(); updateStats(); } // Uncomment the line below to use mock data for testing // loadMockData();