233 lines
12 KiB
PHP
233 lines
12 KiB
PHP
{{-- Account Security – 2/3 : 1/3 Layout --}}
|
||
<div class="grid grid-cols-1 xl:grid-cols-3 gap-5">
|
||
|
||
{{-- ========== LEFT (2/3) ========== --}}
|
||
<div class="xl:col-span-2 space-y-5">
|
||
|
||
{{-- Konto / Profil --}}
|
||
<div class="glass-card p-5">
|
||
<div class="flex items-center justify-between mb-4">
|
||
<div class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1">
|
||
<i class="ph ph-identification-badge text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] uppercase tracking-wide text-white/70">Konto-Informationen</span>
|
||
</div>
|
||
<button wire:click="saveAccount"
|
||
class="inline-flex items-center gap-2 rounded-xl border border-white/10 bg-white/5 px-3 py-1.5 text-white/80 hover:text-white hover:border-white/20">
|
||
<i class="ph ph-floppy-disk text-[14px]"></i> Speichern
|
||
</button>
|
||
</div>
|
||
|
||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||
{{-- Name --}}
|
||
<div>
|
||
<label class="block text-white/60 text-sm mb-1">Name</label>
|
||
<input type="text" wire:model.defer="name"
|
||
class="w-full h-11 rounded-xl border border-white/10 bg-white/[0.04] px-3 text-white/90">
|
||
<p class="mt-1 text-xs text-white/45">Wird in Übersichten und Benachrichtigungen angezeigt.</p>
|
||
</div>
|
||
{{-- Benutzername --}}
|
||
<div>
|
||
<label class="block text-white/60 text-sm mb-1">Benutzername</label>
|
||
<input type="text" wire:model.defer="username"
|
||
class="w-full h-11 rounded-xl border border-white/10 bg-white/[0.04] px-3 text-white/90">
|
||
<p class="mt-1 text-xs text-white/45">Kurzname für Login & UI.</p>
|
||
</div>
|
||
|
||
{{-- Maskierte E-Mail – nur Anzeige --}}
|
||
<div class="md:col-span-2">
|
||
<label class="block text-white/60 text-sm mb-1">E-Mail</label>
|
||
<div class="h-11 flex items-center rounded-xl border border-white/10 bg-white/[0.04] px-3 text-white/70">
|
||
{{ $maskedEmail }}
|
||
</div>
|
||
<p class="mt-1 text-xs text-white/45">Änderung erfolgt rechts in „E-Mail ändern“.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Zwei-Faktor-Authentifizierung --}}
|
||
<div class="glass-card p-5">
|
||
<div class="flex items-center justify-between mb-4">
|
||
<div class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1">
|
||
<i class="ph ph-shield-check text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] uppercase tracking-wide text-white/70">Zwei-Faktor-Authentifizierung</span>
|
||
</div>
|
||
|
||
<span class="px-2.5 py-0.5 rounded-full text-xs border
|
||
{{ $userHas2fa ? 'border-emerald-400/30 text-emerald-300 bg-emerald-500/10'
|
||
: 'border-white/15 text-white/60 bg-white/5' }}">
|
||
{{ $userHas2fa ? '2FA aktiv' : '2FA inaktiv' }}
|
||
</span>
|
||
</div>
|
||
|
||
<div class="space-y-3">
|
||
{{-- TOTP --}}
|
||
<div class="flex items-center justify-between rounded-xl border border-white/10 bg-white/[0.04] px-4 py-3">
|
||
<div class="flex items-center gap-2">
|
||
<span class="w-2 h-2 rounded-full {{ $totpActive ? 'bg-emerald-400' : 'bg-white/30' }}"></span>
|
||
<div>
|
||
<div class="text-white/90">Google Authenticator (TOTP)</div>
|
||
<div class="text-xs text-white/50">
|
||
Einmalcodes via Authenticator-App.
|
||
@if($totpActive)
|
||
<span class="ml-2 text-emerald-300">aktiv</span>
|
||
@else
|
||
<span class="ml-2">nicht eingerichtet</span>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="flex items-center gap-2">
|
||
@if($totpActive)
|
||
<button
|
||
class="text-[13px] px-2.5 py-1 rounded-lg border border-white/10 bg-white/[0.06] text-white/80 hover:border-white/20"
|
||
wire:click="$dispatch('openModal', { component: 'ui.security.totp-setup-modal' })">
|
||
Verwalten
|
||
</button>
|
||
@else
|
||
<button
|
||
class="text-[13px] px-2.5 py-1 rounded-lg border border-white/10 bg-white/[0.06] text-white/80 hover:border-white/20"
|
||
wire:click="$dispatch('openModal', { component: 'ui.security.modal.totp-setup-modal' })">
|
||
Einrichten
|
||
</button>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
|
||
{{-- E-Mail-Code (Fallback/Alternative) --}}
|
||
<div class="flex items-center justify-between rounded-xl border border-white/10 bg-white/[0.04] px-4 py-3">
|
||
<div class="flex items-center gap-2">
|
||
<span class="w-2 h-2 rounded-full {{ $email2faActive ? 'bg-emerald-400' : 'bg-white/30' }}"></span>
|
||
<div>
|
||
<div class="text-white/90">E-Mail-Code</div>
|
||
<div class="text-xs text-white/50">
|
||
Einmalcode per E-Mail.
|
||
@if($email2faActive)
|
||
<span class="ml-2 text-emerald-300">aktiv</span>
|
||
@else
|
||
<span class="ml-2">nicht eingerichtet</span>
|
||
@endif
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<button
|
||
class="text-[13px] px-2.5 py-1 rounded-lg border border-white/10 bg-white/[0.06] text-white/80 hover:border-white/20"
|
||
wire:click="$dispatch('openModal', { component: 'ui.security.modal.email2fa-setup-modal' })">
|
||
{{ $email2faActive ? 'Verwalten' : 'Einrichten' }}
|
||
</button>
|
||
</div>
|
||
|
||
{{-- Recovery-Codes (optional, wenn du das implementierst) --}}
|
||
<div class="flex items-center justify-between rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2.5">
|
||
<div class="text-white/85">
|
||
<div class="font-medium">Recovery-Codes</div>
|
||
<div class="text-white/60 text-sm">Einmal nutzbare Notfallcodes. Sicher aufbewahren.</div>
|
||
</div>
|
||
<button type="button"
|
||
class="text-[13px] px-2.5 py-1 rounded-lg border border-white/10 bg-white/[0.06] text-white/80 hover:border-white/20"
|
||
wire:click="$dispatch('openModal', { component: 'ui.security.modal.recovery-codes-modal' })">
|
||
Recovery-Codes
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- ========== RIGHT (1/3) ========== --}}
|
||
<div class="space-y-5">
|
||
|
||
{{-- Passwort ändern --}}
|
||
<div class="glass-card p-5">
|
||
<div class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1 mb-4">
|
||
<i class="ph ph-lock text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] uppercase tracking-wide text-white/70">Passwort ändern</span>
|
||
</div>
|
||
|
||
<div class="space-y-3">
|
||
<div>
|
||
<label class="block text-white/60 text-sm mb-1">Neues Passwort</label>
|
||
<input type="password" wire:model.defer="new_password"
|
||
class="w-full h-11 rounded-xl border border-white/10 bg-white/[0.04] px-3 text-white/90">
|
||
</div>
|
||
<div>
|
||
<label class="block text-white/60 text-sm mb-1">Bestätigung</label>
|
||
<input type="password" wire:model.defer="new_password_confirmation"
|
||
class="w-full h-11 rounded-xl border border-white/10 bg-white/[0.04] px-3 text-white/90">
|
||
</div>
|
||
<button wire:click="changePassword" class="primary-btn w-full justify-center">
|
||
Setzen
|
||
</button>
|
||
@error('new_password') <p class="text-sm text-rose-400">{{ $message }}</p> @enderror
|
||
@error('new_password_confirmation') <p class="text-sm text-rose-400">{{ $message }}</p> @enderror
|
||
</div>
|
||
</div>
|
||
|
||
{{-- E-Mail ändern (editierbar) --}}
|
||
<div class="glass-card p-5">
|
||
<div class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1 mb-4">
|
||
<i class="ph ph-at text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] uppercase tracking-wide text-white/70">E-Mail ändern</span>
|
||
</div>
|
||
|
||
<div class="space-y-3">
|
||
<div>
|
||
<label class="block text-white/60 text-sm mb-1">Aktuelle E-Mail</label>
|
||
<input type="email" wire:model.defer="email_current"
|
||
placeholder="deine aktuelle E-Mail"
|
||
class="w-full h-11 rounded-xl border border-white/10 bg-white/[0.04] px-3 text-white/90">
|
||
</div>
|
||
<div>
|
||
<label class="block text-white/60 text-sm mb-1">Neue E-Mail</label>
|
||
<input type="email" wire:model.defer="email_new"
|
||
placeholder="neue E-Mail"
|
||
class="w-full h-11 rounded-xl border border-white/10 bg-white/[0.04] px-3 text-white/90">
|
||
</div>
|
||
<button wire:click="changeEmail" class="primary-btn w-full justify-center">
|
||
Speichern
|
||
</button>
|
||
|
||
<p class="text-xs text-white/50">Wir senden dir einen Bestätigungslink an die neue Adresse.</p>
|
||
@error('email_current') <p class="text-xs text-rose-400">{{ $message }}</p> @enderror
|
||
@error('email_new') <p class="text-xs text-rose-400">{{ $message }}</p> @enderror
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Anmeldungen & Geräte --}}
|
||
<div class="glass-card p-5">
|
||
<div class="flex items-center justify-between mb-3">
|
||
<div class="inline-flex items-center gap-2 rounded-full bg-white/5 border border-white/10 px-2.5 py-1">
|
||
<i class="ph ph-devices text-white/70 text-[13px]"></i>
|
||
<span class="text-[11px] uppercase tracking-wide text-white/70">Anmeldungen & Geräte</span>
|
||
</div>
|
||
<button wire:click="logoutOthers"
|
||
class="text-[13px] px-2.5 py-1 rounded-lg border border-white/10 bg-white/[0.06] text-white/80 hover:border-white/20">
|
||
Alle abmelden
|
||
</button>
|
||
</div>
|
||
|
||
@if(empty($sessions))
|
||
<div class="text-sm text-white/50">Keine Sitzungen gefunden.</div>
|
||
@else
|
||
<ul class="space-y-2">
|
||
@foreach($sessions as $s)
|
||
<li class="flex items-center justify-between rounded-lg border border-white/10 bg-white/[0.03] px-3 py-2">
|
||
<div class="text-sm text-white/80">
|
||
{{ $s['device'] }} · {{ $s['ip'] }}
|
||
<span class="text-white/50">— {{ $s['seen'] }}</span>
|
||
</div>
|
||
@if(!$s['current'])
|
||
<button class="text-[12px] px-2 py-0.5 rounded border border-white/10 hover:border-white/20"
|
||
wire:click="logoutSession('{{ $s['id'] }}')">Abmelden</button>
|
||
@else
|
||
<span class="text-[12px] text-emerald-300">Aktuelle Sitzung</span>
|
||
@endif
|
||
</li>
|
||
@endforeach
|
||
</ul>
|
||
@endif
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|