| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /proc/3951573/root/tmp/ |
Upload File : |
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="favicon.ico">
<title>Buchungssystem - Parken-am-Schiff.de</title>
<!-- Theme vor dem Paint setzen (kein FOUC) -->
<script>(function(){try{var t=localStorage.getItem('pacim:theme');if(t){document.documentElement.setAttribute('data-theme',t);}}catch(e){}})();</script>
<!-- Fonts: Inter (Gentelella v4) -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<!-- Bootstrap 5 (Content-Komponenten) + Plugins -->
<link href="https://seaside.pacim.de/assets/css/bootstrap.min.css" rel="stylesheet">
<link href="https://seaside.pacim.de/assets/css/fonts/material-icon-font.css" rel="stylesheet">
<link href="https://seaside.pacim.de/assets/css/plugins/quill.snow.min.css" rel="stylesheet">
<link href="https://seaside.pacim.de/assets/css/plugins/choices.min.css" rel="stylesheet">
<link href="https://seaside.pacim.de/assets/css/styles.css" rel="stylesheet">
<!-- Gentelella v4 Shell + Akzente (zuletzt, überschreibt) -->
<link href="https://seaside.pacim.de/assets/css/gentelella.css?v=1780513076" rel="stylesheet">
<link href="https://seaside.pacim.de/assets/css/gentelella-accents.css?v=1780439034" rel="stylesheet">
<link href="https://seaside.pacim.de/assets/css/search.css?v=1780917534" rel="stylesheet">
<!-- Favicon -->
<link rel="apple-touch-icon" sizes="57x57" href="https://seaside.pacim.de/assets/favico/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="76x76" href="https://seaside.pacim.de/assets/favico/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="120x120" href="https://seaside.pacim.de/assets/favico/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="152x152" href="https://seaside.pacim.de/assets/favico/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="https://seaside.pacim.de/assets/favico/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="32x32" href="https://seaside.pacim.de/assets/favico/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="https://seaside.pacim.de/assets/favico/favicon-16x16.png">
<link rel="manifest" href="https://seaside.pacim.de/assets/favico/manifest.json">
<meta name="theme-color" content="#ffffff">
</head>
<body data-page="pacim/system">
<a class="skip-link" href="#main-content">Zum Inhalt springen</a>
<style>
.nav-link .nav-count{ margin-left:auto; background:var(--red,#d63939); color:#fff; font-size:11px; font-weight:600; line-height:1; padding:3px 7px; border-radius:999px; min-width:18px; text-align:center; }
.nav-link .nav-count.nav-count-warn{ background:var(--yellow,#f59f00); color:#fff; }
</style>
<aside class="sidebar" id="sidebar" aria-label="Hauptnavigation">
<div class="sidebar-brand">
<a class="brand-link" href="https://seaside.pacim.de/" aria-label="Zum Cockpit">
<div class="brand-icon">P</div>
<div class="brand-name">PaCIM <small>v4</small></div>
</a>
</div>
<nav class="sidebar-nav">
<div class="nav-group">
<div class="nav-label">Übersicht</div>
<a class="nav-link" href="https://seaside.pacim.de/">
<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="3" width="7" height="7" rx="1.5"/><rect x="14" y="3" width="7" height="4" rx="1.5"/><rect x="3" y="14" width="7" height="7" rx="1.5"/><rect x="14" y="10" width="7" height="11" rx="1.5"/></svg>
<span class="nav-text">Cockpit</span>
</a>
<a class="nav-link" href="https://seaside.pacim.de/tasks/dashboard/">
<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="4" width="18" height="16" rx="2"/><path d="M3 10h18M8 4v6M16 4v6"/></svg>
<span class="nav-text">Kalender</span>
</a>
<a class="nav-link" href="https://seaside.pacim.de/events/">
<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M16 3v4M8 3v4M3 11h18M8 15h.01M12 15h.01M16 15h.01"/></svg>
<span class="nav-text">Events</span>
</a>
<a class="nav-link" href="https://seaside.pacim.de/requests/">
<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>
<span class="nav-text">Anfragen</span>
</a>
</div>
<div class="nav-group">
<div class="nav-label">Reports</div>
<a class="nav-link" href="https://seaside.pacim.de/accounting/dashboard/">
<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M5 21V3h14v18l-3-2-3 2-3-2-3 2-2-2z"/><path d="M9 8h6M9 12h6M9 16h4"/></svg>
<span class="nav-text">Buchhaltung</span>
</a>
<a class="nav-link" href="https://seaside.pacim.de/reports/yearly/">
<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M4 19V5M8 19v-8M12 19V9M16 19v-5M20 19v-9"/></svg>
<span class="nav-text">Buchungen nach Jahren</span>
</a>
<div class="nav-tree">
<button type="button" class="nav-link nav-toggle" aria-expanded="false">
<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
<span class="nav-text">Zeiterfassung</span>
<svg class="nav-chev" width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M6 4l4 4-4 4"/></svg>
</button>
<div class="nav-sub"><div class="nav-sub-inner">
<a class="nav-sublink" href="https://seaside.pacim.de/worktime/dashboard/">Übersicht</a>
<a class="nav-sublink" href="https://seaside.pacim.de/worktime/employees/">Mitarbeiter</a>
<a class="nav-sublink" href="https://seaside.pacim.de/worktime/create/">Zeitnachweise</a>
</div></div>
</div>
</div>
<div class="nav-group">
<div class="nav-label">System</div>
<a class="nav-link" href="https://seaside.pacim.de/mailing/">
<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 6 9-6"/></svg>
<span class="nav-text">Mailing</span>
</a>
<a class="nav-link" href="https://seaside.pacim.de/partner/">
<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M17 20v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 20v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75"/></svg>
<span class="nav-text">Partnerprogramm</span>
</a>
<div class="nav-tree open has-active">
<button type="button" class="nav-link nav-toggle" aria-expanded="true">
<svg class="icon" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="12" cy="12" r="3"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1"/></svg>
<span class="nav-text">Einstellungen</span>
<svg class="nav-chev" width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M6 4l4 4-4 4"/></svg>
</button>
<div class="nav-sub"><div class="nav-sub-inner">
<a class="nav-sublink active" href="https://seaside.pacim.de/pacim/system/">System</a>
<a class="nav-sublink" href="https://seaside.pacim.de/pacim/products/">Produkte</a>
<a class="nav-sublink" href="https://seaside.pacim.de/imports/manager/">Import-Manager</a>
<a class="nav-sublink" href="https://seaside.pacim.de/pacim/debug/">Debug</a>
</div></div>
</div>
</div>
</nav>
<div class="sidebar-footer">
<div class="sidebar-user">
<div class="avatar">P<span class="online"></span></div>
<div class="sidebar-user-info">
<div class="name">Daniel Großklags</div>
<div class="role">Administrator</div>
</div>
</div>
</div>
</aside>
<main class="main">
<header class="topbar">
<div class="topbar-left">
<button class="sidebar-toggle" type="button" aria-label="Menü umschalten" aria-controls="sidebar" aria-expanded="false">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M4 6h16M4 12h16M4 18h16"/></svg>
</button>
<nav class="breadcrumb" aria-label="Breadcrumb"><span>PaCIM</span><span class="sep" aria-hidden="true">›</span><span class="current" aria-current="page">pacim/system</span></nav>
</div>
<div class="search-box" id="global-search">
<svg class="s-icon" width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="7" cy="7" r="5"/><path d="M11 11l3.5 3.5"/></svg>
<input type="text" id="searchform" placeholder="Suche: Kunde, Buchung, Kennzeichen …" aria-label="Suche" autocomplete="off" role="combobox" aria-expanded="false" aria-controls="search-overlay" aria-autocomplete="list">
<div class="search-overlay" id="search-overlay" role="listbox" hidden></div>
</div>
<div class="topbar-right">
<button class="tb-btn theme-toggle" type="button" title="Design umschalten" aria-label="Design umschalten" aria-pressed="false">
<svg class="theme-icon-light" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/></svg>
<svg class="theme-icon-dark" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
</button>
<a class="tb-btn" href="https://seaside.pacim.de/logout.php" title="Abmelden" aria-label="Abmelden">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M9 21H5a2 2 0 01-2-2V5a2 2 0 012-2h4"/><path d="M16 17l5-5-5-5M21 12H9"/></svg>
</a>
<div class="dropdown">
<button class="tb-avatar" type="button" id="userMenu" data-bs-toggle="dropdown" aria-expanded="false" title="Benutzerkonto" aria-label="Benutzerkonto">DA</button>
<ul class="dropdown-menu dropdown-menu-end shadow-sm" aria-labelledby="userMenu">
<li><h6 class="dropdown-header text-truncate">Daniel Großklags</h6></li>
<li><a class="dropdown-item d-flex align-items-center gap-2" href="https://seaside.pacim.de/pacim/system/"><i class="material-icons sm">settings</i> Einstellungen</a></li> <li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item d-flex align-items-center gap-2 text-danger" href="https://seaside.pacim.de/logout.php"><i class="material-icons sm">logout</i> Abmelden</a></li>
</ul>
</div>
</div>
</header>
<div class="page-wrapper" id="main-content" role="main">
<link rel="stylesheet" href="https://seaside.pacim.de/assets/css/cockpit.css?v=1780917736">
<div class="page-header">
<div class="page-header-row d-flex justify-content-between align-items-center flex-wrap gap-2">
<div>
<div class="stat-label">PaCIM System</div>
<h1 class="h3 mb-0">Einstellungen</h1>
</div>
</div>
</div>
<ul class="nav nav-tabs mb-3" role="tablist">
<li class="nav-item"><button class="nav-link active" data-bs-toggle="tab" data-bs-target="#set-overview" type="button" role="tab">Übersicht</button></li>
<li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#set-company" type="button" role="tab">Unternehmen</button></li>
<li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#set-accounting" type="button" role="tab">Buchhaltung</button></li>
<li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#set-sources" type="button" role="tab">Buchungsquellen</button></li>
<li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#set-mail" type="button" role="tab">E-Mail</button></li>
<li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#set-api" type="button" role="tab">API</button></li>
<li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#set-users" type="button" role="tab">Benutzer</button></li>
</ul>
<div class="tab-content">
<div class="tab-pane fade show active" id="set-overview" role="tabpanel">
<form id="overview-settings-form" autocomplete="off" style="max-width:560px;">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span class="fw-bold">Benachrichtigungen (Pushover)</span>
<button type="submit" class="btn btn-sm btn-primary"><i class="material-icons sm">save</i> Speichern</button>
</div>
<div class="card-body">
<label class="form-label">Pushover App-Token <span class="text-muted">(systemweit)</span></label>
<input type="text" class="form-control" id="set-pushover-app" name="pushover_app_token" autocomplete="off" placeholder="leer lassen = unverändert">
<div class="form-text">
Gilt für alle Benutzer. Einmal in <a href="https://pushover.net/apps/build" target="_blank" rel="noopener">Pushover</a> eine Anwendung anlegen und den API-Token hier eintragen.
Den persönlichen User-Key und die gewünschten Benachrichtigungen legt jeder Benutzer selbst fest (Reiter <em>Benutzer</em> → bearbeiten → <em>Benachrichtigungen</em>).
<span id="set-pushover-app-state" class="fw-semibold"></span>
</div>
<div id="set-overview-msg" class="small mt-2"></div>
</div>
</div>
</form>
</div>
<div class="tab-pane fade" id="set-company" role="tabpanel">
<form id="company-form" autocomplete="off">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span class="fw-bold">Unternehmensdaten</span>
<button type="submit" class="btn btn-sm btn-primary"><i class="material-icons sm">save</i> Speichern</button>
</div>
<div class="card-body">
<p class="text-muted small">Diese Angaben erscheinen als Absender/Kontakt und in der Fußzeile auf <strong>Rechnungen</strong> und <strong>Buchungsbestätigungen</strong>.</p>
<div class="row g-3">
<div class="col-md-8">
<label class="form-label">Firmenname</label>
<input type="text" class="form-control" id="co-name" name="name">
</div>
<div class="col-md-4">
<label class="form-label">Zusatz / Rechtsform</label>
<input type="text" class="form-control" id="co-suffix" name="suffix" placeholder="z. B. & Co. KG">
</div>
<div class="col-md-8">
<label class="form-label">Straße & Hausnummer</label>
<input type="text" class="form-control" id="co-street" name="street" autocomplete="off" data-addr-street data-addr-zip="#co-zip" data-addr-city="#co-city">
</div>
<div class="col-md-2">
<label class="form-label">PLZ</label>
<input type="text" class="form-control" id="co-zip" name="zip">
</div>
<div class="col-md-2">
<label class="form-label">Ort</label>
<input type="text" class="form-control" id="co-city" name="city">
</div>
<div class="col-md-4">
<label class="form-label">Telefon</label>
<input type="text" class="form-control" id="co-phone" name="phone">
</div>
<div class="col-md-4">
<label class="form-label">E-Mail</label>
<input type="email" class="form-control" id="co-email" name="email">
</div>
<div class="col-md-4">
<label class="form-label">Website</label>
<input type="text" class="form-control" id="co-web" name="web">
</div>
</div>
</div>
</div>
<div class="card mt-3">
<div class="card-header fw-bold">Rechtliche Angaben & Bankverbindung</div>
<div class="card-body">
<div class="row g-4">
<div class="col-md-4">
<div class="text-muted text-uppercase small fw-bold mb-2">Gerichtsstand</div>
<div class="mb-2"><label class="form-label">Amtsgericht</label><input type="text" class="form-control" id="co-court" name="court"></div>
<div class="mb-2"><label class="form-label">Handelsregister</label><input type="text" class="form-control" id="co-hra" name="hra" placeholder="z. B. HRA 3768"></div>
<div><label class="form-label">Steuer-Nr.</label><input type="text" class="form-control" id="co-taxnr" name="taxnr"></div>
</div>
<div class="col-md-4">
<div class="text-muted text-uppercase small fw-bold mb-2">Persönlich haftender Gesellschafter</div>
<div class="mb-2"><label class="form-label">Name</label><input type="text" class="form-control" id="co-partner_name" name="partner_name"></div>
<div class="mb-2"><label class="form-label">Anschrift</label><input type="text" class="form-control" id="co-partner_addr" name="partner_addr"></div>
<div><label class="form-label">Geschäftsführer</label><input type="text" class="form-control" id="co-ceo" name="ceo"></div>
</div>
<div class="col-md-4">
<div class="text-muted text-uppercase small fw-bold mb-2">Bankverbindung</div>
<div class="mb-2"><label class="form-label">Bank</label><input type="text" class="form-control" id="co-bank_name" name="bank_name"></div>
<div class="mb-2"><label class="form-label">IBAN</label><input type="text" class="form-control" id="co-iban" name="iban"></div>
<div><label class="form-label">SWIFT/BIC</label><input type="text" class="form-control" id="co-bic" name="bic"></div>
</div>
</div>
<div class="small mt-3" id="co-status"></div>
</div>
</div>
</form>
</div>
<div class="tab-pane fade" id="set-accounting" role="tabpanel">
<form id="accounting-settings-form" autocomplete="off">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span class="fw-bold">Google Drive – Buchhaltung</span>
<button type="submit" class="btn btn-sm btn-primary"><i class="material-icons sm">save</i> Speichern</button>
</div>
<div class="card-body">
<div class="mb-3" style="max-width:560px;">
<label class="form-label">Google-Drive-Zielordner (Ordner-ID)</label>
<input type="text" class="form-control" id="set-gdrive-folder" name="gdrive_accounting_folder" placeholder="z. B. 1WwoH_3YU20LSrQEcGK_cGWm46RfNjlq1">
<div class="form-text">In diesen Ordner werden die Monatsabrechnungen (Rechnungen + Excel) übertragen. Die Ordner-ID findest du in der Google-Drive-URL (…/folders/<strong>ID</strong>).</div>
</div>
<div id="set-accounting-msg" class="small"></div>
</div>
</div>
</form>
</div>
<div class="tab-pane fade" id="set-sources" role="tabpanel">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<span class="fw-bold">Buchungsquellen</span>
<button class="btn btn-sm btn-primary" id="srcAddBtn"><i class="material-icons sm">add</i> Quelle hinzufügen</button>
</div>
<div class="card-body">
<div class="text-muted small mb-2">Die Quelle (<code>customer_source</code>) kennzeichnet die Herkunft einer Buchung. Feste Quellen sind nicht löschbar. Partner-/Reisebüro-Buchungen werden automatisch mit der Quelle <strong>partner</strong> erfasst.</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead><tr><th>Bezeichnung</th><th>Wert</th><th>Typ</th><th class="text-end">Kunden</th><th></th></tr></thead>
<tbody id="srcBody"><tr><td colspan="5" class="text-center text-muted py-3">Wird geladen …</td></tr></tbody>
</table>
</div>
<div id="srcOther" class="small text-muted mt-2"></div>
<div id="srcMsg" class="small mt-2"></div>
</div>
</div>
</div>
<div class="tab-pane fade" id="set-mail" role="tabpanel">
<form id="mailSettingsForm" autocomplete="off">
<input type="hidden" name="smtpform" value="1">
<div class="card mb-3">
<div class="card-header d-flex justify-content-between align-items-center">
<span class="fw-bold">SMTP-Versand (PHPMailer)</span>
<button type="submit" class="btn btn-sm btn-primary"><i class="material-icons sm">save</i> Speichern</button>
</div>
<div class="card-body">
<div class="alert alert-info small">Versandweg: <strong>Extern</strong> = bisheriger Versand bleibt aktiv. <strong>SMTP (lokal)</strong> = PaCIM versendet selbst. Erst nach Umschalten auf SMTP wird der lokale Versand produktiv genutzt.</div>
<div class="row g-3">
<div class="col-12 col-md-4"><label class="form-label">Versandweg</label>
<select class="form-select" name="transport" id="ms-transport">
<option value="external">Extern (bisheriger Versand)</option>
<option value="smtp">SMTP lokal (PHPMailer)</option>
</select>
</div>
<div class="col-12 col-md-5"><label class="form-label">SMTP-Host</label><input class="form-control" name="host" id="ms-host"></div>
<div class="col-6 col-md-3"><label class="form-label">Port</label><input class="form-control" type="number" name="port" id="ms-port"></div>
<div class="col-6 col-md-3"><label class="form-label">Verschlüsselung</label>
<select class="form-select" name="secure" id="ms-secure"><option value="">keine</option><option value="tls">TLS (STARTTLS)</option><option value="ssl">SSL</option></select>
</div>
<div class="col-6 col-md-3 d-flex align-items-end"><label class="form-check d-flex align-items-center gap-2"><input class="form-check-input" type="checkbox" name="auth" id="ms-auth" value="1"> <span>Authentifizierung</span></label></div>
<div class="col-12 col-md-6"><label class="form-label">Benutzer</label><input class="form-control" name="user" id="ms-user" autocomplete="off"></div>
<div class="col-12 col-md-6"><label class="form-label">Passwort</label><input class="form-control" type="password" name="pass" id="ms-pass" autocomplete="new-password" placeholder="•••••• (leer = unverändert)"></div>
<div class="col-12 col-md-6"><label class="form-label">Absender-Adresse</label><input class="form-control" type="email" name="from_email" id="ms-from-email"></div>
<div class="col-12 col-md-6"><label class="form-label">Absender-Name</label><input class="form-control" name="from_name" id="ms-from-name"></div>
</div>
<hr>
<div class="d-flex flex-wrap align-items-center gap-2">
<button type="button" class="btn btn-light border" id="ms-test-connect"><i class="material-icons sm">wifi_tethering</i> Verbindung testen</button>
<input class="form-control" style="max-width:260px;" type="email" id="ms-test-to" placeholder="Testmail an …">
<button type="button" class="btn btn-light border" id="ms-test-mail"><i class="material-icons sm">send</i> Testmail senden</button>
<span class="small ms-2" id="ms-test-status"></span>
</div>
<div class="js-status small mt-2" id="ms-status"></div>
<div class="text-muted small mt-2">Universeller Header & Footer sowie Navigations-Links werden im Bereich <a href="https://seaside.pacim.de/mailing/">Mailing → Einstellungen</a> gepflegt.</div>
</div>
</div>
</form>
</div>
<div class="tab-pane fade" id="set-api" role="tabpanel">
<div class="card mb-3">
<div class="card-header d-flex justify-content-between align-items-center">
<span class="fw-bold">API-Schlüssel</span>
<span class="d-flex gap-2">
<a class="btn btn-sm btn-outline-secondary" href="https://seaside.pacim.de/api-docs.php" target="_blank" rel="noopener"><i class="material-icons sm">description</i> Dokumentation</a>
<button class="btn btn-sm btn-primary" id="akAddBtn"><i class="material-icons sm">add</i> Schlüssel anlegen</button>
</span>
</div>
<div class="card-body">
<div class="text-muted small mb-2">
Schlüssel für den externen Zugriff auf die API. Basis-URL: <code id="akBaseUrl">…/api.php</code>.
Authentifizierung per Header <code>Authorization: Bearer <Schlüssel></code>. Der Klartext-Schlüssel wird nur einmal bei der Erstellung angezeigt.
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead><tr><th>Name</th><th>Schlüssel</th><th>Berechtigungen</th><th>Status</th><th>Zuletzt genutzt</th><th class="text-end">Aktion</th></tr></thead>
<tbody id="akBody"><tr><td colspan="6" class="text-center text-muted py-4">Wird geladen …</td></tr></tbody>
</table>
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-header d-flex justify-content-between align-items-center flex-wrap gap-2">
<span class="fw-bold">Zugriffsprotokoll</span>
<span class="d-flex gap-2 align-items-center flex-wrap">
<div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-light border alog-filter active" data-kind="all">Alle <span class="badge bg-secondary ms-1" id="alogCAll">0</span></button>
<button type="button" class="btn btn-light border alog-filter" data-kind="write">Änderungen <span class="badge bg-primary ms-1" id="alogCWrite">0</span></button>
<button type="button" class="btn btn-light border alog-filter" data-kind="read">Zugriffe <span class="badge bg-secondary ms-1" id="alogCRead">0</span></button>
</div>
<div class="input-group input-group-sm" style="max-width:220px;">
<span class="input-group-text"><i class="material-icons sm">search</i></span>
<input type="text" class="form-control" id="alogSearch" placeholder="Aktion / Quelle / IP …">
</div>
</span>
</div>
<div class="card-body p-0">
<div class="text-muted small px-3 pt-2">Vollständiges Protokoll der API-Zugriffe: <em>was wurde abgefragt</em> und <em>was wurde geändert</em>. Feldgenaue Vorher/Nachher-Werte und die Rückgängig-Funktion stehen je Buchung im Tab <strong>Historie</strong> der Buchungsansicht.</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead><tr><th>Zeit</th><th>Quelle</th><th>Aktion</th><th>Ziel</th><th>Status</th><th class="text-end">Buchung</th></tr></thead>
<tbody id="alogBody"><tr><td colspan="6" class="text-center text-muted py-4">Wird geladen …</td></tr></tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="akModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header"><h5 class="modal-title">API-Schlüssel anlegen</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
<form id="akForm" autocomplete="off">
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Name *</label>
<input class="form-control" id="akName" required placeholder="z. B. Reisebüro-Schnittstelle">
</div>
<label class="form-label">Berechtigungen *</label>
<div id="akScopes" class="d-flex flex-column gap-2"></div>
<div class="js-status small mt-2" id="akFormMsg"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Abbrechen</button>
<button class="btn btn-primary" type="submit"><i class="material-icons sm">vpn_key</i> Schlüssel erzeugen</button>
</div>
</form>
</div>
</div>
</div>
<div class="modal fade" id="akEditModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header"><h5 class="modal-title">Berechtigungen bearbeiten</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
<form id="akEditForm" autocomplete="off">
<div class="modal-body">
<input type="hidden" id="akEditId">
<div class="mb-3">
<label class="form-label">Name *</label>
<input class="form-control" id="akEditName" required>
</div>
<label class="form-label">Berechtigungen *</label>
<div id="akEditScopes" class="d-flex flex-column gap-2"></div>
<div class="js-status small mt-2" id="akEditMsg"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Abbrechen</button>
<button class="btn btn-primary" type="submit"><i class="material-icons sm">save</i> Speichern</button>
</div>
</form>
</div>
</div>
</div>
<div class="modal fade" id="akShowModal" tabindex="-1" aria-hidden="true" data-bs-backdrop="static">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header"><h5 class="modal-title"><i class="material-icons sm align-middle me-1">vpn_key</i> Schlüssel erstellt</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
<div class="modal-body">
<div class="alert alert-warning small mb-2"><strong>Jetzt kopieren!</strong> Dieser Schlüssel wird aus Sicherheitsgründen nur dieses eine Mal angezeigt.</div>
<div class="input-group">
<input class="form-control font-monospace" id="akNewKey" readonly>
<button class="btn btn-outline-secondary" type="button" id="akCopyBtn"><i class="material-icons sm">content_copy</i></button>
</div>
<div class="small text-success mt-1" id="akCopyMsg"></div>
</div>
<div class="modal-footer"><button type="button" class="btn btn-primary" data-bs-dismiss="modal">Fertig</button></div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="set-users" role="tabpanel">
<div class="card" id="users-panel">
<div class="card-header d-flex justify-content-between align-items-center">
<span class="fw-bold">Benutzer</span>
<button type="button" class="btn btn-sm btn-primary" id="user-new"><i class="material-icons sm">person_add</i> Neuer Benutzer</button>
</div>
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead>
<tr><th>Name</th><th>E-Mail</th><th>Rolle</th><th>Angelegt</th><th class="text-end">Aktionen</th></tr>
</thead>
<tbody id="users-tbody">
<tr><td colspan="5" class="text-center text-muted py-4"><span class="spinner-border spinner-border-sm text-primary"></span> Benutzer werden geladen …</td></tr>
</tbody>
</table>
</div>
</div>
<!-- Anlegen/Bearbeiten-Modal -->
<div class="modal fade" id="userModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<form id="user-form" autocomplete="off">
<div class="modal-header">
<h5 class="modal-title" id="userModalTitle">Neuer Benutzer</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Schließen"></button>
</div>
<div class="modal-body">
<input type="hidden" name="id" id="user-id" value="">
<ul class="nav nav-tabs mb-3" role="tablist">
<li class="nav-item"><button class="nav-link active" data-bs-toggle="tab" data-bs-target="#user-tab-account" type="button" role="tab">Konto</button></li>
<li class="nav-item"><button class="nav-link" data-bs-toggle="tab" data-bs-target="#user-tab-notify" type="button" role="tab">Benachrichtigungen</button></li>
</ul>
<div class="tab-content">
<!-- Konto -->
<div class="tab-pane fade show active" id="user-tab-account" role="tabpanel">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Vorname</label>
<input type="text" class="form-control" name="firstname" id="user-firstname" required>
</div>
<div class="col-md-6">
<label class="form-label">Nachname</label>
<input type="text" class="form-control" name="lastname" id="user-lastname" required>
</div>
<div class="col-md-8">
<label class="form-label">E-Mail</label>
<input type="email" class="form-control" name="email" id="user-email" required>
</div>
<div class="col-md-4">
<label class="form-label">Rolle</label>
<select class="form-select" name="level" id="user-level">
<option value="1">Mitarbeiter</option>
<option value="5">Verwaltung</option>
<option value="9">Administrator</option>
</select>
</div>
<div class="col-12">
<label class="form-label">Passwort <span class="text-muted" id="user-pw-hint"></span></label>
<div class="input-group">
<input type="text" class="form-control" name="password" id="user-password" autocomplete="new-password">
<button class="btn btn-outline-secondary" type="button" id="user-pw-toggle" title="Anzeigen/Verbergen"><i class="material-icons sm">visibility</i></button>
<button class="btn btn-outline-primary" type="button" id="user-pw-generate"><i class="material-icons sm">autorenew</i> Generieren</button>
</div>
<div class="form-text">Mindestens 6 Zeichen. Der Generator erzeugt ein sicheres Passwort.</div>
</div>
</div>
</div>
<!-- Benachrichtigungen (Pushover) -->
<div class="tab-pane fade" id="user-tab-notify" role="tabpanel">
<div class="alert alert-light border small d-flex gap-2" id="user-notify-newhint" style="display:none !important;">
<i class="material-icons sm">info</i>
<span>Bitte den Benutzer zuerst anlegen (Tab „Konto" → Speichern), danach lassen sich die Benachrichtigungen einstellen.</span>
</div>
<div id="user-notify-wrap">
<div class="alert alert-warning border small d-flex gap-2" id="user-notify-notoken" style="display:none !important;">
<i class="material-icons sm">warning</i>
<span>Es ist noch kein systemweiter <strong>Pushover App-Token</strong> hinterlegt – ohne ihn werden keine Benachrichtigungen versendet. Bitte unter <em>Einstellungen → Übersicht</em> eintragen.</span>
</div>
<div class="mb-3">
<label class="form-label">Mein Pushover User-Key</label>
<div class="input-group">
<input type="text" class="form-control" name="notify_pushover_key" id="user-pushover-key" autocomplete="off" placeholder="z. B. uQiRzpo4DXghDmr9QzzfQu27cmVRsG">
<button class="btn btn-outline-primary" type="button" id="user-notify-test"><i class="material-icons sm">send</i> Test</button>
</div>
<div class="form-text">Der persönliche User-Key aus dem Pushover-Dashboard. <span id="user-notify-teststate"></span></div>
</div>
<hr>
<div class="fw-semibold mb-2">Wann möchtest du benachrichtigt werden?</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" value="1" name="notify_booking" id="user-nf-booking">
<label class="form-check-label" for="user-nf-booking">Buchungseingang</label>
</div>
<div class="mb-3 ps-4" id="user-nf-booking-srcwrap">
<label class="form-label small text-muted mb-1">Quellen</label>
<select class="form-select" id="user-nf-booking-src" multiple size="4">
<option value="own">Eigene (SeaSide, Parken-am-Schiff.de)</option>
<option value="partner">Partnerprogramm</option>
<option value="aida">AIDA</option>
<option value="parkinglist">ParkingList</option>
</select>
<input type="hidden" name="notify_booking_sources" id="user-nf-booking-src-csv" value="">
<div class="form-text">Mehrfachauswahl mit Strg/⌘ bzw. Klick.</div>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" value="1" name="notify_partner_signup" id="user-nf-partner">
<label class="form-check-label" for="user-nf-partner">Anmeldung Partnerprogramm</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" value="1" name="notify_contact" id="user-nf-contact">
<label class="form-check-label" for="user-nf-contact">Kontaktanfrage Eingang</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" value="1" name="notify_period" id="user-nf-period">
<label class="form-check-label" for="user-nf-period">Anfrage Wunschzeitraum</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" value="1" name="notify_booking_update" id="user-nf-update">
<label class="form-check-label" for="user-nf-update">Buchungsänderung (via API)</label>
</div>
</div>
</div>
</div>
<div class="alert alert-danger mt-3 d-none" id="user-error"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Abbrechen</button>
<button type="submit" class="btn btn-primary" id="user-save"><i class="material-icons sm">save</i> Speichern</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="srcModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header"><h5 class="modal-title" id="srcModalTitle">Quelle</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
<form id="srcForm" autocomplete="off">
<div class="modal-body">
<input type="hidden" name="orig" id="srcOrig">
<div class="mb-3"><label class="form-label">Bezeichnung</label><input class="form-control" name="label" id="srcLabel" placeholder="z. B. Costa"></div>
<div class="mb-1"><label class="form-label">Wert (customer_source) *</label><input class="form-control" name="key" id="srcKey" required placeholder="z. B. Costa"></div>
<div class="form-text">Dieser Wert wird in der Datenbank gespeichert. Nach dem Anlegen nicht mehr änderbar.</div>
<div class="js-status small mt-2" id="srcFormMsg"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Abbrechen</button>
<button class="btn btn-primary" type="submit"><i class="material-icons sm">save</i> Speichern</button>
</div>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function () {
if (typeof SITE_URL === 'undefined') return;
var API = SITE_URL + '/settings-api.php';
var accForm = document.getElementById('accounting-settings-form');
var ovForm = document.getElementById('overview-settings-form');
var gdrive = document.getElementById('set-gdrive-folder');
var pushApp = document.getElementById('set-pushover-app');
var pushState= document.getElementById('set-pushover-app-state');
function setPushState(on) {
if (!pushState) return;
pushState.textContent = on ? '✓ hinterlegt' : 'noch nicht hinterlegt';
pushState.className = 'fw-semibold ' + (on ? 'text-success' : 'text-warning');
}
fetch(API).then(function (r) { return r.json(); }).then(function (res) {
if (!res || !res.ok || !res.settings) return;
if (gdrive) gdrive.value = res.settings.gdrive_accounting_folder || '';
setPushState(!!res.settings.pushover_app_token_set);
}).catch(function () {});
function bindSave(form, fields, msgId) {
if (!form) return;
var msg = document.getElementById(msgId);
form.addEventListener('submit', function (e) {
e.preventDefault();
var body = new URLSearchParams();
fields.forEach(function (f) { var el = document.getElementById(f.id); if (el) body.append(f.name, el.value.trim()); });
if (msg) { msg.textContent = 'Speichern …'; msg.className = 'small text-muted'; }
fetch(API, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }, body: body.toString() })
.then(function (r) { return r.json(); })
.then(function (res) {
if (res && res.ok) {
if (msg) { msg.textContent = 'Gespeichert.'; msg.className = 'small text-success'; }
if (res.settings) setPushState(!!res.settings.pushover_app_token_set);
if (pushApp && form.contains(pushApp)) pushApp.value = ''; // Token-Feld nach Speichern leeren
} else {
if (msg) { msg.textContent = 'Speichern fehlgeschlagen.'; msg.className = 'small text-danger'; }
}
})
.catch(function () { if (msg) { msg.textContent = 'Speichern fehlgeschlagen.'; msg.className = 'small text-danger'; } });
});
}
bindSave(accForm, [{ id: 'set-gdrive-folder', name: 'gdrive_accounting_folder' }], 'set-accounting-msg');
bindSave(ovForm, [{ id: 'set-pushover-app', name: 'pushover_app_token' }], 'set-overview-msg');
});
</script>
<script src="https://seaside.pacim.de/assets/js/users.js?v=1782252335"></script>
<script src="https://seaside.pacim.de/assets/js/company.js?v=1780461606"></script>
<script src="https://seaside.pacim.de/assets/js/sources.js?v=1780664461"></script>
<script src="https://seaside.pacim.de/assets/js/mail-settings.js?v=1780674860"></script>
<script src="https://seaside.pacim.de/assets/js/apikeys.js?v=1781839059"></script>
</div><!-- /.page-wrapper -->
<footer class="footer">
<span>PaCIM · Parken-am-Schiff.de</span>
<span>SeaSide Travel GmbH & Co. Immobilien KG</span>
</footer>
</main><!-- /.main -->
<div class="sidebar-backdrop" hidden></div>
<!-- Globale JS-Variable -->
<script>
var SITE_URL = "https://seaside.pacim.de";
</script>
<!-- Bootstrap 5 Bundle (Content-Komponenten, inkl. Popper) -->
<script src="https://seaside.pacim.de/assets/js/bootstrap.bundle.min.js"></script>
<!-- Gentelella v4 Shell-Verhalten (Sidebar/Drawer/Theme) -->
<script src="https://seaside.pacim.de/assets/js/gentelella.js?v=1780438958"></script>
<script src="https://seaside.pacim.de/assets/js/search.js?v=1780917509"></script>
<!-- Vanilla-Plugins -->
<script src="https://seaside.pacim.de/assets/js/plugins/quill.min.js"></script>
<script src="https://seaside.pacim.de/assets/js/plugins/choices.min.js"></script>
<script src="https://seaside.pacim.de/assets/js/plugins/theme-functions.js"></script>
<script src="https://seaside.pacim.de/assets/js/custom.min.js?v=1780452213"></script>
<script src="https://seaside.pacim.de/assets/js/filter.js?v=1780443738"></script>
<script src="https://seaside.pacim.de/assets/js/table-sort.js?v=1780460902"></script>
<script src="https://seaside.pacim.de/assets/js/address-autocomplete.js?v=1780694884"></script>
<!-- Bestätigungs-Modal -->
<div class="modal fade" id="confirmationModal" tabindex="-1" role="dialog" aria-labelledby="confirmationModalTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirmationModalTitle">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<div class="confirmation m-0 row w-100">
<button type="button" class="btn btn-danger col mx-1 d-block" data-bs-dismiss="modal">Abbrechen</button>
<button type="button" class="btn btn-primary col mx-1 d-block btn-send-ajax">Bestätigen</button>
</div>
<div class="editor m-0 row w-100" style="display:none;">
<button type="button" class="btn btn-light border-secondary col mx-1 d-block" data-bs-dismiss="modal">Abbrechen</button>
<button type="button" class="btn btn-success border-secondary col mx-1 d-block btn-send-ajax">Speichern</button>
</div>
</div>
</div>
</div>
</div>
<!-- Datei-Viewer-Modal -->
<div class="modal fade" id="fileModal" tabindex="-1" role="dialog" aria-labelledby="fileModalTitle" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="fileModalTitle">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
...
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-danger col" data-bs-dismiss="modal">Schließen</button>
<button type="button" class="btn btn-primary col">Drucken</button>
</div>
</div>
</div>
</div>
</body>
</html>