Login-Seite individualisierbar (Branding, Texte, Hintergrund)
Some checks failed
CI / PHP Lint (push) Has been cancelled
CI / PHP Lint-1 (push) Has been cancelled
CI / Unit Tests & Static Analysis (push) Has been cancelled
CI / PHP Lint (pull_request) Has been cancelled
CI / PHP Lint-1 (pull_request) Has been cancelled
CI / Unit Tests & Static Analysis (pull_request) Has been cancelled
Some checks failed
CI / PHP Lint (push) Has been cancelled
CI / PHP Lint-1 (push) Has been cancelled
CI / Unit Tests & Static Analysis (push) Has been cancelled
CI / PHP Lint (pull_request) Has been cancelled
CI / PHP Lint-1 (pull_request) Has been cancelled
CI / Unit Tests & Static Analysis (pull_request) Has been cancelled
Neuer Einstellungs-Tab "Login-Seite" (Administration → Einstellungen): - Firmenname und eigenes Logo für die Anmeldeseite - Überschrift, Beschreibungstext, Stichpunkte (eine Zeile je Punkt) und Fußzeile frei setzbar - Hintergrundbild für die linke Bildspalte, alternativ Farbverlauf mit Farbwähler (Start-/Endfarbe) sowie einstellbarer Abdunklung für die Lesbarkeit auf hellen Bildern - Bildspalte abschaltbar: dann zentrierte Anmeldekarte auf dem App-Hintergrund - "Vorschau öffnen" zeigt die Login-Seite als angemeldeter Admin (login.php?preview=1), ohne die Sitzung zu beenden Alle Felder sind optional; leere Werte fallen auf die bisherigen Standardtexte und -farben zurück. Bestehende Installationen sehen unverändert aus, es ist keine Migration nötig. README um den Abschnitt "Login-Seite individualisieren" mit Beispiel- Screenshots ergänzt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
498c7e28e0
commit
9a4b2e1cd4
10 changed files with 308 additions and 16 deletions
|
|
@ -58,6 +58,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['save_settings'])) {
|
|||
$settings['public_access'] = isset($_POST['public_access']) ? '1' : '0';
|
||||
}
|
||||
|
||||
if ($formType === 'login') {
|
||||
$settings['login_panel_enabled'] = isset($_POST['login_panel_enabled']) ? '1' : '0';
|
||||
$settings['login_brand_name'] = trim($_POST['login_brand_name'] ?? '');
|
||||
$settings['login_logo_url'] = trim($_POST['login_logo_url'] ?? '');
|
||||
$settings['login_claim_title'] = trim($_POST['login_claim_title'] ?? '');
|
||||
$settings['login_claim_text'] = trim($_POST['login_claim_text'] ?? '');
|
||||
$settings['login_features'] = trim($_POST['login_features'] ?? '');
|
||||
$settings['login_footer'] = trim($_POST['login_footer'] ?? '');
|
||||
$settings['login_bg_image'] = trim($_POST['login_bg_image'] ?? '');
|
||||
$settings['login_bg_from'] = trim($_POST['login_bg_from'] ?? '');
|
||||
$settings['login_bg_to'] = trim($_POST['login_bg_to'] ?? '');
|
||||
$overlay = (int)($_POST['login_bg_overlay'] ?? 40);
|
||||
$settings['login_bg_overlay'] = (string)max(0, min(90, $overlay));
|
||||
}
|
||||
|
||||
if ($formType === 'defaults') {
|
||||
$expMin = (int)($_POST['default_expire_minutes'] ?? 480);
|
||||
$defDev = (int)($_POST['default_max_uses'] ?? 1);
|
||||
|
|
@ -190,6 +205,17 @@ $cs = [
|
|||
'email_user_notification_body' => $db->getSetting('email_user_notification_body', "Hallo {USER_NAME},\n\n{CHANGES}"),
|
||||
'tinymce_api_key' => $db->getSetting('tinymce_api_key', ''),
|
||||
'print_template' => $db->getSetting('print_template', '<div style="text-align:center;padding:40px"><h1>{APP_TITLE}</h1><h2>WLAN Code</h2><div style="font-size:48px;font-weight:bold;margin:30px 0;font-family:monospace">{VOUCHER_CODE}</div><p><strong>Gültig bis:</strong> {EXPIRY_DATE} {EXPIRY_TIME}</p><p><strong>Site:</strong> {SITE_NAME}</p><p><strong>Geräte:</strong> {MAX_USES}</p><hr style="margin:30px 0"><div>{INSTRUCTIONS}</div></div>'),
|
||||
'login_panel_enabled' => $db->getSetting('login_panel_enabled', '1'),
|
||||
'login_brand_name' => $db->getSetting('login_brand_name', ''),
|
||||
'login_logo_url' => $db->getSetting('login_logo_url', ''),
|
||||
'login_claim_title' => $db->getSetting('login_claim_title', ''),
|
||||
'login_claim_text' => $db->getSetting('login_claim_text', ''),
|
||||
'login_features' => $db->getSetting('login_features', ''),
|
||||
'login_footer' => $db->getSetting('login_footer', ''),
|
||||
'login_bg_image' => $db->getSetting('login_bg_image', ''),
|
||||
'login_bg_from' => $db->getSetting('login_bg_from', '#3b2f8f'),
|
||||
'login_bg_to' => $db->getSetting('login_bg_to', '#6d5ce7'),
|
||||
'login_bg_overlay' => $db->getSetting('login_bg_overlay', '40'),
|
||||
'cron_token' => $db->getSetting('cron_token', ''),
|
||||
'last_cron_sync' => $db->getSetting('last_cron_sync', ''),
|
||||
];
|
||||
|
|
@ -232,6 +258,7 @@ $adminBase = '';
|
|||
<div class="tab-navigation" id="tabNav">
|
||||
<button class="tab-button active" data-tab="general"><i class="fas fa-sliders-h"></i> <?= __('settings_tab_general') ?></button>
|
||||
<button class="tab-button" data-tab="defaults"><i class="fas fa-sliders-h"></i> <?= __('settings_tab_defaults') ?></button>
|
||||
<button class="tab-button" data-tab="login"><i class="fas fa-right-to-bracket"></i> <?= __('settings_tab_login') ?></button>
|
||||
<button class="tab-button" data-tab="cron"><i class="fas fa-clock"></i> <?= __('settings_tab_cron') ?></button>
|
||||
<button class="tab-button" data-tab="m365"><i class="fab fa-microsoft"></i> <?= __('settings_tab_m365') ?></button>
|
||||
<button class="tab-button" data-tab="smtp"><i class="fas fa-envelope"></i> <?= __('settings_tab_smtp') ?></button>
|
||||
|
|
@ -295,6 +322,92 @@ $adminBase = '';
|
|||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Login-Seite -->
|
||||
<div id="tab-login" class="tab-content">
|
||||
<h2 style="margin-bottom: 8px; color: var(--text-primary);"><i class="fas fa-right-to-bracket"></i> <?= __('settings_tab_login') ?></h2>
|
||||
<p style="color: var(--text-muted); font-size: 14px; margin-bottom: 24px;"><?= __('settings_login_intro') ?></p>
|
||||
<form method="post">
|
||||
<input type="hidden" name="csrf_token" value="<?= $auth->getCsrfToken() ?>">
|
||||
<input type="hidden" name="form_type" value="login">
|
||||
|
||||
<div class="checkbox-group" style="margin-bottom: 20px;">
|
||||
<input type="checkbox" name="login_panel_enabled" id="login_panel_enabled" <?= $cs['login_panel_enabled'] === '1' ? 'checked' : '' ?>>
|
||||
<label for="login_panel_enabled" style="margin:0;"><?= __('settings_login_panel') ?></label>
|
||||
</div>
|
||||
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_brand') ?></label>
|
||||
<input type="text" name="login_brand_name" value="<?= htmlspecialchars($cs['login_brand_name']) ?>" placeholder="<?= htmlspecialchars($cs['app_title']) ?>">
|
||||
<div class="help-text"><?= __('settings_login_brand_hint') ?></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_logo') ?></label>
|
||||
<input type="url" name="login_logo_url" value="<?= htmlspecialchars($cs['login_logo_url']) ?>" placeholder="https://example.com/logo.svg">
|
||||
<div class="help-text"><?= __('settings_login_logo_hint') ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_claim_title') ?></label>
|
||||
<input type="text" name="login_claim_title" value="<?= htmlspecialchars($cs['login_claim_title']) ?>" placeholder="<?= htmlspecialchars(__('auth_claim_title')) ?>">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_claim_text') ?></label>
|
||||
<textarea name="login_claim_text" rows="3" placeholder="<?= htmlspecialchars(__('auth_claim_text')) ?>"><?= htmlspecialchars($cs['login_claim_text']) ?></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_features') ?></label>
|
||||
<textarea name="login_features" rows="4" placeholder="<?= htmlspecialchars(__('auth_feature_1') . "\n" . __('auth_feature_2') . "\n" . __('auth_feature_3')) ?>"><?= htmlspecialchars($cs['login_features']) ?></textarea>
|
||||
<div class="help-text"><?= __('settings_login_features_hint') ?></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_footer') ?></label>
|
||||
<input type="text" name="login_footer" value="<?= htmlspecialchars($cs['login_footer']) ?>" placeholder="© <?= date('Y') ?> <?= htmlspecialchars($cs['app_title']) ?>">
|
||||
</div>
|
||||
|
||||
<hr class="section-divider">
|
||||
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_bg_image') ?></label>
|
||||
<input type="url" name="login_bg_image" value="<?= htmlspecialchars($cs['login_bg_image']) ?>" placeholder="https://example.com/empfang.jpg">
|
||||
<div class="help-text"><?= __('settings_login_bg_image_hint') ?></div>
|
||||
</div>
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_bg_from') ?></label>
|
||||
<div class="color-field">
|
||||
<input type="color" class="color-swatch" data-target="login_bg_from"
|
||||
value="<?= preg_match('/^#[0-9a-fA-F]{6}$/', $cs['login_bg_from']) ? htmlspecialchars($cs['login_bg_from']) : '#3b2f8f' ?>">
|
||||
<input type="text" id="login_bg_from" name="login_bg_from" value="<?= htmlspecialchars($cs['login_bg_from']) ?>" placeholder="#3b2f8f">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_bg_to') ?></label>
|
||||
<div class="color-field">
|
||||
<input type="color" class="color-swatch" data-target="login_bg_to"
|
||||
value="<?= preg_match('/^#[0-9a-fA-F]{6}$/', $cs['login_bg_to']) ? htmlspecialchars($cs['login_bg_to']) : '#6d5ce7' ?>">
|
||||
<input type="text" id="login_bg_to" name="login_bg_to" value="<?= htmlspecialchars($cs['login_bg_to']) ?>" placeholder="#6d5ce7">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label><?= __('settings_login_overlay') ?></label>
|
||||
<input type="number" name="login_bg_overlay" min="0" max="90" value="<?= (int)$cs['login_bg_overlay'] ?>">
|
||||
<div class="help-text"><?= __('settings_login_overlay_hint') ?></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex;gap:10px;flex-wrap:wrap;margin-top:16px;">
|
||||
<button type="submit" name="save_settings" class="btn btn-primary"><i class="fas fa-save"></i> <?= __('btn_save') ?></button>
|
||||
<a href="../login.php?preview=1" target="_blank" rel="noopener" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-up-right-from-square"></i> <?= __('settings_login_preview') ?>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Cron-Sync -->
|
||||
<div id="tab-cron" class="tab-content">
|
||||
<h2 style="margin-bottom: 20px; color: var(--text-primary);"><i class="fas fa-clock"></i> <?= __('settings_tab_cron') ?></h2>
|
||||
|
|
@ -466,6 +579,16 @@ document.querySelectorAll('.tab-button').forEach(btn => {
|
|||
});
|
||||
});
|
||||
|
||||
// Farbwähler und Hex-Feld synchron halten
|
||||
document.querySelectorAll('.color-swatch').forEach(swatch => {
|
||||
const field = document.getElementById(swatch.dataset.target);
|
||||
if (!field) return;
|
||||
swatch.addEventListener('input', () => { field.value = swatch.value; });
|
||||
field.addEventListener('input', () => {
|
||||
if (/^#[0-9a-fA-F]{6}$/.test(field.value.trim())) swatch.value = field.value.trim();
|
||||
});
|
||||
});
|
||||
|
||||
// Restore tab from hash
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
const hash = location.hash.substring(1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue