288 lines
9.9 KiB
PHP
288 lines
9.9 KiB
PHP
<?php
|
||
ini_set('display_errors', 1);
|
||
error_reporting(E_ALL);
|
||
date_default_timezone_set("Europe/Berlin");
|
||
// Header / Navbar / Zugriffsschutz falls nötig
|
||
require_once "config/config.php";
|
||
require_once "Data.class.php";
|
||
$Data = new Data($pdo);
|
||
|
||
require_once "config/session.php";
|
||
|
||
if (!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true) {
|
||
header("location: index.php");
|
||
exit;
|
||
}
|
||
|
||
if (isset($_POST['submit'])) {
|
||
|
||
// Required fields
|
||
if (
|
||
!empty($_POST['inputStartzeit_ts']) &&
|
||
!empty($_POST['inputLocation']) &&
|
||
!empty($_POST['inputArt']) // <-- NEU
|
||
) {
|
||
|
||
// Endzeit optional → 0 wenn leer
|
||
$endzeit = !empty($_POST['inputEndzeit_ts']) ? $_POST['inputEndzeit_ts'] : 0;
|
||
|
||
// Gage muss angegeben werden – kann aber 0 sein
|
||
$gage = $_POST['inputGage'];
|
||
if ($gage === '' || $gage === null) {
|
||
$gage = 0;
|
||
}
|
||
$gage = (int)$gage;
|
||
|
||
// Veranstaltungsart absichern
|
||
$art = $_POST['inputArt'] ?? '';
|
||
$validArts = ['Party', 'Club', 'Hochzeit'];
|
||
if (!in_array($art, $validArts, true)) {
|
||
$art = 'Party'; // Fallback (oder Fehler werfen)
|
||
}
|
||
|
||
$terminid = $Data->createTermin(
|
||
$_POST['inputStartzeit_ts'],
|
||
$endzeit,
|
||
$_POST['inputLocation'],
|
||
$_SESSION['id'],
|
||
$gage,
|
||
$art // <-- NEU
|
||
);
|
||
|
||
// Changelog für "TERMIN ERSTELLT"
|
||
$Data->createChanges($terminid, $_SESSION["id"], "create", "", "");
|
||
|
||
// Weiterleitung
|
||
header("Location: termin_show.php?id=" . $terminid);
|
||
exit;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
include('navbar.php');
|
||
|
||
?>
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css">
|
||
<div class="container mt-4">
|
||
|
||
<h3 class="mb-4"><i class="bi bi-plus-circle"></i> Neuen Termin erstellen</h3>
|
||
|
||
<form method="POST" action="termin_create.php" id="createTerminForm">
|
||
|
||
<div class="row g-3">
|
||
|
||
<!-- Startzeit -->
|
||
<div class="col-md-6">
|
||
<label class="form-label fw-bold">Startzeit</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text"><i class="bi bi-clock-fill"></i></span>
|
||
<input
|
||
type="datetime-local"
|
||
class="form-control"
|
||
id="inputStartzeit"
|
||
name="inputStartzeit"
|
||
required
|
||
>
|
||
<input type="hidden" name="inputStartzeit_ts" id="inputStartzeit_ts">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Endzeit -->
|
||
<div class="col-md-6">
|
||
<label class="form-label fw-bold">Endzeit</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text"><i class="bi bi-clock-fill"></i></span>
|
||
<input
|
||
type="datetime-local"
|
||
class="form-control"
|
||
id="inputEndzeit"
|
||
name="inputEndzeit"
|
||
>
|
||
<input type="hidden" name="inputEndzeit_ts" id="inputEndzeit_ts">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Preis pro angefangene Stunde
|
||
<div class="col-md-6">
|
||
<label class="form-label fw-bold">Preis / angefangene Stunde</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text"><i class="bi bi-cash"></i></span>
|
||
<input
|
||
type="text"
|
||
class="form-control"
|
||
name="inputPreisProStunde"
|
||
placeholder="z. B. 50"
|
||
>
|
||
</div>
|
||
</div>-->
|
||
|
||
<!-- Location -->
|
||
<div class="col-md-6">
|
||
<label class="form-label fw-bold">Location</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text"><i class="bi bi-geo-alt"></i></span>
|
||
<input
|
||
type="text"
|
||
class="form-control"
|
||
name="inputLocation"
|
||
placeholder="Veranstaltungsort"
|
||
required
|
||
>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Veranstaltungsart -->
|
||
<div class="col-md-6">
|
||
<label class="form-label fw-bold">Veranstaltungsart</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text"><i class="bi bi-calendar-event"></i></span>
|
||
<select
|
||
class="form-select"
|
||
name="inputArt"
|
||
required
|
||
>
|
||
<option value="" selected disabled>Bitte auswählen</option>
|
||
<option value="Party">Party (eigene Technik, kompletter Aufbau)</option>
|
||
<option value="Club">Club (Technik vor Ort, nur DJ-Setup)</option>
|
||
<option value="Hochzeit">Hochzeit (hoher Orga-Aufwand, eigenes Equipment)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Gage -->
|
||
<div class="col-md-6">
|
||
<label class="form-label fw-bold">Gage</label>
|
||
<div class="input-group">
|
||
<span class="input-group-text"><i class="bi bi-cash-stack"></i></span>
|
||
<input
|
||
type="number"
|
||
class="form-control"
|
||
name="inputGage"
|
||
placeholder="z. B. 350"
|
||
min="0"
|
||
step="1"
|
||
required
|
||
>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div class="text-end mt-4">
|
||
<button type="submit" name="submit" class="btn btn-primary">
|
||
<i class="bi bi-check-circle"></i> Termin speichern
|
||
</button>
|
||
</div>
|
||
|
||
</form>
|
||
|
||
</div>
|
||
|
||
<!-- MODAL: Termin existiert -->
|
||
<div class="modal fade" id="terminConflictModal" tabindex="-1">
|
||
<div class="modal-dialog modal-dialog-centered">
|
||
<div class="modal-content">
|
||
|
||
<div class="modal-header bg-danger text-white">
|
||
<h5 class="modal-title">Achtung – Terminüberschneidung!</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
|
||
<div class="modal-body">
|
||
<p>Für dieses Datum existiert bereits mindestens ein Termin:</p>
|
||
<div id="terminConflictList" class="border rounded p-2 bg-light"></div>
|
||
</div>
|
||
|
||
<div class="modal-footer">
|
||
<button class="btn btn-secondary" data-bs-dismiss="modal">Okay</button>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||
|
||
|
||
<script>
|
||
|
||
document.addEventListener("DOMContentLoaded", () => {
|
||
|
||
const startInput = document.getElementById("inputStartzeit");
|
||
const endInput = document.getElementById("inputEndzeit");
|
||
|
||
let conflictShownForDate = null; // speichert das Datum, für das das Modal schon gezeigt wurde
|
||
|
||
startInput.addEventListener("change", async () => {
|
||
|
||
if (!startInput.value) return;
|
||
|
||
const selectedDate = startInput.value; // YYYY-MM-DDTHH:MM
|
||
|
||
// ---------- 1) TERMIN-KONFLIKT MODAL NUR EINMAL PRO DATUM ----------
|
||
|
||
const dateOnly = selectedDate.split("T")[0]; // 2025-12-08
|
||
|
||
if (conflictShownForDate !== dateOnly) {
|
||
|
||
const ts = Math.floor(new Date(selectedDate).getTime() / 1000);
|
||
const res = await fetch(`check_date.php?ts=${ts}`);
|
||
const data = await res.json();
|
||
|
||
if (Array.isArray(data) && data.length > 0) {
|
||
|
||
let html = "";
|
||
data.forEach(t => {
|
||
html += `
|
||
<div class="p-2 mb-2 bg-white rounded border">
|
||
<strong>Termin #${t.id}</strong><br>
|
||
Start: ${new Date(t.startzeit * 1000).toLocaleString()}<br>
|
||
Location: ${t.location}
|
||
</div>
|
||
`;
|
||
});
|
||
|
||
document.getElementById("terminConflictList").innerHTML = html;
|
||
|
||
const modal = new bootstrap.Modal(document.getElementById("terminConflictModal"));
|
||
modal.show();
|
||
|
||
// merken → für dieses Datum NICHT erneut anzeigen
|
||
conflictShownForDate = dateOnly;
|
||
}
|
||
}
|
||
|
||
// ---------- 2) ENDZEIT BEI JEDER STARTZEIT-ÄNDERUNG +8h ----------
|
||
|
||
if (startInput.value) {
|
||
const startDate = new Date(startInput.value);
|
||
|
||
startDate.setHours(startDate.getHours() + 8);
|
||
|
||
const iso = startDate.toISOString().slice(0, 16);
|
||
endInput.value = iso;
|
||
|
||
const hidden = document.getElementById("inputEndzeit_ts");
|
||
if (hidden) hidden.value = Math.floor(startDate.getTime() / 1000);
|
||
}
|
||
|
||
});
|
||
|
||
});
|
||
|
||
// Timestamp-Konvertierung wie bei termin_show
|
||
function toTimestampLocal(datetime) {
|
||
return datetime ? Math.floor(new Date(datetime).getTime() / 1000) : "";
|
||
}
|
||
|
||
document.getElementById("createTerminForm").addEventListener("submit", function() {
|
||
document.getElementById("inputStartzeit_ts").value = toTimestampLocal(document.getElementById("inputStartzeit").value);
|
||
document.getElementById("inputEndzeit_ts").value = toTimestampLocal(document.getElementById("inputEndzeit").value);
|
||
document.getElementById("inputRealEndzeit_ts").value = toTimestampLocal(document.getElementById("inputRealEndzeit").value);
|
||
});
|
||
</script>
|