{{-- ============================================================ Avisos del sistema — implementado desde `Monitorización.dc.html`. **La pestaña se llamaba «Avisos enviados»**, y el brief señaló el problema: también lista **los fallidos**, que son lo único que hay que mirar de verdad —un aviso de caducidad que no salió es un cliente que se queda sin avisar—. El nombre escondía justo el caso importante. Ver briefs/monitorizacion.md. ============================================================ --}}
{{-- Como slot: la frase lleva un y en un atributo se veria el marcado. --}} Los correos automáticos que ha enviado el Manager, para responder «¿se avisó de esto?» sin buscar en el buzón de nadie — y sobre todo para ver los que no llegaron. @include('livewire.monitoring.components.menu', ['selected' => 'notices'])

Avisos del sistema

Correos automáticos de caducidad y bloqueo — los fallidos primero: un aviso que no salió es un cliente sin avisar.
{{-- ============ Filtros ============ --}}
@php $estados = [ 'all' => 'Todos', 'failed' => 'Fallidos' . ($resumen['fallidos'] > 0 ? ' (' . $resumen['fallidos'] . ')' : ''), 'sent' => 'Enviados', ]; @endphp @foreach ($estados as $clave => $etiqueta) @endforeach
{{ $avisos->total() }} {{ $avisos->total() === 1 ? 'aviso' : 'avisos' }}
{{-- El aviso de los fallidos, arriba y explicando qué va a pasar con ellos: sin esto, «fallido» se lee como «hay que reenviarlo a mano ahora». --}} @if ($resumen['fallidos'] > 0 && $estado !== 'sent')
{{ $resumen['fallidos'] }} {{ $resumen['fallidos'] === 1 ? 'aviso sin entregar' : 'avisos sin entregar' }}. Se reintenta en la siguiente pasada de la tarea; si vuelve a fallar, hay que avisar a mano y revisar el correo del destinatario.
@endif @if ($avisos->isNotEmpty()) @foreach ($avisos as $aviso) @php $fallido = $aviso->sent_at === null; $licencia = $aviso->subject_type === \App\Models\Monitoring\Notice::SUBJECT_LICENSE_TOKEN ? $licencias->get($aviso->subject_id) : null; @endphp
@if ($licencia) {{-- **El token no se pinta entero.** Antes, una licencia sin nombre salía con su credencial completa en una lista que se lee de reojo. Ver `x-token-de-licencia`. --}} @elseif ($aviso->kind === \App\Models\Monitoring\Notice::KIND_BLOCK_ALERT) {{-- **El sujeto del corte sale del `payload`**, no de la fila de `api_blocks`: el episodio se puede borrar con la retención y el aviso tiene que seguir diciendo a quién se avisó. Por eso se guarda al registrarlo. --}} {{ $aviso->payload['sujeto'] ?? ('corte #' . $aviso->subject_id) }} @else {{-- El sujeto se guarda como cadena para que la fila sobreviva al borrado: un aviso de algo ya eliminado sigue en el histórico, aunque sin nombre. --}} {{ $aviso->subject_type }} #{{ $aviso->subject_id }} @endif
@if ($licencia?->client)
{{ $licencia->client->name }}
@elseif ($aviso->kind === \App\Models\Monitoring\Notice::KIND_BLOCK_ALERT) {{-- **Si cortaba o solo observaba.** Es lo primero que se pregunta al leer un aviso de corte: en observación no se quedó nadie sin servicio, y eso cambia la urgencia por completo. --}}
{{ ($aviso->payload['corta'] ?? false) ? 'Cortando' : 'En observación' }} @if (($aviso->payload['rechazos'] ?? 0) > 0) · {{ $aviso->payload['rechazos'] }} rechazos @endif
@endif
{{ $tipos[$aviso->kind] ?? $aviso->kind }} @if ($aviso->threshold !== null) · {{ $aviso->threshold }} d @endif {{ $aviso->sent_to ?: '—' }} {{ ($aviso->sent_at ?? $aviso->updated_at)?->format('d/m/Y H:i') ?? '—' }} @if ($fallido) Fallido{{ $aviso->error ? ' — ' . \Illuminate\Support\Str::limit($aviso->error, 40) : '' }} @else Enviado @endif
@endforeach @if ($avisos->hasPages())
{{ $avisos->links() }}
@endif @else
@if ($estado === 'failed') Ningún aviso ha fallado. @elseif ($tipo !== 'all') Ningún aviso de ese tipo. @else Ningún aviso enviado todavía — no había nada que avisar. @endif
@endif
Los destinatarios, los umbrales de días y la hora de la tarea se configuran en @can('admin.configs.edit') Configuraciones del Manager. @else Configuraciones del Manager. @endcan Esta pantalla solo dice qué salió y qué no.
{{-- ============ Limpieza ============ **Con un aviso que la de acciones no necesita**: esta tabla no es solo histórico. Cada fila dice «de esto ya se avisó», así que borrarla rearma el aviso. --}} @can('admin.configs.edit')
Limpiar el histórico — borra filas de notices acotando por fechas, tipo y si el aviso llegó a enviarse. Los que fallaron no llegaron a nadie y son los que sobran; con los enviados, ojo: borrar un aviso recurrente hace que se vuelva a enviar si la condición sigue cumpliéndose.
@endcan