2026-06-16 16:21:43 +02:00
|
|
|
<div>
|
|
|
|
|
<div class="log-filters" x-data="{ open: {{ $hasFilters ? 'true' : 'false' }} }">
|
|
|
|
|
|
|
|
|
|
<div class="log-filters-main">
|
|
|
|
|
<div class="log-search-wrap">
|
|
|
|
|
<i data-lucide="search" size="13"></i>
|
|
|
|
|
<input
|
|
|
|
|
wire:model.live.debounce.300ms="search"
|
|
|
|
|
type="text"
|
|
|
|
|
class="form-input"
|
|
|
|
|
placeholder="Search description, subject, channel…"
|
|
|
|
|
>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<select wire:model.live="event" class="form-select log-select">
|
|
|
|
|
<option value="">All events</option>
|
|
|
|
|
@foreach($events as $e)
|
|
|
|
|
<option value="{{ $e }}">{{ ucfirst($e) }}</option>
|
|
|
|
|
@endforeach
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<select wire:model.live="logName" class="form-select log-select">
|
|
|
|
|
<option value="">All channels</option>
|
|
|
|
|
@foreach($logNames as $name)
|
|
|
|
|
<option value="{{ $name }}">{{ $name }}</option>
|
|
|
|
|
@endforeach
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
|
|
<button @click="open = !open" class="btn {{ $hasFilters ? 'btn--active' : '' }}">
|
|
|
|
|
<i data-lucide="sliders-horizontal" size="13"></i>
|
|
|
|
|
More filters
|
|
|
|
|
@if($hasFilters)
|
|
|
|
|
<span class="log-filter-dot"></span>
|
|
|
|
|
@endif
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
|
|
@if($search || $hasFilters)
|
|
|
|
|
<button wire:click="clearFilters" class="btn">
|
|
|
|
|
<i data-lucide="x" size="13"></i> Clear
|
|
|
|
|
</button>
|
|
|
|
|
@endif
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
x-show="open"
|
|
|
|
|
x-transition:enter="log-transition-enter"
|
|
|
|
|
x-transition:leave="log-transition-leave"
|
|
|
|
|
class="log-filters-extra"
|
|
|
|
|
>
|
|
|
|
|
<div class="log-filters-extra-inner">
|
|
|
|
|
<div class="log-filter-field">
|
|
|
|
|
<label class="log-filter-label">From</label>
|
|
|
|
|
<input wire:model.live="dateFrom" type="date" class="form-input">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="log-filter-field">
|
|
|
|
|
<label class="log-filter-label">To</label>
|
|
|
|
|
<input wire:model.live="dateTo" type="date" class="form-input">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="log-filter-field">
|
|
|
|
|
<label class="log-filter-label">User ID</label>
|
|
|
|
|
<input
|
|
|
|
|
wire:model.live.debounce.400ms="causerId"
|
|
|
|
|
type="text"
|
|
|
|
|
class="form-input"
|
|
|
|
|
placeholder="XenForo user ID"
|
|
|
|
|
>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="log-results-bar">
|
|
|
|
|
<span class="log-results-count">
|
|
|
|
|
<span wire:loading.class="log-loading">
|
|
|
|
|
{{ number_format($logs->total()) }} log entries
|
|
|
|
|
</span>
|
|
|
|
|
</span>
|
|
|
|
|
<span class="log-results-pages">
|
|
|
|
|
Page {{ $logs->currentPage() }} / {{ $logs->lastPage() }}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@if($logs->isEmpty())
|
|
|
|
|
<div class="modcp-empty">
|
|
|
|
|
<i data-lucide="search-x" size="36"></i>
|
|
|
|
|
<p>No logs match your search.</p>
|
|
|
|
|
</div>
|
|
|
|
|
@else
|
|
|
|
|
<div class="modcp-list">
|
|
|
|
|
@foreach($logs as $log)
|
|
|
|
|
|
|
|
|
|
@php
|
|
|
|
|
$old = $log->properties->get('old', []);
|
|
|
|
|
$attrs = $log->properties->get('attributes', []);
|
|
|
|
|
$extra = array_diff_key($log->properties->toArray(), array_flip(['old', 'attributes']));
|
|
|
|
|
$hasDiff = !empty($old) || !empty($attrs) || !empty($extra);
|
|
|
|
|
@endphp
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
class="modcp-list-item log-item"
|
|
|
|
|
x-data="{ open: false }"
|
|
|
|
|
:class="open && 'log-item--open'"
|
|
|
|
|
>
|
|
|
|
|
<div class="log-event-dot log-event-dot--{{ $log->event ?? 'custom' }}">
|
|
|
|
|
@switch($log->event)
|
|
|
|
|
@case('created') <i data-lucide="plus" size="12"></i> @break
|
|
|
|
|
@case('updated') <i data-lucide="pen-line" size="12"></i> @break
|
|
|
|
|
@case('deleted') <i data-lucide="trash-2" size="12"></i> @break
|
|
|
|
|
@default <i data-lucide="zap" size="12"></i>
|
|
|
|
|
@endswitch
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="modcp-list-item-info">
|
|
|
|
|
<span class="modcp-list-item-title">{{ $log->description }}</span>
|
|
|
|
|
<div class="modcp-list-item-meta">
|
|
|
|
|
|
|
|
|
|
@if($log->log_name)
|
|
|
|
|
<span class="log-channel-badge">{{ $log->log_name }}</span>
|
|
|
|
|
<span class="log-sep">·</span>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
@if($log->subject_type)
|
|
|
|
|
<span>
|
|
|
|
|
{{ class_basename($log->subject_type) }}
|
|
|
|
|
<span class="log-id">#{{ $log->subject_id }}</span>
|
|
|
|
|
</span>
|
|
|
|
|
<span class="log-sep">·</span>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
@if($log->causer_id)
|
|
|
|
|
<span>
|
|
|
|
|
<i data-lucide="user" size="10"></i>
|
|
|
|
|
<x-xf-username-link :user-id="$log->causer_id" />
|
|
|
|
|
</span>
|
|
|
|
|
<span class="log-sep">·</span>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
<span title="{{ $log->created_at->format('d M Y, H:i:s') }}">
|
|
|
|
|
{{ $log->created_at->diffForHumans() }}
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="log-item-right">
|
|
|
|
|
<span class="log-timestamp">{{ $log->created_at->format('d M Y, H:i') }}</span>
|
|
|
|
|
|
|
|
|
|
@if($hasDiff)
|
|
|
|
|
<button
|
|
|
|
|
@click="open = !open"
|
|
|
|
|
class="btn btn--sm log-expand-btn"
|
|
|
|
|
:class="open && 'btn--active'"
|
|
|
|
|
:aria-label="open ? 'Hide details' : 'Show details'"
|
|
|
|
|
>
|
|
|
|
|
<i data-lucide="chevron-down" size="12"
|
|
|
|
|
style="transition: transform .15s"
|
|
|
|
|
:style="open ? 'transform:rotate(180deg)' : ''">
|
|
|
|
|
</i>
|
|
|
|
|
</button>
|
|
|
|
|
@endif
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
@if($hasDiff)
|
|
|
|
|
<div x-show="open" x-transition class="log-properties">
|
|
|
|
|
|
|
|
|
|
@if(!empty($old) || !empty($attrs))
|
|
|
|
|
<div class="log-diff-label">Changes</div>
|
|
|
|
|
<table class="log-diff">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th>Field</th>
|
|
|
|
|
<th class="log-diff-old-head">Before</th>
|
|
|
|
|
<th class="log-diff-new-head">After</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
@foreach(array_unique(array_merge(array_keys((array)$old), array_keys((array)$attrs))) as $key)
|
|
|
|
|
<tr>
|
|
|
|
|
<td class="log-diff-key">{{ $key }}</td>
|
|
|
|
|
<td class="log-diff-old">
|
|
|
|
|
{{ is_array($old[$key] ?? null) ? json_encode($old[$key]) : ($old[$key] ?? '—') }}
|
|
|
|
|
</td>
|
|
|
|
|
<td class="log-diff-new">
|
|
|
|
|
{{ is_array($attrs[$key] ?? null) ? json_encode($attrs[$key]) : ($attrs[$key] ?? '—') }}
|
|
|
|
|
</td>
|
|
|
|
|
</tr>
|
|
|
|
|
@endforeach
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
@if(!empty($extra))
|
|
|
|
|
<div class="log-diff-label" style="margin-top: 10px">Properties</div>
|
|
|
|
|
<pre class="log-raw">{{ json_encode($extra, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) }}</pre>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
@endforeach
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="log-pagination">
|
2026-06-30 14:06:11 +02:00
|
|
|
{{ $logs->links('modcp.pagination') }}
|
2026-06-16 16:21:43 +02:00
|
|
|
</div>
|
|
|
|
|
@endif
|
|
|
|
|
|
|
|
|
|
</div>
|