Entwicklerhinweis "Entwickelt von Loheide.eu" ergänzen
Some checks are pending
CI / PHP Lint (push) Waiting to run
CI / PHP Lint-1 (push) Waiting to run
CI / Unit Tests & Static Analysis (push) Waiting to run
CI / PHP Lint (pull_request) Waiting to run
CI / PHP Lint-1 (pull_request) Waiting to run
CI / Unit Tests & Static Analysis (pull_request) Waiting to run

Zentral in Ui::credit() gepflegt und dezent im Seitenfuß eingebunden:

- Admin-Bereich: unter dem Benutzerbereich in der Sidebar
- öffentliche Voucher-Seite: unter der Karte
- Anmeldung, Installer und Updater: am Ende der jeweiligen Karte
- Wartungsseite: direkt im Markup, da sie bewusst eigenständig bleibt
- README: im Kopf und in der Fußzeile

Der Hinweis ist übersetzt ("Entwickelt von" / "Developed by") und stört
das Branding der Betreiber nicht – die konfigurierbare Fußzeile der
Login-Seite bleibt unverändert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Friederich Loheide 2026-09-23 11:21:53 +00:00
parent 7dc60c5bb0
commit 7fa423a74c
26 changed files with 45 additions and 2 deletions

View file

@ -4,6 +4,8 @@
**Webbasiertes WLAN-Voucher-Management für UniFi OS** mit Multi-Site-Support, Benutzerverwaltung, Microsoft-365-Login und integriertem Auto-Updater.
Entwickelt von **[Loheide.eu](https://loheide.eu)**
![PHP](https://img.shields.io/badge/PHP-7.4%2B-777BB4?logo=php&logoColor=white)
![MySQL](https://img.shields.io/badge/MySQL-5.7%2B%20%2F%20MariaDB-4479A1?logo=mysql&logoColor=white)
![UniFi OS](https://img.shields.io/badge/UniFi%20OS-7.0%2B-0559C9?logo=ubiquiti&logoColor=white)
@ -541,4 +543,6 @@ vendor/bin/phpstan analyse
**Version 2.6.0** · Autor: **Friederich Loheide** · Lizenz: **MIT**
Entwickelt von **[Loheide.eu](https://loheide.eu)**
</div>

View file

@ -1535,6 +1535,20 @@ input.search-bar, .site-selector .search-bar { min-width: 240px; width: auto; fl
.print-qr { display: flex; justify-content: center; line-height: 0; }
.print-qr img, .print-qr canvas { display: block; }
/* Entwicklerhinweis im Seitenfuß */
.app-credit {
margin: 0;
font-size: 11.5px;
color: var(--text-muted);
}
.app-credit a { color: var(--text-secondary); text-decoration: none; }
.app-credit a:hover { color: var(--accent); text-decoration: underline; }
.sidebar-foot .app-credit { margin-top: 10px; padding: 0 4px; text-align: center; }
.app-footer { max-width: 560px; margin: 20px auto 0; text-align: center; }
.login-container .app-credit { margin-top: 26px; text-align: center; }
.focus-card .app-credit { margin-top: 22px; text-align: center; }
.wrap .app-credit { margin-top: 18px; text-align: center; }
/* Sprungmarke zum Inhalt (nur bei Tastaturfokus sichtbar) */
.skip-link {
position: absolute;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 386 KiB

After

Width:  |  Height:  |  Size: 390 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 379 KiB

After

Width:  |  Height:  |  Size: 384 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 320 KiB

After

Width:  |  Height:  |  Size: 320 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 KiB

After

Width:  |  Height:  |  Size: 316 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 309 KiB

After

Width:  |  Height:  |  Size: 313 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 465 KiB

After

Width:  |  Height:  |  Size: 472 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 MiB

After

Width:  |  Height:  |  Size: 1 MiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

After

Width:  |  Height:  |  Size: 250 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 KiB

After

Width:  |  Height:  |  Size: 309 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 325 KiB

After

Width:  |  Height:  |  Size: 330 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 273 KiB

After

Width:  |  Height:  |  Size: 278 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 KiB

After

Width:  |  Height:  |  Size: 285 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 235 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 KiB

After

Width:  |  Height:  |  Size: 235 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 KiB

After

Width:  |  Height:  |  Size: 416 KiB

Before After
Before After

View file

@ -116,6 +116,22 @@ class Ui
. '</style>';
}
/** Entwicklerhinweis bewusst an einer Stelle gepflegt. */
public const CREDIT_NAME = 'Loheide.eu';
public const CREDIT_URL = 'https://loheide.eu';
/**
* Dezenter Hinweis auf den Entwickler, wie er im Seitenfuß erscheint.
*/
public static function credit(): string
{
$label = function_exists('__') ? __('credit_by') : 'Entwickelt von';
return '<p class="app-credit">' . htmlspecialchars($label) . ' '
. '<a href="' . self::CREDIT_URL . '" target="_blank" rel="noopener">'
. self::CREDIT_NAME . '</a></p>';
}
/**
* Standard-Druckvorlage (wird nur verwendet, solange keine eigene
* Vorlage gespeichert ist). {QR_CODE} fuellt der Browser.

View file

@ -76,8 +76,8 @@ foreach ($navGroups as $items) {
<?php endforeach; ?>
</nav>
<?php if ($currentUser): ?>
<div class="sidebar-foot">
<?php if ($currentUser): ?>
<div class="user-menu" style="width:100%;justify-content:flex-start;">
<div class="user-avatar"><?= strtoupper(mb_substr($currentUser['name'], 0, 1)) ?></div>
<div style="min-width:0;flex:1;">
@ -88,8 +88,9 @@ foreach ($navGroups as $items) {
<i class="fas fa-arrow-right-from-bracket" aria-hidden="true"></i>
</a>
</div>
<?php endif; ?>
<?= Ui::credit() ?>
</div>
<?php endif; ?>
</aside>
<header class="topbar">

View file

@ -635,6 +635,8 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
<?php endif; ?>
</main>
<footer class="app-footer no-print"><?= Ui::credit() ?></footer>
<div id="toast-container" role="status" aria-live="polite"></div>
<script src="assets/global.js"></script>
<script>

View file

@ -375,6 +375,7 @@ if ($step === 5 && $_SERVER['REQUEST_METHOD'] === 'POST') {
<button type="submit" class="btn btn-primary btn-lg btn-block">Installation abschließen</button>
</form>
<?php endif; ?>
<?= Ui::credit() ?>
</div>
</body>
</html>

View file

@ -469,6 +469,7 @@ return [
'settings_qr_hint' => '{QR_CODE} fügt einen QR-Code mit dem Voucher-Code ein.',
'print_valid_until' => 'Gültig bis',
'print_devices' => 'Geräte',
'credit_by' => 'Entwickelt von',
'settings_tab_general' => 'Allgemein',
'settings_tab_defaults' => 'Voucher-Standards',
'settings_tab_cron' => 'Cron-Sync',

View file

@ -469,6 +469,7 @@ return [
'settings_qr_hint' => '{QR_CODE} inserts a QR code containing the voucher code.',
'print_valid_until' => 'Valid until',
'print_devices' => 'devices',
'credit_by' => 'Developed by',
'settings_tab_general' => 'General',
'settings_tab_defaults' => 'Voucher Defaults',
'settings_tab_cron' => 'Cron Sync',

View file

@ -288,6 +288,7 @@ try {
<?php if ($publicAccess): ?>
<div class="auth-links"><a href="index.php" class="back-link"><i class="fas fa-arrow-left" aria-hidden="true"></i> <?= __('login_back') ?></a></div>
<?php endif; ?>
<?= Ui::credit() ?>
</div>
</section>

View file

@ -90,6 +90,7 @@
<p>Es wird gerade ein Update eingespielt. Die Seite ist in wenigen Augenblicken wieder erreichbar.</p>
<div class="bar"></div>
<p class="hint">Diese Seite aktualisiert sich automatisch.</p>
<p class="hint" style="margin-top:10px;">Entwickelt von <a href="https://loheide.eu" style="color:inherit;">Loheide.eu</a></p>
</div>
</body>
</html>

View file

@ -116,6 +116,7 @@ $channels = \Updater\UpdateManager::CHANNELS;
<div class="alert alert-ok" id="migAlert"></div>
</div>
</div>
<?= Ui::credit() ?>
</div>
<script>