v1.4.0 - Ausflüge hinzugefügt
This commit is contained in:
402
trip.php
Executable file
402
trip.php
Executable 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'); ?>
|
||||
Reference in New Issue
Block a user