feature/ui-redesign #8
@ -1,19 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* ticketmaster.js – Schnittstelle zum Backend-Proxy für die Ticketmaster Discovery API.
|
||||||
|
* Der direkte API-Aufruf läuft über den eigenen Backend-Server, um den API-Key
|
||||||
|
* nicht im Frontend zu exponieren (OWASP: Sensitive Data Exposure vermeiden).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lädt Events für eine Stadt über den Backend-Proxy.
|
||||||
|
* @param {string} city - Stadtname für die Suche
|
||||||
|
* @returns {Promise<Array>} Array von rohen Ticketmaster-Event-Objekten
|
||||||
|
*/
|
||||||
export async function fetchEvents(city) {
|
export async function fetchEvents(city) {
|
||||||
const url = `http://localhost:3000/api/events?city=${city}`;
|
const url = `http://localhost:3000/api/events?city=${encodeURIComponent(city)}`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error("API request failed");
|
throw new Error(`Backend antwortete mit Status ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
|
// Ticketmaster gibt Events unter _embedded.events zurück; leeres Array als Fallback
|
||||||
return data._embedded?.events || [];
|
return data._embedded?.events || [];
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching events:", error);
|
console.error("Fehler beim Laden der Events:", error);
|
||||||
return [];
|
// Fehler nach oben weitergeben, damit app.js ihn dem Nutzer anzeigen kann
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
31
js/auth.js
31
js/auth.js
@ -1,20 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* auth.js – Kommunikation mit dem Backend für Registrierung und Login.
|
||||||
|
* Nutzt die Fetch-API mit einfachem Header-basiertem Authentifizierungsschema.
|
||||||
|
*
|
||||||
|
* Sicherheitshinweis: Passwörter werden unverschlüsselt als HTTP-Header übertragen.
|
||||||
|
* Dies ist bewusst vereinfacht (kein TLS/HTTPS in der lokalen Entwicklungsumgebung).
|
||||||
|
* In einer Produktionsumgebung müssten JWT-Tokens oder Sessions eingesetzt werden.
|
||||||
|
*/
|
||||||
|
|
||||||
const BASE_URL = "http://localhost:3000/api";
|
const BASE_URL = "http://localhost:3000/api";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registriert einen neuen Benutzer beim Backend.
|
||||||
|
* Das Backend vergibt ein Standard-Passwort ("1234").
|
||||||
|
* @param {string} username - Gewünschter Benutzername
|
||||||
|
* @returns {Promise<Object>} Objekt mit name und password
|
||||||
|
*/
|
||||||
export async function register(username) {
|
export async function register(username) {
|
||||||
|
|
||||||
const res = await fetch(`${BASE_URL}/user`, {
|
const res = await fetch(`${BASE_URL}/user`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: { "Content-Type": "application/json" },
|
||||||
"Content-Type": "application/json"
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ username })
|
body: JSON.stringify({ username })
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.json();
|
return res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Meldet einen Benutzer an.
|
||||||
|
* Credentials werden als HTTP-Header übermittelt (X-Username, X-Password).
|
||||||
|
* @param {string} username
|
||||||
|
* @param {string} password
|
||||||
|
* @returns {Promise<boolean>} true bei Erfolg (HTTP 200), false bei falschen Credentials
|
||||||
|
*/
|
||||||
export async function login(username, password) {
|
export async function login(username, password) {
|
||||||
|
|
||||||
const res = await fetch(`${BASE_URL}/user`, {
|
const res = await fetch(`${BASE_URL}/user`, {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
@ -23,5 +41,6 @@ export async function login(username, password) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status === 201;
|
// HTTP 200 = Anmeldung erfolgreich, 401 = ungültige Credentials
|
||||||
|
return res.status === 200;
|
||||||
}
|
}
|
||||||
@ -1,14 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* eventService.js – Transformiert rohe Ticketmaster-API-Daten in ein vereinfachtes Event-Objekt.
|
||||||
|
* Kapselt die Datenstruktur der externen API, sodass der Rest der App davon unabhängig bleibt.
|
||||||
|
*/
|
||||||
|
|
||||||
import { fetchEvents } from "../api/ticketmaster.js";
|
import { fetchEvents } from "../api/ticketmaster.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lädt und transformiert Events für eine gegebene Stadt.
|
||||||
|
* @param {string} city - Stadtname
|
||||||
|
* @returns {Promise<Array<{id, name, date, time, venue, category}>>}
|
||||||
|
*/
|
||||||
export async function getEvents(city) {
|
export async function getEvents(city) {
|
||||||
const events = await fetchEvents(city);
|
const events = await fetchEvents(city);
|
||||||
|
|
||||||
|
// Rohe API-Daten auf ein einheitliches, einfaches Format abbilden
|
||||||
return events.map(event => ({
|
return events.map(event => ({
|
||||||
id: event.id,
|
id: event.id,
|
||||||
name: event.name,
|
name: event.name,
|
||||||
date: event.dates?.start?.localDate || null,
|
date: event.dates?.start?.localDate || null,
|
||||||
time: event.dates?.start?.localTime || null,
|
time: event.dates?.start?.localTime || null,
|
||||||
venue: event._embedded?.venues?.[0]?.name || "Unknown venue",
|
venue: event._embedded?.venues?.[0]?.name || "Unbekannter Ort",
|
||||||
|
// Kategorie aus dem ersten Klassifizierungs-Segment extrahieren (z.B. "Music", "Sports")
|
||||||
category: event.classifications?.[0]?.segment?.name
|
category: event.classifications?.[0]?.segment?.name
|
||||||
? event.classifications[0].segment.name.toLowerCase()
|
? event.classifications[0].segment.name.toLowerCase()
|
||||||
: null
|
: null
|
||||||
|
|||||||
@ -1,8 +1,17 @@
|
|||||||
export function getFilters() {
|
/**
|
||||||
const city = document.querySelector("#city-input").value.trim();
|
* filters.js – Liest die aktuellen Filterwerte aus den Formularfeldern.
|
||||||
const dateFrom = document.querySelector("#date-from").value;
|
* Gibt ein einheitliches Filter-Objekt zurück, das von app.js ausgewertet wird.
|
||||||
const dateTo = document.querySelector("#date-to").value;
|
*/
|
||||||
const category = document.querySelector("#category-input").value;
|
|
||||||
|
|
||||||
return { city, dateFrom, dateTo, category };
|
/**
|
||||||
}
|
* Liest Stadtname, Datumsbereich und Kategorie aus den Eingabefeldern.
|
||||||
|
* @returns {{ city: string, dateFrom: string, dateTo: string, category: string }}
|
||||||
|
*/
|
||||||
|
export function getFilters() {
|
||||||
|
const city = document.querySelector("#city-input").value.trim();
|
||||||
|
const dateFrom = document.querySelector("#date-from").value;
|
||||||
|
const dateTo = document.querySelector("#date-to").value;
|
||||||
|
const category = document.querySelector("#category-input").value;
|
||||||
|
|
||||||
|
return { city, dateFrom, dateTo, category };
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user