@extends('admin.layouts.app') @section('title', __('admin.logs.show_title') . ' #' . $log->id . ' โ€” ' . __('admin.brand.name')) @section('page_title', __('admin.logs.show_title')) @php $dash = 'โ€”'; /** Localized action / module names with dictionary fallback. */ $actionLabel = trans()->has('admin.logs.actions.' . $log->action) ? __('admin.logs.actions.' . $log->action) : $log->action; $moduleLabel = trans()->has('admin.logs.modules.' . $log->module) ? __('admin.logs.modules.' . $log->module) : $log->module; /** Pretty short class name: "App\\Models\\Startup" -> "Startup". */ $subjectClass = $log->subject_type ? class_basename($log->subject_type) : null; /** Build initials for the actor avatar tile. */ $adminInitials = '๐Ÿ‘ค'; // guest fallback if ($log->admin && $log->admin->name) { $adminInitials = collect(explode(' ', trim($log->admin->name))) ->filter() ->take(2) ->map(fn ($p) => mb_strtoupper(mb_substr($p, 0, 1))) ->implode('') ?: '๐Ÿ‘ค'; } $hasParsedChange = isset($parsed['old']) || isset($parsed['new']); @endphp @push('styles') @endpush @section('content') {{ __('admin.logs.back_to_list') }}
{{-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Summary card โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --}}
{{ $adminInitials }}

@if ($log->admin) {{ $log->admin->name }} ยท {{ $log->admin->email }} @else {{ __('admin.logs.guest') }} ยท {{ __('admin.logs.guest_subtitle') }} @endif

{{ $actionLabel }} {{ $moduleLabel }} @if ($subjectName) ยท @if ($subjectUrl) {{ $subjectName }} @else {{ $subjectName }} @endif @endif

{{ optional($log->created_at)->format('Y-m-d H:i:s') }} {{ optional($log->created_at)->diffForHumans() }}
{{-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Change diff (if structured) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --}} @if ($hasParsedChange)

{{ __('admin.logs.fields.change') }}

{{ __('admin.logs.fields.field_changed') }}: {{ $parsed['field_label'] ?? $dash }}

{{ __('admin.logs.fields.from') }}

{{ $parsed['old'] ?? __('admin.logs.fields.empty_value') }}

{{ __('admin.logs.fields.to') }}

{{ $parsed['new'] ?? __('admin.logs.fields.empty_value') }}

@endif
{{-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Who โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --}}

{{ __('admin.logs.fields.who') }}

{{ __('admin.logs.fields.admin') }}
@if ($log->admin) {{ $log->admin->name }} @else {{ $dash }} @endif
{{ __('admin.logs.fields.email') }}
{{ $log->admin?->email ?: $dash }}
{{ __('admin.logs.fields.admin_id') }}
{{ $log->admin_id ?: $dash }}
{{-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ What / Where โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --}}

{{ __('admin.logs.fields.target') }}

{{ __('admin.logs.fields.module') }}
{{ $moduleLabel }}
{{ __('admin.logs.fields.subject') }}
@if ($subjectClass) {{ $subjectClass }}#{{ $log->subject_id }} @if ($subjectName)
@if ($subjectUrl) {{ $subjectName }} @else {{ $subjectName }} @endif
@endif @else {{ $dash }} @endif
{{ __('admin.logs.fields.action') }}
{{ $actionLabel }}
{{-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ When โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --}}

{{ __('admin.logs.fields.timestamp') }}

{{ __('admin.logs.fields.exact_time') }}
{{ optional($log->created_at)->format('Y-m-d H:i:s') ?: $dash }}
{{ __('admin.logs.fields.relative_time') }}
{{ optional($log->created_at)->diffForHumans() ?: $dash }}
{{ __('admin.logs.fields.timezone') }}
{{ config('app.timezone') }}
{{-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Network context โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --}}

{{ __('admin.logs.fields.context') }}

{{ __('admin.logs.fields.ip') }}
{{ $log->ip_address ?: $dash }}
{{ __('admin.logs.fields.user_agent') }}
{{ $log->user_agent ?: $dash }}
{{ __('admin.logs.fields.log_id') }}
#{{ $log->id }}
{{-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Raw description (always present) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --}} @if (! empty($log->description))

{{ __('admin.logs.fields.description') }}

{{ $log->description }}
@endif {{-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Structured meta payload (signup submissions, etc.) โ”€โ”€โ”€โ”€โ”€ --}} {{-- For signup events the controller stamps every submitted input + file metadata onto `meta` so admins can audit exactly what was typed on the public form. Rendered as nested key/value tables; arrays / nested objects recurse into their own sub-tables. --}} @if (! empty($log->meta) && is_array($log->meta))

@lang('Submission details')

@php /** * Recursive renderer for the meta payload. Scalar leaves * render in a
; nested arrays render as a nested * key/value table inside the same
. Long values stay * wrappable so wide blobs (about / problem / solution) * don't break the layout. * * @var \Closure $renderMeta */ $renderMeta = function (array $data, int $depth = 0) use (&$renderMeta): string { if ($data === []) { return 'โ€”'; } // Numeric-keyed arrays render as bulleted list to match // human intuition for repeaters (members, files, sectors). $isList = array_keys($data) === range(0, count($data) - 1); if ($isList) { $out = '
    '; foreach ($data as $i => $v) { $out .= '
  1. '; if (is_array($v)) { $out .= $renderMeta($v, $depth + 1); } elseif (is_bool($v)) { $out .= $v ? 'โœ“ true' : 'โœ— false'; } elseif ($v === null || $v === '') { $out .= 'โ€”'; } else { $out .= e((string) $v); } $out .= '
  2. '; } $out .= '
'; return $out; } $out = '
'; foreach ($data as $k => $v) { $label = (string) $k; $out .= '
' . e($label) . '
'; if (is_array($v)) { $out .= $renderMeta($v, $depth + 1); } elseif (is_bool($v)) { $out .= $v ? 'โœ“ true' : 'โœ— false'; } elseif ($v === null || $v === '') { $out .= 'โ€”'; } else { $out .= nl2br(e((string) $v)); } $out .= '
'; } $out .= '
'; return $out; }; @endphp
{!! $renderMeta($log->meta) !!}
@endif
@endsection