Files
domili/trip.php
2026-02-02 12:51:45 +01:00

402 lines
20 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?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'); ?>