import { showToast } from "./toast.js"; // Utility function to get cookie value by name function getCookie(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); return null; } // dashboard.js — toggle guest vs. user dashboard and reposition streams link // Global state let isLoggingOut = false; async function handleLogout(event) { // Prevent multiple simultaneous logout attempts if (isLoggingOut) return; isLoggingOut = true; // Prevent default button behavior if (event) { event.preventDefault(); event.stopPropagation(); } try { console.log('[LOGOUT] Starting logout process'); // Clear user data from localStorage localStorage.removeItem('uid'); localStorage.removeItem('uid_time'); localStorage.removeItem('confirmed_uid'); localStorage.removeItem('last_page'); // Clear session cookie with SameSite attribute to match how it was set const isLocalhost = window.location.hostname === 'localhost'; const secureFlag = !isLocalhost ? '; Secure' : ''; document.cookie = `sessionid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT; SameSite=Lax${secureFlag};`; // Update UI state immediately const userDashboard = document.getElementById('user-dashboard'); const guestDashboard = document.getElementById('guest-dashboard'); const logoutButton = document.getElementById('logout-button'); const deleteAccountButton = document.getElementById('delete-account-button'); if (userDashboard) userDashboard.style.display = 'none'; if (guestDashboard) guestDashboard.style.display = 'block'; if (logoutButton) logoutButton.style.display = 'none'; if (deleteAccountButton) deleteAccountButton.style.display = 'none'; // Show success message (only once) if (window.showToast) { showToast('Logged out successfully'); } else { console.log('Logged out successfully'); } // Navigate to register page if (window.showOnly) { window.showOnly('register-page'); } else { // Fallback to URL change if showOnly isn't available window.location.href = '/#register-page'; } console.log('[LOGOUT] Logout completed'); } catch (error) { console.error('[LOGOUT] Logout failed:', error); if (window.showToast) { showToast('Logout failed. Please try again.'); } } finally { isLoggingOut = false; } } // Delete account function async function handleDeleteAccount() { try { const uid = localStorage.getItem('uid'); if (!uid) { showToast('No user session found. Please log in again.'); return; } // Show confirmation dialog const confirmed = confirm('⚠️ WARNING: This will permanently delete your account and all your data. This action cannot be undone.\n\nAre you sure you want to delete your account?'); if (!confirmed) { return; // User cancelled the deletion } // Show loading state const deleteButton = document.getElementById('delete-account-button'); const originalText = deleteButton.textContent; deleteButton.disabled = true; deleteButton.textContent = 'Deleting...'; // Call the delete account endpoint const response = await fetch(`/api/delete-account`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ uid }), }); const result = await response.json(); if (response.ok) { showToast('Account deleted successfully'); // Clear user data localStorage.removeItem('uid'); localStorage.removeItem('uid_time'); localStorage.removeItem('confirmed_uid'); document.cookie = 'uid=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;'; // Redirect to home page setTimeout(() => { window.location.href = '/'; }, 1000); } else { throw new Error(result.detail || 'Failed to delete account'); } } catch (error) { console.error('Delete account failed:', error); showToast(`Failed to delete account: ${error.message}`); // Reset button state const deleteButton = document.getElementById('delete-account-button'); if (deleteButton) { deleteButton.disabled = false; deleteButton.textContent = '🗑️ Delete Account'; } } } // Debug function to check element visibility and styles function debugElementVisibility(elementId) { const el = document.getElementById(elementId); if (!el) { console.error(`[DEBUG] Element ${elementId} not found`); return {}; } const style = window.getComputedStyle(el); return { id: elementId, exists: true, display: style.display, visibility: style.visibility, opacity: style.opacity, hidden: el.hidden, classList: Array.from(el.classList), parentDisplay: el.parentElement ? window.getComputedStyle(el.parentElement).display : 'no-parent', parentVisibility: el.parentElement ? window.getComputedStyle(el.parentElement).visibility : 'no-parent', rect: el.getBoundingClientRect() }; } /** * Initialize the dashboard and handle authentication state */ async function initDashboard() { console.log('[DASHBOARD] Initializing dashboard...'); // Get all dashboard elements const guestDashboard = document.getElementById('guest-dashboard'); const userDashboard = document.getElementById('user-dashboard'); const userUpload = document.getElementById('user-upload-area'); const logoutButton = document.getElementById('logout-button'); const deleteAccountButton = document.getElementById('delete-account-button'); const fileList = document.getElementById('file-list'); // Add click event listeners for logout and delete account buttons if (logoutButton) { console.log('[DASHBOARD] Adding logout button handler'); logoutButton.addEventListener('click', handleLogout); } if (deleteAccountButton) { console.log('[DASHBOARD] Adding delete account button handler'); deleteAccountButton.addEventListener('click', (e) => { e.preventDefault(); handleDeleteAccount(); }); } // Check authentication state - consolidated to avoid duplicate declarations const hasAuthCookie = document.cookie.includes('isAuthenticated=true'); const hasUidCookie = document.cookie.includes('uid='); const hasLocalStorageAuth = localStorage.getItem('isAuthenticated') === 'true'; const hasAuthToken = localStorage.getItem('authToken') !== null; const isAuthenticated = hasAuthCookie || hasUidCookie || hasLocalStorageAuth || hasAuthToken; // Debug authentication state console.log('[AUTH] Authentication state:', { hasAuthCookie, hasUidCookie, hasLocalStorageAuth, hasAuthToken, isAuthenticated, cookies: document.cookie, localStorage: { isAuthenticated: localStorage.getItem('isAuthenticated'), uid: localStorage.getItem('uid'), authToken: localStorage.getItem('authToken') ? 'present' : 'not present' }, bodyClasses: document.body.className }); // Handle authenticated user if (isAuthenticated) { console.log('[DASHBOARD] User is authenticated, showing user dashboard'); if (userDashboard) userDashboard.style.display = 'block'; if (userUpload) userUpload.style.display = 'block'; if (guestDashboard) guestDashboard.style.display = 'none'; // Add authenticated class to body if not present document.body.classList.add('authenticated'); // Get UID from cookies or localStorage let uid = getCookie('uid') || localStorage.getItem('uid'); if (!uid) { console.warn('[DASHBOARD] No UID found in cookies or localStorage'); // Try to get UID from the URL or hash fragment const urlParams = new URLSearchParams(window.location.search); uid = urlParams.get('uid') || window.location.hash.substring(1); if (uid) { console.log(`[DASHBOARD] Using UID from URL/hash: ${uid}`); localStorage.setItem('uid', uid); } else { console.error('[DASHBOARD] No UID available for file listing'); if (fileList) { fileList.innerHTML = `
`; } return; } } // Initialize file listing if we have a UID if (window.fetchAndDisplayFiles) { console.log(`[DASHBOARD] Initializing file listing for UID: ${uid}`); try { await window.fetchAndDisplayFiles(uid); } catch (error) { console.error('[DASHBOARD] Error initializing file listing:', error); if (fileList) { fileList.innerHTML = ` `; } } } } else { // Guest view console.log('[DASHBOARD] User not authenticated, showing guest dashboard'); if (guestDashboard) guestDashboard.style.display = 'block'; if (userDashboard) userDashboard.style.display = 'none'; if (userUpload) userUpload.style.display = 'none'; // Remove authenticated class if present document.body.classList.remove('authenticated'); // Show login prompt if (fileList) { fileList.innerHTML = ` `; } } // Log authentication details for debugging console.log('[DASHBOARD] Authentication details:', { uid: getCookie('uid') || localStorage.getItem('uid'), cookies: document.cookie, localStorage: { uid: localStorage.getItem('uid'), isAuthenticated: localStorage.getItem('isAuthenticated'), authToken: localStorage.getItem('authToken') ? 'present' : 'not present' } }); // If not authenticated, show guest view and return early if (!isAuthenticated) { console.log('[DASHBOARD] User not authenticated, showing guest dashboard'); if (guestDashboard) guestDashboard.style.display = 'block'; if (userDashboard) userDashboard.style.display = 'none'; if (userUpload) userUpload.style.display = 'none'; // Remove authenticated class if present document.body.classList.remove('authenticated'); // Show login prompt if (fileList) { fileList.innerHTML = ` `; } return; } // Logged-in view - show user dashboard console.log('[DASHBOARD] User is logged in, showing user dashboard'); // Get all page elements const mePage = document.getElementById('me-page'); // Log current display states for debugging console.log('[DASHBOARD] Updated display states:', { guestDashboard: guestDashboard ? window.getComputedStyle(guestDashboard).display : 'not found', userDashboard: userDashboard ? window.getComputedStyle(userDashboard).display : 'not found', userUpload: userUpload ? window.getComputedStyle(userUpload).display : 'not found', logoutButton: logoutButton ? window.getComputedStyle(logoutButton).display : 'not found', deleteAccountButton: deleteAccountButton ? window.getComputedStyle(deleteAccountButton).display : 'not found', mePage: mePage ? window.getComputedStyle(mePage).display : 'not found' }); // Hide guest dashboard if (guestDashboard) { console.log('[DASHBOARD] Hiding guest dashboard'); guestDashboard.style.display = 'none'; } // Show user dashboard if (userDashboard) { console.log('[DASHBOARD] Showing user dashboard'); userDashboard.style.display = 'block'; userDashboard.style.visibility = 'visible'; userDashboard.hidden = false; // Log final visibility state after changes console.log('[DEBUG] Final visibility state after showing user dashboard:', { userDashboard: debugElementVisibility('user-dashboard'), guestDashboard: debugElementVisibility('guest-dashboard'), computedDisplay: window.getComputedStyle(userDashboard).display, computedVisibility: window.getComputedStyle(userDashboard).visibility }); // Debug: Check if the element is actually in the DOM console.log('[DASHBOARD] User dashboard parent:', userDashboard.parentElement); console.log('[DASHBOARD] User dashboard computed display:', window.getComputedStyle(userDashboard).display); } else { console.error('[DASHBOARD] userDashboard element not found!'); } // Show essential elements for logged-in users const linksSection = document.getElementById('links'); if (linksSection) { console.log('[DASHBOARD] Showing links section'); linksSection.style.display = 'block'; } const showMeLink = document.getElementById('show-me'); if (showMeLink && showMeLink.parentElement) { console.log('[DASHBOARD] Showing show-me link'); showMeLink.parentElement.style.display = 'block'; } // Show me-page for logged-in users if (mePage) { console.log('[DASHBOARD] Showing me-page'); mePage.style.display = 'block'; } try { // Try to get UID from various sources let uid = getCookie('uid') || localStorage.getItem('uid'); // If we have a valid UID, try to fetch user data if (uid && uid !== 'welcome-page' && uid !== 'undefined' && uid !== 'null') { console.log('[DASHBOARD] Found valid UID:', uid); console.log(`[DEBUG] Fetching user data for UID: ${uid}`); const response = await fetch(`/me/${uid}`); if (!response.ok) { const errorText = await response.text(); console.error(`[ERROR] Failed to fetch user data: ${response.status} ${response.statusText}`, errorText); throw new Error(`HTTP ${response.status}: ${response.statusText}`); } // Parse and handle the response data const data = await response.json(); console.log('[DEBUG] User data loaded:', data); // Ensure upload area is visible if last_page was me-page if (userUpload && localStorage.getItem('last_page') === 'me-page') { // userUpload visibility is now only controlled by nav.js SPA logic } // Remove guest warning if present const guestMsg = document.getElementById('guest-warning-msg'); if (guestMsg && guestMsg.parentNode) guestMsg.parentNode.removeChild(guestMsg); // Show user dashboard and logout button if (userDashboard) userDashboard.style.display = ''; if (logoutButton) { logoutButton.style.display = 'block'; logoutButton.onclick = handleLogout; } // Set audio source const meAudio = document.getElementById('me-audio'); const username = data?.username || ''; if (meAudio) { if (username) { // Use username for the audio file path if available meAudio.src = `/audio/${encodeURIComponent(username)}/stream.opus?t=${Date.now()}`; console.log('Setting audio source to:', meAudio.src); } else if (uid) { // Fallback to UID if username is not available meAudio.src = `/audio/${encodeURIComponent(uid)}/stream.opus?t=${Date.now()}`; console.warn('Using UID fallback for audio source:', meAudio.src); } } // Update quota and ensure quota meter is visible if data is available const quotaMeter = document.getElementById('quota-meter'); const quotaBar = document.getElementById('quota-bar'); const quotaText = document.getElementById('quota-text'); if (quotaBar && data.quota !== undefined) { quotaBar.value = data.quota; } if (quotaText && data.quota !== undefined) { quotaText.textContent = `${data.quota} MB`; } if (quotaMeter) { quotaMeter.hidden = false; quotaMeter.style.display = 'block'; // Ensure it's not hidden by display:none } // Fetch and display the list of uploaded files if the function is available if (window.fetchAndDisplayFiles) { console.log('[DASHBOARD] Calling fetchAndDisplayFiles with UID:', uid); // Ensure we have the most up-to-date UID from the response data if available const effectiveUid = data?.uid || uid; console.log('[DASHBOARD] Using effective UID:', effectiveUid); window.fetchAndDisplayFiles(effectiveUid); } else { console.error('[DASHBOARD] fetchAndDisplayFiles function not found!'); } } else { // No valid UID found, ensure we're in guest mode console.log('[DASHBOARD] No valid UID found, showing guest dashboard'); userDashboard.style.display = 'none'; guestDashboard.style.display = 'block'; userUpload.style.display = 'none'; document.body.classList.remove('authenticated'); return; // Exit early for guest users } // Ensure Streams link remains in nav, not moved // (No action needed if static) } catch (e) { console.warn('Dashboard init error, falling back to guest mode:', e); // Ensure guest UI is shown userUpload.style.display = 'none'; userDashboard.style.display = 'none'; if (guestDashboard) guestDashboard.style.display = 'block'; // Update body classes document.body.classList.remove('authenticated'); document.body.classList.add('guest-mode'); // Ensure navigation is in correct state const registerLink = document.getElementById('guest-login'); const streamsLink = document.getElementById('guest-streams'); if (registerLink && streamsLink) { registerLink.parentElement.insertAdjacentElement('afterend', streamsLink.parentElement); } } } // Function to delete a file - only define if not already defined if (typeof window.deleteFile === 'undefined') { window.deleteFile = async function(uid, fileName, listItem) { if (!confirm(`Are you sure you want to delete "${fileName}"? This cannot be undone.`)) { return; } try { console.log(`[FILES] Deleting file: ${fileName} for user: ${uid}`); const response = await fetch(`/delete-file/${uid}/${encodeURIComponent(fileName)}`, { method: 'DELETE', credentials: 'include', headers: { 'Accept': 'application/json' } }); console.log('[FILES] Delete response:', response.status, response.statusText); if (!response.ok) { const errorText = await response.text(); console.error('[FILES] Delete error:', errorText); showToast(`Error deleting file: ${response.statusText}`, 'error'); return; } // Remove the file from the UI if (listItem && listItem.parentNode) { listItem.parentNode.removeChild(listItem); } showToast('File deleted successfully', 'success'); // If no files left, show "no files" message const fileList = document.getElementById('file-list'); if (fileList && fileList.children.length === 0) { fileList.innerHTML = '