// Admin Panel JavaScript
document.addEventListener("DOMContentLoaded", () => {
// Initialize all components
initSidebar()
initDropdowns()
initTooltips()
initAlerts()
initForms()
// Sidebar functionality
function initSidebar() {
const sidebar = document.querySelector(".admin-sidebar")
const content = document.querySelector(".admin-content")
const toggleBtn = document.querySelector(".sidebar-toggle")
const overlay = document.querySelector(".sidebar-overlay")
// Toggle sidebar
if (toggleBtn) {
toggleBtn.addEventListener("click", () => {
if (window.innerWidth <= 768) {
// Mobile behavior
sidebar.classList.toggle("show")
if (overlay) {
overlay.classList.toggle("show")
}
} else {
// Desktop behavior
sidebar.classList.toggle("collapsed")
content.classList.toggle("expanded")
}
})
}
// Close sidebar on overlay click (mobile)
if (overlay) {
overlay.addEventListener("click", () => {
sidebar.classList.remove("show")
overlay.classList.remove("show")
})
}
// Handle dropdown menus in sidebar
const menuItems = document.querySelectorAll('.menu-link[data-toggle="submenu"]')
menuItems.forEach((item) => {
item.addEventListener("click", function (e) {
e.preventDefault()
const submenu = this.nextElementSibling
const arrow = this.querySelector(".menu-arrow")
if (submenu && submenu.classList.contains("submenu")) {
// Close other submenus
menuItems.forEach((otherItem) => {
if (otherItem !== item) {
const otherSubmenu = otherItem.nextElementSibling
const otherArrow = otherItem.querySelector(".menu-arrow")
if (otherSubmenu) {
otherSubmenu.classList.remove("show")
}
if (otherArrow) {
otherArrow.classList.remove("rotated")
}
}
})
// Toggle current submenu
submenu.classList.toggle("show")
if (arrow) {
arrow.classList.toggle("rotated")
}
}
})
})
// Set active menu item
const currentPath = window.location.pathname
const menuLinks = document.querySelectorAll(".menu-link, .submenu-link")
menuLinks.forEach((link) => {
const href = link.getAttribute("href")
if (href && currentPath.includes(href.split("/").pop())) {
link.classList.add("active")
// If it's a submenu link, show parent submenu
if (link.classList.contains("submenu-link")) {
const submenu = link.closest(".submenu")
const parentLink = submenu.previousElementSibling
const arrow = parentLink.querySelector(".menu-arrow")
submenu.classList.add("show")
if (arrow) {
arrow.classList.add("rotated")
}
}
}
})
}
// Dropdown functionality
// function initDropdowns() {
// // Bootstrap dropdown initialization
// const dropdownTriggers = document.querySelectorAll('[data-bs-toggle="dropdown"]')
// dropdownTriggers.forEach((trigger) => {
// trigger.addEventListener("click", function (e) {
// e.preventDefault()
// const menu = this.nextElementSibling
//
// // Close other dropdowns
// document.querySelectorAll(".dropdown-menu.show").forEach((openMenu) => {
// if (openMenu !== menu) {
// openMenu.classList.remove("show")
// }
// })
//
// // Toggle current dropdown
// if (menu && menu.classList.contains("dropdown-menu")) {
// menu.classList.toggle("show")
// }
// })
// })
//
// // Close dropdowns when clicking outside
// document.addEventListener("click", (e) => {
// if (!e.target.closest(".dropdown")) {
// document.querySelectorAll(".dropdown-menu.show").forEach((menu) => {
// menu.classList.remove("show")
// })
// }
// })
// }
// Tooltip functionality
function initTooltips() {
const tooltipElements = document.querySelectorAll('[data-bs-toggle="tooltip"]')
tooltipElements.forEach((element) => {
element.addEventListener("mouseenter", function () {
const title = this.getAttribute("title") || this.getAttribute("data-bs-title")
if (title) {
showTooltip(this, title)
}
})
element.addEventListener("mouseleave", () => {
hideTooltip()
})
})
}
function showTooltip(element, text) {
const tooltip = document.createElement("div")
tooltip.className = "custom-tooltip"
tooltip.textContent = text
tooltip.style.cssText = `
position: absolute;
background: #333;
color: white;
padding: 5px 10px;
border-radius: 4px;
font-size: 12px;
z-index: 9999;
pointer-events: none;
`
document.body.appendChild(tooltip)
const rect = element.getBoundingClientRect()
tooltip.style.left = rect.left + rect.width / 2 - tooltip.offsetWidth / 2 + "px"
tooltip.style.top = rect.top - tooltip.offsetHeight - 5 + "px"
}
function hideTooltip() {
const tooltip = document.querySelector(".custom-tooltip")
if (tooltip) {
tooltip.remove()
}
}
// Alert functionality
function initAlerts() {
const alertCloseButtons = document.querySelectorAll(".alert .btn-close")
alertCloseButtons.forEach((button) => {
button.addEventListener("click", function () {
const alert = this.closest(".alert")
if (alert) {
alert.style.opacity = "0"
setTimeout(() => {
alert.remove()
}, 300)
}
})
})
// Auto-hide alerts after 5 seconds
const autoHideAlerts = document.querySelectorAll('.alert[data-auto-hide="true"]')
autoHideAlerts.forEach((alert) => {
setTimeout(() => {
alert.style.opacity = "0"
setTimeout(() => {
alert.remove()
}, 300)
}, 5000)
})
}
// Form functionality
function initForms() {
// Form validation
const forms = document.querySelectorAll('form[data-validate="true"]')
forms.forEach((form) => {
form.addEventListener("submit", function (e) {
if (!validateForm(this)) {
e.preventDefault()
}
})
})
// File upload preview
const fileInputs = document.querySelectorAll('input[type="file"][data-preview="true"]')
fileInputs.forEach((input) => {
input.addEventListener("change", function () {
previewFile(this)
})
})
// Auto-resize textareas
const textareas = document.querySelectorAll('textarea[data-auto-resize="true"]')
textareas.forEach((textarea) => {
textarea.addEventListener("input", function () {
this.style.height = "auto"
this.style.height = this.scrollHeight + "px"
})
})
}
function validateForm(form) {
let isValid = true
const requiredFields = form.querySelectorAll("[required]")
requiredFields.forEach((field) => {
if (!field.value.trim()) {
showFieldError(field, "यह फील्ड आवश्यक है")
isValid = false
} else {
clearFieldError(field)
}
})
// Email validation
const emailFields = form.querySelectorAll('input[type="email"]')
emailFields.forEach((field) => {
if (field.value && !isValidEmail(field.value)) {
showFieldError(field, "कृपया वैध ईमेल पता दर्ज करें")
isValid = false
}
})
return isValid
}
function showFieldError(field, message) {
clearFieldError(field)
const errorDiv = document.createElement("div")
errorDiv.className = "field-error text-danger small mt-1"
errorDiv.textContent = message
field.classList.add("is-invalid")
field.parentNode.appendChild(errorDiv)
}
function clearFieldError(field) {
field.classList.remove("is-invalid")
const existingError = field.parentNode.querySelector(".field-error")
if (existingError) {
existingError.remove()
}
}
function isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return emailRegex.test(email)
}
function previewFile(input) {
const file = input.files[0]
if (file) {
const reader = new FileReader()
reader.onload = (e) => {
let preview = input.parentNode.querySelector(".file-preview")
if (!preview) {
preview = document.createElement("div")
preview.className = "file-preview mt-2"
input.parentNode.appendChild(preview)
}
if (file.type.startsWith("image/")) {
preview.innerHTML = ``
} else {
preview.innerHTML = `
फाइल चुनी गई: ${file.name}
` } } reader.readAsDataURL(file) } } // Utility functions window.showAlert = (message, type = "info") => { const alertDiv = document.createElement("div") alertDiv.className = `alert alert-${type} alert-dismissible fade show` alertDiv.innerHTML = ` ${message} ` const container = document.querySelector(".main-content") if (container) { container.insertBefore(alertDiv, container.firstChild) // Auto-hide after 5 seconds setTimeout(() => { alertDiv.style.opacity = "0" setTimeout(() => { alertDiv.remove() }, 300) }, 5000) } } window.confirmAction = (message, callback) => { if (confirm(message)) { callback() } } // AJAX helper window.ajaxRequest = (url, data, method = "POST") => fetch(url, { method: method, headers: { "Content-Type": "application/json", "X-Requested-With": "XMLHttpRequest", }, body: method !== "GET" ? JSON.stringify(data) : null, }) .then((response) => response.json()) .catch((error) => { console.error("AJAX Error:", error) window.showAlert("कुछ गलत हुआ। कृपया पुनः प्रयास करें।", "danger") }) // Handle responsive behavior function handleResize() { const sidebar = document.querySelector(".admin-sidebar") const overlay = document.querySelector(".sidebar-overlay") if (window.innerWidth > 768) { if (sidebar) { sidebar.classList.remove("show") } if (overlay) { overlay.classList.remove("show") } } } window.addEventListener("resize", handleResize) // Initialize on page load handleResize() }) // Additional utility functions for specific admin features function deleteItem(id, type, element) { if (confirm("क्या आप वाकई इसे हटाना चाहते हैं?")) { // AJAX call to delete item window.ajaxRequest(`delete_${type}.php`, { id: id }, "POST").then((response) => { if (response.success) { element.closest("tr").remove() window.showAlert("आइटम सफलतापूर्वक हटा दिया गया।", "success") } else { window.showAlert("हटाने में त्रुटि: " + response.message, "danger") } }) } } function toggleStatus(id, type, element) { const currentStatus = element.textContent.trim() const newStatus = currentStatus === "सक्रिय" ? "निष्क्रिय" : "सक्रिय" window.ajaxRequest(`toggle_status.php`, { id: id, type: type }, "POST").then((response) => { if (response.success) { element.textContent = newStatus element.className = newStatus === "सक्रिय" ? "badge badge-success" : "badge badge-danger" window.showAlert("स्थिति सफलतापूर्वक अपडेट की गई।", "success") } else { window.showAlert("अपडेट में त्रुटि: " + response.message, "danger") } }) } // Export functions for global use window.deleteItem = deleteItem window.toggleStatus = toggleStatus