Files
WebAPP/resources/views/components/pwa-install-banner.blade.php
Rhino 2e24a40d68 Stand: SMTP-Test, Admin-Mail-Tab, Notifiable-Fix, Lazy-Quill
- Fix: Notifiable-Trait zum User-Model hinzugefuegt (behebt notify()-500er)
- Installer: SMTP-Verbindungstest mit EsmtpTransport + Ueberspringen-Link
- Admin: Neuer E-Mail-Tab mit SMTP-Konfiguration + Verbindungstest
- Admin: Lazy Quill-Initialisierung (nur sichtbare Locale wird geladen)
- Uebersetzungen: 17 neue Mail-Keys in allen 6 Sprachen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 07:30:37 +01:00

130 lines
4.3 KiB
PHP

{{-- PWA Install Banner (Android + iOS) --}}
<div id="pwa-install-banner" style="display: none;">
<style>
#pwa-install-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: #1f2937;
color: white;
padding: 1rem;
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
z-index: 9999;
box-shadow: 0 -2px 10px rgba(0,0,0,0.15);
}
#pwa-install-banner .pwa-text {
flex: 1;
font-size: 0.9rem;
line-height: 1.4;
}
#pwa-install-banner .pwa-text strong {
display: block;
font-size: 1rem;
margin-bottom: 0.2rem;
}
#pwa-install-banner .pwa-ios-steps {
font-size: 0.82rem;
margin-top: 0.3rem;
color: rgba(255,255,255,0.85);
}
#pwa-install-banner .pwa-ios-steps .pwa-icon {
display: inline-block;
vertical-align: middle;
font-size: 1.05rem;
}
#pwa-install-banner button {
border: none;
padding: 0.6rem 1.2rem;
border-radius: 0.4rem;
font-size: 0.9rem;
cursor: pointer;
white-space: nowrap;
}
#pwa-install-banner .pwa-install-btn {
background: white;
color: #1f2937;
font-weight: 600;
}
#pwa-install-banner .pwa-dismiss-btn {
background: transparent;
color: rgba(255,255,255,0.8);
padding: 0.6rem;
font-size: 1.2rem;
}
</style>
<div class="pwa-text">
<strong id="pwa-title">{{ __('ui.pwa_install_title') }}</strong>
<span id="pwa-desc">{{ __('ui.pwa_install_text') }}</span>
<div id="pwa-ios-steps" class="pwa-ios-steps" style="display: none;">
{!! app(\App\Services\HtmlSanitizerService::class)->sanitize(__('ui.pwa_ios_steps')) !!}
</div>
</div>
<button class="pwa-install-btn" id="pwa-install-btn">{{ __('ui.pwa_install_btn') }}</button>
<button class="pwa-dismiss-btn" id="pwa-dismiss-btn">&times;</button>
</div>
<script>
(function() {
let deferredPrompt;
const banner = document.getElementById('pwa-install-banner');
const installBtn = document.getElementById('pwa-install-btn');
const dismissBtn = document.getElementById('pwa-dismiss-btn');
const iosSteps = document.getElementById('pwa-ios-steps');
const dismissed = localStorage.getItem('pwa-install-dismissed');
const isStandalone = window.matchMedia('(display-mode: standalone)').matches
|| window.navigator.standalone === true;
// Reset nach 30 Tagen
if (dismissed && (Date.now() - parseInt(dismissed)) > 30 * 24 * 60 * 60 * 1000) {
localStorage.removeItem('pwa-install-dismissed');
}
// Bereits installiert → nichts anzeigen
if (isStandalone) return;
// iOS-Erkennung (iPhone, iPad, iPod)
const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent)
|| (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1);
if (isIOS) {
// iOS: Manuellen Hinweis zeigen (kein beforeinstallprompt)
if (!dismissed) {
installBtn.style.display = 'none';
iosSteps.style.display = 'block';
banner.style.display = 'flex';
}
} else {
// Android/Chrome: beforeinstallprompt abfangen
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
deferredPrompt = e;
if (!dismissed) {
banner.style.display = 'flex';
}
});
}
installBtn.addEventListener('click', async () => {
if (!deferredPrompt) return;
deferredPrompt.prompt();
await deferredPrompt.userChoice;
deferredPrompt = null;
banner.style.display = 'none';
});
dismissBtn.addEventListener('click', () => {
banner.style.display = 'none';
localStorage.setItem('pwa-install-dismissed', Date.now());
});
})();
</script>