Files
fotospiel-app/resources/views/admin.blade.php
Codex Agent 2b4d9e9411
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Add CSP nonce for Tamagui styles
2026-01-24 20:38:36 +01:00

97 lines
5.1 KiB
PHP

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ __('admin.shell.tenant_admin_title') }}</title>
<link rel="icon" href="{{ asset('favicon.ico') }}" type="image/x-icon">
<link rel="manifest" href="/manifest.json">
<meta name="csp-style-nonce" content="{{ $cspStyleNonce }}">
<meta name="theme-color" content="#f43f5e">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="apple-touch-icon" href="/admin-apple-touch-icon.png">
@viteReactRefresh
@vite(['resources/css/app.css', 'resources/js/admin/main.tsx'])
@php
$matomoConfig = config('services.matomo');
$matomoAdmin = ($matomoConfig['enabled'] ?? false) && !empty($matomoConfig['url']) && !empty($matomoConfig['site_id_admin'])
? [
'enabled' => true,
'url' => rtrim($matomoConfig['url'], '/'),
'siteId' => (string) $matomoConfig['site_id_admin'],
]
: ['enabled' => false];
$adminRuntimeConfig = [
'push' => [
'enabled' => config('push.enabled', false),
'vapidPublicKey' => config('push.vapid.public_key'),
],
];
@endphp
<script nonce="{{ $cspNonce }}">
window.__MATOMO_ADMIN__ = {!! json_encode($matomoAdmin) !!};
window.__ADMIN_RUNTIME_CONFIG__ = {!! json_encode($adminRuntimeConfig) !!};
</script>
<style nonce="{{ $cspStyleNonce }}">
#root { min-height: 100vh; }
.ns-admin-bg { background: #0b1224; color: #fff; }
.ns-btn-primary { color: #fff; text-decoration: none; background: #ec4899; }
.ns-btn-outline { color: #e5e7eb; text-decoration: none; border: 1px solid rgba(255,255,255,0.2); }
.ns-card-border { border: 1px solid rgba(255,255,255,0.12); background: rgba(255,255,255,0.05); }
</style>
</head>
<body>
@php
$noscriptLocale = in_array(app()->getLocale(), ['de', 'en'], true) ? app()->getLocale() : 'de';
@endphp
<noscript>
<style nonce="{{ $cspStyleNonce }}">
#root { display: none !important; }
</style>
<div class="min-h-screen bg-slate-950 text-white ns-admin-bg">
<div class="mx-auto flex max-w-4xl flex-col gap-10 px-6 py-14">
<header class="space-y-2">
<p class="text-xs font-semibold uppercase tracking-[0.2em] text-pink-300">Fotospiel Admin</p>
<h1 class="text-3xl font-semibold sm:text-4xl">Admin benötigt JavaScript</h1>
<p class="text-base text-white/70 sm:text-lg">Aktiviere JavaScript, um Events zu verwalten, Fotos zu prüfen und Benachrichtigungen zu senden.</p>
</header>
<section class="grid gap-4 sm:grid-cols-2">
<div class="rounded-2xl border border-white/10 bg-white/5 p-5 shadow-lg backdrop-blur ns-card-border">
<h2 class="text-xl font-semibold text-white">Warum JS?</h2>
<ul class="mt-3 space-y-2 text-sm text-white/80">
<li> Echtzeit-Listen für Fotos, Tasks und Emotion-Tags</li>
<li> Upload-Status, Background-Sync und Notifications</li>
<li> Live-Filter, Suche und Inline-Moderation</li>
<li> Sichere OAuth2-Session mit PKCE</li>
</ul>
</div>
<div class="rounded-2xl border border-white/10 bg-white/5 p-5 shadow-lg backdrop-blur ns-card-border">
<h2 class="text-xl font-semibold text-white">Nächste Schritte</h2>
<ol class="mt-3 space-y-2 text-sm text-white/80">
<li>1) JavaScript im Browser aktivieren</li>
<li>2) Seite neu laden</li>
<li>3) Optional: Admin-App zum Homescreen hinzufügen</li>
</ol>
<div class="mt-4 flex flex-wrap gap-3">
<a href="{{ route('marketing.contact', ['locale' => $noscriptLocale]) }}" class="inline-flex items-center justify-center rounded-full bg-pink-500 px-4 py-2 text-sm font-semibold text-white shadow-lg transition hover:bg-pink-400 ns-btn-primary">
Support kontaktieren
</a>
<a href="{{ route('impressum', ['locale' => $noscriptLocale]) }}" class="inline-flex items-center justify-center rounded-full border border-white/20 px-4 py-2 text-sm font-semibold text-white/80 transition hover:border-white/40 ns-btn-outline">
Impressum
</a>
<a href="{{ route('datenschutz', ['locale' => $noscriptLocale]) }}" class="inline-flex items-center justify-center rounded-full border border-white/20 px-4 py-2 text-sm font-semibold text-white/80 transition hover:border-white/40 ns-btn-outline">
Datenschutz
</a>
</div>
</div>
</section>
</div>
</div>
</noscript>
<div id="root"></div>
</body>
</html>