// Main JavaScript file for Edu-Space Admin $(document).ready(function() { // Initialize tooltips var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { return new bootstrap.Tooltip(tooltipTriggerEl); }); // Initialize popovers var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')); var popoverList = popoverTriggerList.map(function (popoverTriggerEl) { return new bootstrap.Popover(popoverTriggerEl); }); // Auto-hide alerts after 5 seconds setTimeout(function() { $('.alert.fade').alert('close'); }, 5000); // Confirm delete actions $('.delete-confirm').on('click', function(e) { if (!confirm('Are you sure you want to delete this item? This action cannot be undone.')) { e.preventDefault(); return false; } }); // Form validation enhancements $('form').on('submit', function() { var form = $(this); var submitBtn = form.find('button[type="submit"]'); // Show loading state submitBtn.prop('disabled', true); var originalText = submitBtn.html(); submitBtn.html('Loading...'); // Re-enable after 10 seconds in case of error setTimeout(function() { submitBtn.prop('disabled', false); submitBtn.html(originalText); }, 10000); }); // Copy to clipboard functionality $('.copy-to-clipboard').on('click', function() { var text = $(this).data('text'); if (!text) { text = $(this).text(); } navigator.clipboard.writeText(text).then(function() { showToast('Copied to clipboard!', 'success'); }).catch(function() { showToast('Failed to copy to clipboard', 'error'); }); }); // Quick search functionality $('#quickSearch').on('input', function() { var searchTerm = $(this).val().toLowerCase(); $('.searchable-item').each(function() { var item = $(this); var text = item.text().toLowerCase(); if (text.includes(searchTerm)) { item.show(); } else { item.hide(); } }); }); // Initialize datepickers $('.datetimepicker').each(function() { $(this).flatpickr({ enableTime: true, dateFormat: "Y-m-d H:i", time_24hr: true, minDate: "today" }); }); $('.datepicker').each(function() { $(this).flatpickr({ dateFormat: "Y-m-d", minDate: "today" }); }); // Auto-save functionality for multi-step forms $('.auto-save').on('change input', function() { var form = $(this).closest('form'); var formData = form.serialize(); // Save to localStorage localStorage.setItem('autosave_' + form.attr('id'), formData); showToast('Draft saved automatically', 'info'); }); // Restore auto-saved data $('form.auto-save-restore').each(function() { var form = $(this); var savedData = localStorage.getItem('autosave_' + form.attr('id')); if (savedData) { // Show restore prompt if (confirm('Found unsaved changes. Would you like to restore them?')) { var params = new URLSearchParams(savedData); params.forEach(function(value, key) { form.find('[name="' + key + '"]').val(value); }); showToast('Draft restored', 'info'); } } }); // Print functionality $('.btn-print').on('click', function() { window.print(); }); // Export functionality $('.btn-export').on('click', function() { var format = $(this).data('format'); var url = $(this).data('url'); if (format === 'excel') { window.open(url + '?export=excel', '_blank'); } else if (format === 'pdf') { window.open(url + '?export=pdf', '_blank'); } else if (format === 'csv') { window.open(url + '?export=csv', '_blank'); } }); // Keyboard shortcuts $(document).on('keydown', function(e) { // Ctrl/Cmd + K for search if ((e.ctrlKey || e.metaKey) && e.key === 'k') { e.preventDefault(); $('#quickSearch').focus(); } // Escape to close modals if (e.key === 'Escape') { $('.modal.show').modal('hide'); } }); // Initialize tooltips dynamically for AI-generated content initializeDynamicTooltips(); }); // Utility functions function showToast(message, type = 'info') { var toastHtml = ` `; var toastContainer = $('.toast-container'); var toastElement = $(toastHtml); toastContainer.append(toastElement); var toast = new bootstrap.Toast(toastElement[0]); toast.show(); // Remove toast element after it's hidden toastElement.on('hidden.bs.toast', function() { $(this).remove(); }); } function confirmAction(message, callback) { if (confirm(message)) { callback(); } } function formatDateTime(dateTimeString) { var date = new Date(dateTimeString); return date.toLocaleString(); } function formatDate(dateString) { var date = new Date(dateString); return date.toLocaleDateString(); } function formatTime(timeString) { var date = new Date(timeString); return date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}); } function debounce(func, wait) { let timeout; return function executedFunction(...args) { const later = () => { clearTimeout(timeout); func(...args); }; clearTimeout(timeout); timeout = setTimeout(later, wait); }; } function initializeDynamicTooltips() { // Initialize tooltips for dynamically generated content $('[data-bs-toggle="tooltip"]:not([aria-describedby])').each(function() { new bootstrap.Tooltip(this); }); } // API Helper functions function apiCall(url, method = 'GET', data = null) { return $.ajax({ url: url, method: method, data: data, headers: { 'X-CSRFToken': csrfToken || '' } }); } function handleApiError(xhr) { if (xhr.responseJSON && xhr.responseJSON.message) { showToast(xhr.responseJSON.message, 'error'); } else { showToast('An error occurred. Please try again.', 'error'); } } // Form validation helpers function validateForm(form) { var isValid = true; var errors = []; form.find('[required]').each(function() { var field = $(this); if (!field.val()) { isValid = false; errors.push(field.attr('data-label') || field.attr('name')); field.addClass('is-invalid'); } else { field.removeClass('is-invalid'); } }); if (!isValid) { showToast('Please fill in the required fields: ' + errors.join(', '), 'error'); } return isValid; } // Image preview functionality function previewImage(input, previewElement) { if (input.files && input.files[0]) { var reader = new FileReader(); reader.onload = function(e) { previewElement.attr('src', e.target.result); }; reader.readAsDataURL(input.files[0]); } } // Export to CSV function function exportToCSV(data, filename) { var csv = ''; var headers = Object.keys(data[0]); // Add headers csv += headers.join(',') + '\n'; // Add data data.forEach(function(row) { headers.forEach(function(header, index) { if (index > 0) csv += ','; csv += '"' + (row[header] || '') + '"'; }); csv += '\n'; }); // Create download link var hiddenElement = document.createElement('a'); hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv); hiddenElement.target = '_blank'; hiddenElement.download = filename + '.csv'; hiddenElement.click(); }