125 lines
6.6 KiB
PHP
125 lines
6.6 KiB
PHP
<x-slot:breadcrumbParent>Mail</x-slot:breadcrumbParent>
|
||
<x-slot:breadcrumb>Mail-Queue</x-slot:breadcrumb>
|
||
|
||
<div wire:poll.15s>
|
||
|
||
<div class="mq-page-header">
|
||
<div class="mq-page-title">
|
||
<svg width="16" height="16" viewBox="0 0 14 14" fill="none"><path d="M1 4h12M4 4V2h6v2M4 12V7m6 5V7" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
|
||
Mail-Queue
|
||
<span class="mq-total-badge">{{ $counts['all'] }}</span>
|
||
</div>
|
||
<div class="mq-page-actions">
|
||
<div class="mq-search-wrap">
|
||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none"><circle cx="5" cy="5" r="3.8" stroke="currentColor" stroke-width="1.2"/><path d="M8 8l2.5 2.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
|
||
<input type="text" wire:model.live.debounce.300ms="search" class="mq-search-input" placeholder="ID, Sender, Empfänger …">
|
||
</div>
|
||
<button wire:click="flush" class="mq-btn-mute" title="Alle Nachrichten erneut zustellen">
|
||
<svg width="12" height="12" viewBox="0 0 14 14" fill="none"><path d="M2 7a5 5 0 1 1 1 3" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><path d="M2 11V7H6" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||
Flush
|
||
</button>
|
||
@if(count($selected) > 0)
|
||
<button wire:click="deleteSelected" wire:confirm="{{ count($selected) }} Nachrichten löschen?" class="mq-btn-danger">
|
||
<svg width="12" height="12" viewBox="0 0 13 13" fill="none"><path d="M2 3.5h9M5 3.5V2h3v1.5M5.5 6v4M7.5 6v4M3 3.5l.5 7.5h6L10 3.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||
{{ count($selected) }} löschen
|
||
</button>
|
||
@endif
|
||
<button wire:click="deleteAll" wire:confirm="Wirklich alle Nachrichten aus der Queue löschen?" class="mq-btn-danger-outline" title="Gesamte Queue leeren">
|
||
Alle löschen
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
{{-- Filter tabs --}}
|
||
<div class="mq-tabs">
|
||
<button wire:click="$set('filter','all')" class="mq-tab {{ $filter === 'all' ? 'active' : '' }}">
|
||
Alle <span class="mq-tab-n">{{ $counts['all'] }}</span>
|
||
</button>
|
||
<button wire:click="$set('filter','active')" class="mq-tab {{ $filter === 'active' ? 'active' : '' }}">
|
||
<span class="mq-dot ok"></span>Aktiv <span class="mq-tab-n">{{ $counts['active'] }}</span>
|
||
</button>
|
||
<button wire:click="$set('filter','deferred')" class="mq-tab {{ $filter === 'deferred' ? 'active' : '' }}">
|
||
<span class="mq-dot warn"></span>Deferred <span class="mq-tab-n">{{ $counts['deferred'] }}</span>
|
||
</button>
|
||
<button wire:click="$set('filter','hold')" class="mq-tab {{ $filter === 'hold' ? 'active' : '' }}">
|
||
<span class="mq-dot na"></span>Hold <span class="mq-tab-n">{{ $counts['hold'] }}</span>
|
||
</button>
|
||
</div>
|
||
|
||
{{-- Table --}}
|
||
@if(count($messages) > 0)
|
||
<div class="mq-card">
|
||
<table class="mq-table">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:32px;"><input type="checkbox" wire:model.live="selectAll" class="mq-check"></th>
|
||
<th>Queue-ID</th>
|
||
<th>Sender</th>
|
||
<th>Empfänger</th>
|
||
<th>Größe</th>
|
||
<th>Eingang</th>
|
||
<th>Status</th>
|
||
<th>Grund</th>
|
||
<th style="width:40px;"></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
@foreach($messages as $msg)
|
||
<tr wire:key="msg-{{ $msg['id'] }}" class="mq-row">
|
||
<td><input type="checkbox" wire:model.live="selected" value="{{ $msg['id'] }}" class="mq-check"></td>
|
||
<td><code class="mq-id">{{ $msg['id'] }}</code></td>
|
||
<td class="mq-addr">{{ $msg['sender'] ?: '—' }}</td>
|
||
<td class="mq-addr">{{ $msg['recipient'] ?: '—' }}</td>
|
||
<td class="mq-num">{{ $msg['size'] > 0 ? number_format($msg['size'] / 1024, 1) . ' KB' : '—' }}</td>
|
||
<td class="mq-num">{{ $msg['arrival'] > 0 ? date('d.m H:i', $msg['arrival']) : '—' }}</td>
|
||
<td>
|
||
@if($msg['queue'] === 'active')
|
||
<span class="mq-badge ok">Aktiv</span>
|
||
@elseif($msg['queue'] === 'hold')
|
||
<span class="mq-badge na">Hold</span>
|
||
@else
|
||
<span class="mq-badge warn">Deferred</span>
|
||
@endif
|
||
</td>
|
||
<td class="mq-reason">{{ $msg['reason'] ?: '—' }}</td>
|
||
<td>
|
||
<button wire:click="openMessage('{{ $msg['id'] }}')" class="mq-btn-icon" title="Details">
|
||
<svg width="13" height="13" viewBox="0 0 14 14" fill="none"><circle cx="7" cy="7" r="5.5" stroke="currentColor" stroke-width="1.2"/><path d="M7 6.5v4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round"/><circle cx="7" cy="4.5" r=".7" fill="currentColor"/></svg>
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
@endforeach
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
@if($totalPages > 1)
|
||
<div class="mq-pagination">
|
||
<span class="mq-pag-info">{{ ($page - 1) * $perPage + 1 }}–{{ min($page * $perPage, $total) }} von {{ $total }}</span>
|
||
<div class="mq-pag-btns">
|
||
<button wire:click="$set('page', {{ max(1, $page - 1) }})" class="mq-pag-btn" @if($page <= 1) disabled @endif>
|
||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M7.5 2L3.5 6l4 4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||
</button>
|
||
@for($i = max(1, $page - 2); $i <= min($totalPages, $page + 2); $i++)
|
||
<button wire:click="$set('page', {{ $i }})" class="mq-pag-btn {{ $i === $page ? 'active' : '' }}">{{ $i }}</button>
|
||
@endfor
|
||
<button wire:click="$set('page', {{ min($totalPages, $page + 1) }})" class="mq-pag-btn" @if($page >= $totalPages) disabled @endif>
|
||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M4.5 2L8.5 6l-4 4" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
@endif
|
||
@else
|
||
<div class="mq-empty">
|
||
<svg width="36" height="36" viewBox="0 0 14 14" fill="none"><path d="M1 4h12M4 4V2h6v2M4 12V7m6 5V7" stroke="currentColor" stroke-width="1" stroke-linecap="round" opacity=".3"/></svg>
|
||
@if($search !== '')
|
||
<p>Keine Treffer für „{{ $search }}"</p>
|
||
@elseif($filter !== 'all')
|
||
<p>Keine {{ $filter }}-Nachrichten</p>
|
||
@else
|
||
<p>Queue ist leer</p>
|
||
@endif
|
||
</div>
|
||
@endif
|
||
|
||
</div>
|