- 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>
130 lines
4.3 KiB
PHP
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">×</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>
|