prepare intranet for first Dokploy deployment

This commit is contained in:
2026-08-26 12:59:51 +02:00
parent 5cfe688bdc
commit 29dfb85fef
1321 changed files with 227234 additions and 0 deletions
+780
View File
@@ -0,0 +1,780 @@
<?php /* Name: kalli.php
Beschreibung: Kalli: Hauptseite */
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
?>
<!DOCTYPE html>
<html lang="de" dir="ltr">
<head>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/html_head.php'; ?>
</head>
<body class="theme-blue">
<?php // Stelle sicher, dass die Autoload-Datei von PHPSpreadsheet geladen wird
require 'vendor/autoload.php'; ?>
<?php // Durchführung der Aktionen
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
if(isset($_POST['submit'])) {
// if no errors, carry on
if(!isset($error)) {
$name = htmlspecialchars($user["first_name"]) . " " . htmlspecialchars($user["last_name"]);
$info = "Von " . $name . " eingetragen (Eintragungsassistent)";
// Create a new PHPExcel object
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// Set the header row
$sheet->setCellValue('A1', 'ID');
$sheet->setCellValue('B1', 'Lang-ID');
$sheet->setCellValue('C1', 'Termin-Typ');
$sheet->setCellValue('D1', 'Von-Datum');
$sheet->setCellValue('E1', 'Von-Zeit');
$sheet->setCellValue('F1', 'Bis-Datum');
$sheet->setCellValue('G1', 'Bis-Zeit');
$sheet->setCellValue('H1', 'Zeitzusatz');
$sheet->setCellValue('I1', 'Titel');
$sheet->setCellValue('J1', 'Text');
$sheet->setCellValue('K1', 'Ort');
$sheet->setCellValue('L1', 'Planungsstatus');
$sheet->setCellValue('M1', 'Anzeigeziel');
$sheet->setCellValue('N1', 'Gruppenzuordnung');
$sheet->setCellValue('O1', 'Zyklusart');
$sheet->setCellValue('P1', 'Zyklusintervall');
$sheet->setCellValue('Q1', 'Zyklusdetail');
$sheet->setCellValue('R1', 'Notiz');
$sheet->setCellValue('S1', 'Verantwortlich');
$sheet->setCellValue('T1', 'Hintergrundfarbe');
$sheet->setCellValue('U1', 'BucherID');
$sheet->setCellValue('V1', 'Benutzerdefinierte Felder');
$sheet->setCellValue('W1', 'Dokument-Titel');
$sheet->setCellValue('X1', 'Anzeigeziel Ort');
$sheet->setCellValue('Y1', 'Anzeigeziel Notiz');
$sheet->setCellValue('Z1', 'Anzeigeziel Verantwortlicher');
$sheet->setCellValue('AA1', 'Erzeugt');
$sheet->setCellValue('AB1', 'Aktualisiert');
// Set the data row
// Titel
$selectedGroup = isset($_POST['group']) ? $_POST['group'] : '';
$sheet->setCellValue('I2', $selectedGroup);
// Datum
$date_s = isset($_POST['date_s']) ? $_POST['date_s'] : '';
$sheet->setCellValue('D2', date('d.m.Y', strtotime($date_s)));
$date_e = isset($_POST['date_e']) ? $_POST['date_e'] : '';
if (date('d.m.Y', strtotime($date_e)) != "01.01.1970"){
$sheet->setCellValue('F2', date('d.m.Y', strtotime($date_e)));
}
// Zeit
$time_s = isset($_POST['time_s']) ? $_POST['time_s'] : '';
if ($time_s !== '' && preg_match('/^\d{2}:\d{2}$/', $time_s)) {
$sheet->setCellValue('E2', $time_s);
} elseif ($time_s !== '') {
$error[] = "Ungültiges Zeitformat. Verwenden Sie das Format hh:mm.";
}
$time_e = isset($_POST['time_e']) ? $_POST['time_e'] : '';
if ($time_e !== '' && preg_match('/^\d{2}:\d{2}$/', $time_e)) {
$sheet->setCellValue('G2', $time_e);
} elseif ($time_e !== '') {
$error[] = "Ungültiges Zeitformat. Verwenden Sie das Format hh:mm.";
}
// FIX
$sheet->setCellValue('C2', 'Einzel');
$sheet->setCellValue('O2', 'einmalig');
// Setze den Ort in Zelle K2
$location = isset($_POST['location']) ? htmlspecialchars($_POST['location']) : '';
$sheet->setCellValue('K2', $location);
// Setze den Text in Zelle J2
$further_text = isset($_POST['further_text']) ? htmlspecialchars($_POST['further_text']) : '';
$sheet->setCellValue('J2', $further_text);
$sheet->setCellValue('R2', $info);
$responsibility = isset($_POST['responsibility']) ? htmlspecialchars($_POST['responsibility']) : '';
$sheet->setCellValue('S2', $responsibility);
$userInput = isset($_POST['userinput']) ? $_POST['userinput'] : '';
$userInput2 = isset($_POST['userinput2']) ? $_POST['userinput2'] : '';
// DB-Lookup: Preset-Werte für die gewählte Terminart laden
$presetStmt = $pdo->prepare("SELECT planungsstatus, anzeigeziel, gruppenzuordnung, anzeigeziel_ort, anzeigeziel_notiz, anzeigeziel_verantwortlicher, default_text FROM kalli_appointment_types WHERE name = ? LIMIT 1");
$presetStmt->execute([$selectedGroup]);
$preset = $presetStmt->fetch(PDO::FETCH_ASSOC);
if ($preset) {
$sheet->setCellValue('L2', $preset['planungsstatus']);
$sheet->setCellValue('M2', $preset['anzeigeziel']);
$sheet->setCellValue('N2', $preset['gruppenzuordnung']);
$sheet->setCellValue('X2', $preset['anzeigeziel_ort']);
$sheet->setCellValue('Y2', $preset['anzeigeziel_notiz']);
$sheet->setCellValue('Z2', $preset['anzeigeziel_verantwortlicher']);
if (!empty($preset['default_text']) && empty($further_text)) {
$sheet->setCellValue('J2', $preset['default_text']);
}
} elseif ($userInput != "" && $selectedGroup == "oeffentlich") {
$sheet->setCellValue('I2', $userInput);
$sheet->setCellValue('L2', 'fix');
$sheet->setCellValue('M2', 'öffentlich');
$sheet->setCellValue('N2', 'AN ALLE');
$sheet->setCellValue('X2', 'öffentlich');
$sheet->setCellValue('Y2', 'intern');
$sheet->setCellValue('Z2', 'intern');
} elseif ($userInput != "" && $selectedGroup == "intern") {
$sheet->setCellValue('I2', $userInput);
$sheet->setCellValue('L2', 'fix');
$sheet->setCellValue('M2', 'intern');
$sheet->setCellValue('N2', 'AN ALLE');
$sheet->setCellValue('X2', 'intern');
$sheet->setCellValue('Y2', 'intern');
$sheet->setCellValue('Z2', 'intern');
}
// Save the file on the server
$xlsxDir = rtrim(intranet_env('CKAL_XLSX_DIR', '/data/ckal-xlsx'), '/');
if (!is_dir($xlsxDir) && !mkdir($xlsxDir, 0770, true) && !is_dir($xlsxDir)) {
throw new RuntimeException("CKalender-XLSX-Verzeichnis kann nicht angelegt werden: {$xlsxDir}");
}
$FileName = $xlsxDir . "/" . $name . "-" . date("Ymd-His") . ".xlsx";
$writer = new Xlsx($spreadsheet);
$writer->save($FileName);
// Redirect to prevent form resubmission on page reload
print "<script language='javascript'>window.location.href='/intranet_repo/projects/intranet/index.php?kalli_success=1';</script>";
//header("Location: kalli.php");
//exit();
}
}
// ACHTUNG: Die PHP-Header Weiterleitungen müssen hier abgeschlossen sein.
?>
<?php// Es folgen ab hier die HTML-Ausgaben beginnend mit dem HTML-Header:?>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/header.php'; ?>
<?php include $g_phpSnippetsPath.'overlay_message.php'; ?>
<div class="header_title ht_kalli text_white" id="header_title">
<span class="header_title_text">Kalli: Eintragungsassistent</span>
</div>
<div class="content" id="base">
<?php if (isset($_SESSION["user_id"])): ?>
<?php
if (isset($_GET["error"])) {
$error = $_GET["error"];
$isSuccess = in_array($error, [3]);
$toastType = $isSuccess ? 'success' : 'error';
$toastIcon = $isSuccess
? '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="square" stroke-linejoin="miter"><path d="M20 6L9 17l-5-5"/></svg>'
: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="square" stroke-linejoin="miter"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>';
$toastText = ($error == 3) ? 'Eintragung erfolgreich! Kalli wird Ihren Termin direkt vermerken.' : 'Es gab einen Fehler. Bitte kontaktieren Sie uns!';
echo "<div class='nak-toast nak-toast--{$toastType}' id='nakToast'>";
echo "<div class='nak-toast__icon'>{$toastIcon}</div>";
echo "<span class='nak-toast__text'>" . htmlspecialchars($toastText) . "</span>";
echo "<button class='nak-toast__close' onclick='dismissNakToast()' aria-label='Schließen'><svg viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='square' stroke-linejoin='miter'><line x1='18' y1='6' x2='6' y2='18'/><line x1='6' y1='6' x2='18' y2='18'/></svg></button>";
echo "</div>";
echo "<script>
requestAnimationFrame(function(){document.getElementById('nakToast').classList.add('nak-toast--visible');});
setTimeout(function(){dismissNakToast();},4000);
function dismissNakToast(){var t=document.getElementById('nakToast');if(!t||t.classList.contains('nak-toast--hiding'))return;t.classList.add('nak-toast--hiding');t.classList.remove('nak-toast--visible');setTimeout(function(){t.remove();},350);}
</script>";
}
?>
<style>
/* ── Kalli Page Wizard ── */
.kalli-wizard {
max-width: 1400px;
width: 90%;
margin: var(--space-xl) auto;
background: #ffffff;
box-shadow: var(--shadow-md);
overflow: hidden;
}
/* ── Progress Bar ── */
.kalli-progress {
display: flex;
align-items: center;
justify-content: center;
gap: 0;
padding: 20px 28px 16px;
background: var(--gray-50);
border-bottom: 1px solid var(--gray-200);
}
.kalli-progress-step {
display: flex;
flex-direction: column;
align-items: center;
gap: 4px;
flex-shrink: 0;
}
.kalli-progress-circle {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
font-size: var(--font-size-sm);
font-weight: 600;
color: var(--gray-500);
background: var(--gray-200);
border: 2px solid var(--gray-300);
transition: all 250ms ease;
}
.kalli-progress-step.active .kalli-progress-circle {
background: var(--nak-blue);
border-color: var(--nak-blue);
color: #ffffff;
box-shadow: 0 2px 8px rgba(39,134,207,0.35);
}
.kalli-progress-step.done .kalli-progress-circle {
background: #ffffff;
border-color: var(--nak-blue);
color: var(--nak-blue);
}
.kalli-progress-label {
font-size: var(--font-size-xs);
font-weight: 500;
color: var(--gray-500);
white-space: nowrap;
transition: color 250ms ease;
}
.kalli-progress-step.active .kalli-progress-label,
.kalli-progress-step.done .kalli-progress-label {
color: var(--nak-blue);
}
.kalli-progress-line {
flex: 1;
height: 2px;
min-width: 20px;
max-width: 60px;
background: var(--gray-300);
margin: 0 6px;
margin-bottom: 20px;
transition: background 250ms ease;
}
.kalli-progress-line.done {
background: var(--nak-blue);
}
/* ── Body ── */
.kalli-modal-body {
padding: 22px 28px 16px;
}
.kalli-section-title {
margin: 0 0 16px 0;
font-size: var(--font-size-sm);
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--gray-600);
}
/* ── Category Grid (Step 1) ── */
.kalli-category-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: var(--space-lg);
}
.kalli-category {
display: flex;
flex-direction: column;
gap: 2px;
}
.kalli-category-label {
font-size: var(--font-size-sm);
font-weight: 600;
color: var(--gray-700);
margin-bottom: 4px;
text-transform: uppercase;
letter-spacing: 0.03em;
}
label.kalli-radio-item {
display: flex;
align-items: center;
gap:8px;
padding: 0px 5px;
cursor: pointer;
font-size: var(--font-size-sm);
font-weight: 300;
color: var(--gray-600);
border: 1px solid transparent;
transition: background 150ms ease, border-color 150ms ease;
text-transform: none;
letter-spacing: normal;
}
label.kalli-radio-item input[type="radio"],
label.kalli-radio-item input[type="checkbox"] {
width: 16px;
height: 16px;
accent-color: var(--nak-blue);
margin: 0;
flex-shrink: 0;
align-self: center;
}
label.kalli-radio-item span {
hyphens: auto;
-webkit-hyphens: auto;
-ms-hyphens: auto;
word-break: break-word;
overflow-wrap: break-word;
line-height: 1.4;
}
label.kalli-radio-item:hover {
background: var(--gray-50);
border-color: var(--gray-200);
}
.kalli-custom-section {
margin-top: var(--space-lg);
padding: var(--space-md);
background: hsl(0,60%,98%);
border: 1px solid hsl(0,60%,90%);
}
/* ── Field Grid (Steps 2 & 3) ── */
.kalli-field-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-md);
}
.kalli-field-grid-single {
grid-template-columns: 1fr;
}
.kalli-field-group {
display: flex;
flex-direction: column;
gap: 4px;
}
.kalli-label {
font-size: var(--font-size-sm);
font-weight: 500;
color: var(--gray-700);
}
.kalli-field {
padding: 12px 14px;
font-size: var(--font-size-base);
font-family: var(--font-primary);
font-weight: 300;
border: 1px solid var(--gray-300);
background: var(--gray-50);
outline: none;
transition: border-color 150ms ease, box-shadow 150ms ease;
width: 100%;
box-sizing: border-box;
}
.kalli-field:focus {
border-color: var(--nak-blue);
box-shadow: 0 0 0 3px rgba(39,134,207,0.2);
background: #ffffff;
}
/* ── Summary (Step 4) ── */
.kalli-summary {
display: flex;
flex-direction: column;
gap: 0;
border: 1px solid var(--gray-200);
}
.kalli-summary-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 16px;
border-bottom: 1px solid var(--gray-100);
}
.kalli-summary-row:last-child { border-bottom: none; }
.kalli-summary-label {
font-size: var(--font-size-sm);
font-weight: 500;
color: var(--gray-600);
}
.kalli-summary-value {
font-size: var(--font-size-sm);
font-weight: 500;
color: var(--gray-900);
text-align: right;
}
.kalli-validation-error {
margin-top: var(--space-md);
padding: 10px 14px;
background: hsl(0,78%,95%);
color: hsl(0,78%,40%);
font-weight: 600;
font-size: var(--font-size-sm);
}
/* ── Actions ── */
.kalli-modal-actions {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
padding: 16px 28px 20px;
border-top: 1px solid var(--gray-200);
}
.kalli-modal-actions-left,
.kalli-modal-actions-right {
display: flex;
gap: 8px;
}
.kalli-btn {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 38px;
padding: 8px 18px;
font-size: var(--font-size-sm);
font-weight: 600;
font-family: var(--font-primary);
border: 1px solid var(--gray-300);
background: #ffffff;
color: var(--gray-800);
cursor: pointer;
transition: background 150ms ease, transform 150ms ease;
white-space: nowrap;
}
.kalli-btn:hover {
background: var(--gray-100);
transform: translateY(-1px);
}
.kalli-btn-primary {
background: var(--nak-blue);
border-color: var(--nak-blue);
color: #ffffff;
}
.kalli-btn-primary:hover {
background: var(--nak-blue-hover);
border-color: var(--nak-blue-hover);
}
.kalli-btn-submit {
background: linear-gradient(135deg, var(--nak-blue), var(--nak-blue-hover));
border-color: var(--nak-blue-hover);
color: #ffffff;
padding: 10px 24px;
font-weight: 700;
}
.kalli-btn-submit:hover {
background: linear-gradient(135deg, var(--nak-blue-hover), #185d8f);
}
/* ── Responsive ── */
@media (max-width: 600px) {
.kalli-wizard { margin: 0; width: 100%; }
.kalli-progress { padding: 14px 12px 10px; }
.kalli-progress-label { font-size: 0.65rem; }
.kalli-progress-circle { width: 26px; height: 26px; font-size: 0.7rem; }
.kalli-progress-line { min-width: 12px; margin-bottom: 16px; }
.kalli-modal-body { padding: 16px; }
.kalli-category-grid { grid-template-columns: 1fr; }
.kalli-field-grid { grid-template-columns: 1fr; }
.kalli-modal-actions { padding: 12px 16px 16px; flex-wrap: wrap; }
}
</style>
<div class="kalli-wizard">
<!-- Progress Bar -->
<div class="kalli-progress">
<div class="kalli-progress-step active" data-step="1">
<div class="kalli-progress-circle">1</div>
<span class="kalli-progress-label">Terminart</span>
</div>
<div class="kalli-progress-line"></div>
<div class="kalli-progress-step" data-step="2">
<div class="kalli-progress-circle">2</div>
<span class="kalli-progress-label">Zeitraum</span>
</div>
<div class="kalli-progress-line"></div>
<div class="kalli-progress-step" data-step="3">
<div class="kalli-progress-circle">3</div>
<span class="kalli-progress-label">Informationen</span>
</div>
<div class="kalli-progress-line"></div>
<div class="kalli-progress-step" data-step="4">
<div class="kalli-progress-circle">4</div>
<span class="kalli-progress-label">Übersicht</span>
</div>
</div>
<!-- Form wraps all steps -->
<form id="kalliForm" action="" method="post">
<!-- STEP 1: Terminart -->
<div class="kalli-step" id="kalliStep1">
<div class="kalli-modal-body">
<div class="kalli-section-title">Terminart auswählen</div>
<div class="kalli-category-grid">
<?php
// Kategorien und Terminarten aus der Datenbank laden
$catQuery = $pdo->query("SELECT * FROM kalli_categories ORDER BY sort_order, name");
$kalliCategories = [];
while ($cat = $catQuery->fetch(PDO::FETCH_ASSOC)) {
$kalliCategories[] = $cat;
}
$typeQuery = $pdo->query("SELECT * FROM kalli_appointment_types ORDER BY sort_order, name");
$kalliTypesByCategory = [];
while ($type = $typeQuery->fetch(PDO::FETCH_ASSOC)) {
$kalliTypesByCategory[$type['category_id']][] = $type;
}
// Alle verwendeten Rollen sammeln für die "Terminart nicht aufgelistet"-Sektion
$kalliAllRoles = [];
$isAdminUser = (isset($groups["Admin"]) && $groups["Admin"] == 1);
foreach ($kalliCategories as $cat):
$role = $cat['permission_role'];
$kalliAllRoles[$role] = 1;
if (!$isAdminUser && !(isset($groups[$role]) && $groups[$role] == 1)) continue;
$types = $kalliTypesByCategory[$cat['id']] ?? [];
if (empty($types)) continue;
?>
<div class="kalli-category">
<div class="kalli-category-label"><?= htmlspecialchars($cat['name']) ?></div>
<?php foreach ($types as $type):
$displayLabel = !empty($type['display_label']) ? $type['display_label'] : $type['name'];
?>
<label class="kalli-radio-item"><input type="radio" name="group" value="<?= htmlspecialchars($type['name']) ?>"><span><?= htmlspecialchars($displayLabel) ?></span></label>
<?php endforeach; ?>
</div>
<?php endforeach; ?>
</div>
<?php
$hasAnyKalliRole = $isAdminUser || count(array_intersect_key($groups, $kalliAllRoles)) > 0;
if ($hasAnyKalliRole): ?>
<div class="kalli-custom-section">
<div class="kalli-category-label" style="color:var(--nak-red);">Terminart nicht aufgelistet?</div>
<p style="margin:0 0 var(--space-sm) 0;font-size:var(--font-size-sm);color:var(--gray-600);">Nur ausfüllen, wenn die Terminart oben nicht vorhanden ist.</p>
<div style="display:flex;gap:var(--space-lg);flex-wrap:wrap;margin-bottom:var(--space-sm);">
<label class="kalli-radio-item"><input type="radio" name="group" value="oeffentlich"><span>Öffentlich</span></label>
<label class="kalli-radio-item"><input type="radio" name="group" value="intern"><span>Intern</span></label>
</div>
<input class="kalli-field" type="text" name="userinput" id="kalliUserInput" placeholder="Titel (nur für benutzerdefinierte Termine)">
</div>
<?php endif; ?>
</div>
<div class="kalli-modal-actions">
<div></div>
<div class="kalli-modal-actions-right">
<button type="button" class="kalli-btn kalli-btn-primary" onclick="kalliNextStep(2)">Weiter</button>
</div>
</div>
</div>
<!-- STEP 2: Zeitraum -->
<div class="kalli-step" id="kalliStep2" style="display:none;">
<div class="kalli-modal-body">
<div class="kalli-section-title">Zeitraum festlegen</div>
<div class="kalli-field-grid">
<div class="kalli-field-group">
<label class="kalli-label">Datum <span style="color:var(--nak-red);">*</span></label>
<input class="kalli-field" type="date" name="date_s" id="kalliDateS" required>
</div>
<div class="kalli-field-group">
<label class="kalli-label">Enddatum <span style="font-weight:300;color:var(--gray-500);">(falls mehrtägig)</span></label>
<input class="kalli-field" type="date" name="date_e" id="kalliDateE">
</div>
<div class="kalli-field-group">
<label class="kalli-label">Zeit von <span style="font-weight:300;color:var(--gray-500);">(optional)</span></label>
<input class="kalli-field" type="time" name="time_s" id="kalliTimeS">
</div>
<div class="kalli-field-group">
<label class="kalli-label">Zeit bis <span style="font-weight:300;color:var(--gray-500);">(optional)</span></label>
<input class="kalli-field" type="time" name="time_e" id="kalliTimeE">
</div>
</div>
</div>
<div class="kalli-modal-actions">
<div class="kalli-modal-actions-left">
<button type="button" class="kalli-btn" onclick="kalliPrevStep(1)">Zurück</button>
</div>
<div class="kalli-modal-actions-right">
<button type="button" class="kalli-btn kalli-btn-primary" onclick="kalliNextStep(3)">Weiter</button>
</div>
</div>
</div>
<!-- STEP 3: Informationen -->
<div class="kalli-step" id="kalliStep3" style="display:none;">
<div class="kalli-modal-body">
<div class="kalli-section-title">Zusätzliche Informationen</div>
<div class="kalli-field-grid kalli-field-grid-single">
<div class="kalli-field-group">
<label class="kalli-label">Textfeld <span style="font-weight:300;color:var(--gray-500);">(optional)</span></label>
<input class="kalli-field" type="text" name="further_text" id="kalliFurtherText" placeholder="z.B. betreffende Person, etc.">
</div>
<div class="kalli-field-group">
<label class="kalli-label">Ort <span style="font-weight:300;color:var(--gray-500);">(optional)</span></label>
<input class="kalli-field" type="text" name="location" id="kalliLocation">
</div>
<div class="kalli-field-group">
<label class="kalli-label">Verantwortliche/r <span style="font-weight:300;color:var(--gray-500);">(optional)</span></label>
<input class="kalli-field" type="text" name="responsibility" id="kalliResponsibility">
</div>
</div>
</div>
<div class="kalli-modal-actions">
<div class="kalli-modal-actions-left">
<button type="button" class="kalli-btn" onclick="kalliPrevStep(2)">Zurück</button>
</div>
<div class="kalli-modal-actions-right">
<button type="button" class="kalli-btn kalli-btn-primary" onclick="kalliNextStep(4)">Weiter</button>
</div>
</div>
</div>
<!-- STEP 4: Übersicht -->
<div class="kalli-step" id="kalliStep4" style="display:none;">
<div class="kalli-modal-body">
<div class="kalli-section-title">Übersicht – Bitte prüfen Sie Ihre Eingaben</div>
<div class="kalli-summary">
<div class="kalli-summary-row">
<span class="kalli-summary-label">Terminart</span>
<span class="kalli-summary-value" id="sumGroup">–</span>
</div>
<div class="kalli-summary-row">
<span class="kalli-summary-label">Datum</span>
<span class="kalli-summary-value" id="sumDateS">–</span>
</div>
<div class="kalli-summary-row" id="sumDateERow" style="display:none;">
<span class="kalli-summary-label">Enddatum</span>
<span class="kalli-summary-value" id="sumDateE">–</span>
</div>
<div class="kalli-summary-row" id="sumTimeSRow" style="display:none;">
<span class="kalli-summary-label">Zeit von</span>
<span class="kalli-summary-value" id="sumTimeS">–</span>
</div>
<div class="kalli-summary-row" id="sumTimeERow" style="display:none;">
<span class="kalli-summary-label">Zeit bis</span>
<span class="kalli-summary-value" id="sumTimeE">–</span>
</div>
<div class="kalli-summary-row" id="sumTextRow" style="display:none;">
<span class="kalli-summary-label">Textfeld</span>
<span class="kalli-summary-value" id="sumText">–</span>
</div>
<div class="kalli-summary-row" id="sumLocRow" style="display:none;">
<span class="kalli-summary-label">Ort</span>
<span class="kalli-summary-value" id="sumLoc">–</span>
</div>
<div class="kalli-summary-row" id="sumRespRow" style="display:none;">
<span class="kalli-summary-label">Verantwortlich</span>
<span class="kalli-summary-value" id="sumResp">–</span>
</div>
</div>
<div id="kalliValidationError" class="kalli-validation-error" style="display:none;"></div>
</div>
<div class="kalli-modal-actions">
<div class="kalli-modal-actions-left">
<button type="button" class="kalli-btn" onclick="kalliPrevStep(3)">Zurück</button>
</div>
<div class="kalli-modal-actions-right">
<button type="submit" name="submit" class="kalli-btn kalli-btn-submit">Eintragung absenden</button>
</div>
</div>
</div>
</form>
</div>
<script>
var kalliCurrentStep = 1;
function kalliGoToStep(step) {
for (var i = 1; i <= 4; i++) {
document.getElementById('kalliStep' + i).style.display = (i === step) ? '' : 'none';
}
kalliCurrentStep = step;
kalliUpdateProgress(step);
window.scrollTo({top: 0, behavior: 'smooth'});
// Header wieder einblenden, falls er durch Scrollen ausgeblendet war
var headerHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--header-height')) || 64;
var elemHeaderMenue = document.getElementById('header_menue');
var elemHeaderTitle = document.getElementById('header_title');
if (elemHeaderMenue) { elemHeaderMenue.style.top = '0'; }
if (elemHeaderTitle) { elemHeaderTitle.style.top = headerHeight + 'px'; }
}
function kalliUpdateProgress(step) {
var steps = document.querySelectorAll('.kalli-progress-step');
var lines = document.querySelectorAll('.kalli-progress-line');
steps.forEach(function(el, idx) {
var s = idx + 1;
el.classList.remove('active', 'done');
if (s === step) el.classList.add('active');
else if (s < step) el.classList.add('done');
});
lines.forEach(function(el, idx) {
el.classList.toggle('done', idx < step - 1);
});
}
function kalliNextStep(step) {
var errEl = document.getElementById('kalliValidationError');
if (errEl) { errEl.style.display = 'none'; errEl.textContent = ''; }
if (step === 2) {
var sel = document.querySelector('#kalliForm input[name="group"]:checked');
if (!sel) { alert('Bitte wählen Sie eine Terminart aus.'); return; }
if ((sel.value === 'oeffentlich' || sel.value === 'intern') && !document.getElementById('kalliUserInput').value.trim()) {
alert('Bitte geben Sie einen Titel für den benutzerdefinierten Termin ein.'); return;
}
}
if (step === 3) {
if (!document.getElementById('kalliDateS').value) { alert('Bitte geben Sie ein Datum ein.'); return; }
}
if (step === 4) { kalliBuildSummary(); }
kalliGoToStep(step);
}
function kalliPrevStep(step) { kalliGoToStep(step); }
function kalliBuildSummary() {
var grp = document.querySelector('#kalliForm input[name="group"]:checked');
var grpVal = grp ? grp.value : '–';
if ((grpVal === 'oeffentlich' || grpVal === 'intern') && document.getElementById('kalliUserInput')) {
var custom = document.getElementById('kalliUserInput').value.trim();
grpVal = custom ? custom + ' (' + (grpVal === 'oeffentlich' ? 'Öffentlich' : 'Intern') + ')' : grpVal;
}
document.getElementById('sumGroup').textContent = grpVal;
document.getElementById('sumDateS').textContent = kalliFormatDate(document.getElementById('kalliDateS').value);
kalliShowSummaryRow('sumDateERow', document.getElementById('kalliDateE').value, 'sumDateE', kalliFormatDate(document.getElementById('kalliDateE').value));
kalliShowSummaryRow('sumTimeSRow', document.getElementById('kalliTimeS').value, 'sumTimeS', document.getElementById('kalliTimeS').value);
kalliShowSummaryRow('sumTimeERow', document.getElementById('kalliTimeE').value, 'sumTimeE', document.getElementById('kalliTimeE').value);
kalliShowSummaryRow('sumTextRow', document.getElementById('kalliFurtherText').value.trim(), 'sumText', document.getElementById('kalliFurtherText').value.trim());
kalliShowSummaryRow('sumLocRow', document.getElementById('kalliLocation').value.trim(), 'sumLoc', document.getElementById('kalliLocation').value.trim());
kalliShowSummaryRow('sumRespRow', document.getElementById('kalliResponsibility').value.trim(), 'sumResp', document.getElementById('kalliResponsibility').value.trim());
}
function kalliShowSummaryRow(rowId, value, valId, displayVal) {
var row = document.getElementById(rowId);
if (value) { row.style.display = ''; document.getElementById(valId).textContent = displayVal; }
else { row.style.display = 'none'; }
}
function kalliFormatDate(iso) {
if (!iso) return '–';
var parts = iso.split('-');
return parts.length === 3 ? parts[2] + '.' + parts[1] + '.' + parts[0] : iso;
}
</script>
<?php endif; ?>
</div><!-- content -->
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/footer.php'; ?>
</body>
</html>