From f46dc1af332904acd5496f41915d3853169a8685 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9ESophia?= <„sophia.haupt@mni.thm.de“>
Date: Tue, 28 Jan 2025 14:20:55 +0100
Subject: [PATCH] push

---
 userman_all/client/index.html                 |  48 ++++---
 userman_all/client/src/client.ts              | 136 +++++++++++++++++-
 userman_all/client/stylesheet.css             |  21 +++
 userman_all/server/doc/index.html             |   2 +-
 userman_all/server/src/server.ts              |  89 +++++++++++-
 userman_all/server/test/horizon_changers.http |  73 ++++++----
 6 files changed, 317 insertions(+), 52 deletions(-)

diff --git a/userman_all/client/index.html b/userman_all/client/index.html
index 43138b6..2dad744 100644
--- a/userman_all/client/index.html
+++ b/userman_all/client/index.html
@@ -669,34 +669,32 @@
     </aside>
     <div class="reiseberichtFormular">
         <h1>Wie war Deine Reise mit Uns?</h1>
-        <form>
+        <form id="reiseberichtForm">
             <label for="country">Land auswählen</label>
             <select id="country" name="country">
                 <option value="">-- Bitte wählen --</option>
-                <option value="de">Spanien</option>
-                <option value="fr" >Peru</option>
-                <option value="it">Indien</option>
-                <option value="it">Kenia</option>
+                <option value="spanien">Spanien</option>
+                <option value="peru" >Peru</option>
+                <option value="indien">Indien</option>
+                <option value="kenia">Kenia</option>
             </select>
 
-            <label for="firstname">Vorname</label>
-            <input type="text" id="firstname" name="firstname" placeholder="Vorname">
+            <div class="rating" id="ratingReisebericht">
+                <span id="stern1">&#9733;</span>
+                <span id="stern2">&#9733;</span>
+                <span id="stern3">&#9733;</span>
+                <span id="stern4">&#9733;</span>
+                <span id="stern5">&#9733;</span>
+            </div>
 
-            <label for="lastname">Nachname</label>
-            <input type="text" id="lastname" name="lastname" placeholder="Nachname">
+            <label for="titleReisebericht">Titel</label>
+            <input type="text" id="titleReisebericht" name="title" placeholder="titel">
 
-            <div class="rating">
-                <span>&#9733;</span>
-                <span>&#9733;</span>
-                <span>&#9733;</span>
-                <span>&#9733;</span>
-                <span>&#9733;</span>
-            </div>
 
             <label for="feedback">Feedback</label>
             <textarea id="feedback" name="feedback" placeholder="Schreibe hier dein Feedback..."></textarea>
 
-            <button type="submit" class="reiseberichtAbsenden" onclick="showPage('meineReiseberichte')">Absenden</button>
+            <button type="submit" class="reiseberichtAbsenden">Absenden</button>
 
         </form>
     </div>
@@ -715,16 +713,30 @@
                 <li><a>Mein Profil</a></li>
                 <li><a>Merkliste</a></li>
                 <li><a>Meine Supportanfragen</a></li>
-                <li><a onclick="showPage ('meineReiseberichte')">Meine Reiseberichte </a></li>
+                <li><a onclick="showPage ('meineReiseberichte')" id="meineReiseberichteSeite" >Meine Reiseberichte </a></li>
                 <div id="logout-form4">
                     <li><a  id="logout-button4" onclick="showPage('startseite')">Abmelden</a></li>
                 </div>
             </ul>
         </nav>
     </aside>
+    <main class="content">
+        <section id="sectionNewReisebericht">
+            <h2>Meine Reiseberichte</h2>
+            <div class="reisebericht-card" id="reisebericht-card">
+                    <h3 id="titelReise">Meine Reise in Indien</h3>
+                    <h5 id="reiseland"> ...</h5>
+                    <p id="reisebeschreibung">Das Projekt setzt sich dafür ein, Frauen in benachteiligten Regionen Indiens Zugang zu Bildung und beruflichen Chancen zu ermöglichen. Schon bei meiner Ankunft wurde deutlich, wie wichtig diese Arbeit ist: Die strahlenden Augen der Teilnehmerinnen und ihre Geschichten zeigten, dass Bildung für sie ein Tor zu einem besseren Leben bedeutet.</p>
+                    <button class="details-button">Reisebericht löschen</button>
+                    <button class="report-button" onclick="showPage('reiseberichtSchreiben')">Reisebericht bearbeiten</button>
+            </div>
+        </section>
+    </main>
 </div>
 
 
+
+
 <!--Footer-->
 <footer class="footer">
     <div class="footer-container">
diff --git a/userman_all/client/src/client.ts b/userman_all/client/src/client.ts
index 67b8d78..46b510d 100644
--- a/userman_all/client/src/client.ts
+++ b/userman_all/client/src/client.ts
@@ -35,6 +35,16 @@ interface User {
   role: string;
 }
 
+// Reiseberichte schreiben
+interface Review {
+  reviews_id: number;
+  title: string;
+  description: string;
+  rating: number;
+  country: string;
+  user_id: number;
+}
+
 // Ein Modal-Objekt von Bootstrap wird hier deklariert, aber initialisiert erst später im DOMContentLoaded Event.
 let modalEl: bootstrap.Modal
 let modalTest: bootstrap.Modal
@@ -54,6 +64,7 @@ document.addEventListener("DOMContentLoaded", (): void => {
   checkLogin();
   // --- Initialisierung der Benutzeranzeige ---
   readUsers();
+  readReviews();
 
   // --- Registrierungsformular Eventhandler ---
   //Registrierung des Event-Listeners
@@ -109,6 +120,7 @@ document.addEventListener("DOMContentLoaded", (): void => {
       addMessage(data.message);
       showLoggedInStatus(data.user);
       userDataInProfile(data.user);
+      reviewDataInProfile(data.user);
     } else {
       addMessage(data.message);
       showPage('registrieren');
@@ -124,6 +136,7 @@ document.addEventListener("DOMContentLoaded", (): void => {
 
 
   });
+
   const modalDeleteButton = document.getElementById("saveButtonDelete") as HTMLButtonElement;
   modalDeleteButton.addEventListener("click", async () => {
     deleteUser()
@@ -164,6 +177,7 @@ document.addEventListener("DOMContentLoaded", (): void => {
         showPage('profil')// Modal schließen
         addMessage(data.message || "Profil wurde erfolgreich aktualisiert.");
         userDataInProfile(data.user);
+        reviewDataInProfile(data.user);
       } else {
         console.error ("Fehler beim Aktualisieren des Profils.");
       }
@@ -252,6 +266,7 @@ document.addEventListener("DOMContentLoaded", (): void => {
       }
       showLoggedInStatus(data.user);
       userDataInProfile(data.user);
+      reviewDataInProfile(data.user);
     } else {
       console.warn(`Unhandled response code (${response.status}).`)
     }
@@ -267,7 +282,76 @@ document.addEventListener("DOMContentLoaded", (): void => {
     );
     /*showLoggedOutStatus()*/
   });
+
+  // create Reisebericht
+  document.getElementById("reiseberichtForm")!.addEventListener("submit", async (event: SubmitEvent): Promise<void> => {
+    //Verhindern des Standartverhaltens
+    event.preventDefault();
+    console.log('test');
+
+    //Eingabefelder durch ihre IDs (grün) auslesen
+    const countryEl: HTMLInputElement = document.getElementById("country") as HTMLInputElement;
+    const titleEl: HTMLInputElement = document.getElementById("titleReisebericht") as HTMLInputElement;
+    const descriptionEl: HTMLInputElement = document.getElementById("feedback") as HTMLInputElement;
+    const ratingEl: HTMLInputElement = document.getElementById("ratingReisebericht") as HTMLInputElement;
+
+//Die Werte der Eingabefelder werden in Variablen gespeichert
+    const country: string = countryEl.value;
+    const title: string = titleEl.value;
+    const description: string = descriptionEl.value;
+    const rating: string = ratingEl.value;
+
+    // Validieren der Eingaben
+    if (!country|| !title || !description) {
+      addMessage("Bitte alle Felder ausfüllen!");
+      showPage('reiseberichtSchreiben');
+      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('/reviews', {
+      method: 'POST',
+      headers: {
+        "Content-type": "application/json",
+      },
+      body: JSON.stringify({country, title, description, rating: Number(rating) }),
+    });
+
+    //Antwort vom Server verarbeiten
+    const data: any = await res.json();
+
+    addMessage(data.message);
+
+//Verarbeiten des Antwortstatus
+    if (res.status === 201) {
+      addMessage(data.message);
+      showPage('meineReiseberichte' || "Deine Bewertung wurde erfolgreich erstellt. Danke für dein Feedback! :).");
+    } else {
+      addMessage(data.message || "Fehler beim Erstellen deines Berichts, versuche es später erneut.");
+      showPage('reiseberichtSchreiben');
+    }
+
+    // Zurücksetzen der Eingabefelder, sodass Vorlage wieder leer ist
+    countryEl.value = "";
+    titleEl.value = "";
+    descriptionEl.value = "";
+    ratingEl.value = "";
+
+  });
+   ///Read Reisebericht
+  document.getElementById("meineReiseberichteSeite")!.addEventListener("click", async (): Promise<void> => {
+    showPage('meineReiseberichte');
+    readReviews();
+
+  })
+
+
+
 });
+
+
+
 /**
  * Checks if user might be logged
  */
@@ -281,6 +365,7 @@ async function checkLogin(): Promise<void> {
     const data: any = await response.json();
     showLoggedInStatus(data.user);
     userDataInProfile(data.user);
+    reviewDataInProfile(data.user);
   }
 }
 
@@ -296,6 +381,28 @@ async function readUsers(): Promise<void> {
   renderList(data.userList);
 }
 
+async function readReviews(): Promise<void> {
+  const res: Response = await fetch('/reviews', {
+    method: "GET"
+  }
+  );
+  const data: any = await res.json();
+  renderReviews(data.reviewsList);
+}
+
+//Funktion für get REVIEW
+
+function reviewDataInProfile (reviews: Review): void {
+  const countryEl: HTMLInputElement = document.getElementById("reiseland") as HTMLInputElement;
+  const titleEl: HTMLInputElement = document.getElementById('titelReise') as HTMLInputElement;
+  const descriptionEl: HTMLInputElement = document.getElementById('reisebeschreibung') as HTMLInputElement;
+  //const ratingEl: HTMLInputElement = document.getElementById('edit-user-email') as HTMLInputElement;
+
+  countryEl.value = reviews.country;
+  titleEl.value = reviews.title;
+  descriptionEl.value = reviews.description;
+  //ratingEl.value = reviews.rating;
+}
 /**
  * Displays the logged in username
  */
@@ -371,6 +478,34 @@ function showLoggedOutStatus(): void {
  * 1) Clears the user table.
  * 2) Adds all users to the table.
  */
+function renderReviews(reviewsList: Review[]): void {
+  let reviewsListEl: HTMLElement = document.getElementById("sectionNewReisebericht")!;
+
+  // Remove all entries from the table
+  reviewsListEl.replaceChildren();
+
+  for (let reviews of reviewsList) {
+    // The new h3 überschrift
+    let container: HTMLElement = document.createElement("div");
+    container.className = "reisebericht-card"
+
+    let h3: HTMLElement = document.createElement("h3");
+    h3.textContent = reviews.title.toString();
+
+    // New country element h5
+    let h5: HTMLElement = document.createElement("h5");
+    h5.textContent = reviews.country.toString();
+
+    // new description
+    let p: HTMLElement = document.createElement("p");
+    p.textContent = reviews.description.toString();
+
+    container.append(h3, h5, p);
+
+    reviewsListEl.appendChild(container);
+
+  }
+}
 
 //**
 function renderList(userList: User[]): void {
@@ -509,4 +644,3 @@ function addMessage(message: string): void {
     alert.close();
   }, 5000);
 }
-
diff --git a/userman_all/client/stylesheet.css b/userman_all/client/stylesheet.css
index dd162c9..d844338 100644
--- a/userman_all/client/stylesheet.css
+++ b/userman_all/client/stylesheet.css
@@ -1380,4 +1380,25 @@ textarea {
 
 .reiseberichtAbsenden:hover {
     background-color: #e36c20;
+}
+
+
+.reisebericht-card {
+    width: 662px;
+    height: auto;
+    display: flex;
+    flex-direction: column;
+    align-items: normal;
+    background-color: #FCF3E4;
+    border-radius: 30px;
+    padding: 15px;
+    margin-bottom: 20px;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.reisebericht-info {
+    font-family: 'DM Sans', sans-serif;
+    color: #03355C;
+    font-size: 20px;
+    flex-grow: 1;
 }
\ No newline at end of file
diff --git a/userman_all/server/doc/index.html b/userman_all/server/doc/index.html
index e8a7a9c..9e997c1 100644
--- a/userman_all/server/doc/index.html
+++ b/userman_all/server/doc/index.html
@@ -1042,6 +1042,6 @@
   </div>
 </div>
 
-<script src="assets/main.bundle.js?v=1737968153982"></script>
+<script src="assets/main.bundle.js?v=1737724955109"></script>
 </body>
 </html>
diff --git a/userman_all/server/src/server.ts b/userman_all/server/src/server.ts
index 87823e4..df05f0b 100644
--- a/userman_all/server/src/server.ts
+++ b/userman_all/server/src/server.ts
@@ -79,6 +79,15 @@ export interface User {
   role: string;
   eMail: string;
 }
+
+export interface Review {
+  reviews_id: number;
+  title: string;
+  description: string;
+  rating: number;
+  country: string;
+  user_id: number;
+}
 //Middleware: Login-Status prüfen --Prüft, ob ein Benutzer eingeloggt ist. Falls nicht, wird ein HTTP-Status 401 (Unauthorized) zurückgegeben.
 function isLoggedIn(req: Request, res: Response, next: NextFunction) {
   // Abstract middleware route for checking login state of the user
@@ -380,7 +389,6 @@ app.post('/user', async (req: Request, res: Response): Promise<void> => {
   }
 });
 
-//Benutzer abrufen, aktualisieren, löschen
 
 /*****************************************************************************
  * HTTP ROUTES: USER, USERS                                                  *
@@ -859,7 +867,86 @@ app.get('/users', isLoggedIn, async (req: Request, res: Response): Promise<void>
   }
 });
 
+//Reisebericht schreiben
+app.post('/reviews', isLoggedIn, async (req: Request, res: Response): Promise<void> => {
+  const country: string = req.body.country;
+  const title: string = req.body.title;
+  const description: string = req.body.description;
+  const rating: number = req.body.rating;
+  const user_id: number  = Number(req.session.user?.user_id); //user_id wird zu Number gemacht weil könnte "theoretisch" undefined sein,. aber eig wegen isloggedin nicht
+
+  // Check, if any given value is empty
+  if (!country || !title || !description) {
+    res.status(400).send({
+      message: "Bitte alle Felder ausfüllen!",
+    });
+    return;
+  }
+
+//aufrufen titel, beschreibung, land, rating, userid
+  const data: [string, string, string, number, number] = [
+    title,
+    description,
+    country,
+    Number(rating),
+    user_id,
+  ];
+//soll in review tabelle gespeichert werden
+  const query: string = 'INSERT INTO reviews (title, description, country, rating, user_id) VALUES (?, ?, ?, ?, ?);';
 
+  try {
+    const [rows] = await database.query<RowDataPacket[]>(query, data);
+    // Check if database response contains exactly one entry
+      res.status(201).send({
+        message: 'Deine Bewertung wurde erfolgreich erstellt. Danke für dein Feedback! :).',
+      });
+  } catch (error: unknown) {
+    // Unknown error
+    res.status(500).send({
+      message: 'Database request failed: ' + error,
+    });
+  }
+});
+
+/// Read Review
+
+app.get('/reviews', isLoggedIn, async (req: Request, res: Response): Promise<void> => {
+  // Die `user_id` wird aus der Middleware `isLoggedIn` bereitgestellt
+  const user_id: number  = Number(req.session.user?.user_id);
+
+  // SQL-Query für alle Reviews des Users
+  const query: string = 'SELECT * FROM reviews WHERE user_id = ?;';
+
+  try {
+    // Daten aus der Datenbank abrufen
+    const [rows] = await database.query<RowDataPacket[]>(query, [user_id]);
+
+      // Alle Reviews sammeln und formatieren
+      const reviewsList: Review[] = [];
+      for (const row of rows) {
+        const reviews: Review = {
+          reviews_id: row.reviews_id,
+          user_id: row.user_id,
+          country: row.country,
+          title: row.title,
+          description: row.description,
+          rating: row.rating,
+        };
+        reviewsList.push(reviews);
+      }
+      // Erfolgsantwort senden
+      res.status(200).send({
+        reviewsList: reviewsList, // Alle Reviews zurückgeben
+        message: 'Erfolgreicher Zugriff auf Review.',
+      });
+  } catch (error) {
+    // Fehlerbehandlung bei Datenbankoperationen
+    console.error('Database error: ', error);
+    res.status(500).send({
+      message: 'Database request failed: ' + error,
+    });
+  }
+});
 
 
 /*****************************************************************************
diff --git a/userman_all/server/test/horizon_changers.http b/userman_all/server/test/horizon_changers.http
index 86e670f..5f7ee50 100644
--- a/userman_all/server/test/horizon_changers.http
+++ b/userman_all/server/test/horizon_changers.http
@@ -3,8 +3,20 @@ POST http://localhost:8080/login HTTP/1.1
 Content-Type: application/json
 
 {
-  "eMail": "jens@badeke.de",
-  "password": "123"
+  "eMail": "amelieenders@gmail.com",
+  "password": "amelie"
+}
+
+### Update specific user admin
+PUT http://localhost:8080/user/10 HTTP/1.1
+Content-Type: application/json
+
+{
+  "firstName": "Bruce",
+  "lastName": "Kayne",
+  "eMail": "bato",
+  "adress": "Fetzwiesen 4",
+  "role": "user"
 }
 
 ### Update user
@@ -12,16 +24,16 @@ PUT http://localhost:8080/user HTTP/1.1
 Content-Type: application/json
 
 {
-  "firstName": "Selina",
-  "lastName": "Kyle",
-  "eMail": "otto@gmail.com",
-  "password": "otto"
+  "firstName": "Amelie",
+  "lastName": "Dralle",
+  "eMail": "amelie@gmail.com",
+  "password": "amelie"
 }
 
-### Read User - User
-GET http://localhost:8080/user/31 HTTP/1.1
+### Read User
+GET http://localhost:8080/user/76 HTTP/1.1
 
-### Read User - Fehlerfall User gibt es nicht
+### Read User
 GET http://localhost:8080/user/500 HTTP/1.1
 
 
@@ -30,35 +42,35 @@ POST http://localhost:8080/login HTTP/1.1
 Content-Type: application/json
 
 {
-  "eMail": "jens@badeke.de",
+  "eMail": "lilith@fa.gmx.de",
   "password": "passwort"
 }
 
-### Create a new user - Registrieren
+### Create a new user richtige Route
 POST http://localhost:8080/user HTTP/1.1
 Content-Type: application/json
 
 {
-  "firstName": "Felix",
-  "lastName": "Blau",
-  "eMail": "felix@blau.de",
+  "firstName": "Daria",
+  "lastName": "Krawtschenko",
+  "eMail": "daria@gmail.com",
   "password": "1234",
   "repeatPassword": "1234"
 }
 
-### Create a new user Fehlermeldung Passwort unterschiedlich
+### Create a new user verschiedene Paswörter
 POST http://localhost:8080/user HTTP/1.1
 Content-Type: application/json
 
 {
-  "firstName": "Bruce",
-  "lastName": "Wayne",
-  "eMail": "bat@mail.de",
+  "firstName": "Leonie",
+  "lastName": "Lutz",
+  "eMail": "lutzleo@gmail.com",
   "password": "1234",
   "repeatPassword": "123456"
 }
 
-### Create a new user Fehlermeldung Email fehlt
+### Create a new user eMail fehlt
 POST http://localhost:8080/user HTTP/1.1
 Content-Type: application/json
 
@@ -72,29 +84,28 @@ Content-Type: application/json
 ### Logout
 POST http://localhost:8080/logout HTTP/1.1
 
-
 ### Delete user Nutzer
 DELETE  http://localhost:8080/user HTTP/1.1
 
 
-####Read Users Admin
+####Read Users Nutzerliste Admin
 GET http://localhost:8080/users HTTP/1.1
 
 ### Update specific user Admin
-PUT http://localhost:8080/user/31 HTTP/1.1
+PUT http://localhost:8080/user/70 HTTP/1.1
 Content-Type: application/json
 
 {
-  "firstName": "Felix",
-  "lastName": "Blau",
-  "eMail": "felix@blau.de",
+  "firstName": "Minette",
+  "lastName": "Stark",
+  "eMail": "minette@gmail.com",
   "adress": "Fetzwiesen 4",
   "role": "user"
 }
 
 
-### Update specific user - fehlerfall
-PUT http://localhost:8080/user/1 HTTP/1.1
+### Update specific user
+PUT http://localhost:8080/user/79 HTTP/1.1
 Content-Type: application/json
 
 {
@@ -102,12 +113,12 @@ Content-Type: application/json
   "familyName": "Kyle"
 }
 
-### Delete specific user Admin
-DELETE  http://localhost:8080/user/31 HTTP/1.1
+### Delete specific user
+DELETE  http://localhost:8080/user/80 HTTP/1.1
 
 
-### Delete specific user admin fehlerfall
-DELETE  http://localhost:8080/user/1 HTTP/1.1
+### Delete specific user
+DELETE  http://localhost:8080/user/76 HTTP/1.1
 
 
 
-- 
GitLab