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>
This commit is contained in:
Rhino
2026-03-02 07:30:37 +01:00
commit 2e24a40d68
9633 changed files with 1300799 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
<x-layouts.guest :title="__('auth_ui.forgot_password_title')">
<h2 class="text-lg font-bold text-center mb-2">{{ __('auth_ui.forgot_password_title') }}</h2>
<p class="text-sm text-gray-500 text-center mb-6">{{ __('auth_ui.forgot_password_description') }}</p>
@if (session('status'))
<div class="mb-4 p-3 bg-green-50 border border-green-200 rounded-md text-sm text-green-700">
{{ session('status') }}
</div>
@endif
<form method="POST" action="{{ route('password.email') }}">
@csrf
<div class="mb-4">
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">{{ __('auth_ui.email_label') }}</label>
<input
type="email"
name="email"
id="email"
value="{{ old('email') }}"
required
autofocus
autocomplete="email"
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 @error('email') border-red-500 @enderror"
>
@error('email')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<button
type="submit"
class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 font-medium"
>
{{ __('auth_ui.send_reset_link') }}
</button>
</form>
<p class="mt-4 text-sm text-center">
<a href="{{ route('login') }}" class="text-blue-600 hover:text-blue-800 underline">
{{ __('auth_ui.back_to_login') }}
</a>
</p>
</x-layouts.guest>

View File

@@ -0,0 +1,62 @@
<x-layouts.guest :title="__('auth_ui.login_title')">
<h2 class="text-lg font-bold text-center mb-6">{{ __('auth_ui.login_title') }}</h2>
<form method="POST" action="{{ route('login') }}">
@csrf
{{-- Honeypot --}}
<div class="hidden" aria-hidden="true">
<input type="text" name="website" value="" tabindex="-1" autocomplete="off">
</div>
<div class="mb-4">
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">{{ __('auth_ui.email_label') }}</label>
<input
type="email"
name="email"
id="email"
value="{{ old('email') }}"
required
autofocus
autocomplete="email"
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 @error('email') border-red-500 @enderror"
>
@error('email')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<div class="flex items-center justify-between mb-1">
<label for="password" class="block text-sm font-medium text-gray-700">{{ __('auth_ui.password_label') }}</label>
<a href="{{ route('password.request') }}" class="text-xs text-blue-600 hover:text-blue-800 underline">{{ __('auth_ui.forgot_password_link') }}</a>
</div>
<input
type="password"
name="password"
id="password"
required
autocomplete="current-password"
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
</div>
<div class="mb-6 flex items-center">
<input type="checkbox" name="remember" id="remember" class="rounded border-gray-300 mr-2 rtl:ml-2 rtl:mr-0">
<label for="remember" class="text-sm text-gray-600">{{ __('auth_ui.remember_me') }}</label>
</div>
<button
type="submit"
class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 font-medium"
>
{{ __('auth_ui.login_button') }}
</button>
</form>
<p class="mt-4 text-xs text-center text-gray-400 leading-relaxed">
<svg class="inline w-3.5 h-3.5 -mt-0.5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"/></svg>
{{ __('auth_ui.cookie_notice') }}
<a href="/datenschutz#cookies" class="underline hover:text-gray-600">{{ __('auth_ui.cookie_notice_link') }}</a>
</p>
</x-layouts.guest>

View File

@@ -0,0 +1,62 @@
<x-layouts.guest :title="__('auth_ui.register_title')">
<h2 class="text-xl font-bold text-center mb-6">{{ __('auth_ui.register_title') }}</h2>
@if ($invitation->players->isNotEmpty())
<div class="mb-4 p-3 bg-blue-50 border border-blue-200 rounded-md">
<p class="text-sm text-blue-800 font-medium mb-1">{{ __('auth_ui.children_assigned') }}</p>
<ul class="text-sm text-blue-700">
@foreach ($invitation->players as $player)
<li>{{ $player->full_name }} ({{ $player->team->name }})</li>
@endforeach
</ul>
</div>
@endif
<form method="POST" action="{{ route('register', $invitation->token) }}">
@csrf
{{-- Honeypot --}}
<div class="hidden" aria-hidden="true">
<input type="text" name="website" value="" tabindex="-1" autocomplete="off">
</div>
<div class="mb-4">
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">{{ __('auth_ui.name_label') }} *</label>
<input type="text" name="name" id="name" value="{{ old('name') }}" required autofocus
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500 @error('name') border-red-500 @enderror">
@error('name')<p class="mt-1 text-sm text-red-600">{{ $message }}</p>@enderror
</div>
<div class="mb-4">
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">{{ __('auth_ui.email_label') }} *</label>
<input type="email" name="email" id="email" value="{{ old('email', $invitation->email) }}" required
{{ $invitation->email ? 'readonly' : '' }}
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500 @error('email') border-red-500 @enderror {{ $invitation->email ? 'bg-gray-100' : '' }}">
@error('email')<p class="mt-1 text-sm text-red-600">{{ $message }}</p>@enderror
@if ($invitation->email)
<p class="mt-1 text-xs text-gray-500">{{ __('auth_ui.email_fixed_by_invitation') }}</p>
@endif
</div>
<div class="mb-4">
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">{{ __('auth_ui.password_label') }} * <span class="font-normal text-gray-400">{{ __('auth_ui.password_min') }}</span></label>
<input type="password" name="password" id="password" required minlength="8"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500 @error('password') border-red-500 @enderror">
@error('password')<p class="mt-1 text-sm text-red-600">{{ $message }}</p>@enderror
</div>
<div class="mb-6">
<label for="password_confirmation" class="block text-sm font-medium text-gray-700 mb-1">{{ __('auth_ui.password_confirm_label') }} *</label>
<input type="password" name="password_confirmation" id="password_confirmation" required minlength="8"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500">
</div>
<button type="submit" class="w-full bg-blue-600 text-white py-2 rounded-md hover:bg-blue-700 font-medium">
{{ __('auth_ui.create_account') }}
</button>
</form>
<p class="mt-4 text-center text-sm text-gray-500">
{{ __('auth_ui.already_registered') }} <a href="{{ route('login') }}" class="text-blue-600 hover:underline">{{ __('auth_ui.go_to_login') }}</a>
</p>
</x-layouts.guest>

View File

@@ -0,0 +1,65 @@
<x-layouts.guest :title="__('auth_ui.reset_password_title')">
<h2 class="text-lg font-bold text-center mb-6">{{ __('auth_ui.reset_password_title') }}</h2>
<form method="POST" action="{{ route('password.update') }}">
@csrf
<input type="hidden" name="token" value="{{ $token }}">
<div class="mb-4">
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">{{ __('auth_ui.email_label') }}</label>
<input
type="email"
name="email"
id="email"
value="{{ old('email', $email) }}"
required
autocomplete="email"
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 @error('email') border-red-500 @enderror"
>
@error('email')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<div class="mb-4">
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">{{ __('auth_ui.new_password_label') }}</label>
<input
type="password"
name="password"
id="password"
required
autocomplete="new-password"
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 @error('password') border-red-500 @enderror"
>
<p class="mt-1 text-xs text-gray-400">{{ __('auth_ui.password_min') }}</p>
@error('password')
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<div class="mb-6">
<label for="password_confirmation" class="block text-sm font-medium text-gray-700 mb-1">{{ __('auth_ui.confirm_password_label') }}</label>
<input
type="password"
name="password_confirmation"
id="password_confirmation"
required
autocomplete="new-password"
class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
</div>
<button
type="submit"
class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 font-medium"
>
{{ __('auth_ui.reset_password_button') }}
</button>
</form>
<p class="mt-4 text-sm text-center">
<a href="{{ route('login') }}" class="text-blue-600 hover:text-blue-800 underline">
{{ __('auth_ui.back_to_login') }}
</a>
</p>
</x-layouts.guest>