Add facilities, contracts, orders, value lists, audit log, and desktop app modules

Extends omsorgCore with full CRUD for Facility/Contract/Order plus
configurable value lists and an audit trail, and wires the omsorgapp
frontend up to the new facilities, settings, and audit-log modules;
includes a sidebar active-nav-item highlight.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Felix Kemmler
2026-08-08 23:29:16 +02:00
co-authored by Claude Sonnet 5
parent ee74ed65f5
commit e9e96a57dc
528 changed files with 96814 additions and 456 deletions
@@ -0,0 +1,77 @@
<?php
require_once __DIR__ . '/../lib/auth.php';
require_once __DIR__ . '/../lib/layout.php';
require_login();
$forced = isset($_GET['forced']);
$error = '';
$policy = omsorgcore_password_policy(_omsorgcore_config());
$minLength = $policy['ok'] ? (int) $policy['data']['minLength'] : 8;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
verify_csrf();
$current = $_POST['current_password'] ?? '';
$new = $_POST['new_password'] ?? '';
$repeat = $_POST['new_password_repeat'] ?? '';
if (strlen($new) < $minLength) {
$error = "Das neue Passwort muss mindestens {$minLength} Zeichen lang sein.";
} elseif ($new !== $repeat) {
$error = 'Die Passwörter stimmen nicht überein.';
} else {
$result = omsorgcore_change_password(_omsorgcore_config(), $_SESSION['omsorgcore_access_token'], $current, $new);
if ($result['ok']) {
// Erfolgreicher Wechsel widerruft serverseitig alle Sessions (siehe
// UserService.ChangeOwnPasswordAsync) - lokal ausloggen statt weiterzumachen.
$_SESSION = [];
if (ini_get('session.use_cookies')) {
$p = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000, $p['path'], $p['domain'], $p['secure'], $p['httponly']);
}
session_destroy();
header('Location: ../index.php?pwchanged=1');
exit;
}
$error = $result['status'] === 401
? 'Aktuelles Passwort ist falsch.'
: (is_string($result['data'] ?? null) ? $result['data'] : 'Passwort konnte nicht geändert werden.');
}
}
layout_start('Einstellungen Mitarbeiter-App', 'settings');
?>
<h1 class="main-title">Einstellungen</h1>
<?php if ($forced): ?>
<p class="hint" style="margin:0 0 22px">Für diesen Account wurde ein initiales Passwort vergeben. Bitte lege jetzt dein eigenes Passwort fest, bevor du weiterarbeiten kannst.</p>
<?php endif; ?>
<div class="glass" style="max-width:420px;padding:24px">
<h2 style="font-family:'KindelSerif',Georgia,serif;font-size:1.3rem;margin:0 0 18px">Passwort ändern</h2>
<?php if ($error): ?>
<div class="error" style="margin-bottom:16px"><?= e($error) ?></div>
<?php endif; ?>
<form method="post">
<?= csrf_field() ?>
<label>
Aktuelles Passwort
<input type="password" name="current_password" autocomplete="current-password" required autofocus>
</label>
<label>
Neues Passwort
<input type="password" name="new_password" autocomplete="new-password" required minlength="<?= (int) $minLength ?>">
</label>
<label>
Neues Passwort wiederholen
<input type="password" name="new_password_repeat" autocomplete="new-password" required minlength="<?= (int) $minLength ?>">
</label>
<button type="submit" class="btn" style="width:100%;margin-top:6px">Passwort ändern</button>
</form>
</div>
<?php
layout_end();