175 lines
6.6 KiB
JavaScript
175 lines
6.6 KiB
JavaScript
|
|
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<any>} - 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 = '<option value="">Pilih Kategori...</option>';
|
|
data.kategori.forEach(item => {
|
|
kategoriSelect.innerHTML += `<option value="${item.id}">${item.nama_kategori}</option>`;
|
|
});
|
|
|
|
kantorSelect.innerHTML = '<option value="">Pilih Lokasi...</option>';
|
|
data.kantor.forEach(item => {
|
|
kantorSelect.innerHTML += `<option value="${item.id}">${item.nama_kantor}</option>`;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 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 = `
|
|
<tr>
|
|
<td>${asset.kode_aset}</td>
|
|
<td>${asset.nama_aset}</td>
|
|
<td>${asset.nama_kategori}</td>
|
|
<td>${asset.nama_kantor}</td>
|
|
<td><span class="status-badge status-${asset.status}">${asset.status}</span></td>
|
|
<td>
|
|
<button class="btn btn-sm btn-outline-primary" onclick="alert('Fitur Edit belum tersedia.')"><i data-feather="edit-2" class="feather-sm"></i></button>
|
|
<button class="btn btn-sm btn-outline-danger" onclick="alert('Fitur Hapus belum tersedia.')"><i data-feather="trash-2" class="feather-sm"></i></button>
|
|
</td>
|
|
</tr>
|
|
`;
|
|
assetsTableBody.innerHTML += row;
|
|
});
|
|
} else if (assets) {
|
|
assetsTableBody.innerHTML = '<tr><td colspan="6" class="text-center">Belum ada data aset.</td></tr>';
|
|
} else {
|
|
assetsTableBody.innerHTML = '<tr><td colspan="6" class="text-center text-danger">Gagal memuat data aset.</td></tr>';
|
|
}
|
|
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 = '''<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> 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}`);
|
|
});
|
|
|
|
});
|