// Funktion, die die aktive Seite anzeigt und alle anderen ausblendet // (void = kein Rückgabetyp) function showPage(pageId: string): void { // Alle Seiten ausblenden: wählt alle DOM-Elemente aus, die die CSS-Klasse .page haben const pages: NodeListOf<HTMLDivElement> = document.querySelectorAll('.page'); // Schleife, die über jedes Element in der page-Liste iteriert für jedes der gefundenen Seiten-Elemente wird die CSS-Klasse 'active' entfernt. // Dies sorgt dafür, dass alle Seiten zunächst "unsichtbar" oder inaktiv sind, da nur die Seite mit der Klasse 'active' sichtbar ist. pages.forEach((page: HTMLDivElement) => { page.classList.remove('active'); }); // Die ausgewählte Seite anzeigen //Diese Methode sucht nach einem DOM-Element mit der ID, die in pageId übergeben wurde. pageId ist eine Zeichenkette, die die ID des Elements // darstellt, das angezeigt werden soll.HTMLElement | null: Der Rückgabewert von getElementById ist entweder ein HTMLElement // (wenn das Element gefunden wurde) oder null (wenn kein Element mit dieser ID existiert). const activePage: HTMLElement | null = document.getElementById(pageId); if (activePage) { activePage.classList.add('active'); } else { console.error(`Seite mit der ID "${pageId}" wurde nicht gefunden.`); } } // Event-Listener für die Initialisierung beim Laden der Seite eim Laden der Seite wird die Funktion showPage('startseite') aufgerufen, // um die Standardseite (startseite) anzuzeigen. interface User { user_id: number; firstName: string; lastName: string; eMail: string; adress: string; role: string; } // Ein Modal-Objekt von Bootstrap wird hier deklariert, aber initialisiert erst später im DOMContentLoaded Event. let modalEl: bootstrap.Modal let modalTest: bootstrap.Modal document.addEventListener("DOMContentLoaded", (): void => { showPage('startseite'); // Standardmäßig die Seite "Reisen" anzeigen modalEl = new bootstrap.Modal("#edit-user-modal"); modalTest = new bootstrap.Modal("#deleteModal"); //--- check, if user is already logged in (e.g. after refresh) ------------------------------------------------------- checkLogin(); // --- Initialisierung der Benutzeranzeige --- readUsers(); // --- Registrierungsformular Eventhandler --- //Registrierung des Event-Listeners document.getElementById("add-user-form")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => { //Verhindern des Standartverhaltens event.preventDefault(); //Eingabefelder durch ihre IDs (grün) auslesen const firstNameEl: HTMLInputElement = document.getElementById("add-user-first-name") as HTMLInputElement; const lastNameEl: HTMLInputElement = document.getElementById("add-user-last-name") as HTMLInputElement; const eMailEl: HTMLInputElement = document.getElementById("add-user-email") as HTMLInputElement; const passwordEl: HTMLInputElement = document.getElementById("add-user-password") as HTMLInputElement; const repeatPasswordEl: HTMLInputElement = document.getElementById("add-user-repeatPassword") as HTMLInputElement; //Die Werte der Eingabefelder werden in Variablen gespeichert const firstName: string = firstNameEl.value; const lastName: string = lastNameEl.value; const eMail: string = eMailEl.value; const password: string = passwordEl.value; const repeatPassword: string = repeatPasswordEl.value; // Validieren der Eingaben if (!firstName || !lastName || !eMail || !password || !repeatPassword) { addMessage("Bitte alle Felder ausfüllen!"); showPage('registrieren'); return; } // Validierung der Passwörter if (password !== repeatPassword) { addMessage("Passwörter stimmen nicht überein!"); showPage('registrieren') return; } // Sende User Daten an Server - asynchrone HTTP-POST-Anfrage - await sorgt dafür, dass die Ausführung wartet, bis die Anfrage abgeschlossen // ist und eine Antwort vom Server erhalten wurde const res: Response = await fetch('/user', { method: 'POST', headers: { "Content-type": "application/json", }, body: JSON.stringify({firstName, lastName, eMail, password, repeatPassword}), }); //Antwort vom Server verarbeiten const data: any = await res.json(); addMessage(data.message); //Verarbeiten des Antwortstatus if (res.status === 201) { addMessage(data.message); showLoggedInStatus(data.user); userDataInProfile(data.user); } else { addMessage(data.message); showPage('registrieren'); } // Zurücksetzen der Eingabefelder, sodass Vorlage wieder leer ist firstNameEl.value = ""; lastNameEl.value = ""; eMailEl.value = ""; passwordEl.value = ""; repeatPasswordEl.value = ""; }); const modalDeleteButton = document.getElementById("saveButtonDelete") as HTMLButtonElement; modalDeleteButton.addEventListener("click", async () => { deleteUser() }) //Bearbeiten eines Nutzers //Registrierung des Event-listeners Event-Listener wird auf das submit-Event des Formulars gesetzt. Das bedeutet, dass der folgende Code // ausgeführt wird, wenn der Benutzer das Formular absendet. document.getElementById("edit-profile-form")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => { event.preventDefault(); //Eingabefelder abrufen. const firstNameEl = document.getElementById("edit-user-first-name") as HTMLInputElement; const lastNameEl = document.getElementById("edit-user-last-name") as HTMLInputElement; const eMailEl = document.getElementById("edit-user-email") as HTMLInputElement; const adressEl = document.getElementById("edit-user-adress") as HTMLInputElement; const passwordEl = document.getElementById("modal-password") as HTMLInputElement; // Werte aus den Eingabefeldern lesen const firstName = firstNameEl.value; const lastName = lastNameEl.value; const eMail = eMailEl.value; const adress = adressEl.value; const password = passwordEl.value; // Validierung if (!password) { addMessage("Bitte geben Sie Ihr Passwort ein, um Änderungen zu speichern."); return; } //Daten an den Server senden - Put anfrage um daten zu aktualisieren const res: Response = await fetch(`/user`, { method: 'put', headers: { "Content-type": "application/json" }, body: JSON.stringify({ firstName, lastName, eMail, adress, password }), }); //ANtwort vom Server verarbeiten try { const data: any = await res.json(); addMessage(data.message); if (res.ok) { addMessage(data.message || "Profil wurde erfolgreich aktualisiert."); userDataInProfile(data.user); modalEl.hide(); // Modal schließen } else { addMessage(data.message || "Fehler beim Aktualisieren des Profils."); } } catch (error) { console.error("Fehler beim Senden der Anfrage:", error); addMessage("Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut."); } }) //Login document.getElementById("dropdown-anmelden")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => { event.preventDefault(); //Abrufen der Formulardaten (document.getElementById('exampleDropdownFormEmail2'): Holt das HTML-Element mit der ID exampleDropdownFormEmail2, // das das Eingabefeld für die E-Mail-Adresse ist. const eMailInput: HTMLInputElement = document.getElementById('exampleDropdownFormEmail2') as HTMLInputElement; const passwordInput: HTMLInputElement = document.getElementById('exampleDropdownFormPassword2') as HTMLInputElement; //Werte, die der Benutzer in die E-Mail- und Passwortfelder eingegeben hat, extrahiert und in den Variablen gespeichert const eMail: string = eMailInput.value; const password: string = passwordInput.value; // Senden der Login-Daten an den Server const response: Response = await fetch('http://localhost:8080/login', { method: "POST", headers: { "Content-type": "application/json" }, body: JSON.stringify({eMail, password}), } ); //Der Code überprüft die HTTP-Antwort vom Server und reagiert je nach Statuscode: if (response.status === 400) { const data: any = await response.json(); addMessage(data.message); } else if (response.status === 401) { const data: any = await response.json(); addMessage(data.message); showPage('startseite') } else if (response.status === 200) { const data: any = await response.json(); addMessage(data.message); showLoggedInStatus(data.user); userDataInProfile(data.user); } else { console.warn(`Unhandled response code (${response.status}).`) } }); //Logout durch POST-Anfrage an http://localhost:8080/logout, um den Benutzer abzumelden. document.getElementById("logout-form")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => { event.preventDefault(); await fetch('http://localhost:8080/logout', { method: "POST", } ); /*showLoggedOutStatus()*/ }); }); /** * Checks if user might be logged */ //schaut ob der User eingeloggt ist, wenn ja schickt er die Daten vom User zurück async function checkLogin(): Promise<void> { const response: Response = await fetch('/login', { method: "GET" } ); if (response.status === 200) { const data: any = await response.json(); showLoggedInStatus(data.user); userDataInProfile(data.user); } } /** * Gets and displays all users */ async function readUsers(): Promise<void> { const res: Response = await fetch('/users', { method: "GET" } ); const data: any = await res.json(); renderList(data.userList); } // Hallo "..." /** * Displays the logged in username */ function showLoggedInStatus(user: User): void { const firstName: HTMLElement = document.getElementById('current-user-firstName')!; firstName.innerHTML = `Hallo, ${user.firstName}!`; //firstName.innerHTML: Die innerHTML-Eigenschaft eines HTML-Elements enthält den HTML-Inhalt // des Elements. Hier wird der Inhalt des firstName-Elements (wahrscheinlich ein Textfeld oder ein div) auf den Text "Hallo, {user.firstName}!" gesetzt. readUsers(); } //Funktion für get function userDataInProfile (user: User): void { const firstNameEl: HTMLInputElement = document.getElementById('edit-user-first-name') as HTMLInputElement; const lastNameEl: HTMLInputElement = document.getElementById('edit-user-last-name') as HTMLInputElement; const eMailEl: HTMLInputElement = document.getElementById('edit-user-email') as HTMLInputElement; firstNameEl.value = user.firstName; lastNameEl.value = user.lastName; eMailEl.value = user.eMail; } //Delete async function deleteUser(): Promise<void> { console.log("Enter delete function") //Daten an den Server senden - delete anfrage, um daten zu aktualisieren const res: Response = await fetch(`/user`, { method: 'delete', headers: { "Content-type": "application/json" }, }); //Antwort vom Server verarbeiten try { //modalEl.hide(); // Modal schließen const data: any = await res.json(); if (res.ok) { modalTest.hide();// Modal schließen showPage('startseite') addMessage(data.message || "Profil wurde erfolgreich gelöscht."); } else { addMessage(data.message || "Fehler beim Löschen des Profils."); } } catch (error) { console.error("Fehler beim Senden der Löschen-Anfrage:", error); addMessage("Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut."); } } /** * Resets the site to the logged-out state. * Clears user list, shows login form, hides logout form- */ /*function showLoggedOutStatus(): void { const eMail: HTMLElement = document.getElementById('current-user-email')!; eMail.innerHTML = ``; const addUserForm: HTMLElement = document.getElementById('add-user-container')!; addUserForm.classList.add("d-none"); // hide content area const contentArea: HTMLElement = document.getElementById('user-list-container')!; contentArea.classList.add("d-none"); // hide content area const login: HTMLElement = document.getElementById('login-container')!; login.classList.remove("d-none"); // show login (document.getElementById('add-user-form') as HTMLFormElement).reset(); }*/ /// für ADMIN wieder relevant /** * 1) Clears the user table. * 2) Adds all users to the table. */ //Benutzerliste function renderList(userList: User[]): void { let userListEl: HTMLElement = document.getElementById("user-list")!; // Remove all entries from the table userListEl.replaceChildren(); for (let user of userList) { // The new table row let tr: HTMLTableRowElement = document.createElement("tr"); // ID cell let tdUser_id: HTMLTableCellElement = document.createElement("td"); tdUser_id.textContent = user.user_id.toString(); // Given name cell let tdFirstName: HTMLTableCellElement = document.createElement("td"); tdFirstName.textContent = user.firstName; // Family name cell let tdLastName: HTMLTableCellElement = document.createElement("td"); tdLastName.textContent = user.lastName; // email cell let tdEmail: HTMLTableCellElement = document.createElement("td"); tdEmail.textContent = user.eMail; // adress cell let tdAdress: HTMLTableCellElement = document.createElement("td"); tdAdress.textContent = user.adress; // role cell let tdRole: HTMLTableCellElement = document.createElement("td"); tdRole.textContent = user.role; // Buttons cell let tdButtons: HTMLTableCellElement = document.createElement("td"); // Delete button let deleteButton: HTMLButtonElement = document.createElement("button"); deleteButton.className = "btn btn-danger"; deleteButton.addEventListener("click", async () => { const res: Response = await fetch('/user/' + user.user_id, { method: 'DELETE' }); const data: any = await res.json(); addMessage(data.message); readUsers(); }); // Delete button icon let deleteButtonIcon: HTMLElement = document.createElement("i"); deleteButtonIcon.className = "fa-solid fa-trash"; deleteButton.append(deleteButtonIcon); // Add the cells to the table row tr.append(tdUser_id, tdFirstName, tdLastName, tdEmail,tdAdress, tdRole, tdButtons); // Add the table row to the table userListEl.append(tr); } } /** * 1) Fills the modal window with the given user's data. * 2) Opens the modal window. */ /** * Creates a new alert message. */ function addMessage(message: string): void { const messagesEl: HTMLElement = document.getElementById('messages')!; // The alert element let alertEl: HTMLElement = document.createElement('div'); alertEl.classList.add('alert', 'alert-warning', 'alert-dismissible', 'fade', 'show'); alertEl.setAttribute('role', 'alert'); alertEl.textContent = message; // Close button let buttonEl: HTMLElement = document.createElement("button"); // btn-close changes the button into an 'X' icon. buttonEl.className = "btn-close"; // data-bs-dismiss enables the button to automatically close the alert on click. buttonEl.setAttribute("data-bs-dismiss", "alert"); // Add the close button to the alert. alertEl.appendChild(buttonEl); // Convert to Bootstrap Alert type const alert: bootstrap.Alert = new bootstrap.Alert(alertEl); // Add message to DOM messagesEl.appendChild(alertEl); // Auto-remove message after 5 seconds (5000ms) setTimeout(() => { alert.close(); }, 5000); }