import { showAlert, showConfirm, sanitizeInput } from './shared_functions.js'; import * as api from './api_service.js'; import { initializeChat, createNewChat, handleSendMessage } from './chat_manager.js'; // Only import needed functions directly used by main import * as ui from './chat_ui.js'; // Need UI functions // --- DOM Elements --- // Moved some element selections inside setup functions to ensure they exist const bodyElement = document.body; console.log("main: ") console.log(bodyElement) let themeToggleButton = null; // Initialize as null let logoutBtn = null; // Initialize as null // --- Initialization --- document.addEventListener('DOMContentLoaded', () => { console.log("DOM Content Loaded. Body ID:", bodyElement.id); // Log body ID // Common elements present on all/most pages themeToggleButton = document.getElementById('themeToggleBtn'); logoutBtn = document.getElementById('logoutBtn'); loadThemePreference(); // Load theme early // Add common listeners if elements exist if (themeToggleButton) { console.log("Attaching theme listener"); themeToggleButton.addEventListener('click', toggleTheme); } else { console.warn("Theme toggle button not found"); } if (logoutBtn) { console.log("Attaching logout listener"); logoutBtn.addEventListener('click', logout); } else { console.warn("Logout button not found"); } // Page specific initialization with error handling for the setup promises if (bodyElement.id === 'chat-page') { console.log("Running Chat Page Setup"); setupChatPage() .catch(error => { console.error("Error during Chat Page Setup:", error); showAlert("Ein kritischer Fehler ist beim Laden der Chat-Seite aufgetreten.", "error"); }); } else if (bodyElement.id === 'admin-page') { console.log("Running Admin Page Setup"); setupAdminPage() .catch(error => { // This catch is now primarily for unexpected errors *within* setupAdminPage's try block // as checkAdminStatus errors should be handled more specifically inside. console.error("Unhandled error during Admin Page Setup:", error); if (!error.message?.includes("handled")) { // Avoid double alerts if handled internally showAlert("Ein unerwarteter Fehler ist beim Laden der Admin-Seite aufgetreten.", "error"); } }); } else if (bodyElement.id === 'login-page') { console.log("Login/Register page setup handled by auth.js"); } else { console.warn("No specific page setup for body ID:", bodyElement.id); } }); // --- Page Setup Functions --- async function setupChatPage() { console.log("setupChatPage started"); if (!localStorage.getItem('token')) { redirectToLogin('Kein Token gefunden. Bitte einloggen.'); return; } // Select elements specific to chat page *inside* setup const adminPermissionsBtn = document.getElementById('adminPermissionsBtn'); const newChatButton = document.getElementById('newChatButton'); const chatInput = document.getElementById('chatInput'); const sendButton = document.getElementById('sendButton'); // Load user data first await loadUserDataForChat(); // This function now handles UI updates internally // Setup chat specific event listeners *after* confirming elements exist if (newChatButton) { console.log("Attaching new chat listener"); newChatButton.addEventListener('click', createNewChat); } else { console.error("New Chat button not found!"); } if (sendButton) { console.log("Attaching send listener"); sendButton.addEventListener('click', processUserInput); } else { console.error("Send button not found!"); } if (chatInput) { console.log("Attaching input listeners"); chatInput.addEventListener('keydown', handleChatInputKeydown); chatInput.addEventListener('input', ui.autoResizeTextarea); // Initial resize ui.autoResizeTextarea(); } else { console.error("Chat input not found!"); } if (adminPermissionsBtn) { console.log("Attaching admin button listener"); adminPermissionsBtn.addEventListener('click', () => { window.location.href = 'admin.html'; }); } else { // This might be expected if the user is not admin, handled by loadUserDataForChat // console.warn("Admin permissions button not found (may be expected)"); } // Initialize chat manager AFTER setting up listeners that might use its functions try { console.log("Initializing Chat Manager..."); await initializeChat(); console.log("Chat Manager Initialized."); } catch(error) { console.error("Error initializing chat manager:", error); showAlert("Fehler beim Initialisieren des Chats.", "error"); } } async function setupAdminPage() { console.log("setupAdminPage started"); if (!localStorage.getItem('token')) { redirectToLogin('Kein Token gefunden. Bitte einloggen.'); return; } // Select elements specific to admin page const loadUserListBtn = document.getElementById('loadUserListBtn'); const welcomeButton = document.getElementById('welcomeButton'); const userListDiv = document.getElementById('user-list'); // Also select user list container if (!userListDiv) { console.error("User list container ('user-list') not found on admin page!"); // Optionally show an error message in the main area if the container is missing } try { // Check admin status first. If this fails, it will throw an error. // checkAdminStatus handles redirection/alerts for 401/403. await checkAdminStatus(); console.log("Admin status confirmed. Proceeding with admin setup."); // ---- If admin check passes, THEN setup listeners and load list ---- // Setup 'Reload List' button listener if (loadUserListBtn) { console.log("Attaching load user list listener"); loadUserListBtn.addEventListener('click', () => { console.log("Reload list button clicked."); loadUserList(); // Call loadUserList on click }); } else { console.error("Load user list button ('loadUserListBtn') not found!"); } // Setup 'Back to Chat' button listener if (welcomeButton) { console.log("Attaching welcome button listener"); welcomeButton.addEventListener('click', () => { console.log("Welcome button clicked, redirecting..."); window.location.href = 'welcome.html'; }); } else { console.error("Welcome (back to chat) button ('welcomeButton') not found!"); } // Load list initially ONLY if admin check succeeded console.log("Initiating initial user list load."); await loadUserList(); // Load the list data console.log("Initial user list load attempt finished."); } catch (error) { // This catch block now primarily handles errors from checkAdminStatus // or potentially the initial loadUserList call if it throws unexpectedly. console.error("SetupAdminPage failed during admin check or initial load:", error); // Most user-facing errors (like redirection or alerts for auth/network issues) // should have been handled within checkAdminStatus or loadUserList's call to handleApiError. // We might not need to show another alert here unless it's a truly unexpected setup problem. // Mark the error as handled to avoid potential double alerts from the outer catch block. error.message += " (handled in setupAdminPage)"; } } // --- Event Handlers --- function handleChatInputKeydown(event) { // console.log("Keydown:", event.key); // Debugging keystrokes if (event.key === 'Enter' && !event.shiftKey) { console.log("Enter pressed"); // Debugging Enter key event.preventDefault(); processUserInput(); } } function processUserInput() { const chatInput = document.getElementById('chatInput'); // Re-select or ensure it's available if (!chatInput) { console.error("Cannot process user input: chatInput not found."); return; } const messageText = sanitizeInput(chatInput.value.trim()); console.log("Processing user input:", messageText); // Debugging input processing if (messageText) { handleSendMessage(messageText) // Call chat manager function .then(() => { console.log("Message handled by manager."); ui.clearChatInput(); }) .catch(error => { console.error("Error sending message via manager:", error); // UI should already be enabled by chat_manager's finally block }); } else { console.log("Input is empty, not sending."); } } // --- User Data and Auth --- async function loadUserDataForChat() { const usernameSpan = document.getElementById('username'); const isAdminSpan = document.getElementById('isAdmin'); const adminPermissionsBtn = document.getElementById('adminPermissionsBtn'); try { console.log("Loading user data for chat page..."); const data = await api.getUserData(); console.log("User data received:", data); if (usernameSpan) usernameSpan.textContent = data.user || 'Unbekannt'; if (isAdminSpan) isAdminSpan.textContent = data.isAdmin ? 'Ja' : 'Nein'; if (adminPermissionsBtn) { // Control display based on fetched data adminPermissionsBtn.style.display = data.isAdmin ? 'inline-block' : 'none'; console.log("Admin button display set to:", adminPermissionsBtn.style.display); } } catch (error) { console.error("Failed to load user data:", error); // Display error state in UI if (usernameSpan) usernameSpan.textContent = 'Fehler'; if (isAdminSpan) isAdminSpan.textContent = 'Fehler'; handleApiError(error, 'Benutzerdaten laden'); // Show alert, potentially redirect } } // --- Definition of checkAdminStatus --- Moved here to ensure it's defined before use async function checkAdminStatus() { console.log("Checking admin status..."); try { // Assuming api.getAdminData() makes the /api/auth/admin call // and throws an error (e.g., 401, 403) if the user is not an admin. await api.getAdminData(); console.log("Admin access confirmed."); // No need to return true, successful execution implies admin status } catch (error) { console.warn("Admin status check failed:", error.status, error.message); if (error.status === 403 || error.status === 401) { // Forbidden or Unauthorized showAlert('Zugriff verweigert. Nur Admins erlaubt.', 'error'); window.location.href = 'welcome.html'; // Redirect non-admins immediately } else { // Handle other errors (e.g., network error) handleApiError(error, 'Admin-Status prüfen'); } // IMPORTANT: Re-throw the error AFTER handling redirection/alert // This signals to the caller (setupAdminPage) that the check failed. throw error; } } async function loadUserList() { const userListDiv = document.getElementById('user-list'); // Select inside function if (!userListDiv) { console.error("User list container not found!"); return; } userListDiv.innerHTML = '
Lade Benutzer...
'; // Loading state try { const users = await api.getAllUsers(); userListDiv.innerHTML = ''; // Clear loading/previous list if (users && users.length > 0) { users.forEach(user => { const userDiv = document.createElement('div'); userDiv.classList.add('user-list-item'); userDiv.dataset.userId = user._id; const usernameP = document.createElement('p'); usernameP.innerHTML = `User: ${sanitizeInput(user.username)}`; const emailP = document.createElement('p'); emailP.innerHTML = `Email: ${sanitizeInput(user.email)}`; const adminP = document.createElement('p'); adminP.innerHTML = `Admin: ${user.isAdmin ? 'Ja' : 'Nein'}`; const deleteButton = document.createElement('button'); deleteButton.classList.add('button-delete', 'header-btn'); deleteButton.style.backgroundColor = 'var(--error-color)'; deleteButton.textContent = 'Löschen'; deleteButton.addEventListener('click', () => handleDeleteUser(user._id, user.isAdmin, user.username)); // Pass userListDiv here if needed userDiv.append(usernameP, emailP, adminP, deleteButton); userListDiv.appendChild(userDiv); }); } else { userListDiv.innerHTML = 'Keine Benutzer gefunden.
'; } } catch (error) { handleApiError(error, 'Benutzerliste laden'); userListDiv.innerHTML = 'Fehler beim Laden der Benutzerliste.
'; } } async function handleDeleteUser(userId, isAdmin, username) { const userListDiv = document.getElementById('user-list'); // Select inside function if needed const message = `Möchten Sie den Benutzer "${sanitizeInput(username)}" wirklich löschen? ${isAdmin ? ' Dies ist ein Admin!' : ''}`; const confirmed = await showConfirm(message, 'error'); if (confirmed) { try { await api.deleteUserById(userId); showAlert(`Benutzer "${sanitizeInput(username)}" erfolgreich gelöscht.`, 'success'); // Remove user from list visually immediately const userDiv = userListDiv?.querySelector(`.user-list-item[data-user-id="${userId}"]`); if (userDiv) userDiv.remove(); // Or reload the whole list: await loadUserList(); } catch (error) { handleApiError(error, 'Benutzer löschen'); } } } // --- Theme Toggling --- function toggleTheme() { const isDarkMode = bodyElement.classList.toggle('dark-theme'); if (themeToggleButton) { themeToggleButton.textContent = isDarkMode ? '🌙' : '☀️'; } localStorage.setItem('theme', isDarkMode ? 'dark' : 'light'); } function loadThemePreference() { const savedTheme = localStorage.getItem('theme'); const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; const isDark = savedTheme === 'dark' || (!savedTheme && prefersDark); bodyElement.classList.toggle('dark-theme', isDark); // Set class based on isDark boolean if (themeToggleButton) { // Check if button exists before setting text themeToggleButton.textContent = isDark ? '🌙' : '☀️'; } } // --- Generic Error Handling --- function handleApiError(error, context) { console.error(`API Error during ${context}:`, error); if (error.status === 401 || error.status === 403) { redirectToLogin(`Sitzung abgelaufen oder nicht autorisiert (${context}). Bitte erneut einloggen.`); } else if (error.message.includes('Network Error')) { showAlert(`Netzwerkfehler bei "${context}". Server nicht erreichbar.`, 'error'); } else { // Show specific message from API if available, otherwise generic showAlert(`Fehler bei "${context}": ${error.data?.message || error.message || 'Unbekannter Fehler'}`, 'error'); } } // --- Utility Functions --- (logout, redirectToLogin same as before) function logout() { localStorage.removeItem('token'); window.location.href = 'index.html'; } function redirectToLogin(message) { if (message) showAlert(message, 'error'); setTimeout(() => { window.location.href = 'index.html'; }, 1500); }