Separieren vom css und js und fixes

This commit is contained in:
2025-09-04 14:14:59 +02:00
parent 0cfac629b5
commit f6cd5c734f
12 changed files with 3130 additions and 2462 deletions

View File

@@ -1455,9 +1455,50 @@ router.get('/admin-runs', requireAdminAuth, async (req, res) => {
});
} catch (error) {
console.error('Error loading runs:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Laden der Läufe'
res.status(500).json({
success: false,
message: 'Fehler beim Laden der Läufe'
});
}
});
// GET einzelner Lauf
router.get('/admin-runs/:id', requireAdminAuth, async (req, res) => {
try {
const { id } = req.params;
const result = await pool.query(`
SELECT
t.id,
t.player_id,
t.location_id,
t.recorded_time,
EXTRACT(EPOCH FROM t.recorded_time) as time_seconds,
t.created_at,
COALESCE(CONCAT(p.firstname, ' ', p.lastname), p.firstname, p.lastname) as player_name,
l.name as location_name
FROM times t
LEFT JOIN players p ON t.player_id = p.id
LEFT JOIN locations l ON t.location_id = l.id
WHERE t.id = $1
`, [id]);
if (result.rows.length === 0) {
return res.status(404).json({
success: false,
message: 'Lauf nicht gefunden'
});
}
res.json({
success: true,
data: result.rows[0]
});
} catch (error) {
console.error('Error loading run:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Laden des Laufs'
});
}
});
@@ -1581,4 +1622,296 @@ router.delete('/admin-adminusers/:id', requireAdminAuth, async (req, res) => {
}
});
// ============================================================================
// POST/PUT ROUTES FÜR CRUD-OPERATIONEN
// ============================================================================
// Admin Spieler - POST (Hinzufügen)
router.post('/admin-players', requireAdminAuth, async (req, res) => {
try {
const { full_name, rfiduid, supabase_user_id } = req.body;
// Name in firstname und lastname aufteilen
const nameParts = full_name ? full_name.trim().split(' ') : [];
const firstname = nameParts[0] || '';
const lastname = nameParts.slice(1).join(' ') || '';
const result = await pool.query(
`INSERT INTO players (firstname, lastname, rfiduid, supabase_user_id, created_at)
VALUES ($1, $2, $3, $4, NOW())
RETURNING *`,
[firstname, lastname, rfiduid || null, supabase_user_id || null]
);
res.json({
success: true,
message: 'Spieler erfolgreich hinzugefügt',
data: result.rows[0]
});
} catch (error) {
console.error('Error creating player:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Hinzufügen des Spielers'
});
}
});
// Admin Spieler - PUT (Bearbeiten)
router.put('/admin-players/:id', requireAdminAuth, async (req, res) => {
try {
const playerId = req.params.id;
const { full_name, rfiduid, supabase_user_id } = req.body;
// Name in firstname und lastname aufteilen
const nameParts = full_name ? full_name.trim().split(' ') : [];
const firstname = nameParts[0] || '';
const lastname = nameParts.slice(1).join(' ') || '';
const result = await pool.query(
`UPDATE players
SET firstname = $1, lastname = $2, rfiduid = $3, supabase_user_id = $4
WHERE id = $5
RETURNING *`,
[firstname, lastname, rfiduid || null, supabase_user_id || null, playerId]
);
if (result.rowCount > 0) {
res.json({
success: true,
message: 'Spieler erfolgreich aktualisiert',
data: result.rows[0]
});
} else {
res.status(404).json({ success: false, message: 'Spieler nicht gefunden' });
}
} catch (error) {
console.error('Error updating player:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Aktualisieren des Spielers'
});
}
});
// Admin Standorte - POST (Hinzufügen)
router.post('/admin-locations', requireAdminAuth, async (req, res) => {
try {
const { name, latitude, longitude, time_threshold } = req.body;
const result = await pool.query(
`INSERT INTO locations (name, latitude, longitude, time_threshold, created_at)
VALUES ($1, $2, $3, $4, NOW())
RETURNING *`,
[name, latitude, longitude, time_threshold || null]
);
res.json({
success: true,
message: 'Standort erfolgreich hinzugefügt',
data: result.rows[0]
});
} catch (error) {
console.error('Error creating location:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Hinzufügen des Standorts'
});
}
});
// Admin Standorte - PUT (Bearbeiten)
router.put('/admin-locations/:id', requireAdminAuth, async (req, res) => {
try {
const locationId = req.params.id;
const { name, latitude, longitude, time_threshold } = req.body;
const result = await pool.query(
`UPDATE locations
SET name = $1, latitude = $2, longitude = $3, time_threshold = $4
WHERE id = $5
RETURNING *`,
[name, latitude, longitude, time_threshold || null, locationId]
);
if (result.rowCount > 0) {
res.json({
success: true,
message: 'Standort erfolgreich aktualisiert',
data: result.rows[0]
});
} else {
res.status(404).json({ success: false, message: 'Standort nicht gefunden' });
}
} catch (error) {
console.error('Error updating location:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Aktualisieren des Standorts'
});
}
});
// Admin Läufe - POST (Hinzufügen)
router.post('/admin-runs', requireAdminAuth, async (req, res) => {
try {
const { player_id, location_id, time_seconds } = req.body;
// Zeit in INTERVAL konvertieren
const timeInterval = `${time_seconds} seconds`;
const result = await pool.query(
`INSERT INTO times (player_id, location_id, recorded_time, created_at)
VALUES ($1, $2, $3, NOW())
RETURNING *`,
[player_id, location_id, timeInterval]
);
res.json({
success: true,
message: 'Lauf erfolgreich hinzugefügt',
data: result.rows[0]
});
} catch (error) {
console.error('Error creating run:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Hinzufügen des Laufs'
});
}
});
// Admin Läufe - PUT (Bearbeiten)
router.put('/admin-runs/:id', requireAdminAuth, async (req, res) => {
try {
const runId = req.params.id;
const { player_id, location_id, time_seconds } = req.body;
// Zeit in INTERVAL konvertieren
const timeInterval = `${time_seconds} seconds`;
const result = await pool.query(
`UPDATE times
SET player_id = $1, location_id = $2, recorded_time = $3
WHERE id = $4
RETURNING *`,
[player_id, location_id, timeInterval, runId]
);
if (result.rowCount > 0) {
res.json({
success: true,
message: 'Lauf erfolgreich aktualisiert',
data: result.rows[0]
});
} else {
res.status(404).json({ success: false, message: 'Lauf nicht gefunden' });
}
} catch (error) {
console.error('Error updating run:', error);
res.status(500).json({
success: false,
message: 'Fehler beim Aktualisieren des Laufs'
});
}
});
// Admin-Benutzer - POST (Hinzufügen)
router.post('/admin-adminusers', requireAdminAuth, async (req, res) => {
try {
const { username, password, access_level } = req.body;
// Passwort hashen
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);
const result = await pool.query(
`INSERT INTO adminusers (username, password_hash, access_level, is_active, created_at)
VALUES ($1, $2, $3, true, NOW())
RETURNING id, username, access_level, is_active, created_at`,
[username, hashedPassword, access_level]
);
res.json({
success: true,
message: 'Admin-Benutzer erfolgreich hinzugefügt',
data: result.rows[0]
});
} catch (error) {
console.error('Error creating admin user:', error);
if (error.code === '23505') { // Unique constraint violation
res.status(400).json({
success: false,
message: 'Benutzername bereits vergeben'
});
} else {
res.status(500).json({
success: false,
message: 'Fehler beim Hinzufügen des Admin-Benutzers'
});
}
}
});
// Admin-Benutzer - PUT (Bearbeiten)
router.put('/admin-adminusers/:id', requireAdminAuth, async (req, res) => {
try {
const userId = req.params.id;
const { username, password, access_level } = req.body;
// Verhindern, dass sich selbst bearbeitet
if (parseInt(userId) === req.session.userId) {
return res.status(400).json({
success: false,
message: 'Sie können sich nicht selbst bearbeiten'
});
}
let query, params;
if (password) {
// Passwort hashen
const saltRounds = 10;
const hashedPassword = await bcrypt.hash(password, saltRounds);
query = `UPDATE adminusers
SET username = $1, password_hash = $2, access_level = $3
WHERE id = $4
RETURNING id, username, access_level, is_active, created_at`;
params = [username, hashedPassword, access_level, userId];
} else {
query = `UPDATE adminusers
SET username = $1, access_level = $2
WHERE id = $3
RETURNING id, username, access_level, is_active, created_at`;
params = [username, access_level, userId];
}
const result = await pool.query(query, params);
if (result.rowCount > 0) {
res.json({
success: true,
message: 'Admin-Benutzer erfolgreich aktualisiert',
data: result.rows[0]
});
} else {
res.status(404).json({ success: false, message: 'Admin-Benutzer nicht gefunden' });
}
} catch (error) {
console.error('Error updating admin user:', error);
if (error.code === '23505') { // Unique constraint violation
res.status(400).json({
success: false,
message: 'Benutzername bereits vergeben'
});
} else {
res.status(500).json({
success: false,
message: 'Fehler beim Aktualisieren des Admin-Benutzers'
});
}
}
});
module.exports = { router, requireApiKey };