diff --git a/Homepage.css b/Homepage.css index e02919e..c5dfa6e 100644 --- a/Homepage.css +++ b/Homepage.css @@ -517,4 +517,319 @@ footer p { padding: 14px 28px; font-size: 15px; } +} + +/* =========================== + LOGOUT BUTTON STYLES - ADD TO HOMEPAGE.CSS +=========================== */ + +/* Logout Button (Red Version of Login) */ +.btn-logout { + background: linear-gradient(135deg, #ff0066, #cc0033) !important; + color: #fff !important; + font-weight: 900; + box-shadow: 0 6px 30px rgba(255, 0, 102, 0.7), 0 0 20px rgba(204, 0, 51, 0.5); + border: 2px solid rgba(255, 0, 102, 0.5); + position: relative; + z-index: 1; + animation: logoutPulse 2s ease-in-out infinite; +} + +@keyframes logoutPulse { + 0%, 100% { + box-shadow: 0 6px 30px rgba(255, 0, 102, 0.7), 0 0 20px rgba(204, 0, 51, 0.5); + } + 50% { + box-shadow: 0 8px 40px rgba(255, 0, 102, 0.9), 0 0 35px rgba(204, 0, 51, 0.7); + } +} + +.btn-logout:hover { + background: linear-gradient(135deg, #ff0088, #dd0044) !important; + box-shadow: 0 12px 50px rgba(255, 0, 102, 1), 0 0 50px rgba(204, 0, 51, 0.9); + transform: translateY(-5px) scale(1.1); + border-color: rgba(255, 0, 102, 0.8); +} + +/* =========================== + LOGOUT CONFIRMATION MODAL +=========================== */ +.logout-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.85); + backdrop-filter: blur(12px); + display: none; + align-items: center; + justify-content: center; + z-index: 9999; + opacity: 0; + transition: opacity 0.3s ease; +} + +.logout-overlay.active { + opacity: 1; +} + +.logout-modal { + background: linear-gradient(145deg, rgba(30, 0, 50, 0.98), rgba(45, 0, 70, 0.98)); + backdrop-filter: blur(30px); + border: 3px solid rgba(255, 0, 102, 0.5); + border-radius: 28px; + padding: 50px 45px 40px; + max-width: 440px; + width: 90%; + text-align: center; + box-shadow: + 0 40px 100px rgba(0, 0, 0, 0.8), + 0 0 80px rgba(255, 0, 102, 0.4), + inset 0 2px 60px rgba(255, 0, 102, 0.08); + animation: modalSlideUp 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); +} + +@keyframes modalSlideUp { + from { + opacity: 0; + transform: translateY(50px) scale(0.9); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +.logout-icon { + width: 80px; + height: 80px; + margin: 0 auto 25px; + background: linear-gradient(135deg, rgba(255, 0, 102, 0.2), rgba(204, 0, 51, 0.2)); + border: 3px solid rgba(255, 0, 102, 0.6); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + box-shadow: + 0 0 30px rgba(255, 0, 102, 0.4), + inset 0 0 20px rgba(255, 0, 102, 0.1); + animation: iconPulse 2s ease-in-out infinite; +} + +@keyframes iconPulse { + 0%, 100% { + transform: scale(1); + box-shadow: 0 0 30px rgba(255, 0, 102, 0.4); + } + 50% { + transform: scale(1.05); + box-shadow: 0 0 45px rgba(255, 0, 102, 0.6); + } +} + +.logout-icon svg { + width: 40px; + height: 40px; + color: #ff0066; + filter: drop-shadow(0 0 10px rgba(255, 0, 102, 0.6)); +} + +.logout-title { + font-size: 28px; + font-weight: 900; + font-family: 'Orbitron', sans-serif; + background: linear-gradient(135deg, #ff0066 0%, #ff0088 50%, #ff0066 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 15px; + letter-spacing: 2px; + filter: drop-shadow(0 0 20px rgba(255, 0, 102, 0.5)); +} + +.logout-message { + color: rgba(255, 255, 255, 0.8); + font-size: 16px; + margin-bottom: 35px; + line-height: 1.6; + font-family: 'Exo 2', sans-serif; +} + +.logout-buttons { + display: flex; + gap: 15px; + justify-content: center; +} + +.btn-logout-cancel, +.btn-logout-confirm { + padding: 14px 32px; + border: none; + border-radius: 12px; + font-weight: 800; + font-size: 15px; + font-family: 'Orbitron', sans-serif; + cursor: pointer; + text-transform: uppercase; + letter-spacing: 2px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} + +.btn-logout-cancel { + background: rgba(255, 255, 255, 0.1); + color: rgba(255, 255, 255, 0.9); + border: 2px solid rgba(255, 255, 255, 0.3); +} + +.btn-logout-cancel:hover { + background: rgba(255, 255, 255, 0.15); + border-color: rgba(255, 255, 255, 0.5); + transform: translateY(-2px); + box-shadow: 0 5px 20px rgba(255, 255, 255, 0.2); +} + +.btn-logout-confirm { + background: linear-gradient(135deg, #ff0066, #cc0033); + color: #fff; + border: 2px solid rgba(255, 0, 102, 0.6); + box-shadow: 0 4px 20px rgba(255, 0, 102, 0.5); +} + +.btn-logout-confirm:hover { + background: linear-gradient(135deg, #ff0088, #dd0044); + transform: translateY(-2px); + box-shadow: 0 8px 30px rgba(255, 0, 102, 0.7); + border-color: rgba(255, 0, 102, 0.9); +} + +/* =========================== + LOGOUT SUCCESS MODAL +=========================== */ +.logout-success-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.9); + backdrop-filter: blur(15px); + display: none; + align-items: center; + justify-content: center; + z-index: 10000; + opacity: 0; + transition: opacity 0.3s ease; +} + +.logout-success-overlay.active { + opacity: 1; +} + +.logout-success-modal { + background: linear-gradient(145deg, rgba(20, 0, 40, 0.98), rgba(35, 0, 60, 0.98)); + backdrop-filter: blur(30px); + border: 3px solid rgba(0, 255, 136, 0.5); + border-radius: 28px; + padding: 50px 45px; + max-width: 400px; + width: 90%; + text-align: center; + box-shadow: + 0 40px 100px rgba(0, 0, 0, 0.8), + 0 0 80px rgba(0, 255, 136, 0.4), + inset 0 2px 60px rgba(0, 255, 136, 0.08); + animation: successBounce 0.6s cubic-bezier(0.68, -0.55, 0.265, 1.55); +} + +@keyframes successBounce { + 0% { + opacity: 0; + transform: scale(0.3) rotate(-10deg); + } + 50% { + transform: scale(1.1) rotate(5deg); + } + 100% { + opacity: 1; + transform: scale(1) rotate(0deg); + } +} + +.success-icon { + width: 90px; + height: 90px; + margin: 0 auto 25px; + background: linear-gradient(135deg, rgba(0, 255, 136, 0.2), rgba(0, 200, 100, 0.2)); + border: 3px solid rgba(0, 255, 136, 0.6); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + box-shadow: + 0 0 40px rgba(0, 255, 136, 0.5), + inset 0 0 25px rgba(0, 255, 136, 0.1); + animation: successIconPulse 1.5s ease-in-out infinite; +} + +@keyframes successIconPulse { + 0%, 100% { + transform: scale(1); + box-shadow: 0 0 40px rgba(0, 255, 136, 0.5); + } + 50% { + transform: scale(1.08); + box-shadow: 0 0 60px rgba(0, 255, 136, 0.7); + } +} + +.success-icon svg { + width: 50px; + height: 50px; + color: #00ff88; + filter: drop-shadow(0 0 15px rgba(0, 255, 136, 0.8)); +} + +.success-title { + font-size: 26px; + font-weight: 900; + font-family: 'Orbitron', sans-serif; + background: linear-gradient(135deg, #00ff88 0%, #00cc66 50%, #00ff88 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + margin-bottom: 12px; + letter-spacing: 2px; + filter: drop-shadow(0 0 25px rgba(0, 255, 136, 0.5)); +} + +.success-message { + color: rgba(255, 255, 255, 0.85); + font-size: 15px; + line-height: 1.6; + font-family: 'Exo 2', sans-serif; +} + +/* =========================== + RESPONSIVE FOR LOGOUT MODALS +=========================== */ +@media (max-width: 480px) { + .logout-modal, + .logout-success-modal { + padding: 40px 30px; + } + + .logout-title, + .success-title { + font-size: 24px; + } + + .logout-message, + .success-message { + font-size: 14px; + } + + .logout-buttons { + flex-direction: column; + gap: 12px; + } + + .btn-logout-cancel, + .btn-logout-confirm { + width: 100%; + } } \ No newline at end of file diff --git a/Logout.js b/Logout.js index bca6b26..bbdf788 100644 --- a/Logout.js +++ b/Logout.js @@ -1,136 +1,133 @@ -// ========================== -// LOGOUT SYSTEM WITH PHP INTEGRATION -// ========================== - -document.addEventListener("DOMContentLoaded", () => { - checkLoginStatus(); - setupLogoutListeners(); -}); - -// Cek status login dan update button -function checkLoginStatus() { - const loggedInUser = sessionStorage.getItem("loggedInUser"); - const authToken = localStorage.getItem("authToken"); // Cek token juga - const loginBtn = document.querySelector('.login-btn, .logout-btn'); // Cari button +(function() { + 'use strict'; - if (!loginBtn) return; - - // Kalau ada user login ATAU ada authToken - if (loggedInUser || authToken) { - // User sudah login - ubah jadi logout button - loginBtn.textContent = 'Logout'; - loginBtn.className = 'logout-btn'; // Set class langsung - loginBtn.onclick = showLogoutConfirmation; - } else { - // User belum login - tampilkan login button - loginBtn.textContent = 'Login'; - loginBtn.className = 'login-btn'; // Set class langsung - loginBtn.onclick = () => window.location.href = 'Login.html'; - } -} - -// Setup event listeners untuk logout modals -function setupLogoutListeners() { - const btnLogoutCancel = document.getElementById('btn-logout-cancel'); - const btnLogoutConfirm = document.getElementById('btn-logout-confirm'); - const logoutOverlay = document.getElementById('logout-overlay'); - - if (btnLogoutCancel) { - btnLogoutCancel.addEventListener('click', hideLogoutConfirmation); + // ==================== CHECK LOGIN STATUS ==================== + function checkLoginStatus() { + const loggedInUser = sessionStorage.getItem("loggedInUser"); + const loginBtn = document.querySelector('.btn-login'); + + if (loggedInUser && loginBtn) { + // User is logged in - change to Logout button + loginBtn.textContent = 'Logout'; + loginBtn.classList.remove('btn-login'); + loginBtn.classList.add('btn-logout'); + loginBtn.href = '#'; // Prevent navigation + + // Add logout click handler + loginBtn.addEventListener('click', handleLogoutClick); + + console.log('✅ User logged in:', loggedInUser); + } else { + console.log('ℹ️ No user logged in'); + } } - if (btnLogoutConfirm) { - btnLogoutConfirm.addEventListener('click', performLogout); + // ==================== LOGOUT CLICK HANDLER ==================== + function handleLogoutClick(e) { + e.preventDefault(); + showLogoutModal(); } - // Close modal ketika klik di luar - if (logoutOverlay) { - logoutOverlay.addEventListener('click', (e) => { - if (e.target === logoutOverlay) { - hideLogoutConfirmation(); + // ==================== SHOW LOGOUT CONFIRMATION MODAL ==================== + function showLogoutModal() { + const overlay = document.getElementById('logout-overlay'); + if (overlay) { + overlay.style.display = 'flex'; + setTimeout(() => overlay.classList.add('active'), 10); + + // Setup modal buttons + setupModalButtons(); + } + } + + // ==================== SETUP MODAL BUTTONS ==================== + function setupModalButtons() { + const cancelBtn = document.getElementById('btn-logout-cancel'); + const confirmBtn = document.getElementById('btn-logout-confirm'); + + // Cancel button + if (cancelBtn) { + cancelBtn.onclick = closeLogoutModal; + } + + // Confirm button + if (confirmBtn) { + confirmBtn.onclick = confirmLogout; + } + + // Close on overlay click + const overlay = document.getElementById('logout-overlay'); + if (overlay) { + overlay.addEventListener('click', function(e) { + if (e.target === overlay) { + closeLogoutModal(); + } + }); + } + + // ESC key to close + document.addEventListener('keydown', function(e) { + if (e.key === 'Escape') { + closeLogoutModal(); } }); } -} - -// Tampilkan konfirmasi logout -function showLogoutConfirmation() { - const overlay = document.getElementById('logout-overlay'); - if (overlay) { - overlay.style.display = 'flex'; - } -} - -// Sembunyikan konfirmasi logout -function hideLogoutConfirmation() { - const overlay = document.getElementById('logout-overlay'); - if (overlay) { - overlay.style.display = 'none'; - } -} - -// Perform logout dengan integrasi PHP -async function performLogout() { - try { - // Panggil PHP untuk hapus session - const response = await fetch("http://localhost/Kelompok06_2048/Logout.php", { - method: "POST", - headers: { - 'Content-Type': 'application/json' - } - }); - - const result = await response.json(); - - // Hapus data dari localStorage & sessionStorage - localStorage.removeItem("authToken"); - localStorage.removeItem("username"); - sessionStorage.removeItem("loggedInUser"); - sessionStorage.removeItem("showTutorial"); - - // Sembunyikan confirmation modal - hideLogoutConfirmation(); - - // Tampilkan success modal - showLogoutSuccess(); - - // Setelah 2 detik, reload/redirect ke homepage - setTimeout(() => { - window.location.href = "Homepage.html"; - }, 2000); - - } catch (error) { - console.error("Logout error:", error); - - // Kalau gagal koneksi ke PHP, tetap logout dari client side - localStorage.removeItem("authToken"); - localStorage.removeItem("username"); - sessionStorage.removeItem("loggedInUser"); - sessionStorage.removeItem("showTutorial"); - - // Tampilkan error modal (opsional) - showLogoutError(); - - // Tetap redirect setelah 2 detik - setTimeout(() => { - window.location.href = "Homepage.html"; - }, 2000); - } -} - -// Tampilkan logout success -function showLogoutSuccess() { - const overlay = document.getElementById('logout-success-overlay'); - if (overlay) { - overlay.style.display = 'flex'; - } -} - -// Tampilkan logout error (OPSIONAL - tambahkan modal error jika mau) -function showLogoutError() { - // Bisa pakai alert sederhana atau buat modal error sendiri - console.log("Logout gagal terhubung ke server, tapi data lokal sudah dihapus"); - // Atau tetap tampilkan success (karena client-side logout berhasil) - showLogoutSuccess(); -} \ No newline at end of file + // ==================== CLOSE LOGOUT MODAL ==================== + function closeLogoutModal() { + const overlay = document.getElementById('logout-overlay'); + if (overlay) { + overlay.classList.remove('active'); + setTimeout(() => { + overlay.style.display = 'none'; + }, 300); + } + } + + // ==================== CONFIRM LOGOUT ==================== + function confirmLogout() { + // Clear session + sessionStorage.removeItem("loggedInUser"); + + // Close logout modal + closeLogoutModal(); + + // Show success modal + showSuccessModal(); + + // Redirect after 1.5 seconds + setTimeout(() => { + window.location.href = 'index.html'; + }, 1500); + } + + // ==================== SHOW SUCCESS MODAL ==================== + function showSuccessModal() { + const successOverlay = document.getElementById('logout-success-overlay'); + if (successOverlay) { + successOverlay.style.display = 'flex'; + setTimeout(() => successOverlay.classList.add('active'), 10); + + // Auto close after 1.3 seconds + setTimeout(() => { + successOverlay.classList.remove('active'); + setTimeout(() => { + successOverlay.style.display = 'none'; + }, 300); + }, 1300); + } + } + + // ==================== INITIALIZE ==================== + function init() { + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', checkLoginStatus); + } else { + checkLoginStatus(); + } + } + + // Start + init(); + +})(); \ No newline at end of file