@extends('admin.layouts.app') @section('title', __('admin.notification_logs_admin.list_title') . ' โ€” ' . __('admin.brand.name')) @section('page_title', __('admin.notification_logs_admin.list_title')) @php use App\Models\NotificationLog; $filterKeys = ['type', 'channel', 'status', 'module', 'admin_id', 'recipient_type', 'from', 'to']; $activeFilters = collect($filterKeys)->filter(fn ($k) => filled(request($k)))->count(); $locale = app()->getLocale(); $nameField = $locale === 'ar' ? 'name_ar' : 'name_en'; /** Channel display: icon + colour. */ $channelMeta = [ NotificationLog::CHANNEL_EMAIL => ['icon' => 'โœ‰๏ธ', 'fg' => '#1d4ed8', 'bg' => '#dbeafe', 'label' => __('admin.notification_logs_admin.channels.email')], NotificationLog::CHANNEL_SMS => ['icon' => '๐Ÿ’ฌ', 'fg' => '#7c2d12', 'bg' => '#fed7aa', 'label' => __('admin.notification_logs_admin.channels.sms')], NotificationLog::CHANNEL_WHATSAPP => ['icon' => '๐ŸŸข', 'fg' => '#166534', 'bg' => '#bbf7d0', 'label' => __('admin.notification_logs_admin.channels.whatsapp')], NotificationLog::CHANNEL_PUSH => ['icon' => 'โ†‘', 'fg' => '#0369a1', 'bg' => '#e0f2fe', 'label' => __('admin.notification_logs_admin.channels.push')], NotificationLog::CHANNEL_NOTIFICATION => ['icon' => '๐Ÿ””', 'fg' => '#4338ca', 'bg' => '#e0e7ff', 'label' => __('admin.notification_logs_admin.channels.notification')], ]; @endphp @section('content') @include('admin.partials.flash') {{-- Bulk-retry form lives OUTSIDE the table so per-row action forms are never nested. Row checkboxes attach to it via the HTML5 `form=` attribute; their failed-row ids are injected on submit by JS. --}}
@csrf
{{-- โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Summary counters โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ --}}
{{ number_format($counters['events']) }}
{{ __('admin.notification_logs_admin.counters.events') }}
{{ number_format($counters['sent']) }}
{{ __('admin.notification_logs_admin.counters.sent') }}
{{ number_format($counters['failed']) }}
{{ __('admin.notification_logs_admin.counters.failed') }}
{{ number_format($counters['pending']) }}
{{ __('admin.notification_logs_admin.counters.pending') }}
@foreach (request()->only(['q', 'sort', 'dir']) as $key => $value) @endforeach
@if ($events->isEmpty()) @else {{-- Bulk action bar โ€” appears when failed rows exist on the page. --}}
{{ __('admin.notification_logs_admin.retry.test_send_hint') }}
@foreach ($events as $event) @php $detailUrl = $event->event_id ? route('admin.notification-logs.event', $event->event_id) : route('admin.notification-logs.show', $event->first_id); // occurred_at comes back as a string from MAX(created_at) โ€” cast for display. $when = $event->occurred_at ? \Illuminate\Support\Carbon::parse($event->occurred_at) : null; $newOptName = $event->new_option?->{$nameField} ?: $event->new_option?->name_en; $oldOptName = $event->old_option?->{$nameField} ?: $event->old_option?->name_en; // Automation dispatches stamp triggered_event as // 'automation:'; label-option changes don't. $isAutomation = \Illuminate\Support\Str::startsWith((string) $event->triggered_event, 'automation:'); $autoTrigger = $isAutomation ? \Illuminate\Support\Str::after((string) $event->triggered_event, 'automation:') : null; // Failed/undelivered channel-row ids in this event โ€” the // exact rows a retry should re-fire (one per failed channel). $failedIds = collect(explode(',', (string) $event->failed_ids_csv)) ->filter(fn ($v) => $v !== '' && $v !== null) ->map(fn ($v) => (int) $v) ->values(); $hasFailures = $failedIds->isNotEmpty(); $firstFailedId = $failedIds->first(); $recipient = $event->recipient_model; $recipientName = $recipient->name ?? '#'.$event->recipient_id; $recipientUrl = null; if ($event->recipient_type === \App\Models\Investor::class && $event->recipient_id) { $recipientUrl = route('admin.investors.show', $event->recipient_id); } elseif ($event->recipient_type === \App\Models\Startup::class && $event->recipient_id) { $recipientUrl = route('admin.startups.show', $event->recipient_id); } @endphp @endforeach
{{ __('admin.notification_logs_admin.fields.occurred_at') }} {{ __('admin.notification_logs_admin.fields.action') }} {{ __('admin.notification_logs_admin.fields.recipient') }} {{ __('admin.notification_logs_admin.fields.channels') }} {{ __('admin.notification_logs_admin.fields.summary') }} {{ __('admin.notification_logs_admin.fields.admin') }}
@if ($hasFailures) @endif @if ($when) {{ $when->format('Y-m-d H:i:s') }} {{ $when->diffForHumans() }} @else โ€” @endif @if ($isAutomation) {{-- Automation dispatch โ€” name lives in new_value. --}} {{ __('admin.notification_logs_admin.types.automation') }} {{ $event->new_value ?: __('admin.notification_logs_admin.types.automation') }} @if ($autoTrigger) {{ $autoTrigger }} @endif @else {{-- Label-option change (Action). --}} {{ __('admin.notification_logs_admin.types.action') }} @if ($newOptName) {{ $newOptName }} @else โ€” @endif @if ($event->label_key) {{ $event->label_key }} @endif @if ($oldOptName) {{ $oldOptName }} โ†’ {{ $newOptName }} @endif @endif @if ($recipientUrl) {{ $recipientName }} @else {{ $recipientName }} @endif {{ class_basename($event->recipient_type) }}#{{ $event->recipient_id }}
@foreach ($event->channels_list as $ch) @php $cm = $channelMeta[$ch] ?? ['icon' => 'โ€ข', 'fg' => '#475569', 'bg' => '#f1f5f9', 'label' => $ch]; @endphp {{ $cm['icon'] }} {{ $cm['label'] }} @endforeach
@if ((int) $event->sent_count > 0) โœ“ {{ $event->sent_count }} {{ __('admin.notification_logs_admin.counters.sent') }} @endif @if ((int) $event->failed_count > 0) โœ— {{ $event->failed_count }} {{ __('admin.notification_logs_admin.counters.failed') }} @endif @if ((int) $event->pending_count > 0) โณ {{ $event->pending_count }} {{ __('admin.notification_logs_admin.counters.pending') }} @endif @if ((int) $event->sent_count === 0 && (int) $event->failed_count === 0 && (int) $event->pending_count === 0) โ€” @endif
@if ($event->admin_actor) {{ $event->admin_actor->name }} @else โ€” @endif
{{ __('admin.actions.view') ?? 'View' }} @if ($hasFailures) {{-- Retry every failed channel of this event (each row on its OWN channel โ€” already-sent channels untouched). --}}
@csrf @foreach ($failedIds as $fid) @endforeach
{{-- Validation send to the test recipients (reference: first failed row). --}}
@csrf
@endif
{{ $events->links() }}
@endif
@push('styles') @endpush @endsection