@extends('layouts.dashboard') @section('content') @php /** * SMS delivery log — every text the gateway sent, every one the provider refused, and every * one that never left the building. The sibling of the email log for the other channel. * * `blocked` is its own outcome on purpose: "we never called the provider" and "the provider * said no" are different problems with different fixes, and one shared "failed" hides which * one an operator is looking at. There is no resend action — see SmsLogController. * * @var array $rows the current page, newest first * @var array $counts ['sent'=>int,'failed'=>int,'blocked'=>int] across the whole log * @var int $segments billed segments across every delivered message * @var int $total rows matching the active filter * @var array $pagination paginate() metadata * @var string $status active status filter ('' = all) * @var string $purpose active purpose filter ('' = all) * @var string $q active search term * @var array $purposes the purposes the gateway sends * @var string $reason why sending is not possible right now ('' = the gateway is ready) */ $statusPill = [ 'sent' => 'qm-pill-green', 'failed' => 'qm-pill-red', 'blocked' => 'qm-pill-amber', ]; $statusLabel = [ 'sent' => t_raw('admin.sms_log.status_sent'), 'failed' => t_raw('admin.sms_log.status_failed'), 'blocked' => t_raw('admin.sms_log.status_blocked'), ]; $hasFilters = $status !== '' || $purpose !== '' || $q !== ''; $delivered = (int) $counts['sent']; $attempted = $delivered + (int) $counts['failed']; @endphp @php /* .qm-d2: the dashboard density standard (app.css §35) */ @endphp
@partial('kpi-card', ['label' => t_raw('admin.sms_log.kpi_sent'), 'value' => number_format($delivered), 'icon' => 'fa-paper-plane', 'accent' => 'green']) @partial('kpi-card', ['label' => t_raw('admin.sms_log.kpi_failed'), 'value' => number_format($counts['failed']), 'icon' => 'fa-exclamation-triangle', 'accent' => 'rose']) @partial('kpi-card', ['label' => t_raw('admin.sms_log.kpi_blocked'), 'value' => number_format($counts['blocked']), 'icon' => 'fa-ban', 'accent' => 'amber']) @partial('kpi-card', ['label' => t_raw('admin.sms_log.kpi_delivery_rate'), 'value' => $attempted > 0 ? number_format($delivered / $attempted * 100, 1) . '%' : '—', 'icon' => 'fa-percentage', 'accent' => 'blue']) @php // What the operator is actually billed for. A 400-character message is one row here // and three messages on the invoice, so a count of rows would understate the bill. @endphp @partial('kpi-card', ['label' => t_raw('admin.sms_log.kpi_segments'), 'value' => number_format($segments), 'icon' => 'fa-sms', 'accent' => 'violet'])

{{ t_raw('admin.sms_log.list_heading') }}

@if ($reason !== '') @php // The exact reason, not a generic "not configured": switched off, no // credentials and no sender identity are three different fixes. @endphp @endif @if ($total > 0){{ t_raw('admin.sms_log.total_pill', [':count' => number_format($total)]) }}@endif
@partial('filter-collapse')
@if ($rows) @foreach ($rows as $r) @php $st = (string) $r['status']; $pu = (string) ($r['purpose'] ?? ''); @endphp @endforeach @else @partial('table-empty', ['colspan' => 5, 'icon' => 'fa-sms', 'msg' => $hasFilters ? t_raw('admin.sms_log.empty_search') : t_raw('admin.sms_log.empty')]) @endif
{{ t_raw('admin.sms_log.caption') }}
{{ t_raw('admin.sms_log.col_recipient') }} {{ t_raw('admin.sms_log.col_message') }} {{ t_raw('common.status') }} {{ t_raw('admin.sms_log.col_segments') }} {{ t_raw('admin.sms_log.col_when') }}
{{ $r['to_number'] }} @php // Who the message belongs to: the purpose always, and the restaurant // when it is one restaurant's (the table-ready alert). @endphp {!! $pu !== '' ? t('admin.sms_log.purpose_' . $pu) : '—' !!}{!! !empty($r['restaurant_name']) ? ' · ' . e((string) $r['restaurant_name']) : '' !!}
{{ $r['body'] }} {{ $statusLabel[$st] ?? $st }} @if ($st !== 'sent' && !empty($r['error'])) @php // The provider's own sentence, verbatim. On a trial account "the number is // unverified" is the whole answer, and paraphrasing it loses it. @endphp {{ $r['error'] }} @endif {{ (int) $r['segments'] }} {!! fmt_datetime($r['sent_at'] ?: $r['created_at']) !!}
@partial('table-toolbar', ['pager' => $pagination, 'base' => '/admin/sms-log'])
@if ($counts['sent'] > 0)

{{ t_raw('admin.sms_log.housekeeping_title') }}

@csrf
@endif
@php /* /.qm-d2 */ @endphp @endsection