Updatweb
This commit is contained in:
@@ -7,8 +7,8 @@ window.adminAuth = {
|
||||
isAuthenticated: false,
|
||||
};
|
||||
|
||||
// Check authentication and redirect if needed
|
||||
async function checkAuth() {
|
||||
// Check authentication and redirect if needed - attach to window
|
||||
window.checkAuth = async function () {
|
||||
try {
|
||||
const response = await fetch("/api/admin/session", {
|
||||
credentials: "include",
|
||||
@@ -18,36 +18,272 @@ async function checkAuth() {
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
redirectToLogin();
|
||||
window.redirectToLogin();
|
||||
return false;
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
if (!data.authenticated) {
|
||||
redirectToLogin();
|
||||
window.redirectToLogin();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store user data
|
||||
window.adminAuth.user = data.user;
|
||||
window.adminAuth.isAuthenticated = true;
|
||||
|
||||
// Initialize mobile menu after auth check
|
||||
window.initMobileMenu();
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error("Authentication check failed:", error);
|
||||
redirectToLogin();
|
||||
// Only log in development
|
||||
if (window.location.hostname === "localhost") {
|
||||
console.error("Authentication check failed:", error);
|
||||
}
|
||||
window.redirectToLogin();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Redirect to login page
|
||||
function redirectToLogin() {
|
||||
window.redirectToLogin = function () {
|
||||
if (window.location.pathname !== "/admin/login.html") {
|
||||
window.location.href = "/admin/login.html";
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize mobile menu toggle
|
||||
window.initMobileMenu = function () {
|
||||
// Check if mobile menu button exists
|
||||
let menuToggle = document.getElementById("mobileMenuToggle");
|
||||
|
||||
if (!menuToggle && window.innerWidth <= 768) {
|
||||
// Create mobile menu button
|
||||
menuToggle = document.createElement("button");
|
||||
menuToggle.id = "mobileMenuToggle";
|
||||
menuToggle.className = "mobile-menu-toggle";
|
||||
menuToggle.setAttribute("aria-label", "Toggle navigation menu");
|
||||
menuToggle.setAttribute("aria-expanded", "false");
|
||||
menuToggle.innerHTML = '<i class="bi bi-list"></i>';
|
||||
document.body.appendChild(menuToggle);
|
||||
}
|
||||
|
||||
if (menuToggle) {
|
||||
menuToggle.addEventListener("click", function () {
|
||||
const sidebar = document.querySelector(".sidebar");
|
||||
if (sidebar) {
|
||||
const isActive = sidebar.classList.toggle("active");
|
||||
this.setAttribute("aria-expanded", isActive ? "true" : "false");
|
||||
this.innerHTML = isActive
|
||||
? '<i class="bi bi-x"></i>'
|
||||
: '<i class="bi bi-list"></i>';
|
||||
}
|
||||
});
|
||||
|
||||
// Close sidebar when clicking outside on mobile
|
||||
document.addEventListener("click", function (event) {
|
||||
const sidebar = document.querySelector(".sidebar");
|
||||
const menuToggle = document.getElementById("mobileMenuToggle");
|
||||
|
||||
if (sidebar && menuToggle && window.innerWidth <= 768) {
|
||||
if (
|
||||
!sidebar.contains(event.target) &&
|
||||
event.target !== menuToggle &&
|
||||
!menuToggle.contains(event.target)
|
||||
) {
|
||||
if (sidebar.classList.contains("active")) {
|
||||
sidebar.classList.remove("active");
|
||||
menuToggle.setAttribute("aria-expanded", "false");
|
||||
menuToggle.innerHTML = '<i class="bi bi-list"></i>';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Close menu on link click (mobile)
|
||||
const sidebarLinks = document.querySelectorAll(".sidebar-menu a");
|
||||
sidebarLinks.forEach((link) => {
|
||||
link.addEventListener("click", function () {
|
||||
if (window.innerWidth <= 768) {
|
||||
const sidebar = document.querySelector(".sidebar");
|
||||
if (sidebar && sidebar.classList.contains("active")) {
|
||||
sidebar.classList.remove("active");
|
||||
if (menuToggle) {
|
||||
menuToggle.setAttribute("aria-expanded", "false");
|
||||
menuToggle.innerHTML = '<i class="bi bi-list"></i>';
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Handle window resize
|
||||
let resizeTimer;
|
||||
window.addEventListener("resize", function () {
|
||||
clearTimeout(resizeTimer);
|
||||
resizeTimer = setTimeout(function () {
|
||||
if (window.innerWidth > 768) {
|
||||
const sidebar = document.querySelector(".sidebar");
|
||||
if (sidebar) {
|
||||
sidebar.classList.remove("active");
|
||||
}
|
||||
if (menuToggle) {
|
||||
menuToggle.setAttribute("aria-expanded", "false");
|
||||
menuToggle.innerHTML = '<i class="bi bi-list"></i>';
|
||||
}
|
||||
}
|
||||
}, 250);
|
||||
});
|
||||
};
|
||||
|
||||
// Custom logout confirmation modal
|
||||
window.showLogoutConfirm = function (onConfirm) {
|
||||
// Create modal backdrop
|
||||
const backdrop = document.createElement("div");
|
||||
backdrop.style.cssText = `
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 10000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
animation: fadeIn 0.2s ease;
|
||||
`;
|
||||
|
||||
// Create modal
|
||||
const modal = document.createElement("div");
|
||||
modal.style.cssText = `
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
max-width: 400px;
|
||||
width: 90%;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
|
||||
animation: slideIn 0.3s ease;
|
||||
`;
|
||||
|
||||
modal.innerHTML = `
|
||||
<style>
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
@keyframes slideIn {
|
||||
from { transform: translateY(-20px); opacity: 0; }
|
||||
to { transform: translateY(0); opacity: 1; }
|
||||
}
|
||||
</style>
|
||||
<div style="text-align: center;">
|
||||
<div style="font-size: 48px; margin-bottom: 15px;">
|
||||
<i class="bi bi-box-arrow-right" style="color: #dc3545;"></i>
|
||||
</div>
|
||||
<h3 style="margin: 0 0 10px 0; color: #2c3e50; font-weight: 600;">Confirm Logout</h3>
|
||||
<p style="color: #6c757d; margin: 0 0 25px 0;">Are you sure you want to logout?</p>
|
||||
<div style="display: flex; gap: 10px; justify-content: center;">
|
||||
<button id="cancelLogout" style="
|
||||
padding: 10px 24px;
|
||||
border: 2px solid #6c757d;
|
||||
background: white;
|
||||
color: #6c757d;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s;
|
||||
">Cancel</button>
|
||||
<button id="confirmLogout" style="
|
||||
padding: 10px 24px;
|
||||
border: none;
|
||||
background: linear-gradient(135deg, #dc3545 0%, #c82333 100%);
|
||||
color: white;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s;
|
||||
box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
|
||||
">Logout</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
backdrop.appendChild(modal);
|
||||
document.body.appendChild(backdrop);
|
||||
|
||||
// Add hover effects
|
||||
const cancelBtn = modal.querySelector("#cancelLogout");
|
||||
const confirmBtn = modal.querySelector("#confirmLogout");
|
||||
|
||||
cancelBtn.addEventListener("mouseenter", function () {
|
||||
this.style.background = "#6c757d";
|
||||
this.style.color = "white";
|
||||
});
|
||||
cancelBtn.addEventListener("mouseleave", function () {
|
||||
this.style.background = "white";
|
||||
this.style.color = "#6c757d";
|
||||
});
|
||||
|
||||
confirmBtn.addEventListener("mouseenter", function () {
|
||||
this.style.transform = "translateY(-2px)";
|
||||
this.style.boxShadow = "0 4px 12px rgba(220, 53, 69, 0.4)";
|
||||
});
|
||||
confirmBtn.addEventListener("mouseleave", function () {
|
||||
this.style.transform = "translateY(0)";
|
||||
this.style.boxShadow = "0 2px 8px rgba(220, 53, 69, 0.3)";
|
||||
});
|
||||
|
||||
// Handle buttons
|
||||
const closeModal = () => {
|
||||
backdrop.style.animation = "fadeIn 0.2s ease reverse";
|
||||
setTimeout(() => backdrop.remove(), 200);
|
||||
};
|
||||
|
||||
cancelBtn.addEventListener("click", closeModal);
|
||||
backdrop.addEventListener("click", function (e) {
|
||||
if (e.target === backdrop) closeModal();
|
||||
});
|
||||
|
||||
confirmBtn.addEventListener("click", function () {
|
||||
closeModal();
|
||||
onConfirm();
|
||||
});
|
||||
|
||||
// ESC key to close
|
||||
const escHandler = (e) => {
|
||||
if (e.key === "Escape") {
|
||||
closeModal();
|
||||
document.removeEventListener("keydown", escHandler);
|
||||
}
|
||||
};
|
||||
document.addEventListener("keydown", escHandler);
|
||||
};
|
||||
|
||||
// Logout function - explicitly attach to window for onclick handlers
|
||||
window.logout = async function (skipConfirm = false) {
|
||||
if (!skipConfirm) {
|
||||
window.showLogoutConfirm(async () => {
|
||||
await performLogout();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await performLogout();
|
||||
};
|
||||
|
||||
// CRITICAL: Global function for inline onclick="logout()" handlers
|
||||
// This must be at global scope so inline onclick can find it
|
||||
function logout(skipConfirm = false) {
|
||||
window.logout(skipConfirm);
|
||||
}
|
||||
|
||||
// Logout function
|
||||
async function logout() {
|
||||
// Actual logout logic
|
||||
async function performLogout() {
|
||||
try {
|
||||
const response = await fetch("/api/admin/logout", {
|
||||
method: "POST",
|
||||
@@ -58,15 +294,20 @@ async function logout() {
|
||||
window.adminAuth.user = null;
|
||||
window.adminAuth.isAuthenticated = false;
|
||||
window.location.href = "/admin/login.html";
|
||||
} else {
|
||||
console.error("Logout failed with status:", response.status);
|
||||
// Still redirect to login even if logout fails
|
||||
window.location.href = "/admin/login.html";
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Logout failed:", error);
|
||||
console.error("Logout error:", error);
|
||||
// Still redirect to login even if logout fails
|
||||
window.location.href = "/admin/login.html";
|
||||
}
|
||||
}
|
||||
|
||||
// Show success notification
|
||||
function showSuccess(message) {
|
||||
window.showSuccess = function (message) {
|
||||
const alert = document.createElement("div");
|
||||
alert.className =
|
||||
"alert alert-success alert-dismissible fade show position-fixed";
|
||||
@@ -78,10 +319,10 @@ function showSuccess(message) {
|
||||
`;
|
||||
document.body.appendChild(alert);
|
||||
setTimeout(() => alert.remove(), 5000);
|
||||
}
|
||||
};
|
||||
|
||||
// Show error notification
|
||||
function showError(message) {
|
||||
window.showError = function (message) {
|
||||
const alert = document.createElement("div");
|
||||
alert.className =
|
||||
"alert alert-danger alert-dismissible fade show position-fixed";
|
||||
@@ -93,12 +334,29 @@ function showError(message) {
|
||||
`;
|
||||
document.body.appendChild(alert);
|
||||
setTimeout(() => alert.remove(), 5000);
|
||||
}
|
||||
};
|
||||
|
||||
// Auto-check authentication when this script loads
|
||||
// Only run if we're not on the login page
|
||||
if (window.location.pathname !== "/admin/login.html") {
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
checkAuth();
|
||||
window.checkAuth();
|
||||
|
||||
// Attach logout event listeners to all logout buttons
|
||||
const logoutButtons = document.querySelectorAll(
|
||||
'.btn-logout, [data-logout], [onclick*="logout"]'
|
||||
);
|
||||
logoutButtons.forEach((button) => {
|
||||
// Remove inline onclick if it exists
|
||||
button.removeAttribute("onclick");
|
||||
|
||||
// Add proper event listener
|
||||
button.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
window.logout();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user