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
@@ -0,0 +1,79 @@
<?php
header('Content-Type: application/json; charset=utf-8');
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
try {
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'Nicht angemeldet.'], JSON_UNESCAPED_UNICODE);
exit;
}
$pdo = require($_SERVER['DOCUMENT_ROOT'] . "/intranet_repo/general_files/ini/database.php");
// Eingaben
$last_name = trim($_POST['last_name'] ?? '');
$first_name = trim($_POST['first_name'] ?? '');
$birth_date = trim($_POST['birth_date'] ?? '');
$address_street = trim($_POST['address_street'] ?? '');
$address_plz = trim($_POST['address_plz'] ?? '');
$address_link = trim($_POST['address_link'] ?? '');
$phone_raw = trim($_POST['phone'] ?? '');
$comment = trim($_POST['comment'] ?? '');
$letzter_besuch = trim($_POST['letzter_besuch'] ?? '');
$priority = isset($_POST['priority']) ? (int)$_POST['priority'] : 0;
$pr_bezirk_raw = trim($_POST['pr_bezirk'] ?? '');
// Pflichtfelder
if ($last_name === '' || $first_name === '' || $birth_date === '' || $address_street === '' || $address_plz === '') {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Pflichtfelder fehlen.'], JSON_UNESCAPED_UNICODE);
exit;
}
// Telefon: nur Ziffern (robust gegen +49/Leerzeichen)
$phone = preg_replace('/\D+/', '', $phone_raw);
if ($phone === '') {
$phone = null; // phone darf NULL sein (laut Tabelle)
}
// WICHTIG: diese Spalten sind NOT NULL in deiner Tabelle -> niemals NULL senden
if ($address_link === '') $address_link = '';
if ($comment === '') $comment = '';
if ($letzter_besuch === '') $letzter_besuch = "2024-07-11";
if ($pr_bezirk_raw === '') $pr_bezirk_raw = ''; // pr_bezirk ist NOT NULL (varchar)
$sql = "INSERT INTO seelsorge_besuchsstellen
(last_name, first_name, birth_date, address_street, address_plz, address_link, phone, comment, letzter_besuch, priority, pr_bezirk, reservation)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)";
$stmt = $pdo->prepare($sql);
$stmt->execute([
$last_name,
$first_name,
$birth_date,
$address_street,
$address_plz,
$address_link,
$phone,
$comment,
$letzter_besuch,
$priority,
$pr_bezirk_raw
]);
$newId = $pdo->lastInsertId();
echo json_encode(['status' => 'success', 'besuch_id' => $newId], JSON_UNESCAPED_UNICODE);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'DB-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Server-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
}
@@ -0,0 +1,24 @@
<?php /* Name: content/calendar.php
Beschreibung: Kalendarium
Aufgerufen über seelsorge.php */
?>
<?php
require_once('util/connector_feiertage.php');
$connector_feiertage = lib_Feiertage_Connector::getInstance();
require_once('util/connector_kalendertage.php');
$connector_kalendertage = lib_Kalendertage_Connector::getInstance();
?>
<div class='page_calendar unselectable active' id="calendar_view">
<?php include "content/calendar_view.php"; ?>
</div>
<?php include "content/calendar_help.php"; ?>
<?php
// Profiloverlay für Kalenderbereich
$isPageCalendar = true;
include "content/profile.php";
?>
@@ -0,0 +1,124 @@
<?php
/* Name: content/calendar_day.php
Beschreibung: AJAX-Endpoint: Liefert Inhalt fuer das Tages-Modal
Aufgerufen per fetch() aus seelsorge.js */
// CWD auf seelsorge/ setzen (Connector nutzt relative Pfade wie data/)
chdir(dirname(__DIR__));
// Initialisierung
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
if (isset($_POST['calendarDate'])):
$p_selectedDate = $_POST['calendarDate'];
require_once($g_projectsPath . 'seelsorge/util/connector_feiertage.php');
$connector_feiertage = lib_Feiertage_Connector::getInstance();
require_once($g_projectsPath . 'seelsorge/util/connector_kalendertage.php');
$connector_kalendertage = lib_Kalendertage_Connector::getInstance();
// Tagesinformationen
$p_calendarMonthName = $connector_kalendertage->get_KalenderMonatsname($p_selectedDate);
$p_calendarWeekdayName = $connector_kalendertage->get_KalenderWochentag($p_selectedDate);
$p_dayNumber = date("j", strtotime($p_selectedDate));
$p_year = date("Y", strtotime($p_selectedDate));
$p_kw = date("W", strtotime($p_selectedDate));
$feiertagsname = $connector_feiertage->get_feiertagsname($p_selectedDate);
$p_dateTitle = $p_calendarWeekdayName . ", " . $p_dayNumber . ". " . $p_calendarMonthName . " " . $p_year;
// Verfuegbare Diakon*innen laden
$sql = "SELECT u.*, p.\"DiakonIn\" FROM user_general_information u
LEFT JOIN user_permissions p ON u.user_id = p.user_id
ORDER BY RANDOM()";
$result = $pdo->query($sql);
$availableUsers = [];
$allRows = $result->fetchAll();
if (count($allRows) > 0) {
foreach($allRows as $row) {
$userId = $row['user_id'];
$name = $row['first_name'] . " " . $row['last_name'];
if ($row['first_name'] != null && $row['last_name'] != null && $row['DiakonIn'] == 1) {
$stmt_av = $pdo->prepare("SELECT * FROM verfuegbarkeiten WHERE user_id = ? AND datum = ?");
$stmt_av->execute([$userId, $p_selectedDate]);
if ($stmt_av->rowCount() > 0) {
$availableUsers[$userId] = $name;
}
}
}
}
// Pruefe ob aktueller User eingetragen ist
$stmt_self = $pdo->prepare("SELECT COUNT(*) AS count FROM verfuegbarkeiten WHERE datum=? AND user_id=?");
$stmt_self->execute([$p_selectedDate, $_SESSION["user_id"]]);
$selfResult = $stmt_self->fetch();
$selfAvailable = $selfResult['count'] > 0;
// JSON-Metadaten fuer JS
echo '<script type="application/json" id="modal-meta">';
echo json_encode([
'title' => $p_dateTitle,
'kw' => $p_kw,
'feiertag' => $feiertagsname,
'selfAvailable' => $selfAvailable,
'date' => $p_selectedDate
], JSON_UNESCAPED_UNICODE);
echo '</script>';
?>
<!-- Tagesinformationen -->
<div class="seelsorge-modal-section">
<?php if ($feiertagsname): ?>
<div class="seelsorge-modal-field">
<div class="seelsorge-modal-field-label">Feiertag</div>
<div class="seelsorge-modal-field-value"><?= htmlspecialchars($feiertagsname) ?></div>
</div>
<?php endif; ?>
</div>
<!-- Verfuegbare Diakon*innen -->
<div class="seelsorge-modal-section">
<div class="seelsorge-section-title">Verf&uuml;gbare Personen</div>
<?php if (count($availableUsers) > 0): ?>
<div class="diakon-grid" id="modal-galery">
<?php foreach ($availableUsers as $userId => $name):
$profileImg = glob($_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/profile_pictures/' . $userId . '-*.jpg');
if (!empty($profileImg)) {
usort($profileImg, function($a, $b) { return filemtime($b) - filemtime($a); });
$imgPath = str_replace($_SERVER['DOCUMENT_ROOT'], '', $profileImg[0]);
} else {
$imgPath = '/intranet_repo/general_files/profile_pictures/default.jpg';
}
?>
<div class="diakon-card" onclick="openCalendarProfile(<?= (int)$userId ?>)" title="Profil anzeigen">
<img class="diakon-card-img" src="<?= htmlspecialchars($imgPath) ?>" alt="<?= htmlspecialchars($name) ?>">
<div class="diakon-card-info">
<div class="diakon-card-name"><?= htmlspecialchars($name) ?></div>
<div class="diakon-card-role">Verfügbar</div>
</div>
<div class="diakon-card-arrow">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="square"><path d="M9 18l6-6-6-6"/></svg>
</div>
</div>
<?php endforeach; ?>
</div>
<?php else: ?>
<div class="seelsorge-modal-empty">Keine Personen verf&uuml;gbar.</div>
<?php endif; ?>
</div>
<!-- Eintragen / Austragen -->
<div class="seelsorge-modal-actions">
<button type="button"
class="seelsorge-action-button <?= $selfAvailable ? 'seelsorge-remove-button' : 'seelsorge-add-button' ?>"
id="modal-toggle-btn"
onclick="toggleAvailabilityModal('<?= $p_selectedDate ?>')">
<?= $selfAvailable ? 'Verf&uuml;gbarkeit entfernen' : 'Als verf&uuml;gbar eintragen' ?>
</button>
</div>
<?php
$pdo = null;
endif;
?>
@@ -0,0 +1,138 @@
<?php /* Name: content/calendar_edit.php
Beschreibung: Kalenderblatt zum Bearbeiten der Verfügbarkeit des jeweiligen Users
Aufgerufen über calendar.php
*/
?>
<div class="calendar_title_modus">Bearbeitung der eigenen Verfügbarkeit</div>
<div id="toggleViewEdit" class="button tooltip borderradius_round" onclick="toggleViewEdit()">
<?php display_button('calendar', null, 'right'); ?>
<span class="tooltiptext">Kalender anzeigen</span>
</div>
<?php
// 2 Kalendermonate laden
for ($t = 1; $t <= 2; $t++) {
// Startdatum und Stile festlegen
$p_startDate = date("Y-m-d", strtotime($t === 1 ? "first day of this month" : "first day of next month"));
$p_style = $t === 1 ? "display:flex" : "display:none";
$p_class_arrow_left = $t === 1 ? "arrow_light" : "arrow_dark";
$p_class_arrow_right = $t === 1 ? "arrow_dark" : "arrow_light";
// Monatsnamen und Titel holen
$p_calendarMonthName = $connector_kalendertage->get_KalenderMonatsname($p_startDate);
$p_calendarTitle = $p_calendarMonthName . " " . date("Y", strtotime($p_startDate));
// Kalenderkopf ausgeben
?>
<div class="calendar_header" style="<?= $p_style ?>" id="calendar_edit_header_<?= $t ?>">
<div class="arrow_item" onclick="switchCalendarEdit('left')">
<div class="<?= $p_class_arrow_left ?>" id="left">
<?php display_button('arrow_left', null, 'left'); ?>
</div>
</div>
<div class="calendar_title"><?= $p_calendarTitle ?></div>
<div class="arrow_item" onclick="switchCalendarEdit('right')">
<div class="<?= $p_class_arrow_right ?>" id="right">
<?php display_button('arrow_right', null, 'right'); ?>
</div>
</div>
</div>
<?php
}
?>
<div class="calendar_content">
<table>
<thead>
<tr>
<th class="calendar_head">MO</th>
<th class="calendar_head">DI</th>
<th class="calendar_head">MI</th>
<th class="calendar_head">DO</th>
<th class="calendar_head">FR</th>
<th class="calendar_head_sat">SA</th>
<th class="calendar_head_sun">SO</th>
</tr>
</thead>
<tbody>
<?php
for ($c = 1; $c <= 2; $c++) { // Zwei Monatsansichten laden
$p_startDate = $c === 1 ? date("Y-m-d", strtotime("first day of this month")) : date("Y-m-d", strtotime("first day of next month"));
$p_endDate = $c === 1 ? date("Y-m-d", strtotime("last day of this month")) : date("Y-m-d", strtotime("last day of next month"));
$p_style = $c === 1 ? "visibility:visible" : "visibility:collapse";
$p_calendarStartDate = $connector_kalendertage->get_KalenderStart($p_startDate);
// Kalender: 6 Wochen in Zeilen
for ($i = 0; $i < 42; $i++) {
$datum = date('Y-m-d', strtotime("$p_calendarStartDate +$i days"));
$tag = date('j', strtotime("$p_calendarStartDate +$i days"));
$wochentag = date("w", strtotime("$p_calendarStartDate +$i days"));
$wochennr = (int)date("W o", strtotime("$p_calendarStartDate +$i days"));
$isFeiertagInBerlin = $connector_feiertage->isFeiertagInBerlin($datum); // Nur Berlin
$feiertagsname = $connector_feiertage->get_feiertagsname($datum); // (alle Bundesländer)
if ($i % 7 === 0) { // Beginn der Tabellenzeile
echo "<tr name='calendar_edit_$c' style='$p_style'>";
}
// Sichtbarkeit
if ($datum < date("Y-m-d")) { // vor Heute - nicht anklickbar
echo "<td class='calendar_day_area' style='filter:brightness(60%);opacity:0.3;'>";
echo "<div class='calendar_day'>$tag</div>";
} elseif ($datum < $p_startDate || $datum > $p_endDate) { // außerhalb des Monats
echo "<td class='calendar_day_area' style='filter:brightness(100%);opacity:0.5;'>";
echo "<div class='calendar_day'>$tag</div>";
} else {
echo "<td class='calendar_day_area'>";
echo "<div class='calendar_day'>";
// Verfügbarkeit des Users nur für zukünftige Tage
$sql = "SELECT COUNT(datum) AS count FROM verfuegbarkeiten WHERE datum=? and user_id=?";
$stmt = $pdo->prepare($sql);
if ($stmt) {
$stmt->execute([$datum, $_SESSION["user_id"]]);
$row = $stmt->fetch();
if ($row) {
$count = $row['count'];
} else {
echo "Error retrieving result";
}
} else {
echo "Error preparing statement";
}
// Falls das Datum heute oder in der Zukunft liegt
$Id_cDayItem = "id='calendar_day_item'";
if ($count > 0) { // User ist schon eingetragen
echo "<div $Id_cDayItem class='calendar_day_item availableday editmode' title='Verfügbar' onclick='toggleAvailability(\"$datum\", this)'>";
} else { // User ist noch nicht eingetragen
echo "<div $Id_cDayItem class='calendar_day_item normalday editmode' onclick='toggleAvailability(\"$datum\", this)'>";
}
echo $tag;
if ($feiertagsname != null) {
echo "<div class='feiertagsname'>$feiertagsname</div>";
}
echo "</div>"; // END: calendar_day
}
echo "</td>"; // END: calendar_day_area
if ($i % 7 === 6) { // Ende der Tabellenzeile
echo "</tr>";
}
// Reset der Variablen
$feiertagsname = null;
}
} // Schleifenende: Zwei Monatsansichten laden
?>
</tbody>
</table> <!-- END: calendar -->
</div> <!-- END: calendar_content -->
@@ -0,0 +1,67 @@
<!-- Hilfe-Modal fuer Kalendarium -->
<div class="standard_overlay" id="calendar-help-modal" onclick="if(event.target===this)closeCalendarHelp()">
<div class="seelsorge-modal-card" style="max-width:460px;">
<button type="button" class="exit" aria-label="Schließen" onclick="closeCalendarHelp()">×</button>
<div class="seelsorge-modal-hero">
<div class="seelsorge-modal-hero-icon">
<svg viewBox="0 0 24 24" width="40" height="40" fill="none" stroke="#FFFFFF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
</div>
<div>
<div class="seelsorge-modal-title">Hilfe zum Kalendarium</div>
<div class="seelsorge-modal-subtitle">So funktioniert der Seelsorgeplaner</div>
</div>
</div>
<div class="seelsorge-modal-body">
<div class="seelsorge-modal-section">
<div class="seelsorge-section-title">Bedienung</div>
<p style="font-size:0.9em;line-height:1.6;color:#374151;margin:0 0 12px 0;">
Im Kalendarium siehst du auf einen Blick die Verfügbarkeiten aller Personen.
Mit einem Klick auf einen Tag öffnet sich ein Fenster mit den Tagesdetails.
Dort siehst du, wer an diesem Tag verfügbar ist, und kannst dich selbst
eintragen oder wieder austragen. Mithilfe der Pfeile wechselst du zwischen
aktuellem und nächstem Monat.
</p>
</div>
<div class="seelsorge-modal-section">
<div class="seelsorge-section-title">Farblegende</div>
<div class="calendar-help-legend">
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:#1243a0;"></span>
<span>Heute (keine Verfügbarkeit)</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:#ffdc0f;"></span>
<span>Eine Person verfügbar</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:#006e14;"></span>
<span>Zwei oder mehr Personen verfügbar (Match)</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:hsl(297, 80%, 40%);"></span>
<span>Sonntag / Feiertag</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:hsl(297, 25%, 45%);"></span>
<span>Samstag</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:hsl(297, 10%, 98%);border:1px solid #e9ecef;"></span>
<span>Normaler Tag</span>
</div>
<div class="calendar-help-legend-item">
<span class="calendar-help-swatch" style="background:hsl(0, 0%, 90%);border:1px solid #e9ecef;"></span>
<span>Vergangener Tag</span>
</div>
</div>
</div>
<div class="seelsorge-modal-section" style="margin-bottom:0;">
<div class="seelsorge-section-title">Benachrichtigungen</div>
<p style="font-size:0.9em;line-height:1.6;color:#374151;margin:0;">
Sobald sich zwei oder mehr Personen am selben Tag eintragen, werden alle
Beteiligten automatisch per SMS und E-Mail benachrichtigt.
</p>
</div>
</div>
</div>
</div>
@@ -0,0 +1,139 @@
<?php /* Name: content/calendar_view.php
Beschreibung: Kalenderblatt mit Übersicht und Interaktion per Modal
Aufgerufen über calendar.php */
?>
<?php
// 2 Kalendermonate laden
for ($t = 1; $t <= 2; $t++) {
$p_startDate = date("Y-m-d", strtotime($t === 1 ? "first day of this month" : "first day of next month"));
$p_style = $t === 1 ? "display:flex" : "display:none";
$p_class_arrow_left = $t === 1 ? "arrow_light" : "arrow_dark";
$p_class_arrow_right = $t === 1 ? "arrow_dark" : "arrow_light";
$p_calendarMonthName = $connector_kalendertage->get_KalenderMonatsname($p_startDate);
$p_calendarTitle = $p_calendarMonthName . " " . date("Y", strtotime($p_startDate));
?>
<div class="calendar_header" style="<?= $p_style ?>" id="calendar_header_<?= $t ?>">
<div class="arrow_item" onclick="switchCalendar('left')">
<div class="<?= $p_class_arrow_left ?>" id="left">
<?php display_button('arrow_left', null, 'left'); ?>
</div>
</div>
<div class="calendar_title"><?= $p_calendarTitle ?></div>
<div class="arrow_item" onclick="switchCalendar('right')">
<div class="<?= $p_class_arrow_right ?>" id="right">
<?php display_button('arrow_right', null, 'right'); ?>
</div>
</div>
<button class="calendar-help-btn" onclick="openCalendarHelp()" aria-label="Hilfe" title="Hilfe">?</button>
</div>
<?php } ?>
<div class="calendar_content">
<table>
<thead>
<tr>
<td class="calendar_head">MO</td>
<td class="calendar_head">DI</td>
<td class="calendar_head">MI</td>
<td class="calendar_head">DO</td>
<td class="calendar_head">FR</td>
<td class="calendar_head_sat">SA</td>
<td class="calendar_head_sun">SO</td>
</tr>
</thead>
<tbody>
<?php
// Zwei Monatsansichten laden
for ($c = 1; $c <= 2; $c++) {
$p_startDate = date("Y-m-d", strtotime($c === 1 ? "first day of this month" : "first day of next month"));
$p_endDate = date("Y-m-d", strtotime($c === 1 ? "last day of this month" : "last day of next month"));
$p_style = $c === 1 ? "visibility:visible" : "visibility:collapse";
$p_calendarStartDate = $connector_kalendertage->get_KalenderStart($p_startDate);
//Kalender: 6 Wochen in Zeilen
for ($i = 0; $i < 42; $i++) {
$datum = date('Y-m-d', strtotime("$p_calendarStartDate +$i days"));
$tag = date('j', strtotime("$p_calendarStartDate +$i days"));
$wochentag = date("w", strtotime("$p_calendarStartDate +$i days"));
$isFeiertagInBerlin = $connector_feiertage->isFeiertagInBerlin($datum);
$feiertagsname = $connector_feiertage->get_feiertagsname($datum);
if ($i % 7 === 0) echo "<tr name='calendar_$c' style='$p_style'>";
$class = 'calendar_day_area';
$style = '';
if ($datum < $p_startDate || $datum > $p_endDate) {
$style = 'filter:brightness(100%);opacity:0.5;';
}
echo "<td class='$class' style='$style'><div class='calendar_day'>";
$Id_cDayItem = $datum >= date("Y-m-d") ? 'id="calendar_day_item" onclick="openDayModal(\'' . $datum . '\')"' : '';
$sql_count = "SELECT COUNT(datum) AS count FROM verfuegbarkeiten WHERE datum=?";
$stmt_count = $pdo->prepare($sql_count);
$count = 0;
if ($stmt_count) {
$stmt_count->execute([$datum]);
$row_count = $stmt_count->fetch();
if ($row_count) {
$count = $row_count['count'];
} else {
echo "Fehler beim Abrufen des Ergebnisses";
}
} else {
echo "Fehler beim Vorbereiten der Anweisung";
}
$sql_user_check = "SELECT user_id FROM verfuegbarkeiten WHERE datum=? AND user_id=?";
$stmt_user_check = $pdo->prepare($sql_user_check);
$userAvailable = false;
if ($stmt_user_check) {
$stmt_user_check->execute([$datum, $_SESSION["user_id"]]);
if ($stmt_user_check->fetch()) {
$userAvailable = true;
}
}
$class = 'calendar_day_item';
$title = '';
if ($datum < date("Y-m-d")) {
$class .= ' past';
} elseif ($count >= 2 && $datum >= date("Y-m-d")) {
$class .= ' available_multiple';
$title = $userAvailable ? "It&acute;s a Match!" : "$count Personen verfügbar";
} elseif ($count == 1 && $datum >= date("Y-m-d")) {
$class .= ' available_single';
$title = 'Eine Person verfügbar';
} elseif ($datum == date("Y-m-d")) {
$class .= ' today';
$title = 'Heute';
} elseif ($isFeiertagInBerlin) {
$class .= ' sunday';
} elseif ($feiertagsname != null) {
$class .= ' localholiday';
$title = 'Regionaler Feiertag';
} elseif ($wochentag == 0) {
$class .= ' sunday';
} elseif ($wochentag == 6) {
$class .= ' saturday';
} else {
$class .= ' normalday';
}
echo "<div $Id_cDayItem class='$class' title='$title'>$tag</div>";
// Feiertagsbezeichnungen im Kalenderblatt ausgeblendet
echo "</div></td>";
if ($i % 7 === 6) echo "</tr>";
}
}
//Schleifenende: Zwei Monatsansichten laden
?>
</tbody>
</table> <!-- END: calendar -->
</div> <!-- END: calendar_content -->
@@ -0,0 +1,28 @@
<?php
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
header('Content-Type: application/json; charset=utf-8');
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'Nicht angemeldet.']);
exit;
}
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
$besuch_id = isset($_POST['besuch_id']) ? (int)$_POST['besuch_id'] : 0;
if ($besuch_id <= 0) {
echo json_encode(['status' => 'error', 'message' => 'Ungültige Besuchs-ID.']);
exit;
}
try {
$stmt = $pdo->prepare("DELETE FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
echo json_encode(['status' => 'success']);
} catch (PDOException $e) {
echo json_encode(['status' => 'error', 'message' => 'Löschen fehlgeschlagen: ' . $e->getMessage()]);
}
@@ -0,0 +1,161 @@
<?php
/* Name: manage_visits.php
Beschreibung: Verwaltung der Seelsorge-Besuchsstellen
- Hinzufügen, Bearbeiten und Löschen von Einträgen
*/
// Initialisierung
require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/general_files/initialise.php';
// Eintrag hinzufügen
if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['add_entry'])) {
$last_name = $_POST['last_name'];
$first_name = $_POST['first_name'];
$birth_date = $_POST['birth_date'];
$address_street = $_POST['address_street'];
$address_plz = $_POST['address_plz'];
$address_link = $_POST['address_link'];
$phone = $_POST['phone'];
$comment = $_POST['comment'];
$letzter_besuch = $_POST['letzter_besuch'];
$priority = $_POST['priority'];
$pr_bezirk = $_POST['pr_bezirk'];
$reservation = $_POST['reservation'];
$sql = "INSERT INTO seelsorge_besuchsstellen (last_name, first_name, birth_date, address_street, address_plz, address_link, phone, comment, letzter_besuch, priority, pr_bezirk, reservation)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$last_name, $first_name, $birth_date, $address_street, $address_plz, $address_link, $phone, $comment, $letzter_besuch, $priority, $pr_bezirk, $reservation])) {
echo "Neuer Eintrag hinzugefügt.";
} else {
echo "Fehler: " . implode(', ', $stmt->errorInfo());
}
}
// Eintrag löschen
if (isset($_GET['delete_id'])) {
$delete_id = $_GET['delete_id'];
$sql = "DELETE FROM seelsorge_besuchsstellen WHERE besuch_id = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$delete_id])) {
echo "Eintrag gelöscht.";
} else {
echo "Fehler beim Löschen des Eintrags: " . implode(', ', $stmt->errorInfo());
}
}
// Daten abrufen
$sql = "SELECT * FROM seelsorge_besuchsstellen";
$result = $pdo->query($sql);
?>
<!DOCTYPE html>
<html lang="de" dir="ltr">
<head>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/html_head.php'; ?>
<script src="/intranet_repo/projects/_central/scripts/seelsorge.js"></script>
<link rel="stylesheet" href="/intranet_repo/projects/_central/layouts/seelsorge.css">
</head>
<body class="theme-purple">
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/header.php'; ?>
<div class="header_title ht_pastoral text_white" id="header_title">
<span class="header_title_text">Besuchsstellen Verwaltung</span>
</div>
<h1>Seelsorge Besuchsstellen Verwaltung</h1>
<!-- Formular zum Hinzufügen eines neuen Eintrags -->
<h2>Neuen Eintrag hinzufügen</h2>
<form method="POST" action="">
<label>Nachname:</label>
<input type="text" name="last_name" required><br>
<label>Vorname:</label>
<input type="text" name="first_name" required><br>
<label>Geburtsdatum:</label>
<input type="date" name="birth_date" required><br>
<label>Straße:</label>
<input type="text" name="address_street" required><br>
<label>PLZ:</label>
<input type="text" name="address_plz" required><br>
<label>Link zur Adresse:</label>
<input type="text" name="address_link"><br>
<label>Telefonnummer:</label>
<input type="number" name="phone"><br>
<label>Kommentar:</label>
<input type="text" name="comment"><br>
<label>Letzter Besuch:</label>
<input type="date" name="letzter_besuch"><br>
<label>Priorität:</label>
<input type="number" name="priority" required><br>
<label>Bezirk:</label>
<input type="text" name="pr_bezirk"><br>
<label>Reservierung:</label>
<input type="number" name="reservation"><br>
<input type="submit" name="add_entry" value="Eintrag hinzufügen">
</form>
<!-- Tabelle der vorhandenen Einträge -->
<h2>Vorhandene Einträge</h2>
<table border="1">
<tr>
<th>ID</th>
<th>Nachname</th>
<th>Vorname</th>
<th>Geburtsdatum</th>
<th>Adresse</th>
<th>PLZ</th>
<th>Link zur Adresse</th>
<th>Telefonnummer</th>
<th>Kommentar</th>
<th>Letzter Besuch</th>
<th>Priorität</th>
<th>Bezirk</th>
<th>Reservierung</th>
<th>Aktionen</th>
</tr>
<?php while ($row = $result->fetch()) { ?>
<tr>
<td><?php echo $row['besuch_id']; ?></td>
<td><?php echo $row['last_name']; ?></td>
<td><?php echo $row['first_name']; ?></td>
<td><?php echo $row['birth_date']; ?></td>
<td><?php echo $row['address_street']; ?></td>
<td><?php echo $row['address_plz']; ?></td>
<td><?php echo $row['address_link']; ?></td>
<td><?php echo $row['phone']; ?></td>
<td><?php echo $row['comment']; ?></td>
<td><?php echo $row['letzter_besuch']; ?></td>
<td><?php echo $row['priority']; ?></td>
<td><?php echo $row['pr_bezirk']; ?></td>
<td><?php echo $row['reservation']; ?></td>
<td>
<a href="manage_visits.php?delete_id=<?php echo $row['besuch_id']; ?>" onclick="return confirm('Eintrag wirklich löschen?');">Löschen</a>
</td>
</tr>
<?php } ?>
</table>
<?php require_once $_SERVER['DOCUMENT_ROOT'].'/intranet_repo/projects/_central/php/footer.php'; ?>
</body>
</html>
<?php
$pdo = null;
?>
@@ -0,0 +1,13 @@
<?php /* Name: menue.php
Beschreibung: Seitenmenü des Seelsorgeplaners */
?>
<div class="menue" id="seelsorge">
<div class="list">
<div class="menu-item unselectable active" data-target="content_calendar">Kalendarium</div>
<div class="menu-item unselectable" data-target="content_visit">Besuchsstellen</div>
<div class="indicator" id="indicator"></div>
</div>
</div>
@@ -0,0 +1,33 @@
<?php
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Get the besuch_id from the GET request
$besuch_id = $_GET['besuch_id'];
// SQL query to update priority to 2
$stmt = $pdo->prepare("UPDATE seelsorge_besuchsstellen SET priority = 2 WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
if ($stmt->rowCount() >= 0) {
// Berechne die Monate seit dem letzten Besuch, um sie in der Antwort zurückzugeben
$stmtQ = $pdo->prepare("SELECT CURRENT_DATE - letzter_besuch AS days_since_last_visit FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmtQ->execute([$besuch_id]);
$row = $stmtQ->fetch();
$monthsSinceLastVisit = floor($row['days_since_last_visit'] / 30);
// Gib die aktualisierten Daten als JSON zurück
echo json_encode([
'status' => 'success',
'priority' => 2,
'months_since_last_visit' => $monthsSinceLastVisit
]);
} else {
// Fehlerbehandlung
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Setzen der Priorität"
]);
}
$pdo = null;
?>
@@ -0,0 +1,38 @@
<?php
/*
Name: content/profile.php
Beschreibung: Popup innerhalb von Kalendertag bzw. Besuchsstellen: Profilanzeige
Zur Verwendung ist die nachfolgende Unterscheidung zu treffen/erweitern
*/
// Unterscheidung zwischen den aufrufenden Seitenbereichen
// --> Name ist außerdem beim Aufruf der JS-Funktion openCloseProfile(id, name, overlay) zu bilden!
// --> Bei einem neuen Seitenbereich ist zusätzlich der Listener (Escape-Taste) zu erweitern!
// --> In overlay_profile.php wird bei Escape-Taste bzw. Klick auf Exit mit id=0 sowie den entsprechenden name und overlay weggeblendet!
if (($isPageVisit ?? false) === true) {
$profile_container_name = "profile_visit";
$profile_overlay_id = "profile_visit_overlay";
$isPageVisit = false;
} elseif (($isPageCalendar ?? false) === true) {
$profile_container_name = "profile_calendar";
$profile_overlay_id = "profile_calendar_overlay";
$isPageCalendar = false;
}
// Statement für alle Profile vorbereiten
$stmt_all_profiles = $pdo->prepare("SELECT * FROM user_general_information");
$stmt_all_profiles->execute();
?>
<div class="standard_overlay" id="<?= $profile_overlay_id ?>"> <!-- Overlay: Profile -->
<div class="bg_blur"></div>
<?php
while ($profile_all = $stmt_all_profiles->fetch()) {
?>
<div class="profile_container" name="<?= $profile_container_name ?>" id="<?= $profile_all['user_id'] ?>">
<?php $_SESSION["profile_id"] = $profile_all['user_id'];
include $g_phpSnippetsPath. "overlay_profile.php"; ?>
</div>
<?php } ?>
</div>
@@ -0,0 +1,48 @@
<?php
session_start();
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Hole die Besuchs-ID aus dem GET-Request
if (isset($_GET['besuch_id']) && is_numeric($_GET['besuch_id'])) {
$besuch_id = (int)$_GET['besuch_id'];
// Adresse laden für Haushalt-Tracking
$stmt = $pdo->prepare("SELECT address_street, address_plz FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
$current = $stmt->fetch();
if ($current) {
// Reservation für alle im Haushalt entfernen
$sql = "UPDATE seelsorge_besuchsstellen SET reservation = NULL WHERE address_street = ? AND address_plz = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$current['address_street'], $current['address_plz']])) {
$stmtH = $pdo->prepare("SELECT besuch_id FROM seelsorge_besuchsstellen WHERE address_street = ? AND address_plz = ?");
$stmtH->execute([$current['address_street'], $current['address_plz']]);
$householdIds = [];
while ($r = $stmtH->fetch()) {
$householdIds[] = (int)$r['besuch_id'];
}
echo json_encode(['status' => 'success', 'household_ids' => $householdIds]);
} else {
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Entfernen der Reservation"
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Eintrag nicht gefunden.'
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Ungültige oder fehlende Besuchs-ID.'
]);
}
$pdo = null;
?>
@@ -0,0 +1,56 @@
<?php
session_start();
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Hole die Besuchs-ID aus dem GET-Request
if (isset($_GET['besuch_id']) && is_numeric($_GET['besuch_id'])) {
$besuch_id = (int)$_GET['besuch_id'];
// Hole die ID des aktuell angemeldeten Benutzers aus der Session
$user_id = $_SESSION['user_id'];
// Adresse laden für Haushalt-Tracking
$stmt = $pdo->prepare("SELECT address_street, address_plz FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
$current = $stmt->fetch();
if ($current) {
// Alle Personen im Haushalt reservieren
$sql = "UPDATE seelsorge_besuchsstellen SET reservation = ? WHERE address_street = ? AND address_plz = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$user_id, $current['address_street'], $current['address_plz']])) {
// Alle betroffenen IDs zurückgeben
$stmtH = $pdo->prepare("SELECT besuch_id FROM seelsorge_besuchsstellen WHERE address_street = ? AND address_plz = ?");
$stmtH->execute([$current['address_street'], $current['address_plz']]);
$householdIds = [];
while ($r = $stmtH->fetch()) {
$householdIds[] = (int)$r['besuch_id'];
}
echo json_encode([
'status' => 'success',
'reservation_user_id' => $user_id,
'household_ids' => $householdIds
]);
} else {
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Setzen der Reservation"
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Eintrag nicht gefunden.'
]);
}
} else {
echo json_encode([
'status' => 'error',
'message' => 'Ungültige oder fehlende Besuchs-ID.'
]);
}
$pdo = null;
?>
@@ -0,0 +1,24 @@
<?php
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Überprüfen, ob die erforderlichen Parameter übergeben wurden
if (isset($_GET['besuch_id']) && isset($_GET['comment'])) {
$besuch_id = $_GET['besuch_id'];
$comment = $_GET['comment'];
// SQL-Update-Statement vorbereiten und ausführen
$stmt = $pdo->prepare("UPDATE seelsorge_besuchsstellen SET comment = ? WHERE besuch_id = ?");
if ($stmt->execute([$comment, $besuch_id])) {
// Erfolgreich aktualisiert
echo "Hinweis erfolgreich aktualisiert";
} else {
// Fehler beim Aktualisieren
echo "Fehler beim Aktualisieren des Hinweises";
}
} else {
// Fehler: Fehlende Parameter
echo "Fehler: Nicht alle erforderlichen Parameter wurden übergeben";
}
$pdo = null;
?>
@@ -0,0 +1,57 @@
<?php
session_start();
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
// Get the besuch_id from the GET request
$besuch_id = (int)($_GET['besuch_id'] ?? 0);
if ($besuch_id <= 0) {
echo json_encode(['status' => 'error', 'message' => 'Ungültige Besuchs-ID.']);
exit;
}
// Adresse der aktuellen Besuchsstelle laden
$stmt = $pdo->prepare("SELECT address_street, address_plz FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmt->execute([$besuch_id]);
$current = $stmt->fetch();
if (!$current) {
echo json_encode(['status' => 'error', 'message' => 'Eintrag nicht gefunden.']);
exit;
}
// Alle Personen im gleichen Haushalt (gleiche Adresse) aktualisieren
$sql = "UPDATE seelsorge_besuchsstellen SET letzter_besuch = CURRENT_DATE, priority = 0 WHERE address_street = ? AND address_plz = ?";
$stmt = $pdo->prepare($sql);
if ($stmt->execute([$current['address_street'], $current['address_plz']])) {
// Monate seit letztem Besuch berechnen (für den angefragten Eintrag)
$query = "SELECT CURRENT_DATE - letzter_besuch AS days_since_last_visit FROM seelsorge_besuchsstellen WHERE besuch_id = ?";
$stmtQ = $pdo->prepare($query);
$stmtQ->execute([$besuch_id]);
$row = $stmtQ->fetch();
$monthsSinceLastVisit = floor(($row['days_since_last_visit'] ?? 0) / 30);
// Alle IDs im Haushalt zurückgeben für Frontend-Aktualisierung
$stmtH = $pdo->prepare("SELECT besuch_id FROM seelsorge_besuchsstellen WHERE address_street = ? AND address_plz = ?");
$stmtH->execute([$current['address_street'], $current['address_plz']]);
$householdIds = [];
while ($r = $stmtH->fetch()) {
$householdIds[] = (int)$r['besuch_id'];
}
echo json_encode([
'status' => 'success',
'last_visit' => date('Y-m-d'),
'months_since_last_visit' => $monthsSinceLastVisit,
'household_ids' => $householdIds
]);
} else {
echo json_encode([
'status' => 'error',
'message' => "Fehler beim Aktualisieren des Besuchsdatums"
]);
}
$pdo = null;
?>
@@ -0,0 +1,132 @@
<?php
header('Content-Type: application/json; charset=utf-8');
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
try {
if (!isset($_SESSION['user_id'])) {
http_response_code(401);
echo json_encode(['status' => 'error', 'message' => 'Nicht angemeldet.'], JSON_UNESCAPED_UNICODE);
exit;
}
$pdo = require($_SERVER['DOCUMENT_ROOT']."/intranet_repo/general_files/ini/database.php");
$besuch_id = isset($_POST['besuch_id']) ? (int)$_POST['besuch_id'] : 0;
$last_name = trim($_POST['last_name'] ?? '');
$first_name = trim($_POST['first_name'] ?? '');
$birth_date = trim($_POST['birth_date'] ?? '');
$address_street = trim($_POST['address_street'] ?? '');
$address_plz = trim($_POST['address_plz'] ?? '');
$address_link = trim($_POST['address_link'] ?? '');
$phone_raw = trim($_POST['phone'] ?? '');
$comment = trim($_POST['comment'] ?? '');
$letzter_besuch = trim($_POST['letzter_besuch'] ?? '');
$priority = isset($_POST['priority']) ? (int)$_POST['priority'] : 0;
$pr_bezirk_raw = trim($_POST['pr_bezirk'] ?? '');
// einfache Validierung
if ($besuch_id <= 0 || $last_name === '' || $first_name === '' || $birth_date === '' || $address_street === '' || $address_plz === '') {
http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Pflichtfelder fehlen.'], JSON_UNESCAPED_UNICODE);
exit;
}
// Telefon: nur Ziffern
$phone = preg_replace('/\D+/', '', $phone_raw);
if ($phone === '') $phone = null; // phone darf NULL sein
// NOT NULL Spalten: niemals NULL senden
if ($address_link === '') $address_link = '';
if ($comment === '') $comment = '';
if ($letzter_besuch === '') $letzter_besuch = "2024-07-11";
if ($pr_bezirk_raw === '') $pr_bezirk_raw = '';
// Alten Eintrag laden, um Änderungen zu erkennen
$stmtOld = $pdo->prepare("SELECT last_name, first_name, birth_date, address_street, address_plz, address_link, phone, comment, letzter_besuch, priority, pr_bezirk FROM seelsorge_besuchsstellen WHERE besuch_id = ?");
$stmtOld->execute([$besuch_id]);
$oldEntry = $stmtOld->fetch();
$sql = "UPDATE seelsorge_besuchsstellen
SET last_name = ?, first_name = ?, birth_date = ?, address_street = ?, address_plz = ?,
address_link = ?, phone = ?, comment = ?, letzter_besuch = ?, priority = ?, pr_bezirk = ?
WHERE besuch_id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([
$last_name,
$first_name,
$birth_date,
$address_street,
$address_plz,
$address_link,
$phone,
$comment,
$letzter_besuch,
$priority,
$pr_bezirk_raw,
$besuch_id
]);
// Vermerk in erledigte Tasks wenn sich irgendein Feld geändert hat
if ($oldEntry) {
$newValues = [
'last_name' => $last_name,
'first_name' => $first_name,
'birth_date' => $birth_date,
'address_street' => $address_street,
'address_plz' => $address_plz,
'address_link' => $address_link,
'phone' => $phone,
'comment' => $comment,
'letzter_besuch' => $letzter_besuch,
'priority' => $priority,
'pr_bezirk' => $pr_bezirk_raw,
];
$fieldLabels = [
'last_name' => 'Nachname',
'first_name' => 'Vorname',
'birth_date' => 'Geburtsdatum',
'address_street' => 'Adresse',
'address_plz' => 'PLZ/Ort',
'address_link' => 'Karten-Link',
'phone' => 'Telefon',
'comment' => 'Kommentar',
'letzter_besuch' => 'Letzter Besuch',
'priority' => 'Priorität',
'pr_bezirk' => 'Priester-Bezirk',
];
$changedFields = [];
foreach ($newValues as $key => $newVal) {
$oldVal = $oldEntry[$key] ?? '';
if ((string)$oldVal !== (string)$newVal) {
$changedFields[] = $fieldLabels[$key];
}
}
if (!empty($changedFields)) {
$personName = ($oldEntry['last_name'] ?? $last_name) . ", " . ($oldEntry['first_name'] ?? $first_name);
$changedList = implode(', ', $changedFields);
$taskSubject = "Besuchsstelle geändert: {$personName}";
$taskMessage = "Besuchsstelle #{$besuch_id} ({$personName}) wurde geändert. Geänderte Felder: {$changedList}.";
$senderName = "Seelsorgeplaner";
$stmtLog = $pdo->prepare("INSERT INTO admin_messages (type, sender_name, sender_email, subject, message, status, processed_at, created_at) VALUES ('system', ?, '', ?, ?, 'done', NOW(), NOW())");
$stmtLog->execute([$senderName, $taskSubject, $taskMessage]);
}
}
echo json_encode(['status' => 'success', 'besuch_id' => $besuch_id], JSON_UNESCAPED_UNICODE);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'DB-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
} catch (Throwable $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => 'Server-Fehler: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
}
File diff suppressed because it is too large Load Diff