/** * © 2025-2026 Skoci Admin * Designed and Developed by Abimanyu * Contact : abimanyuag12@gmail.com * All Rights Reserved */ window.addEventListener('load', () => { // 1. Logika Preloader const preloader = document.getElementById('bz-preloader'); if (preloader) { preloader.classList.add('hide'); setTimeout(() => { preloader.remove(); }, 300); } // 2. Logika penyimpanan tab perhalaman // Memilih semua elemen toggle const tabTriggers = document.querySelectorAll('[data-bs-toggle="pill"], [data-bs-toggle="tab"]'); tabTriggers.forEach(trigger => { // Membuat key unik berdasarkan path DAN tipe toggle (pill atau tab) const toggleType = trigger.getAttribute('data-bs-toggle'); const storageKey = `activeTab_${location.pathname}_${toggleType}`; // Event saat tab ditampilkan trigger.addEventListener('shown.bs.tab', event => { const targetIdentifier = event.target.getAttribute('data-bs-target'); localStorage.setItem(storageKey, targetIdentifier); }); // Cek storage saat halaman dimuat (hanya jalankan sekali untuk masing-masing tipe) const savedTarget = localStorage.getItem(storageKey); if (savedTarget) { const targetElement = document.querySelector(`[data-bs-target="${savedTarget}"]`); if (targetElement) { const tabInstance = new bootstrap.Tab(targetElement); tabInstance.show(); } } }); // 3. Logika sidebar Toggle const sidebar = document.querySelector('.sidebar-right'); const topbar = document.querySelector('.topbar-right'); const toggleBtn = document.getElementById('toggleSidebarRight'); const mobileToggle = document.getElementById('mobileToogle'); const hoverTargets = [sidebar, topbar]; // Ambil status awal dari localStorage const isCollapsedSaved = localStorage.getItem('sidebar-collapsed') === 'true'; // Terapkan hanya jika di desktop (window width > 992) if (isCollapsedSaved && window.innerWidth >= 992) { sidebar.classList.add('collapsed'); } hoverTargets.forEach(target => { if (!target) return; target.addEventListener('mouseenter', () => { // Hanya aktifkan temp-expanded jika sidebar memang sedang collapsed if (sidebar.classList.contains('collapsed')) { sidebar.classList.remove('collapsed'); sidebar.classList.add('temp-expanded'); } }); target.addEventListener('mouseleave', () => { // Kembalikan ke collapsed hanya jika statusnya temp-expanded if (sidebar.classList.contains('temp-expanded')) { sidebar.classList.add('collapsed'); sidebar.classList.remove('temp-expanded'); } }); }); if (toggleBtn && sidebar) { toggleBtn.addEventListener('click', (e) => { // Mencegah bubbling agar tidak terpicu dua kali e.stopPropagation(); if (sidebar.classList.contains('temp-expanded')) { // Jika sedang di-hover lalu diklik, hapus status 'temp' // agar sidebar tetap terbuka saat kursor keluar sidebar.classList.remove('temp-expanded'); } else { // Kondisi klik normal (buka/tutup) sidebar.classList.toggle('collapsed'); } // --- SIMPAN KE LOCALSTORAGE --- // Kita simpan true jika class 'collapsed' ada, false jika tidak ada const isCurrentlyCollapsed = sidebar.classList.contains('collapsed'); localStorage.setItem('sidebar-collapsed', isCurrentlyCollapsed); }); } if (mobileToggle && sidebar) { mobileToggle.addEventListener('click', function(e) { e.stopPropagation(); // Mencegah klik menyebar sidebar.classList.toggle('mobile-show'); }); // Opsional: Klik di mana saja di luar sidebar untuk menutupnya document.addEventListener('click', function(e) { if (!sidebar.contains(e.target) && sidebar.classList.contains('mobile-show')) { sidebar.classList.remove('mobile-show'); } }); } // Fungsi untuk bersihkan class collapsed di mobile const cleanMobileSidebar = () => { if (!sidebar) return; if (window.innerWidth < 992) { sidebar.classList.remove('collapsed'); } }; // Jalankan saat pertama kali load cleanMobileSidebar(); // Jalankan juga saat layar di-resize (penting!) window.addEventListener('resize', cleanMobileSidebar); // Hide Alert const alerts = document.querySelectorAll('.bz-alert'); alerts.forEach(alert => { setTimeout(() => { alert.classList.remove('show'); // fade out alert.addEventListener('transitionend', () => { alert.remove(); // hapus dari DOM setelah animasi selesai }); }, 5000); }); // Tab pada mobile mode document.querySelectorAll('.js-tab-trigger').forEach(el => { el.addEventListener('click', function (e) { e.preventDefault(); const targetId = this.dataset.tabTarget; const desktopTrigger = document.querySelector( `[data-bs-toggle="tab"][data-bs-target="#${targetId}"]` ); if (desktopTrigger) { bootstrap.Tab.getOrCreateInstance(desktopTrigger).show(); } }); }); }); function adjustQuantity(button, change) { const container = button.closest('.quantity-control'); // cari parent terdekat if (!container) return; const input = container.querySelector('.qty-input'); // ambil input di dalam container if (!input) return; // ambil value, min, max dari HTML langsung let value = +input.value; // unary + → convert string ke number const min = +input.min; // ambil min dari HTML const max = +input.max; // ambil max dari HTML value += change; // jaga value tetap dalam batas min & max if (value < min) value = min; if (value > max) value = max; input.value = value; } // File upload handling function handleFileUpload(input, previewId, inputId) { const previewContainer = document.getElementById(previewId); previewContainer.innerHTML = ''; if (input.files.length > 0) { previewContainer.style.display = 'block'; for (let i = 0; i < input.files.length; i++) { const file = input.files[i]; const fileSize = formatFileSize(file.size); const fileExtension = getFileExtension(file.name); const fileIcon = getFileIcon(fileExtension); const fileItem = document.createElement('div'); fileItem.className = 'file-item'; fileItem.innerHTML = `
${file.name}
${fileSize}
`; previewContainer.appendChild(fileItem); } } else { previewContainer.style.display = 'none'; } } function removeFile(inputId, previewId, index) { const input = document.getElementById(inputId); const dt = new DataTransfer(); for (let i = 0; i < input.files.length; i++) { if (i !== index) { dt.items.add(input.files[i]); } } input.files = dt.files; handleFileUpload(input, previewId, inputId); } function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } function getFileExtension(filename) { return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2).toLowerCase(); } function getFileIcon(extension) { const icons = { 'pdf': 'bi bi-file-earmark-pdf', 'doc': 'bi bi-file-earmark-word', 'docx': 'bi bi-file-earmark-word', 'xls': 'bi bi-file-earmark-excel', 'xlsx': 'bi bi-file-earmark-excel', 'jpg': 'bi bi-file-earmark-image', 'jpeg': 'bi bi-file-earmark-image', 'png': 'bi bi-file-earmark-image', 'gif': 'bi bi-file-earmark-image', 'zip': 'bi bi-file-earmark-zip', 'rar': 'bi bi-file-earmark-zip', 'txt': 'bi bi-file-earmark-text', 'csv': 'bi bi-filetype-csv' }; return icons[extension] || 'bi bi-file-earmark'; } // generate icon untuk file lama document.querySelectorAll('.icon-wrapper[data-extension]').forEach(wrapper => { const ext = wrapper.dataset.extension.toLowerCase(); const iconClass = getFileIcon(ext); wrapper.innerHTML = ``; }); function showDeleteConfirmation( inputId, previewId, index, ) { Swal.fire({ html: '

Delete this file?

', showCancelButton: true, cancelButtonText: 'Cancel', confirmButtonText: 'Delete', reverseButtons: true, customClass: { popup: 'swal-minimal' } }).then((result) => { if (result.isConfirmed) { /* 1. Ubah nilai hidden input agar server tahu harus hapus database const deleteInput = document.getElementById('delete_existing_file'); if (deleteInput) { deleteInput.value = "true"; } */ // 2. Jalankan fungsi visual yang sudah Anda buat removeFile(inputId, previewId, index); /* 3. Hapus preview secara visual (front-end) const previewContainer = document.getElementById(previewId); if (previewContainer) { previewContainer.style.display = 'none'; } */ // hapus sessionStorage sessionStorage.removeItem('file_draft'); // BERSIHKAN URL (Mencegah "Resend" saat Reload) if (window.history.replaceState) { window.history.replaceState(null, null, window.location.href); } Swal.fire({ html: '

File has been removed.

', showConfirmButton: true, customClass: { popup: 'swal-minimal' } }); } }); } if (typeof flatpickr !== 'undefined' && $('.date').length) { flatpickr(".date", { // dateFormat: "d-m-Y", dateFormat: "d/m/Y H:i", // Ditambah H:i untuk jam dan menit enableTime: true, allowInput: true, // locale: "id", onDayCreate: function(_, __, ___, dayElem) { const d = dayElem.dateObj; if ( dayElem.classList.contains("prevMonthDay") || dayElem.classList.contains("nextMonthDay") ) { return; } // Sunday (0) if (d.getDay() === 0) { dayElem.classList.add("sunday"); } // Friday (5) if (d.getDay() === 5) { dayElem.classList.add("friday"); } } }); }