clusev/resources/views/livewire/settings/login-protection.blade.php

93 lines
5.3 KiB
PHP

@php
$field = 'h-9 w-full rounded-md border border-line bg-inset px-3 font-sans text-sm text-ink placeholder:text-ink-4 focus:border-accent/40 focus:outline-none';
$label = 'mb-1 block font-mono text-[11px] uppercase tracking-wider text-ink-3';
$err = 'mt-1 flex items-center gap-1.5 font-mono text-[11px] text-offline';
@endphp
<div class="space-y-5">
<x-panel :title="__('settings.lp_title')" :subtitle="__('settings.lp_subtitle')">
<form wire:submit="save" class="space-y-4">
<x-checkbox wire:model="enabled" label="{{ __('settings.lp_enabled') }}" />
<div class="grid gap-4 sm:grid-cols-3">
<div>
<label class="{{ $label }}">{{ __('settings.lp_maxretry') }}</label>
<input wire:model="maxretry" type="text" inputmode="numeric" class="{{ $field }}" />
@error('maxretry') <p class="{{ $err }}"><x-icon name="alert" class="h-3.5 w-3.5 shrink-0" />{{ $message }}</p> @enderror
</div>
<div>
<label class="{{ $label }}">{{ __('settings.lp_findtime') }}</label>
<input wire:model="findtime" type="text" inputmode="numeric" class="{{ $field }}" />
@error('findtime') <p class="{{ $err }}"><x-icon name="alert" class="h-3.5 w-3.5 shrink-0" />{{ $message }}</p> @enderror
</div>
<div>
<label class="{{ $label }}">{{ __('settings.lp_bantime') }}</label>
<input wire:model="bantime" type="text" inputmode="numeric" class="{{ $field }}" />
@error('bantime') <p class="{{ $err }}"><x-icon name="alert" class="h-3.5 w-3.5 shrink-0" />{{ $message }}</p> @enderror
</div>
</div>
<div>
<label class="{{ $label }}">{{ __('settings.lp_whitelist') }}</label>
<textarea wire:model="whitelist" rows="4" class="{{ $field }} h-auto py-2 font-mono"></textarea>
<p class="mt-1 font-mono text-[11px] text-ink-4">{{ __('settings.lp_whitelist_hint') }}</p>
@error('whitelist') <p class="{{ $err }}"><x-icon name="alert" class="h-3.5 w-3.5 shrink-0" />{{ $message }}</p> @enderror
</div>
<div class="flex flex-wrap items-center justify-between gap-3 border-t border-line pt-4">
<p class="font-mono text-[11px] text-ink-4">
{{ __('settings.lp_current_ip') }}: <span class="text-ink-2">{{ $currentIp }}</span>
@if ($currentIpExempt) <span class="text-online">· {{ __('settings.lp_current_ip_exempt') }}</span> @endif
<button type="button" wire:click="whitelistMyIp" class="ml-2 text-accent-text hover:underline">{{ __('settings.lp_whitelist_my_ip') }}</button>
</p>
<x-btn variant="primary" size="lg" type="submit">{{ __('settings.lp_save') }}</x-btn>
</div>
</form>
</x-panel>
<x-panel :title="__('settings.lp_bans_title')">
<div class="divide-y divide-line">
@forelse ($bans as $ban)
<div wire:key="ban-{{ $ban->getKey() }}" class="flex flex-wrap items-center gap-3 py-3">
<div class="min-w-0 flex-1">
<p class="truncate font-mono text-sm text-ink">{{ $ban->ip }}</p>
<p class="truncate font-mono text-[11px] text-ink-3">
{{ __('settings.lp_ban_reason') }}: {{ $ban->reason ?? '—' }}
· {{ __('settings.lp_ban_attempts') }}: {{ $ban->attempts }}
· {{ __('settings.lp_ban_until', ['time' => $ban->banned_until->diffForHumans()]) }}
</p>
</div>
<x-modal-trigger variant="secondary" class="shrink-0" action="confirmUnban('{{ $ban->ip }}')">
{{ __('settings.lp_unban') }}
</x-modal-trigger>
</div>
@empty
<p class="py-3 font-mono text-[11px] text-ink-4">{{ __('settings.lp_no_bans') }}</p>
@endforelse
</div>
@if ($bans->isNotEmpty())
<div class="flex justify-end border-t border-line pt-4">
<x-modal-trigger variant="danger-soft" action="confirmUnbanAll">{{ __('settings.lp_unban_all') }}</x-modal-trigger>
</div>
@endif
</x-panel>
{{-- Honeypot deception layer read-only status (env-driven, no toggle here). --}}
<x-panel :title="__('settings.hp_title')" :subtitle="__('settings.hp_subtitle')">
<div class="flex flex-wrap items-center justify-between gap-3">
<p class="flex items-start gap-2 font-mono text-[11px] text-ink-3">
<x-icon name="shield-alert" class="mt-0.5 h-3.5 w-3.5 shrink-0 text-ink-4" />
<span>{{ __('settings.hp_note') }}</span>
</p>
<x-status-pill :status="$honeypotEnabled ? 'online' : 'offline'" class="shrink-0">
{{ $honeypotEnabled ? __('settings.hp_on') : __('settings.hp_off') }}
</x-status-pill>
</div>
</x-panel>
<p class="flex items-start gap-2 px-1 font-mono text-[11px] text-ink-4">
<x-icon name="shield" class="mt-0.5 h-3.5 w-3.5 shrink-0" />
<span>{{ __('settings.lp_lockout_note') }}</span>
</p>
</div>