presseportale/resources/views/livewire/auth/register.blade.php
Kevin Adametz 9fadfe6458 5.5: <x-password-input> + 6 Auth-Passwortfelder umgestellt
Self-contained Alpine-Toggle (Anzeigen/Verbergen) pro Feld; Props name/label/
autocomplete/placeholder/required/autofocus/show-error, id default auth-<name>,
Slot :labelAction fuer den 'Passwort vergessen?'-Link (login). Ersetzt die
field-pw-wrap-Bloecke in login, register (2), reset-password (2), confirm-
password (1). Die nun ungenutzten form-level x-data={showPassword...} entfernt.

Nebeneffekt/Bugfix: register+reset nutzten :placeholder="__(...)" auf rohem
<input> -> wurde als Alpine-Bind woertlich ausgegeben und schlug fehl (leerer
Platzhalter). Als Component-Prop wird __() korrekt in PHP aufgeloest, der
Hinweistext (z. B. 'Mindestens 8 Zeichen') erscheint jetzt.

Bestaetigungsfelder ohne Fehleranzeige (show-error=false, wie zuvor).
116 Auth-Tests gruen, alle Views kompilieren.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 09:04:26 +00:00

159 lines
6.6 KiB
PHP

<?php
use App\Models\User;
use Illuminate\Auth\Events\Registered;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\Rules;
use Livewire\Attributes\Layout;
use Livewire\Volt\Component;
new #[Layout('components.layouts.auth.pressekonto', ['heading' => 'Konto erstellen', 'eyebrow' => 'Registrierung im Publisher-Hub', 'topRightLabel' => 'Bereits Konto?', 'topRightLinkText' => 'Anmelden', 'topRightLinkHref' => '/login'])] class extends Component {
public string $name = '';
public string $email = '';
public string $password = '';
public string $password_confirmation = '';
public bool $terms_accepted = false;
/**
* Handle an incoming registration request.
*/
public function register(): void
{
$validated = $this->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
'password' => ['required', 'string', 'confirmed', Rules\Password::defaults()],
'terms_accepted' => ['accepted'],
], [
'terms_accepted.accepted' => 'Bitte bestätigen Sie unsere AGB und die Datenschutzerklärung.',
]);
unset($validated['terms_accepted']);
$validated['password'] = Hash::make($validated['password']);
// Konto bleibt bis zur E-Mail-Verifizierung inaktiv und rollenlos
// (Entscheidung 15.06.). Rolle + Aktivierung erfolgen erst nach dem
// bestätigten Verifizierungslink (ActivateUserAfterVerification).
$validated['is_active'] = false;
// Das Registered-Event versendet über den verdrahteten
// SendEmailVerificationNotification-Listener die Bestätigungsmail.
event(new Registered($user = User::create($validated)));
Auth::login($user);
// Direkt zur Bestätigungs-/Notice-Seite. Ohne navigate:true, weil das
// Panel ein anderes Vite-Bundle nutzt als das Hub-Auth-Layout.
$this->redirect(route('verification.notice', absolute: false));
}
}; ?>
<div>
<x-session-status class="mb-4" />
<form wire:submit="register" class="space-y-[18px]" novalidate>
<div>
<label class="field-label" for="auth-name">{{ __('Name') }}</label>
<input
id="auth-name"
type="text"
wire:model="name"
required
autofocus
autocomplete="name"
class="field-input"
:placeholder="__('Vor- und Nachname')"
@error('name') aria-invalid="true" @enderror
/>
@error('name')
<p class="field-error">{{ $message }}</p>
@enderror
</div>
<div>
<label class="field-label" for="auth-email">{{ __('E-Mail-Adresse') }}</label>
<input
id="auth-email"
type="email"
wire:model="email"
required
autocomplete="email"
class="field-input"
placeholder="redaktion@ihr-unternehmen.de"
@error('email') aria-invalid="true" @enderror
/>
@error('email')
<p class="field-error">{{ $message }}</p>
@enderror
</div>
<x-password-input
name="password"
:label="__('Passwort')"
autocomplete="new-password"
:placeholder="__('Mindestens 8 Zeichen')"
/>
<x-password-input
name="password_confirmation"
:label="__('Passwort bestätigen')"
autocomplete="new-password"
:placeholder="__('Passwort wiederholen')"
:show-error="false"
/>
<div class="!mt-5">
<label for="auth-terms" class="flex items-start gap-3 cursor-pointer select-none">
<input
id="auth-terms"
type="checkbox"
wire:model="terms_accepted"
required
class="auth-check !mt-[3px]"
@error('terms_accepted') aria-invalid="true" @enderror
/>
<span class="text-[12.5px] text-ink-2 leading-[1.55]">
{{ __('Ich habe die') }}
<a href="{{ route('agb') }}" target="_blank" rel="noopener" class="link-hub">{{ __('AGB') }}</a>
{{ __('und die') }}
<a href="{{ route('datenschutz') }}" target="_blank" rel="noopener" class="link-hub">{{ __('Datenschutzerklärung') }}</a>
{{ __('gelesen und stimme der Verarbeitung meiner Daten zur Konto-Erstellung ausdrücklich zu.') }}
</span>
</label>
@error('terms_accepted')
<p class="field-error !ml-7">{{ $message }}</p>
@enderror
</div>
<button type="submit" class="auth-btn-primary !mt-[18px]" wire:loading.attr="disabled" wire:target="register">
<span wire:loading.remove wire:target="register">{{ __('Konto erstellen') }}</span>
<span wire:loading wire:target="register">{{ __('Konto wird angelegt …') }}</span>
</button>
<div class="flex items-center gap-3 !mt-[22px] !mb-[14px]">
<span class="flex-1 h-px bg-bg-rule"></span>
<span class="text-[11px] font-semibold tracking-[0.18em] uppercase text-ink-3">{{ __('Bereits Konto?') }}</span>
<span class="flex-1 h-px bg-bg-rule"></span>
</div>
<a href="{{ route('login') }}" class="auth-btn-outline !mt-0" wire:navigate>
{{ __('Stattdessen anmelden') }}
</a>
<a href="{{ route('oauth.google.redirect') }}" class="auth-btn-outline !mt-3">
<svg width="15" height="15" viewBox="0 0 18 18" aria-hidden="true">
<path fill="#4285F4" d="M17.64 9.2c0-.64-.06-1.25-.16-1.84H9v3.48h4.84a4.14 4.14 0 0 1-1.8 2.72v2.26h2.92c1.71-1.57 2.68-3.89 2.68-6.62z"/>
<path fill="#34A853" d="M9 18c2.43 0 4.47-.8 5.96-2.18l-2.92-2.26c-.81.54-1.84.86-3.04.86-2.34 0-4.32-1.58-5.03-3.7H.96v2.33A9 9 0 0 0 9 18z"/>
<path fill="#FBBC05" d="M3.97 10.72A5.4 5.4 0 0 1 3.68 9c0-.6.1-1.18.29-1.72V4.95H.96A9 9 0 0 0 0 9c0 1.45.35 2.82.96 4.05l3.01-2.33z"/>
<path fill="#EA4335" d="M9 3.58c1.32 0 2.5.45 3.44 1.35l2.58-2.59C13.46.89 11.43 0 9 0A9 9 0 0 0 .96 4.95l3.01 2.33C4.68 5.16 6.66 3.58 9 3.58z"/>
</svg>
<span>{{ __('Mit Google registrieren') }}</span>
</a>
</form>
</div>