Files
WebAPP/resources/views/admin/activity-logs/index.blade.php
Rhino 2e24a40d68 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>
2026-03-02 07:30:37 +01:00

150 lines
11 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<x-layouts.admin :title="__('admin.activity_log_title')">
<h1 class="text-2xl font-bold mb-6">{{ __('admin.activity_log_title') }}</h1>
{{-- Filter --}}
<form method="GET" class="bg-white rounded-lg shadow p-4 mb-6">
<div class="flex flex-wrap gap-4 items-end">
<div>
<label class="block text-xs font-medium text-gray-600 mb-1">{{ __('admin.log_category') }}</label>
<select name="category" class="px-3 py-2 border border-gray-300 rounded-md text-sm">
<option value="">{{ __('admin.log_all_categories') }}</option>
<option value="auth" {{ request('category') === 'auth' ? 'selected' : '' }}>{{ __('admin.log_cat_auth') }}</option>
<option value="users" {{ request('category') === 'users' ? 'selected' : '' }}>{{ __('admin.log_cat_users') }}</option>
<option value="players" {{ request('category') === 'players' ? 'selected' : '' }}>{{ __('admin.log_cat_players') }}</option>
<option value="events" {{ request('category') === 'events' ? 'selected' : '' }}>{{ __('admin.log_cat_events') }}</option>
<option value="files" {{ request('category') === 'files' ? 'selected' : '' }}>{{ __('admin.log_cat_files') }}</option>
<option value="settings" {{ request('category') === 'settings' ? 'selected' : '' }}>{{ __('admin.log_cat_settings') }}</option>
<option value="dsgvo" {{ request('category') === 'dsgvo' ? 'selected' : '' }}>{{ __('admin.log_cat_dsgvo') }}</option>
</select>
</div>
<div>
<label class="block text-xs font-medium text-gray-600 mb-1">{{ __('admin.log_from') }}</label>
<input type="date" name="from" value="{{ request('from') }}" class="px-3 py-2 border border-gray-300 rounded-md text-sm">
</div>
<div>
<label class="block text-xs font-medium text-gray-600 mb-1">{{ __('admin.log_to') }}</label>
<input type="date" name="to" value="{{ request('to') }}" class="px-3 py-2 border border-gray-300 rounded-md text-sm">
</div>
<div class="flex gap-2">
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded-md text-sm font-medium hover:bg-blue-700">{{ __('admin.log_filter') }}</button>
<a href="{{ route('admin.activity-logs.index') }}" class="bg-gray-200 text-gray-700 px-4 py-2 rounded-md text-sm font-medium hover:bg-gray-300">{{ __('admin.log_reset') }}</a>
</div>
</div>
</form>
{{-- Tabelle --}}
<div class="bg-white rounded-lg shadow overflow-hidden overflow-x-auto">
<table class="w-full text-sm">
<thead class="bg-gray-50 border-b">
<tr>
<th class="text-left px-4 py-3 font-medium text-gray-700">{{ __('admin.log_time') }}</th>
<th class="text-left px-4 py-3 font-medium text-gray-700">{{ __('admin.log_user') }}</th>
<th class="text-center px-4 py-3 font-medium text-gray-700">{{ __('admin.log_action') }}</th>
<th class="text-left px-4 py-3 font-medium text-gray-700">{{ __('admin.log_description') }}</th>
<th class="text-right px-4 py-3 font-medium text-gray-700">{{ __('admin.log_ip') }}</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100">
@forelse ($logs as $log)
@php
$actionColors = [
'login' => 'bg-green-100 text-green-800',
'logout' => 'bg-gray-100 text-gray-800',
'login_failed' => 'bg-red-100 text-red-800',
'registered' => 'bg-blue-100 text-blue-800',
'created' => 'bg-blue-100 text-blue-800',
'updated' => 'bg-yellow-100 text-yellow-800',
'deleted' => 'bg-red-100 text-red-800',
'restored' => 'bg-green-100 text-green-800',
'toggled_active' => 'bg-yellow-100 text-yellow-800',
'role_changed' => 'bg-purple-100 text-purple-800',
'password_reset' => 'bg-orange-100 text-orange-800',
'parent_assigned' => 'bg-blue-100 text-blue-800',
'parent_removed' => 'bg-red-100 text-red-800',
'participant_status_changed' => 'bg-yellow-100 text-yellow-800',
'status_changed' => 'bg-yellow-100 text-yellow-800',
'uploaded' => 'bg-blue-100 text-blue-800',
'reverted' => 'bg-orange-100 text-orange-800',
'bot_blocked' => 'bg-red-100 text-red-800',
'dsgvo_consent_uploaded' => 'bg-blue-100 text-blue-800',
'dsgvo_consent_confirmed' => 'bg-green-100 text-green-800',
'dsgvo_consent_revoked' => 'bg-yellow-100 text-yellow-800',
'dsgvo_consent_removed' => 'bg-orange-100 text-orange-800',
'dsgvo_consent_rejected' => 'bg-red-100 text-red-800',
'account_self_deleted' => 'bg-red-100 text-red-800',
'child_auto_deactivated' => 'bg-red-100 text-red-800',
];
$color = $actionColors[$log->action] ?? 'bg-gray-100 text-gray-800';
$hasDetails = !empty($log->properties);
@endphp
<tr class="hover:bg-gray-50" x-data="{ open: false }">
<td class="px-4 py-3 text-gray-500 whitespace-nowrap">{{ $log->created_at->format('d.m.Y H:i') }}</td>
<td class="px-4 py-3 text-gray-900">{{ $log->user?->name ?? __('admin.log_system') }}</td>
<td class="px-4 py-3 text-center">
<span class="inline-block px-2 py-0.5 rounded-full text-xs font-medium {{ $color }}">{{ $log->action }}</span>
</td>
<td class="px-4 py-3 text-gray-600">
<div>{{ $log->description }}</div>
@if ($hasDetails)
<button @click="open = !open" class="text-xs text-blue-600 hover:text-blue-800 mt-1 flex items-center gap-1">
<svg class="w-3 h-3 transition-transform" :class="open ? 'rotate-90' : ''" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/></svg>
{{ __('admin.log_details') }}
</button>
<div x-show="open" x-cloak x-transition class="mt-2 bg-gray-50 rounded-md p-3 text-xs space-y-1">
@php
$oldData = $log->properties['old'] ?? [];
$newData = $log->properties['new'] ?? [];
$allKeys = array_unique(array_merge(array_keys($oldData), array_keys($newData)));
@endphp
@if (count($allKeys) > 0)
<table class="w-full">
<thead>
<tr class="text-gray-500">
<th class="text-left font-medium pr-3 pb-1">{{ __('admin.log_field') }}</th>
<th class="text-left font-medium pr-3 pb-1">{{ __('admin.log_old_value') }}</th>
<th class="text-left font-medium pb-1">{{ __('admin.log_new_value') }}</th>
</tr>
</thead>
<tbody>
@foreach ($allKeys as $key)
<tr>
<td class="pr-3 py-0.5 font-medium text-gray-600">{{ $key }}</td>
<td class="pr-3 py-0.5 {{ isset($oldData[$key]) ? 'text-red-600 line-through' : 'text-gray-400' }}">{{ $oldData[$key] ?? '' }}</td>
<td class="py-0.5 {{ isset($newData[$key]) ? 'text-green-700' : 'text-gray-400' }}">{{ $newData[$key] ?? '' }}</td>
</tr>
@endforeach
</tbody>
</table>
@endif
</div>
@endif
</td>
<td class="px-4 py-3 text-right whitespace-nowrap">
<span class="text-gray-400 text-xs">{{ $log->ip_address }}</span>
@php
$revertableActions = ['deleted', 'toggled_active', 'role_changed', 'status_changed', 'participant_status_changed'];
$canRevert = in_array($log->action, $revertableActions) && $log->model_id;
@endphp
@if ($canRevert)
<form method="POST" action="{{ route('admin.activity-logs.revert', $log) }}"
onsubmit="return confirm(@js(__('admin.log_revert_confirm')))" class="inline ml-2">
@csrf
<button type="submit" class="text-xs text-orange-600 hover:text-orange-800 font-medium">
{{ __('admin.log_revert') }}
</button>
</form>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="5" class="px-4 py-8 text-center text-gray-500">{{ __('admin.log_empty') }}</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<div class="mt-4">{{ $logs->links() }}</div>
</x-layouts.admin>