Skip to content
Snippets Groups Projects
Commit f46dc1af authored by „Sophia's avatar „Sophia
Browse files

push

parent 68d284c0
Branches reiseberichte-crud
No related merge requests found
......@@ -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">
......
......@@ -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);
}
......@@ -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
......@@ -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>
......@@ -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,
});
}
});
/*****************************************************************************
......
......@@ -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
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment