821 lines
20 KiB
JavaScript
821 lines
20 KiB
JavaScript
const express = require("express");
|
||
const { Pool } = require("pg");
|
||
const os = require("os");
|
||
const multer = require('multer');
|
||
const path = require('path');
|
||
const fs = require('fs');
|
||
|
||
const cors = require('cors');
|
||
const app = express();
|
||
const port = process.env.PORT || 3000;
|
||
|
||
const bcrypt = require('bcryptjs');
|
||
const jwt = require('jsonwebtoken');
|
||
|
||
const JWT_SECRET = "supergeheimes_tg_cms_secret";
|
||
|
||
// Bodyparser für JSON aktivieren
|
||
app.use(cors({
|
||
origin: ["http://localhost:8080", "http://192.168.50.65:8080"],
|
||
methods: ["GET", "POST", "PUT", "DELETE"],
|
||
credentials: true
|
||
}));
|
||
|
||
app.use(express.json());
|
||
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
|
||
|
||
|
||
// PostgreSQL Verbindung aufbauen
|
||
const pool = new Pool({
|
||
user: "tgadmin",
|
||
host: "db", // Docker Container Name!
|
||
database: "tg-cms",
|
||
password: "secretpass",
|
||
port: 5432,
|
||
});
|
||
|
||
// Testroute API-Check
|
||
app.get("/api/hello", (req, res) => {
|
||
res.send("Hello World from TG CMS API! 🚀");
|
||
});
|
||
|
||
// Testroute DB-Check
|
||
app.get("/api/test-db", async (req, res) => {
|
||
try {
|
||
const result = await pool.query("SELECT NOW()");
|
||
res.json({ time: result.rows[0].now });
|
||
} catch (err) {
|
||
console.error(err);
|
||
res.status(500).send("Fehler bei DB-Verbindung");
|
||
}
|
||
});
|
||
|
||
// Alle News abrufen
|
||
app.get("/api/news", async (req, res) => {
|
||
try {
|
||
const result = await pool.query('SELECT * FROM news ORDER BY created_at DESC');
|
||
res.json(result.rows);
|
||
} catch (err) {
|
||
console.error(err);
|
||
res.status(500).send("Fehler beim Abrufen der News");
|
||
}
|
||
});
|
||
|
||
// Neue News anlegen
|
||
app.post("/api/news", async (req, res) => {
|
||
const { title, description, image_url, team } = req.body;
|
||
|
||
if (!title || !description) {
|
||
return res.status(400).send("Titel und Beschreibung sind Pflichtfelder");
|
||
}
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
'INSERT INTO news (title, description, image_url, team) VALUES ($1, $2, $3, $4) RETURNING *',
|
||
[title, description, image_url, team]
|
||
);
|
||
res.status(201).json(result.rows[0]);
|
||
} catch (err) {
|
||
console.error(err);
|
||
res.status(500).send("Fehler beim Anlegen der News");
|
||
}
|
||
});
|
||
|
||
// News bearbeiten
|
||
app.put("/api/news/:id", async (req, res) => {
|
||
const { id } = req.params;
|
||
const { title, description, image_url, team } = req.body;
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
'UPDATE news SET title = $1, description = $2, image_url = $3, team = $4 WHERE id = $5 RETURNING *',
|
||
[title, description, image_url, team, id]
|
||
);
|
||
|
||
if (result.rowCount === 0) {
|
||
return res.status(404).send("News-Eintrag nicht gefunden");
|
||
}
|
||
|
||
res.json(result.rows[0]);
|
||
} catch (err) {
|
||
console.error(err);
|
||
res.status(500).send("Fehler beim Aktualisieren der News");
|
||
}
|
||
});
|
||
|
||
// News löschen
|
||
app.delete("/api/news/:id", async (req, res) => {
|
||
const { id } = req.params;
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
'DELETE FROM news WHERE id = $1',
|
||
[id]
|
||
);
|
||
|
||
if (result.rowCount === 0) {
|
||
return res.status(404).send("News-Eintrag nicht gefunden");
|
||
}
|
||
|
||
res.send("News-Eintrag erfolgreich gelöscht");
|
||
} catch (err) {
|
||
console.error(err);
|
||
res.status(500).send("Fehler beim Löschen der News");
|
||
}
|
||
});
|
||
|
||
// Neuen Benutzer anlegen
|
||
app.post("/api/users", async (req, res) => {
|
||
const { username, password, role, email } = req.body;
|
||
|
||
if (!username || !password || !email) {
|
||
return res.status(400).send("Username, Email & Passwort sind Pflicht");
|
||
}
|
||
|
||
try {
|
||
// Passwort hashen
|
||
const hashedPassword = await bcrypt.hash(password, 10);
|
||
|
||
// In DB speichern
|
||
const result = await pool.query(
|
||
'INSERT INTO users (username, password, role, email) VALUES ($1, $2, $3, $4) RETURNING id, username, role, email, created_at',
|
||
[username, hashedPassword, role ||'user', email]
|
||
);
|
||
|
||
res.status(201).json(result.rows[0]);
|
||
} catch (err) {
|
||
console.error(err);
|
||
res.status(500).send("Fehler beim Anlegen des Benutzers");
|
||
}
|
||
});
|
||
|
||
// Benutzer Login
|
||
app.post("/api/login", async (req, res) => {
|
||
const { username, password } = req.body;
|
||
|
||
if (!username || !password) {
|
||
return res.status(400).send("Username und Passwort erforderlich");
|
||
}
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
'SELECT * FROM users WHERE username = $1',
|
||
[username]
|
||
);
|
||
|
||
const user = result.rows[0];
|
||
|
||
if (!user) {
|
||
return res.status(400).send("Benutzer existiert nicht");
|
||
}
|
||
|
||
// Passwort prüfen
|
||
const validPassword = await bcrypt.compare(password, user.password);
|
||
|
||
if (!validPassword) {
|
||
return res.status(401).send("Passwort falsch");
|
||
}
|
||
|
||
await pool.query(
|
||
'UPDATE users SET last_logged = NOW() WHERE id = $1',
|
||
[user.id]
|
||
);
|
||
|
||
// JWT Token erzeugen
|
||
const token = jwt.sign(
|
||
{ id: user.id, username: user.username, role: user.role },
|
||
JWT_SECRET,
|
||
{ expiresIn: "6h" }
|
||
);
|
||
|
||
res.json({ token });
|
||
} catch (err) {
|
||
console.error(err);
|
||
res.status(500).send("Fehler beim Login");
|
||
}
|
||
});
|
||
|
||
|
||
// Alle Benutzer abrufen
|
||
app.get("/api/users", async (req, res) => {
|
||
try {
|
||
const result = await pool.query(
|
||
'SELECT id, username, role, email, created_at FROM users ORDER BY created_at DESC'
|
||
);
|
||
res.json(result.rows);
|
||
} catch (err) {
|
||
console.error(err);
|
||
res.status(500).send("Fehler beim Abrufen der Benutzer");
|
||
}
|
||
});
|
||
|
||
// Benutzer l<>loeschen
|
||
app.delete("/api/users/:id", async (req, res) => {
|
||
const { id } = req.params;
|
||
|
||
try {
|
||
// Prüfen, ob der Benutzer existiert
|
||
const checkResult = await pool.query('SELECT * FROM users WHERE id = $1', [id]);
|
||
if (checkResult.rowCount === 0) {
|
||
return res.status(404).send("Benutzer nicht gefunden");
|
||
}
|
||
|
||
// Benutzer löschen
|
||
await pool.query('DELETE FROM users WHERE id = $1', [id]);
|
||
|
||
res.send("Benutzer erfolgreich gelöscht");
|
||
} catch (err) {
|
||
console.error(err);
|
||
res.status(500).send("Fehler beim Löschen des Benutzers");
|
||
}
|
||
});
|
||
|
||
// Benutzer bearbeiten
|
||
app.put("/api/users/:id", async (req, res) => {
|
||
const { id } = req.params;
|
||
const { username, password, role } = req.body;
|
||
|
||
try {
|
||
// Passwort optional neu setzen
|
||
let query = 'UPDATE users SET username = $1, role = $2';
|
||
let params = [username, role, id];
|
||
|
||
if (password) {
|
||
const hashedPassword = await bcrypt.hash(password, 10);
|
||
query = 'UPDATE users SET username = $1, password = $2, role = $3 WHERE id = $4';
|
||
params = [username, hashedPassword, role, id];
|
||
} else {
|
||
query += ' WHERE id = $3';
|
||
}
|
||
|
||
const result = await pool.query(query, params);
|
||
|
||
if (result.rowCount === 0) {
|
||
return res.status(404).send("Benutzer nicht gefunden");
|
||
}
|
||
|
||
res.send("Benutzer erfolgreich aktualisiert");
|
||
} catch (err) {
|
||
console.error(err);
|
||
res.status(500).send("Fehler beim Aktualisieren des Benutzers");
|
||
}
|
||
});
|
||
|
||
|
||
// Speicherort definieren
|
||
const newsStorage = multer.diskStorage({
|
||
destination: (req, file, cb) => {
|
||
const dir = "./uploads/news";
|
||
fs.mkdirSync(dir, { recursive: true });
|
||
cb(null, dir);
|
||
},
|
||
filename: (req, file, cb) => {
|
||
const ext = path.extname(file.originalname);
|
||
const filename = Date.now() + ext;
|
||
cb(null, filename);
|
||
},
|
||
});
|
||
|
||
const playerStorage = multer.diskStorage({
|
||
destination: (req, file, cb) => {
|
||
const dir = "./uploads/players";
|
||
fs.mkdirSync(dir, { recursive: true });
|
||
cb(null, dir);
|
||
},
|
||
filename: (req, file, cb) => {
|
||
const ext = path.extname(file.originalname);
|
||
const filename = Date.now() + ext;
|
||
cb(null, filename);
|
||
},
|
||
});
|
||
|
||
const uploadNewsImage = multer({ storage: newsStorage });
|
||
const uploadPlayerImage = multer({ storage: playerStorage });
|
||
|
||
|
||
|
||
|
||
|
||
//Neues Bild zu den News hinzufügen
|
||
app.post("/api/upload-news-image", uploadNewsImage.single("image"), (req, res) => {
|
||
if (!req.file) {
|
||
return res.status(400).send("Kein Bild hochgeladen");
|
||
}
|
||
const imageUrl = `/uploads/news/${req.file.filename}`;
|
||
res.json({ imageUrl });
|
||
});
|
||
|
||
|
||
//Teams abfragen
|
||
app.get("/api/teams", async (req, res) => {
|
||
try {
|
||
const result = await pool.query(`
|
||
SELECT
|
||
t.id,
|
||
t.name,
|
||
t.liga,
|
||
t.sucht_spieler,
|
||
t.social_media,
|
||
t.trainer_name,
|
||
t.karussell_bilder, -- 👉 Hier angepasst!
|
||
COUNT(pt.player_id) AS player_count
|
||
FROM teams t
|
||
LEFT JOIN player_teams pt ON pt.team_id = t.id
|
||
GROUP BY
|
||
t.id,
|
||
t.name,
|
||
t.liga,
|
||
t.sucht_spieler,
|
||
t.social_media,
|
||
t.trainer_name,
|
||
t.karussell_bilder -- 👉 Hier auch
|
||
ORDER BY t.name ASC
|
||
`);
|
||
res.json(result.rows);
|
||
} catch (err) {
|
||
console.error("Fehler beim Abrufen der Teams:", err);
|
||
res.status(500).send("Fehler beim Abrufen der Teams");
|
||
}
|
||
});
|
||
|
||
|
||
// Team aktualisieren
|
||
app.put("/api/teams/:id", async (req, res) => {
|
||
const { id } = req.params;
|
||
const {
|
||
name,
|
||
liga,
|
||
sucht_spieler,
|
||
social_media,
|
||
karussell_bilder,
|
||
trainer_name,
|
||
trainingszeiten,
|
||
trainingsort,
|
||
kontakt_name,
|
||
kontakt_email,
|
||
teamfarben,
|
||
beschreibung,
|
||
tabellenlink
|
||
} = req.body;
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
`UPDATE teams SET
|
||
name = $1,
|
||
liga = $2,
|
||
sucht_spieler = $3,
|
||
social_media = $4,
|
||
karussell_bilder = $5,
|
||
trainer_name = $6,
|
||
trainingszeiten = $7,
|
||
trainingsort = $8,
|
||
kontakt_name = $9,
|
||
kontakt_email = $10,
|
||
teamfarben = $11,
|
||
beschreibung = $12,
|
||
tabellenlink = $13
|
||
WHERE id = $14
|
||
RETURNING *`,
|
||
[
|
||
name,
|
||
liga,
|
||
sucht_spieler,
|
||
social_media,
|
||
karussell_bilder,
|
||
trainer_name,
|
||
trainingszeiten,
|
||
trainingsort,
|
||
kontakt_name,
|
||
kontakt_email,
|
||
teamfarben,
|
||
beschreibung,
|
||
tabellenlink,
|
||
id
|
||
]
|
||
);
|
||
|
||
if (result.rowCount === 0) {
|
||
return res.status(404).send("Team nicht gefunden");
|
||
}
|
||
|
||
res.json(result.rows[0]);
|
||
} catch (err) {
|
||
console.error("Fehler beim Aktualisieren des Teams:", err);
|
||
res.status(500).send("Fehler beim Aktualisieren des Teams");
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
|
||
//Teams anlegen
|
||
app.post("/api/teams", async (req, res) => {
|
||
const {
|
||
name,
|
||
liga,
|
||
sucht_spieler,
|
||
social_media,
|
||
karussell_bilder,
|
||
trainer_name,
|
||
trainingszeiten,
|
||
trainingsort,
|
||
kontakt_name,
|
||
kontakt_email,
|
||
teamfarben,
|
||
beschreibung,
|
||
tabellenlink
|
||
} = req.body;
|
||
|
||
if (!name) return res.status(400).send("Teamname ist erforderlich");
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
`INSERT INTO teams (
|
||
name, liga, sucht_spieler, social_media, karussell_bilder,
|
||
trainer_name, trainingszeiten, trainingsort, kontakt_name,
|
||
kontakt_email, teamfarben, beschreibung, tabellenlink
|
||
) VALUES (
|
||
$1, $2, $3, $4, $5,
|
||
$6, $7, $8, $9,
|
||
$10, $11, $12, $13
|
||
) RETURNING *`,
|
||
[
|
||
name,
|
||
liga,
|
||
sucht_spieler,
|
||
social_media,
|
||
karussell_bilder,
|
||
trainer_name,
|
||
trainingszeiten,
|
||
trainingsort,
|
||
kontakt_name,
|
||
kontakt_email,
|
||
teamfarben,
|
||
beschreibung,
|
||
tabellenlink
|
||
]
|
||
);
|
||
|
||
res.status(201).json(result.rows[0]);
|
||
} catch (err) {
|
||
console.error("Fehler beim Anlegen des Teams:", err);
|
||
res.status(500).send("Fehler beim Anlegen des Teams");
|
||
}
|
||
});
|
||
|
||
|
||
|
||
//Team loeschen
|
||
app.delete("/api/teams/:id", async (req, res) => {
|
||
const { id } = req.params;
|
||
|
||
try {
|
||
const result = await pool.query("DELETE FROM teams WHERE id = $1", [id]);
|
||
|
||
if (result.rowCount === 0) {
|
||
return res.status(404).send("Team nicht gefunden");
|
||
}
|
||
|
||
res.send("Team gelöscht");
|
||
} catch (err) {
|
||
console.error("Fehler beim Löschen:", err);
|
||
res.status(500).send("Fehler beim Löschen");
|
||
}
|
||
});
|
||
|
||
|
||
//Spieler anlegen
|
||
app.post("/api/players", async (req, res) => {
|
||
const { name, nickname, birthdate, position, jersey_number, favorite_food, image_url, status, team_ids } = req.body;
|
||
|
||
if (!name || !position) {
|
||
return res.status(400).send("Name und Position sind Pflichtfelder");
|
||
}
|
||
|
||
const client = await pool.connect();
|
||
try {
|
||
await client.query("BEGIN");
|
||
|
||
const result = await client.query(
|
||
`INSERT INTO players (name, nickname, birthdate, position, jersey_number, favorite_food, image_url, status)
|
||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id`,
|
||
[name, nickname, birthdate, position, jersey_number, favorite_food, image_url, status || "aktiv"]
|
||
);
|
||
|
||
const playerId = result.rows[0].id;
|
||
|
||
if (team_ids && team_ids.length > 0) {
|
||
const teamInsert = team_ids.map((teamId) => `(${playerId}, ${teamId})`).join(",");
|
||
await client.query(`INSERT INTO player_teams (player_id, team_id) VALUES ${teamInsert}`);
|
||
}
|
||
|
||
await client.query("COMMIT");
|
||
res.status(201).json({ id: playerId });
|
||
} catch (err) {
|
||
await client.query("ROLLBACK");
|
||
console.error("Fehler beim Anlegen des Spielers:", err);
|
||
res.status(500).send("Fehler beim Anlegen des Spielers");
|
||
} finally {
|
||
client.release();
|
||
}
|
||
});
|
||
|
||
|
||
// Einzelnes Team inkl. Metadaten + Spieler laden
|
||
app.get("/api/teams/:id", async (req, res) => {
|
||
const { id } = req.params;
|
||
|
||
try {
|
||
// Team-Daten holen
|
||
const teamResult = await pool.query(
|
||
`SELECT
|
||
id,
|
||
name,
|
||
liga,
|
||
sucht_spieler,
|
||
social_media,
|
||
trainer_name,
|
||
karussell_bilder,
|
||
trainingszeiten,
|
||
trainingsort,
|
||
kontakt_name,
|
||
kontakt_email,
|
||
teamfarben,
|
||
beschreibung,
|
||
tabellenlink
|
||
FROM teams
|
||
WHERE id = $1`,
|
||
[id]
|
||
);
|
||
|
||
if (teamResult.rowCount === 0) {
|
||
return res.status(404).send("Team nicht gefunden");
|
||
}
|
||
|
||
// Spieler für dieses Team holen
|
||
const playerResult = await pool.query(`
|
||
SELECT
|
||
p.id,
|
||
p.name,
|
||
p.nickname,
|
||
p.position,
|
||
p.jersey_number,
|
||
p.image_url
|
||
FROM players p
|
||
INNER JOIN player_teams pt ON p.id = pt.player_id
|
||
WHERE pt.team_id = $1
|
||
ORDER BY p.name ASC
|
||
`, [id]);
|
||
|
||
res.json({
|
||
...teamResult.rows[0],
|
||
players: playerResult.rows,
|
||
});
|
||
} catch (err) {
|
||
console.error("Fehler beim Laden des Teams:", err);
|
||
res.status(500).send("Fehler beim Laden des Teams");
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
//Alle Spieler abrufen
|
||
app.get("/api/players", async (req, res) => {
|
||
try {
|
||
const result = await pool.query("SELECT * FROM players ORDER BY name ASC");
|
||
res.json(result.rows);
|
||
} catch (err) {
|
||
console.error("Fehler beim Abrufen der Spieler:", err);
|
||
res.status(500).send("Fehler beim Abrufen der Spieler");
|
||
}
|
||
});
|
||
|
||
|
||
//Upload Player Image
|
||
app.post("/api/upload-player-image", uploadPlayerImage.single("image"), (req, res) => {
|
||
if (!req.file) {
|
||
return res.status(400).send("Kein Bild hochgeladen");
|
||
}
|
||
const imageUrl = `/uploads/players/${req.file.filename}`;
|
||
res.json({ imageUrl });
|
||
});
|
||
|
||
//Carousell Bilder für Teams hochladen
|
||
|
||
const carouselStorage = multer.diskStorage({
|
||
destination: function (req, file, cb) {
|
||
const dir = "./uploads/carousel";
|
||
fs.mkdirSync(dir, { recursive: true });
|
||
cb(null, dir);
|
||
},
|
||
filename: function (req, file, cb) {
|
||
const uniqueName = Date.now() + "-" + file.originalname;
|
||
cb(null, uniqueName);
|
||
},
|
||
});
|
||
|
||
const uploadCarouselImage = multer({ storage: carouselStorage });
|
||
|
||
app.post("/api/teams/:id/carousel-upload", uploadCarouselImage.single("image"), (req, res) => {
|
||
if (!req.file) return res.status(400).json({ error: "Keine Datei hochgeladen" });
|
||
|
||
const filePath = `/uploads/carousel/${req.file.filename}`;
|
||
res.json({ path: filePath });
|
||
});
|
||
|
||
|
||
|
||
//Spieler bearbeiten
|
||
// Spieler aktualisieren
|
||
app.put("/api/players/:id", async (req, res) => {
|
||
const { id } = req.params;
|
||
const {
|
||
name,
|
||
nickname,
|
||
birthdate,
|
||
position,
|
||
jersey_number,
|
||
favorite_food,
|
||
status,
|
||
image_url,
|
||
} = req.body;
|
||
|
||
if (!name || !position) {
|
||
return res.status(400).send("Name und Position sind Pflichtfelder");
|
||
}
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
`UPDATE players
|
||
SET
|
||
name = $1,
|
||
nickname = $2,
|
||
birthdate = $3,
|
||
position = $4,
|
||
jersey_number = $5,
|
||
favorite_food = $6,
|
||
status = $7,
|
||
image_url = $8
|
||
WHERE id = $9
|
||
RETURNING *`,
|
||
[
|
||
name,
|
||
nickname || null,
|
||
birthdate || null,
|
||
position,
|
||
jersey_number ? Number(jersey_number) : null,
|
||
favorite_food || null,
|
||
status || "aktiv",
|
||
image_url || null,
|
||
id,
|
||
]
|
||
);
|
||
|
||
if (result.rowCount === 0) {
|
||
return res.status(404).send("Spieler nicht gefunden");
|
||
}
|
||
|
||
res.json(result.rows[0]);
|
||
} catch (err) {
|
||
console.error("Fehler beim Aktualisieren des Spielers:", err);
|
||
res.status(500).send("Fehler beim Aktualisieren des Spielers");
|
||
}
|
||
});
|
||
|
||
|
||
//Einzelnen Spieler abrufen
|
||
app.get("/api/players/:id", async (req, res) => {
|
||
const { id } = req.params;
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
"SELECT * FROM players WHERE id = $1",
|
||
[id]
|
||
);
|
||
|
||
if (result.rowCount === 0) {
|
||
return res.status(404).send("Spieler nicht gefunden");
|
||
}
|
||
|
||
const player = result.rows[0];
|
||
|
||
// 🔥 Team-IDs abfragen
|
||
const teamResult = await pool.query(
|
||
"SELECT team_id FROM player_teams WHERE player_id = $1",
|
||
[id]
|
||
);
|
||
|
||
const team_ids = teamResult.rows.map(r => r.team_id);
|
||
|
||
res.json({ ...player, team_ids });
|
||
} catch (err) {
|
||
console.error("Fehler beim Abrufen des Spielers:", err);
|
||
res.status(500).send("Fehler beim Abrufen des Spielers");
|
||
}
|
||
});
|
||
|
||
|
||
|
||
// Spieler aus einem Team entfernen
|
||
app.delete("/api/teams/:teamId/players/:playerId", async (req, res) => {
|
||
const { teamId, playerId } = req.params;
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
"DELETE FROM player_teams WHERE team_id = $1 AND player_id = $2",
|
||
[teamId, playerId]
|
||
);
|
||
|
||
if (result.rowCount === 0) {
|
||
return res.status(404).send("Spieler nicht im Team gefunden");
|
||
}
|
||
|
||
res.send("Spieler erfolgreich aus dem Team entfernt");
|
||
} catch (err) {
|
||
console.error("Fehler beim Entfernen des Spielers:", err);
|
||
res.status(500).send("Fehler beim Entfernen des Spielers");
|
||
}
|
||
});
|
||
|
||
|
||
// Existierenden Spieler einem Team hinzufügen
|
||
app.post("/api/teams/:teamId/players", async (req, res) => {
|
||
const { teamId } = req.params;
|
||
const { playerId } = req.body;
|
||
|
||
if (!playerId) {
|
||
return res.status(400).send("playerId ist erforderlich");
|
||
}
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
"INSERT INTO player_teams (player_id, team_id) VALUES ($1, $2)",
|
||
[playerId, teamId]
|
||
);
|
||
res.status(201).send("Spieler erfolgreich dem Team zugeordnet");
|
||
} catch (err) {
|
||
if (err.code === "23505") {
|
||
return res.status(400).send("Spieler ist bereits im Team");
|
||
}
|
||
console.error("Fehler beim Hinzufügen des Spielers zum Team:", err);
|
||
res.status(500).send("Fehler beim Hinzufügen des Spielers");
|
||
}
|
||
});
|
||
|
||
|
||
// Alle Teams abrufen
|
||
app.get("/api/all-teams", async (req, res) => {
|
||
try {
|
||
const result = await pool.query("SELECT id, name FROM teams ORDER BY name ASC");
|
||
res.json(result.rows);
|
||
} catch (err) {
|
||
console.error("Fehler beim Laden der Teams:", err);
|
||
res.status(500).send("Fehler beim Laden der Teams");
|
||
}
|
||
});
|
||
|
||
//Spieler einem Team zuweisen
|
||
app.post("/api/players/:id/assign-team", async (req, res) => {
|
||
const { id } = req.params;
|
||
const { team_id } = req.body;
|
||
|
||
if (!team_id) return res.status(400).send("team_id erforderlich");
|
||
|
||
try {
|
||
await pool.query("DELETE FROM player_teams WHERE player_id = $1", [id]);
|
||
await pool.query("INSERT INTO player_teams (player_id, team_id) VALUES ($1, $2)", [id, team_id]);
|
||
|
||
res.send("Teamzugehörigkeit aktualisiert");
|
||
} catch (err) {
|
||
console.error("Fehler beim Aktualisieren der Teamzugehörigkeit:", err);
|
||
res.status(500).send("Fehler beim Aktualisieren");
|
||
}
|
||
});
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
// Server starten
|
||
app.listen(port, () => {
|
||
const nets = os.networkInterfaces();
|
||
const addresses = [];
|
||
|
||
for (const name of Object.keys(nets)) {
|
||
for (const net of nets[name]) {
|
||
if (net.family === 'IPv4' && !net.internal) {
|
||
addresses.push(net.address);
|
||
}
|
||
}
|
||
}
|
||
|
||
console.log("Backend erreichbar unter:");
|
||
addresses.forEach(ip => {
|
||
console.log(`http://${ip}:${port}`);
|
||
});
|
||
});
|