Automated Office Supply Inventory Tracker

Automated Office Supply Inventory Tracker

Total Item Types

0

Items Low in Stock

0

Items Out of Stock

0

Low Stock Items

Recent Activity

${new Date(log.date).toLocaleString()}

`; }).join('') || '

No recent activity.

'; } function renderUpdateForm() { updateItemSelect.innerHTML = state.items.map(i => ``).join(''); } function renderConfiguration() { itemCategorySelect.innerHTML = state.categories.map(c => ``).join(''); itemsList.innerHTML = state.items.map(item => { const category = state.categories.find(c => c.id === item.categoryId); return `
${item.name} ${category?.name || 'N/A'} Stock: ${item.currentStock}
` }).join('') || '

No items configured.

'; categoriesList.innerHTML = state.categories.map(c => `
${c.name}
`).join(''); } // SECTION: Event Handlers function handleTabClick(tabName) { state.activeTab = tabName; render(); } function handleNavClick(dir) { const i = TABS.indexOf(state.activeTab); const newI = i + dir; if (newI >= 0 && newI < TABS.length) { state.activeTab = TABS[newI]; render(); } } function handleAddCategory(e) { e.preventDefault(); const name = categoryNameInput.value.trim(); if(name){ state.categories.push({id: Date.now(), name}); categoryNameInput.value = ''; saveState(); render(); } } function handleDelete(type, id) { if(confirm(`Delete this ${type}? This action cannot be undone.`)){ state[type+'s'] = state[type+'s'].filter(item => item.id !== id); saveState(); render(); } } function handleAddItem(e) { e.preventDefault(); const item = { id: Date.now(), name: itemNameInput.value.trim(), categoryId: parseInt(itemCategorySelect.value), lowStockThreshold: parseInt(itemLowStockInput.value), currentStock: 0 }; state.items.push(item); state.activityLog.push({ id: Date.now(), itemId: item.id, action: 'created', quantity: 0, date: new Date() }); addItemForm.reset(); saveState(); render(); } function handleUpdateInventory(e) { e.preventDefault(); const itemId = parseInt(updateItemSelect.value); const action = updateActionSelect.value; const quantity = parseInt(updateQuantityInput.value); const item = state.items.find(i => i.id === itemId); if (action === 'check_out' && quantity > item.currentStock) { alert('Error: Cannot check out more items than are in stock.'); return; } item.currentStock = action === 'check_in' ? item.currentStock + quantity : item.currentStock - quantity; state.activityLog.push({ id: Date.now(), itemId, action, quantity, date: new Date() }); updateForm.reset(); saveState(); alert('Inventory updated successfully!'); state.activeTab = 'dashboard'; render(); } function generatePDF() { const { jsPDF } = window.jspdf; const doc = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); doc.setFontSize(22); doc.text('Office Supply Inventory Report', 105, 20, { align: 'center' }); doc.setFontSize(10); doc.setTextColor(150); doc.text(`Generated on: ${new Date().toLocaleDateString()}`, 105, 27, { align: 'center' }); const tableBody = state.items.map(item => { const category = state.categories.find(c => c.id === item.categoryId)?.name || 'N/A'; let status = 'In Stock'; if (item.currentStock === 0) status = 'Out of Stock'; else if (item.currentStock <= item.lowStockThreshold) status = 'Low Stock'; return [item.name, category, item.currentStock, item.lowStockThreshold, status]; }); doc.autoTable({ head: [['Item Name', 'Category', 'Current Stock', 'Low Stock Level', 'Status']], body: tableBody, startY: 40, theme: 'grid', headStyles: { fillColor: [37, 99, 235] }, didDrawPage: data => { doc.setFontSize(8); doc.setTextColor(150); doc.text('Page ' + data.pageNumber, data.settings.margin.left, doc.internal.pageSize.height - 10); } }); doc.save(`Inventory_Report_${new Date().toISOString().slice(0,10)}.pdf`); } // SECTION: Event Listeners Object.keys(tabButtons).forEach(id => tabButtons[id]?.addEventListener('click', () => handleTabClick(id))); prevTabBtn?.addEventListener('click', () => handleNavClick(-1)); nextTabBtn?.addEventListener('click', () => handleNavClick(1)); downloadPdfBtn?.addEventListener('click', generatePDF); updateForm?.addEventListener('submit', handleUpdateInventory); addItemForm?.addEventListener('submit', handleAddItem); addCategoryForm?.addEventListener('submit', handleAddCategory); itemsList?.addEventListener('click', e => { if(e.target.classList.contains('delete-item-btn')) handleDelete('item', parseInt(e.target.dataset.id)); }); categoriesList?.addEventListener('click', e => { if(e.target.classList.contains('delete-category-btn')) handleDelete('category', parseInt(e.target.dataset.id)); }); // SECTION: Initial Load loadState(); render(); });
Scroll to Top