Barrierefreiheit und mobile Darstellung
- Kontrast: gedämpfter Text war mit 3,1:1 unter WCAG AA, jetzt 4,9:1 (hell) bzw. 6,4:1 (dunkel) - Sprungmarke „Zum Inhalt springen" in Admin-Shell und Voucher-Seite - aria-label für alle reinen Icon-Schaltflächen (Theme, Menü, Abmelden, Zeilenaktionen), aria-current auf dem aktiven Navigationspunkt, role="group" für den Sprachumschalter - 194 dekorative Icons mit aria-hidden versehen, damit Screenreader sie nicht vorlesen - Toast-Container als aria-live-Bereich ausgezeichnet - prefers-reduced-motion schaltet Animationen und Übergänge ab Tabellen (Benutzer, Vouchers, Profile, Audit-Log, Dashboard, API-Keys) werden unter 720 px zu Karten: die Spaltenüberschrift steht per data-label vor dem Wert, statt horizontal zu scrollen. Datums- und Zeitformat in der Voucher-Liste folgen jetzt der gewählten Sprache statt fest de-DE. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
850a04d628
commit
7f1d93debd
21 changed files with 716 additions and 632 deletions
53
index.php
53
index.php
|
|
@ -308,43 +308,44 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
</head>
|
||||
<body class="app-body">
|
||||
|
||||
<a class="skip-link no-print" href="#main-content"><?= __('a11y_skip') ?></a>
|
||||
<header class="app-topbar no-print">
|
||||
<a href="index.php" class="brand">
|
||||
<span class="brand-mark"><i class="fas fa-wifi"></i></span>
|
||||
<span class="brand-mark"><i class="fas fa-wifi" aria-hidden="true"></i></span>
|
||||
<span class="brand-name"><?= htmlspecialchars($appTitle) ?></span>
|
||||
</a>
|
||||
<div class="app-actions">
|
||||
<div class="lang-switcher">
|
||||
<div class="lang-switcher" role="group" aria-label="<?= __('a11y_language') ?>">
|
||||
<?php foreach (I18n::getAvailable() as $code => $label): ?>
|
||||
<button class="lang-btn <?= I18n::getLanguage() === $code ? 'active' : '' ?>"
|
||||
onclick="switchLanguage('<?= $code ?>')"><?= strtoupper($code) ?></button>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<button id="darkModeBtn" class="dark-mode-toggle" onclick="toggleDarkMode()" title="Dark Mode">
|
||||
<i class="fas fa-moon"></i>
|
||||
<button id="darkModeBtn" class="dark-mode-toggle" onclick="toggleDarkMode()" aria-label="<?= __('a11y_theme') ?>" title="<?= __('a11y_theme') ?>">
|
||||
<i class="fas fa-moon" aria-hidden="true"></i>
|
||||
</button>
|
||||
<?php if ($currentUser): ?>
|
||||
<?php if ($auth->isAdmin()): ?>
|
||||
<a href="admin/" class="btn btn-secondary">
|
||||
<i class="fas fa-sliders"></i> <span class="hide-mobile"><?= __('nav_administration') ?></span>
|
||||
<i class="fas fa-sliders" aria-hidden="true"></i> <span class="hide-mobile"><?= __('nav_administration') ?></span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
<div class="user-menu">
|
||||
<div class="user-avatar"><?= strtoupper(mb_substr($currentUser['name'], 0, 1)) ?></div>
|
||||
<div class="user-name hide-mobile"><?= htmlspecialchars($currentUser['name']) ?></div>
|
||||
<a href="logout.php" class="icon-btn" title="<?= __('btn_logout') ?>" style="width:28px;height:28px;font-size:11px;">
|
||||
<i class="fas fa-arrow-right-from-bracket"></i>
|
||||
<a href="logout.php" class="icon-btn" title="<?= __('btn_logout') ?>" aria-label="<?= __('btn_logout') ?>" style="width:28px;height:28px;font-size:11px;">
|
||||
<i class="fas fa-arrow-right-from-bracket" aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>
|
||||
<?php elseif ($publicAccess): ?>
|
||||
<a href="login.php" class="btn btn-secondary">
|
||||
<i class="fas fa-right-to-bracket"></i> <?= __('btn_login') ?>
|
||||
<i class="fas fa-right-to-bracket" aria-hidden="true"></i> <?= __('btn_login') ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container">
|
||||
<main class="container" id="main-content">
|
||||
<?php if ($logoUrl && !$voucherCreated && !$bulkCreated): ?>
|
||||
<img src="<?= htmlspecialchars(Ui::mediaUrl($logoUrl)) ?>" alt="Logo" class="logo">
|
||||
<?php endif; ?>
|
||||
|
|
@ -366,17 +367,17 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
</div>
|
||||
|
||||
<div class="voucher-result no-print">
|
||||
<div class="result-label"><i class="fas fa-circle-check"></i> <?= __('voucher_success_title') ?></div>
|
||||
<div class="result-label"><i class="fas fa-circle-check" aria-hidden="true"></i> <?= __('voucher_success_title') ?></div>
|
||||
<div class="voucher-code" id="voucherCode" onclick="copyCode()" title="<?= __('js_click_to_copy') ?>">
|
||||
<?= htmlspecialchars($voucherCode) ?>
|
||||
</div>
|
||||
<div class="voucher-info">
|
||||
<i class="fas fa-copy"></i> <?= __('voucher_copy_hint') ?>
|
||||
<i class="fas fa-copy" aria-hidden="true"></i> <?= __('voucher_copy_hint') ?>
|
||||
</div>
|
||||
<div class="voucher-meta">
|
||||
<span><i class="fas fa-clock"></i> <?= str_replace('{minutes}', $voucherData['expire_min'], __('voucher_validity')) ?></span>
|
||||
<span><i class="fas fa-location-dot"></i> <?= htmlspecialchars($voucherData['site_name']) ?></span>
|
||||
<span><i class="fas fa-mobile-screen"></i> <?= (int)$voucherData['max_uses'] ?> <?= __('label_devices') ?></span>
|
||||
<span><i class="fas fa-clock" aria-hidden="true"></i> <?= str_replace('{minutes}', $voucherData['expire_min'], __('voucher_validity')) ?></span>
|
||||
<span><i class="fas fa-location-dot" aria-hidden="true"></i> <?= htmlspecialchars($voucherData['site_name']) ?></span>
|
||||
<span><i class="fas fa-mobile-screen" aria-hidden="true"></i> <?= (int)$voucherData['max_uses'] ?> <?= __('label_devices') ?></span>
|
||||
</div>
|
||||
<div class="ticket-divider"></div>
|
||||
<div class="qr-wrapper no-print">
|
||||
|
|
@ -395,11 +396,11 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
<div class="no-print" style="display:flex;gap:10px;margin-top:18px;">
|
||||
<form method="get" style="flex:1;">
|
||||
<button type="submit" class="btn btn-primary btn-lg btn-block">
|
||||
<i class="fas fa-plus"></i> <?= __('btn_new_code') ?>
|
||||
<i class="fas fa-plus" aria-hidden="true"></i> <?= __('btn_new_code') ?>
|
||||
</button>
|
||||
</form>
|
||||
<button onclick="window.print()" class="btn btn-secondary btn-lg">
|
||||
<i class="fas fa-print"></i> <?= __('voucher_print_btn') ?>
|
||||
<i class="fas fa-print" aria-hidden="true"></i> <?= __('voucher_print_btn') ?>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
|
@ -441,12 +442,12 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="copy-hint"><i class="fas fa-copy"></i> <?= __('voucher_copy_hint') ?></p>
|
||||
<p class="copy-hint"><i class="fas fa-copy" aria-hidden="true"></i> <?= __('voucher_copy_hint') ?></p>
|
||||
</div>
|
||||
|
||||
<div class="no-print" style="display:flex;gap:10px;margin-top:20px;">
|
||||
<button onclick="window.print()" class="btn btn-primary btn-lg" style="flex:1;">
|
||||
<i class="fas fa-print"></i> <?= __('bulk_print_all') ?>
|
||||
<i class="fas fa-print" aria-hidden="true"></i> <?= __('bulk_print_all') ?>
|
||||
</button>
|
||||
<form method="get" style="flex:1;">
|
||||
<button type="submit" class="btn btn-secondary btn-lg btn-block"><?= __('btn_new_code') ?></button>
|
||||
|
|
@ -455,7 +456,7 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
|
||||
<?php elseif (empty($sites)): ?>
|
||||
<div class="empty-state">
|
||||
<div class="empty-icon"><i class="fas fa-wifi"></i></div>
|
||||
<div class="empty-icon"><i class="fas fa-wifi" aria-hidden="true"></i></div>
|
||||
<p><?= __('voucher_no_sites') ?><br>
|
||||
<?php if ($auth->isAdmin()): ?>
|
||||
<a href="admin/" style="color:var(--accent);"><?= __('voucher_no_sites_admin') ?></a>
|
||||
|
|
@ -539,7 +540,7 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
<div class="email-checkbox-wrapper">
|
||||
<input type="checkbox" id="send_email" name="send_email" onchange="toggleEmailField()">
|
||||
<label for="send_email">
|
||||
<i class="fas fa-envelope" style="color:var(--accent);"></i> <?= __('voucher_email_send') ?>
|
||||
<i class="fas fa-envelope" style="color:var(--accent);" aria-hidden="true"></i> <?= __('voucher_email_send') ?>
|
||||
</label>
|
||||
</div>
|
||||
<div class="email-input-wrapper" id="email_field">
|
||||
|
|
@ -556,7 +557,7 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
<div class="email-option">
|
||||
<div class="email-checkbox-wrapper">
|
||||
<input type="checkbox" id="send_sms" name="send_sms" onchange="document.getElementById('sms_field').style.display=this.checked?'block':'none'">
|
||||
<label for="send_sms"><i class="fas fa-comment-sms" style="color:var(--accent);"></i> Code per SMS versenden</label>
|
||||
<label for="send_sms"><i class="fas fa-comment-sms" style="color:var(--accent);" aria-hidden="true"></i> Code per SMS versenden</label>
|
||||
</div>
|
||||
<div id="sms_field" style="display:none;margin-top:12px;">
|
||||
<label for="recipient_phone">Telefonnummer (international, z.B. +49170…)</label>
|
||||
|
|
@ -566,7 +567,7 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
<?php endif; ?>
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-lg btn-block" id="submitBtn">
|
||||
<i class="fas fa-ticket"></i> <?= __('voucher_create_btn') ?>
|
||||
<i class="fas fa-ticket" aria-hidden="true"></i> <?= __('voucher_create_btn') ?>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -629,9 +630,9 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div id="toast-container"></div>
|
||||
<div id="toast-container" role="status" aria-live="polite"></div>
|
||||
<script src="assets/global.js"></script>
|
||||
<script>
|
||||
<?php if ($voucherCreated): ?>
|
||||
|
|
@ -711,7 +712,7 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
const btn = document.getElementById('submitBtn');
|
||||
if (!btn || btn.disabled) { e.preventDefault(); return; }
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-circle-notch fa-spin"></i> <?= __('voucher_creating') ?>';
|
||||
btn.innerHTML = '<i class="fas fa-circle-notch fa-spin" aria-hidden="true"></i> <?= __('voucher_creating') ?>';
|
||||
});
|
||||
|
||||
document.getElementById('bulkForm')?.addEventListener('submit', function(e) {
|
||||
|
|
@ -719,7 +720,7 @@ function buildPrintCard($template, $data, $instructionHeader, $instructionText,
|
|||
if (!btn || btn.disabled) { e.preventDefault(); return; }
|
||||
const count = document.getElementById('bulk_count').value;
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<i class="fas fa-circle-notch fa-spin"></i> <?= addslashes(str_replace('{count}', "' + count + '", __('bulk_creating'))) ?>';
|
||||
btn.innerHTML = '<i class="fas fa-circle-notch fa-spin" aria-hidden="true"></i> <?= addslashes(str_replace('{count}', "' + count + '", __('bulk_creating'))) ?>';
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue