v1.4.0 - Ausflüge hinzugefügt

This commit is contained in:
Borgal
2026-02-02 12:51:45 +01:00
parent 0e5530b139
commit 72f55b0aed

402
trip.php Executable file
View File

@@ -0,0 +1,402 @@
<?php
include('inc/check_login.php');
require_once('inc/db.php');
define('APP_URL', 'https://domili.borgal.de');
$is_admin = ($_SESSION['role'] === 'admin');
$message = '';
$message_type = '';
if (isset($_SESSION['message'])) {
$message = $_SESSION['message'];
$message_type = $_SESSION['message_type'];
unset($_SESSION['message'], $_SESSION['message_type']);
}
function get_all_users($conn)
{
$stmt = mysqli_prepare($conn, "SELECT id, username FROM users ORDER BY username");
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$users = [];
while ($row = mysqli_fetch_assoc($result)) {
$users[] = $row;
}
mysqli_stmt_close($stmt);
return $users;
}
function get_trip_groups($conn, $trip_id)
{
$stmt = mysqli_prepare($conn, "
SELECT tg.driver_id, d.username AS driver_name,
tg.passenger_id, p.username AS passenger_name,
tg.notes
FROM trip_groups tg
JOIN users d ON tg.driver_id = d.id
JOIN users p ON tg.passenger_id = p.id
WHERE tg.trip_id = ?
ORDER BY d.username, p.username
");
mysqli_stmt_bind_param($stmt, "i", $trip_id);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$groups = [];
while ($row = mysqli_fetch_assoc($result)) {
$groups[] = $row;
}
mysqli_stmt_close($stmt);
return $groups;
}
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['action']) && $_POST['action'] === 'save_trip') {
$trip_id = !empty($_POST['trip_id']) ? (int)$_POST['trip_id'] : null;
$title = trim($_POST['title'] ?? '');
$description = trim($_POST['description'] ?? '');
$hotel = trim($_POST['hotel'] ?? '');
$hotel_address = trim($_POST['hotel_address'] ?? '');
$start_date = trim($_POST['start_date'] ?? '');
$end_date = trim($_POST['end_date'] ?? '');
if (empty($title) || empty($start_date) || empty($end_date)) {
$_SESSION['message'] = "Titel, Start- und Enddatum sind erforderlich.";
$_SESSION['message_type'] = 'danger';
$message = $_SESSION['message'];
$message_type = $_SESSION['message_type'];
} elseif (strtotime($start_date) > strtotime($end_date)) {
$_SESSION['message'] = "Startdatum darf nicht nach dem Enddatum liegen.";
$_SESSION['message_type'] = 'danger';
$message = $_SESSION['message'];
$message_type = $_SESSION['message_type'];
} else {
mysqli_autocommit($conn, false);
$success = false;
if ($trip_id) {
$stmt = mysqli_prepare($conn, "UPDATE trips SET title = ?, description = ?, hotel = ?, hotel_address = ?, start_date = ?, end_date = ? WHERE id = ?");
mysqli_stmt_bind_param($stmt, "ssssssi", $title, $description, $hotel, $hotel_address, $start_date, $end_date, $trip_id);
} else {
$stmt = mysqli_prepare($conn, "INSERT INTO trips (title, description, hotel, hotel_address, start_date, end_date) VALUES (?, ?, ?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, "ssssss", $title, $description, $hotel, $hotel_address, $start_date, $end_date);
}
if (mysqli_stmt_execute($stmt)) {
if (!$trip_id) {
$trip_id = mysqli_insert_id($conn);
}
mysqli_query($conn, "DELETE FROM trip_groups WHERE trip_id = $trip_id");
$drivers = $_POST['drivers'] ?? [];
foreach ($drivers as $driver_id => $passengers) {
$driver_id = (int)$driver_id;
if (!empty($passengers['list'])) {
foreach ($passengers['list'] as $passenger_id) {
$passenger_id = (int)$passenger_id;
if ($driver_id !== $passenger_id) {
$notes = trim($passengers['notes'][$passenger_id] ?? '');
$stmt_ins = mysqli_prepare($conn, "INSERT INTO trip_groups (trip_id, driver_id, passenger_id, notes) VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt_ins, "iiis", $trip_id, $driver_id, $passenger_id, $notes);
mysqli_stmt_execute($stmt_ins);
mysqli_stmt_close($stmt_ins);
}
}
}
}
$success = true;
}
mysqli_stmt_close($stmt);
if ($success) {
mysqli_commit($conn);
$_SESSION['message'] = $trip_id ? "Reise aktualisiert!" : "Neue Reise erstellt!";
$_SESSION['message_type'] = 'success';
header("Location: trip.php");
exit();
} else {
mysqli_rollback($conn);
$_SESSION['message'] = "Fehler beim Speichern der Reise.";
$_SESSION['message_type'] = 'danger';
$message = $_SESSION['message'];
$message_type = $_SESSION['message_type'];
}
mysqli_autocommit($conn, true);
}
}
if (isset($_GET['action']) && $_GET['action'] === 'delete' && isset($_GET['trip_id'])) {
$trip_id = (int)$_GET['trip_id'];
$stmt = mysqli_prepare($conn, "DELETE FROM trips WHERE id = ?");
mysqli_stmt_bind_param($stmt, "i", $trip_id);
if (mysqli_stmt_execute($stmt)) {
$_SESSION['message'] = "Reise gelöscht!";
$_SESSION['message_type'] = 'success';
} else {
$_SESSION['message'] = "Fehler beim Löschen.";
$_SESSION['message_type'] = 'danger';
}
mysqli_stmt_close($stmt);
header("Location: trip.php");
exit();
}
$trips = [];
$result = mysqli_query($conn, "SELECT * FROM trips ORDER BY start_date DESC");
while ($row = mysqli_fetch_assoc($result)) {
$row['groups'] = get_trip_groups($conn, $row['id']);
$trips[] = $row;
}
$edit_trip = null;
if (isset($_GET['action']) && $_GET['action'] === 'edit' && isset($_GET['trip_id'])) {
$trip_id = (int)$_GET['trip_id'];
$stmt = mysqli_prepare($conn, "SELECT * FROM trips WHERE id = ?");
mysqli_stmt_bind_param($stmt, "i", $trip_id);
mysqli_stmt_execute($stmt);
$edit_trip = mysqli_fetch_assoc(mysqli_stmt_get_result($stmt));
mysqli_stmt_close($stmt);
if ($edit_trip) {
$edit_trip['groups'] = get_trip_groups($conn, $trip_id);
$grouped = [];
foreach ($edit_trip['groups'] as $g) {
$grouped[$g['driver_id']][$g['passenger_id']] = $g['notes'];
}
$edit_trip['grouped'] = $grouped;
}
}
$all_users = get_all_users($conn);
require_once('inc/header.php');
?>
<div class="container mt-5 mb-4">
<?php if ($message): ?>
<div class="alert alert-<?= htmlspecialchars($message_type) ?> alert-dismissible fade show" role="alert">
<?= htmlspecialchars($message) ?>
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
<?php endif; ?>
<h2 class="mb-4">🧳 Gemeinsame Reisen</h2>
<?php if ($is_admin): ?>
<div class="card shadow mb-4">
<div class="card-header bg-primary-subtle text-secondary d-flex justify-content-between align-items-center">
<h4 class="mb-0"><?= $edit_trip ? 'Reise bearbeiten' : 'Neue Reise anlegen' ?></h4>
<?php if (!$edit_trip): ?>
<a class="btn btn-sm d-flex align-items-center justify-content-center"
data-bs-toggle="collapse" href="#tripFormCollapse" role="button" aria-expanded="false" aria-controls="tripFormCollapse">
Add
<span class="material-symbols-outlined ms-1">add</span>
</a>
<?php endif; ?>
</div>
<div class="collapse <?= $edit_trip ? 'show' : '' ?>" id="tripFormCollapse">
<div class="card card-body bg-light">
<form method="POST">
<input type="hidden" name="action" value="save_trip">
<?php if ($edit_trip): ?>
<input type="hidden" name="trip_id" value="<?= $edit_trip['id'] ?>">
<?php endif; ?>
<div class="mb-3">
<label class="form-label">Reisetitel *</label>
<input type="text" class="form-control" name="title" value="<?= htmlspecialchars($edit_trip['title'] ?? '') ?>" required>
</div>
<div class="mb-3">
<label class="form-label">Hotel</label>
<input type="text" class="form-control" name="hotel" value="<?= htmlspecialchars($edit_trip['hotel'] ?? '') ?>">
</div>
<div class="mb-3">
<label class="form-label">Hoteladresse</label>
<textarea class="form-control" name="hotel_address" rows="2" placeholder="Straße, PLZ Ort, Land"><?= htmlspecialchars($edit_trip['hotel_address'] ?? '') ?></textarea>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label class="form-label">Von *</label>
<input type="date" class="form-control" name="start_date" value="<?= htmlspecialchars($edit_trip['start_date'] ?? date('Y-m-d')) ?>" required>
</div>
<div class="col-md-6">
<label class="form-label">Bis *</label>
<input type="date" class="form-control" name="end_date" value="<?= htmlspecialchars($edit_trip['end_date'] ?? '') ?>" required>
</div>
</div>
<div class="mb-3">
<label class="form-label">Beschreibung</label>
<textarea class="form-control" name="description" rows="2"><?= htmlspecialchars($edit_trip['description'] ?? '') ?></textarea>
</div>
<h5 class="mt-4 mb-3">🚗 Fahrer und Mitfahrer</h5>
<?php foreach ($all_users as $driver): ?>
<div class="card mb-3">
<div class="card-header">
<div class="form-check">
<input class="form-check-input driver-checkbox" type="checkbox" id="driver_<?= $driver['id'] ?>"
onchange="togglePassengerSection(<?= $driver['id'] ?>)"
<?= (isset($edit_trip['grouped'][$driver['id']]) || (!empty($_POST) && isset($_POST['drivers'][$driver['id']]))) ? 'checked' : '' ?>>
<label class="form-check-label" for="driver_<?= $driver['id'] ?>">
<strong><?= htmlspecialchars($driver['username']) ?></strong> (Fahrer)
</label>
</div>
</div>
<div class="card-body <?= (!isset($edit_trip['grouped'][$driver['id']]) && empty($_POST)) ? 'd-none' : '' ?>" id="passengers_<?= $driver['id'] ?>">
<div class="row">
<?php foreach ($all_users as $passenger): ?>
<?php if ($passenger['id'] == $driver['id']) continue; ?>
<div class="col-md-6 mb-2">
<div class="input-group">
<div class="form-check me-2 mt-1">
<input class="form-check-input passenger-checkbox" type="checkbox"
name="drivers[<?= $driver['id'] ?>][list][]"
value="<?= $passenger['id'] ?>"
id="p_<?= $driver['id'] ?>_<?= $passenger['id'] ?>"
<?= (isset($edit_trip['grouped'][$driver['id']][$passenger['id']]) || (!empty($_POST) && in_array($passenger['id'], $_POST['drivers'][$driver['id']]['list'] ?? []))) ? 'checked' : '' ?>>
<label class="form-check-label" for="p_<?= $driver['id'] ?>_<?= $passenger['id'] ?>">
<?= htmlspecialchars($passenger['username']) ?>
</label>
</div>
<input type="text" class="form-control form-control-sm"
placeholder="Notizen"
name="drivers[<?= $driver['id'] ?>][notes][<?= $passenger['id'] ?>]"
value="<?= htmlspecialchars($edit_trip['grouped'][$driver['id']][$passenger['id']] ?? '') ?>">
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<?php endforeach; ?>
<div class="mt-3">
<button type="submit" class="btn btn-sm btn-primary"><?= $edit_trip ? 'Speichern' : 'Erstellen' ?></button>
<?php if ($edit_trip): ?>
<a href="trip.php" class="btn btn-sm btn-outline-secondary">Abbrechen</a>
<?php endif; ?>
</div>
</form>
</div>
</div>
</div>
<script>
function togglePassengerSection(driverId) {
const section = document.getElementById('passengers_' + driverId);
const checkbox = document.getElementById('driver_' + driverId);
if (checkbox.checked) {
section.classList.remove('d-none');
} else {
section.classList.add('d-none');
}
}
</script>
<?php endif; ?>
<!-- 🔸 Bestehende Reisen -->
<?php if (!empty($trips)): ?>
<?php foreach ($trips as $trip): ?>
<div class="card shadow mb-4">
<div class="card-header bg-light d-flex justify-content-between align-items-center">
<div>
<h5 class="mb-0"><?= htmlspecialchars($trip['title']) ?></h5>
<small class="text-muted">
<?= date('d.m.Y', strtotime($trip['start_date'])) ?> <?= date('d.m.Y', strtotime($trip['end_date'])) ?>
</small>
</div>
<?php if ($is_admin): ?>
<div class="dropdown">
<a href="#" class="text-secondary" data-bs-toggle="dropdown">
<span class="material-icons">more_vert</span>
</a>
<ul class="dropdown-menu dropdown-menu-end">
<li><a class="dropdown-item" href="trip.php?action=edit&trip_id=<?= $trip['id'] ?>"><span class="material-icons me-2">edit</span> Bearbeiten</a></li>
<li><a class="dropdown-item text-danger" href="trip.php?action=delete&trip_id=<?= $trip['id'] ?>" onclick="return confirm('Wirklich löschen?')"><span class="material-icons me-2">delete</span> Löschen</a></li>
</ul>
</div>
<?php endif; ?>
</div>
<div class="card-body">
<?php
$has_hotel = !empty($trip['hotel']) || !empty($trip['hotel_address']);
$has_info = !empty($trip['description']);
$has_driver = !empty($trip['groups']);
?>
<!-- 🏨 Hotel -->
<?php if ($has_hotel): ?>
<h6 class="mt-0 mb-2"><strong>🏨 Hotel</strong></h6>
<?php if (!empty($trip['hotel'])): ?>
<p class="mb-1"><strong><?= htmlspecialchars($trip['hotel']) ?></strong></p>
<?php endif; ?>
<?php if (!empty($trip['hotel_address'])): ?>
<p class="mb-2"><?= nl2br(htmlspecialchars($trip['hotel_address'])) ?></p>
<?php
$clean_address = preg_replace('/\s+/', ' ', trim(str_replace(["\r", "\n"], ' ', $trip['hotel_address'])));
$maps_url = 'https://www.google.com/maps/search/?api=1&query=' . urlencode($clean_address);
?>
<a href="<?= htmlspecialchars($maps_url) ?>" target="_blank" class="btn btn-sm btn-outline-primary mt-1">
<span class="material-icons me-1" style="font-size: 16px;">location_on</span>
Auf Karte anzeigen
</a>
<?php endif; ?>
<!-- Trennlinie, wenn danach Info oder Fahrer kommen -->
<?php if ($has_info || $has_driver): ?>
<hr class="my-3">
<?php endif; ?>
<?php endif; ?>
<!-- Info -->
<?php if ($has_info): ?>
<h6 class="mb-2"><strong> Info</strong></h6>
<p><?= nl2br(htmlspecialchars($trip['description'])) ?></p>
<!-- Trennlinie, wenn danach Fahrer kommen -->
<?php if ($has_driver): ?>
<hr class="my-3">
<?php endif; ?>
<?php endif; ?>
<!-- 🚗 Fahrer -->
<?php if ($has_driver): ?>
<h6 class="mb-2"><strong>🚗 Fahrer</strong></h6>
<?php
$by_driver = [];
foreach ($trip['groups'] as $g) {
$by_driver[$g['driver_id']][] = $g;
}
?>
<?php foreach ($by_driver as $driver_id => $passengers): ?>
<p class="mb-1"><strong><?= htmlspecialchars($passengers[0]['driver_name']) ?></strong></p>
<ul class="list-unstyled ms-3 mb-2">
<?php foreach ($passengers as $p): ?>
<li>
<?= htmlspecialchars($p['passenger_name']) ?>
<?php if (!empty($p['notes'])): ?>
<br><small class="text-muted"><?= htmlspecialchars($p['notes']) ?></small>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php endforeach; ?>
<?php else: ?>
<h6 class="mb-2 text-success"><strong>🚗 Fahrer</strong></h6>
<p class="text-muted">Keine Fahrer/Mitfahrer eingetragen.</p>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
<?php else: ?>
<div class="card shadow">
<div class="card-body text-center text-muted py-4">
<p>Keine Reisen geplant.</p>
</div>
</div>
<?php endif; ?>
</div>
<?php include('inc/footer.php'); ?>