|
|
@@ -0,0 +1,190 @@
|
|
|
+<x-admin::layouts>
|
|
|
+ <x-slot:title>
|
|
|
+ @lang('email::app.email.logs')
|
|
|
+ </x-slot:title>
|
|
|
+
|
|
|
+ <div class="flex items-center justify-between gap-4 max-sm:flex-wrap">
|
|
|
+ <p class="text-xl font-bold text-gray-800 dark:text-white">
|
|
|
+ @lang('email::app.email.logs')
|
|
|
+ </p>
|
|
|
+
|
|
|
+ <div class="flex items-center gap-x-2.5">
|
|
|
+ <!-- 清理旧日志按钮 -->
|
|
|
+ <form action="{{ route('admin.email.logs.clean_old') }}" method="POST" onsubmit="return confirm('@lang('email::app.email.clean_old_logs_confirm')')">
|
|
|
+ @csrf
|
|
|
+ <input type="hidden" name="days" value="30">
|
|
|
+ <button type="submit" class="secondary-button">
|
|
|
+ @lang('email::app.email.clean_old_logs')
|
|
|
+ </button>
|
|
|
+ </form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 统计卡片 -->
|
|
|
+ <div class="mt-4 grid grid-cols-4 gap-4">
|
|
|
+ <div class="rounded-lg bg-white p-4 shadow dark:bg-gray-900">
|
|
|
+ <p class="text-sm text-gray-500">@lang('email::app.email.total_logs')</p>
|
|
|
+ <p class="text-2xl font-bold">{{ number_format($stats['total']) }}</p>
|
|
|
+ </div>
|
|
|
+ <div class="rounded-lg bg-white p-4 shadow dark:bg-gray-900">
|
|
|
+ <p class="text-sm text-green-600">@lang('email::app.email.sent_count')</p>
|
|
|
+ <p class="text-2xl font-bold text-green-600">{{ number_format($stats['sent']) }}</p>
|
|
|
+ </div>
|
|
|
+ <div class="rounded-lg bg-white p-4 shadow dark:bg-gray-900">
|
|
|
+ <p class="text-sm text-red-600">@lang('email::app.email.failed_count')</p>
|
|
|
+ <p class="text-2xl font-bold text-red-600">{{ number_format($stats['failed']) }}</p>
|
|
|
+ </div>
|
|
|
+ <div class="rounded-lg bg-white p-4 shadow dark:bg-gray-900">
|
|
|
+ <p class="text-sm text-yellow-600">@lang('email::app.email.pending_count')</p>
|
|
|
+ <p class="text-2xl font-bold text-yellow-600">{{ number_format($stats['pending']) }}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 筛选表单 -->
|
|
|
+ <div class="mt-4 rounded-lg bg-white p-4 shadow dark:bg-gray-900">
|
|
|
+ <form method="GET" action="{{ route('admin.email.logs.index') }}" class="grid grid-cols-4 gap-4">
|
|
|
+ <div>
|
|
|
+ <label class="block text-sm font-medium text-gray-700 mb-1">
|
|
|
+ @lang('email::app.email.filter_by_status')
|
|
|
+ </label>
|
|
|
+ <select name="status" class="control">
|
|
|
+ <option value="">@lang('email::app.email.all_status')</option>
|
|
|
+ <option value="sent" {{ request('status') == 'sent' ? 'selected' : '' }}>@lang('email::app.email.status_sent')</option>
|
|
|
+ <option value="failed" {{ request('status') == 'failed' ? 'selected' : '' }}>@lang('email::app.email.status_failed')</option>
|
|
|
+ <option value="pending" {{ request('status') == 'pending' ? 'selected' : '' }}>@lang('email::app.email.status_pending')</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <label class="block text-sm font-medium text-gray-700 mb-1">
|
|
|
+ @lang('email::app.email.filter_by_email')
|
|
|
+ </label>
|
|
|
+ <input type="text" name="email" value="{{ request('email') }}" placeholder="输入邮箱地址" class="control">
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <label class="block text-sm font-medium text-gray-700 mb-1">
|
|
|
+ @lang('email::app.email.filter_by_date')
|
|
|
+ </label>
|
|
|
+ <input type="date" name="date_from" value="{{ request('date_from') }}" class="control">
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="flex items-end">
|
|
|
+ <button type="submit" class="primary-button w-full">
|
|
|
+ @lang('admin::app.common.filter')
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </form>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 日志列表 -->
|
|
|
+ <div class="mt-4 rounded-lg bg-white shadow dark:bg-gray-900">
|
|
|
+ <form id="massDeleteForm" method="POST" action="{{ route('admin.email.logs.mass_delete') }}">
|
|
|
+ @csrf
|
|
|
+ @method('DELETE')
|
|
|
+
|
|
|
+ <div class="overflow-x-auto">
|
|
|
+ <table class="w-full">
|
|
|
+ <thead>
|
|
|
+ <tr class="border-b dark:border-gray-800">
|
|
|
+ <th class="px-4 py-3 text-left">
|
|
|
+ <input type="checkbox" id="selectAll" class="cursor-pointer">
|
|
|
+ </th>
|
|
|
+ <th class="px-4 py-3 text-left text-sm font-medium text-gray-600 dark:text-gray-300">
|
|
|
+ @lang('email::app.email.recipient_email')
|
|
|
+ </th>
|
|
|
+ <th class="px-4 py-3 text-left text-sm font-medium text-gray-600 dark:text-gray-300">
|
|
|
+ @lang('email::app.email.subject')
|
|
|
+ </th>
|
|
|
+ <th class="px-4 py-3 text-left text-sm font-medium text-gray-600 dark:text-gray-300">
|
|
|
+ @lang('email::app.email.status')
|
|
|
+ </th>
|
|
|
+ <th class="px-4 py-3 text-left text-sm font-medium text-gray-600 dark:text-gray-300">
|
|
|
+ @lang('email::app.email.created_at')
|
|
|
+ </th>
|
|
|
+ <th class="px-4 py-3 text-left text-sm font-medium text-gray-600 dark:text-gray-300">
|
|
|
+ @lang('admin::app.common.actions')
|
|
|
+ </th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ @forelse($logs as $log)
|
|
|
+ <tr class="border-b dark:border-gray-800 hover:bg-gray-50 dark:hover:bg-gray-800">
|
|
|
+ <td class="px-4 py-3">
|
|
|
+ <input type="checkbox" name="ids[]" value="{{ $log->id }}" class="cursor-pointer">
|
|
|
+ </td>
|
|
|
+ <td class="px-4 py-3 text-sm text-gray-800 dark:text-white">
|
|
|
+ {{ $log->recipient_email }}
|
|
|
+ @if($log->recipient_name)
|
|
|
+ <br><small class="text-gray-500">{{ $log->recipient_name }}</small>
|
|
|
+ @endif
|
|
|
+ </td>
|
|
|
+ <td class="px-4 py-3 text-sm text-gray-800 dark:text-white max-w-xs truncate">
|
|
|
+ {{ Str::limit($log->subject, 50) }}
|
|
|
+ </td>
|
|
|
+ <td class="px-4 py-3">
|
|
|
+ @if($log->status === 'sent')
|
|
|
+ <span class="rounded bg-green-100 px-2 py-1 text-xs text-green-600">
|
|
|
+ @lang('email::app.email.status_sent')
|
|
|
+ </span>
|
|
|
+ @elseif($log->status === 'failed')
|
|
|
+ <span class="rounded bg-red-100 px-2 py-1 text-xs text-red-600">
|
|
|
+ @lang('email::app.email.status_failed')
|
|
|
+ </span>
|
|
|
+ @else
|
|
|
+ <span class="rounded bg-yellow-100 px-2 py-1 text-xs text-yellow-600">
|
|
|
+ @lang('email::app.email.status_pending')
|
|
|
+ </span>
|
|
|
+ @endif
|
|
|
+ </td>
|
|
|
+ <td class="px-4 py-3 text-sm text-gray-600 dark:text-gray-300">
|
|
|
+ {{ $log->created_at->format('Y-m-d H:i:s') }}
|
|
|
+ </td>
|
|
|
+ <td class="px-4 py-3">
|
|
|
+ <div class="flex gap-2">
|
|
|
+ <a href="{{ route('admin.email.logs.show', $log->id) }}"
|
|
|
+ class="cursor-pointer text-blue-600 hover:underline">
|
|
|
+ @lang('email::app.email.view_details')
|
|
|
+ </a>
|
|
|
+ <form action="{{ route('admin.email.logs.delete', $log->id) }}"
|
|
|
+ method="POST"
|
|
|
+ onsubmit="return confirm('确定删除?')"
|
|
|
+ style="display:inline;">
|
|
|
+ @csrf
|
|
|
+ @method('DELETE')
|
|
|
+ <button type="submit" class="text-red-600 hover:underline">
|
|
|
+ @lang('email::app.email.delete')
|
|
|
+ </button>
|
|
|
+ </form>
|
|
|
+ </div>
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ @empty
|
|
|
+ <tr>
|
|
|
+ <td colspan="6" class="px-4 py-8 text-center text-gray-500">
|
|
|
+ @lang('admin::app.common.no-record')
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ @endforelse
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ @if($logs->hasPages())
|
|
|
+ <div class="border-t px-4 py-3 dark:border-gray-800">
|
|
|
+ {{ $logs->links() }}
|
|
|
+ </div>
|
|
|
+ @endif
|
|
|
+ </form>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ @push('scripts')
|
|
|
+ <script>
|
|
|
+ // 全选功能
|
|
|
+ document.getElementById('selectAll').addEventListener('change', function() {
|
|
|
+ const checkboxes = document.querySelectorAll('input[name="ids[]"]');
|
|
|
+ checkboxes.forEach(cb => cb.checked = this.checked);
|
|
|
+ });
|
|
|
+ </script>
|
|
|
+ @endpush
|
|
|
+</x-admin::layouts>
|