document.addEventListener('DOMContentLoaded', function () { // --- Constants --- const API_BASE = 'api/'; const addAssetForm = document.getElementById('addAssetForm'); const assetsTableBody = document.getElementById('assets-table-body'); const loadingIndicator = document.getElementById('loading-indicator'); const notificationToastEl = document.getElementById('notificationToast'); const notificationToast = new bootstrap.Toast(notificationToastEl); // --- Functions --- /** * Shows a toast notification. * @param {string} title - The title of the toast. * @param {string} body - The body message of the toast. * @param {string} type - 'success' or 'error'. */ function showToast(title, body, type = 'success') { const toastHeader = notificationToastEl.querySelector('.toast-header'); // Reset classes toastHeader.classList.remove('bg-success', 'text-white', 'bg-danger'); if (type === 'success') { toastHeader.classList.add('bg-success', 'text-white'); } else if (type === 'error') { toastHeader.classList.add('bg-danger', 'text-white'); } document.getElementById('toast-title').textContent = title; document.getElementById('toast-body').textContent = body; notificationToast.show(); } /** * Fetches data from the API. * @param {string} endpoint - The API endpoint to fetch from. * @returns {Promise} - The JSON response. */ async function fetchApi(endpoint) { try { const response = await fetch(API_BASE + endpoint); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return await response.json(); } catch (error) { console.error(`Error fetching ${endpoint}:`, error); showToast('Error', `Gagal memuat data dari server: ${error.message}`, 'error'); return null; } } /** * Populates select dropdowns. */ async function populateSelectOptions() { const data = await fetchApi('get_options.php'); if (!data) return; const kategoriSelect = document.getElementById('id_kategori'); const kantorSelect = document.getElementById('id_kantor_lokasi'); kategoriSelect.innerHTML = ''; data.kategori.forEach(item => { kategoriSelect.innerHTML += ``; }); kantorSelect.innerHTML = ''; data.kantor.forEach(item => { kantorSelect.innerHTML += ``; }); } /** * Fetches assets and renders them in the table. */ async function loadAssets() { loadingIndicator.style.display = 'block'; assetsTableBody.innerHTML = ''; const assets = await fetchApi('get_assets.php'); loadingIndicator.style.display = 'none'; if (assets && assets.length > 0) { assets.forEach(asset => { const row = ` ${asset.kode_aset} ${asset.nama_aset} ${asset.nama_kategori} ${asset.nama_kantor} ${asset.status} `; assetsTableBody.innerHTML += row; }); } else if (assets) { assetsTableBody.innerHTML = 'Belum ada data aset.'; } else { assetsTableBody.innerHTML = 'Gagal memuat data aset.'; } feather.replace(); // Re-initialize Feather icons } /** * Handles the submission of the 'Add Asset' form. * @param {Event} event - The form submission event. */ async function handleAddAssetSubmit(event) { event.preventDefault(); event.stopPropagation(); if (!addAssetForm.checkValidity()) { addAssetForm.classList.add('was-validated'); return; } const formData = new FormData(addAssetForm); const submitButton = addAssetForm.querySelector('button[type="submit"]'); submitButton.disabled = true; submitButton.innerHTML = ''' Menyimpan...'''; try { const response = await fetch(API_BASE + 'add_asset.php', { method: 'POST', body: formData }); const result = await response.json(); if (result.success) { showToast('Sukses', 'Aset baru berhasil ditambahkan.'); addAssetForm.reset(); addAssetForm.classList.remove('was-validated'); bootstrap.Modal.getInstance(document.getElementById('addAssetModal')).hide(); loadAssets(); // Refresh the table } else { showToast('Error', result.message || 'Terjadi kesalahan yang tidak diketahui.', 'error'); } } catch (error) { console.error('Error submitting form:', error); showToast('Error', `Gagal mengirim data: ${error.message}`, 'error'); } finally { submitButton.disabled = false; submitButton.innerHTML = 'Simpan Aset'; } } // --- Initializations --- feather.replace(); // Initial call for icons populateSelectOptions(); loadAssets(); // --- Event Listeners --- addAssetForm.addEventListener('submit', handleAddAssetSubmit); // Add feather icon class for easier styling document.querySelectorAll('i[data-feather]').forEach(el => { if(el.classList.contains('feather-sm')) return; const iconName = el.getAttribute('data-feather'); el.classList.add(`icon-${iconName}`); }); });