simedkom/resources/views/filament/pages/admin-verification.blade.php

327 lines
19 KiB
PHP

<x-filament-panels::page>
{{-- Status Filter Tabs --}}
@php
$counts = $this->getStatusCounts();
@endphp
<div class="mb-6">
<div class="flex flex-wrap gap-2">
<button wire:click="setFilter('all')" @class([
'inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200',
'bg-primary-500 text-white shadow-md shadow-primary-500/20' =>
$filterStatus === 'all',
'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700' =>
$filterStatus !== 'all',
])>
<span>Semua</span>
<span @class([
'px-2 py-0.5 text-xs rounded-full',
'bg-white/20' => $filterStatus === 'all',
'bg-gray-200 dark:bg-gray-700' => $filterStatus !== 'all',
])>{{ $counts['all'] }}</span>
</button>
<button wire:click="setFilter('{{ \App\Enums\VerificationStatus::PENDING->value }}')"
@class([
'inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200',
'bg-warning-500 text-white shadow-md shadow-warning-500/20' =>
$filterStatus == \App\Enums\VerificationStatus::PENDING->value,
'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700' =>
$filterStatus != \App\Enums\VerificationStatus::PENDING->value,
])>
<x-heroicon-s-clock class="w-4 h-4" />
<span>Menunggu</span>
<span @class([
'px-2 py-0.5 text-xs rounded-full',
'bg-white/20' =>
$filterStatus == \App\Enums\VerificationStatus::PENDING->value,
'bg-warning-100 text-warning-700 dark:bg-warning-500/20 dark:text-warning-400' =>
$filterStatus != \App\Enums\VerificationStatus::PENDING->value,
])>{{ $counts['pending'] }}</span>
</button>
<button wire:click="setFilter('{{ \App\Enums\VerificationStatus::NEED_REVISION->value }}')"
@class([
'inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200',
'bg-info-500 text-white shadow-md shadow-info-500/20' =>
$filterStatus == \App\Enums\VerificationStatus::NEED_REVISION->value,
'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700' =>
$filterStatus != \App\Enums\VerificationStatus::NEED_REVISION->value,
])>
<x-heroicon-s-pencil-square class="w-4 h-4" />
<span>Revisi</span>
<span @class([
'px-2 py-0.5 text-xs rounded-full',
'bg-white/20' =>
$filterStatus == \App\Enums\VerificationStatus::NEED_REVISION->value,
'bg-info-100 text-info-700 dark:bg-info-500/20 dark:text-info-400' =>
$filterStatus != \App\Enums\VerificationStatus::NEED_REVISION->value,
])>{{ $counts['revision'] }}</span>
</button>
<button wire:click="setFilter('{{ \App\Enums\VerificationStatus::APPROVED->value }}')"
@class([
'inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200',
'bg-success-500 text-white shadow-md shadow-success-500/20' =>
$filterStatus == \App\Enums\VerificationStatus::APPROVED->value,
'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700' =>
$filterStatus != \App\Enums\VerificationStatus::APPROVED->value,
])>
<x-heroicon-s-check-circle class="w-4 h-4" />
<span>Disetujui</span>
<span @class([
'px-2 py-0.5 text-xs rounded-full',
'bg-white/20' =>
$filterStatus == \App\Enums\VerificationStatus::APPROVED->value,
'bg-success-100 text-success-700 dark:bg-success-500/20 dark:text-success-400' =>
$filterStatus != \App\Enums\VerificationStatus::APPROVED->value,
])>{{ $counts['approved'] }}</span>
</button>
<button wire:click="setFilter('{{ \App\Enums\VerificationStatus::REJECTED->value }}')"
@class([
'inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg transition-all duration-200',
'bg-danger-500 text-white shadow-md shadow-danger-500/20' =>
$filterStatus == \App\Enums\VerificationStatus::REJECTED->value,
'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-700' =>
$filterStatus != \App\Enums\VerificationStatus::REJECTED->value,
])>
<x-heroicon-s-x-circle class="w-4 h-4" />
<span>Ditolak</span>
<span @class([
'px-2 py-0.5 text-xs rounded-full',
'bg-white/20' =>
$filterStatus == \App\Enums\VerificationStatus::REJECTED->value,
'bg-danger-100 text-danger-700 dark:bg-danger-500/20 dark:text-danger-400' =>
$filterStatus != \App\Enums\VerificationStatus::REJECTED->value,
])>{{ $counts['rejected'] }}</span>
</button>
</div>
</div>
{{-- Verification Cards Grid --}}
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
@forelse ($this->getVerifications() as $verification)
@php
$entityType = $this->getEntityTypeLabel($verification);
$entityName = $this->getEntityName($verification);
$detailUrl = $this->getDetailUrl($verification);
$latestReview = $verification->reviews->first();
@endphp
<x-filament::section class="h-full">
<x-slot name="heading">
<div class="flex items-start justify-between gap-3">
<div class="min-w-0 flex-1">
<div class="flex items-center gap-2 mb-1">
{{-- Entity Type Badge --}}
@php
$typeColor = match ($entityType) {
'Perusahaan' => 'primary',
'Media' => 'info',
'Jurnalis' => 'success',
default => 'gray',
};
@endphp
<x-filament::badge :color="$typeColor" size="sm">
{{ $entityType }}
</x-filament::badge>
</div>
<h3 class="font-bold text-lg text-gray-900 dark:text-white truncate"
title="{{ $entityName }}">
{{ $entityName }}
</h3>
</div>
{{-- Status Badge --}}
<x-filament::badge :color="$verification->status->getColor()" size="lg">
{{ $verification->status->getLabel() }}
</x-filament::badge>
</div>
</x-slot>
<div class="space-y-4">
{{-- Submitter Info --}}
<div class="flex items-center gap-3 p-3 bg-gray-50 dark:bg-gray-800 rounded-lg">
<div class="shrink-0">
<div
class="w-10 h-10 rounded-full bg-primary-100 dark:bg-primary-500/20 flex items-center justify-center">
<x-heroicon-s-user class="w-5 h-5 text-primary-500" />
</div>
</div>
<div class="min-w-0 flex-1">
<p class="text-xs text-gray-500 dark:text-gray-400 uppercase font-semibold">Diajukan oleh
</p>
<p class="text-sm font-medium text-gray-900 dark:text-white truncate">
{{ $verification->submittedBy?->name ?? 'Unknown' }}
</p>
</div>
</div>
{{-- Timeline Info --}}
<div class="grid grid-cols-2 gap-3 text-sm">
<div>
<p class="text-xs text-gray-500 dark:text-gray-400 uppercase font-semibold">Diajukan</p>
<p class="text-gray-700 dark:text-gray-300">
{{ $verification->created_at->format('d M Y') }}
</p>
<p class="text-xs text-gray-500">
{{ $verification->created_at->format('H:i') }}
</p>
</div>
<div>
<p class="text-xs text-gray-500 dark:text-gray-400 uppercase font-semibold">Update Terakhir
</p>
<p class="text-gray-700 dark:text-gray-300">
{{ $verification->updated_at->format('d M Y') }}
</p>
<p class="text-xs text-gray-500">
{{ $verification->updated_at->diffForHumans() }}
</p>
</div>
</div>
{{-- Latest Review Note --}}
@if ($latestReview && $latestReview->note)
<div
class="p-3 rounded-lg border
{{ match ($latestReview->decision) {
\App\Enums\DecisionAdmin::APPROVED
=> 'bg-success-50 dark:bg-success-500/10 border-success-200 dark:border-success-500/20',
\App\Enums\DecisionAdmin::NEED_REVISION
=> 'bg-warning-50 dark:bg-warning-500/10 border-warning-200 dark:border-warning-500/20',
\App\Enums\DecisionAdmin::REJECTED
=> 'bg-danger-50 dark:bg-danger-500/10 border-danger-200 dark:border-danger-500/20',
} }}">
<p
class="text-xs font-semibold uppercase mb-1
{{ match ($latestReview->decision) {
\App\Enums\DecisionAdmin::APPROVED => 'text-success-700 dark:text-success-400',
\App\Enums\DecisionAdmin::NEED_REVISION => 'text-warning-700 dark:text-warning-400',
\App\Enums\DecisionAdmin::REJECTED => 'text-danger-700 dark:text-danger-400',
} }}">
Catatan Terakhir
</p>
<p class="text-sm text-gray-700 dark:text-gray-300 line-clamp-2">
{{ $latestReview->note }}
</p>
<p class="text-xs text-gray-500 mt-1">
oleh {{ $latestReview->reviewer?->name ?? 'Admin' }}
{{ $latestReview->created_at->diffForHumans() }}
</p>
</div>
@endif
{{-- Review History Accordion --}}
@if ($verification->reviews->count() > 0)
<div x-data="{ open: false }"
class="border border-gray-200 dark:border-gray-700 rounded-xl overflow-hidden">
<button @click="open = !open"
class="w-full flex items-center justify-between p-3 bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors">
<div
class="flex items-center gap-2 text-sm font-medium text-gray-700 dark:text-gray-300">
<x-heroicon-o-clock class="w-4 h-4" />
Riwayat Review ({{ $verification->reviews->count() }})
</div>
<x-heroicon-o-chevron-down
class="w-4 h-4 text-gray-500 transition-transform duration-200"
x-bind:class="{ 'rotate-180': open }" />
</button>
<div x-show="open" x-collapse class="border-t border-gray-200 dark:border-gray-700">
<div class="divide-y divide-gray-100 dark:divide-gray-700 max-h-60 overflow-y-auto">
@foreach ($verification->reviews as $review)
<div class="p-3">
<div class="flex items-start justify-between gap-3">
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1">
<x-filament::badge :color="$review->decision->getColor()" size="sm">
{{ $review->decision->getLabel() }}
</x-filament::badge>
<span class="text-xs text-gray-500 dark:text-gray-400">
oleh {{ $review->reviewer?->name ?? 'Admin' }}
</span>
</div>
@if ($review->note)
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1">
{{ $review->note }}
</p>
@endif
</div>
<div class="shrink-0 text-xs text-gray-400">
{{ $review->created_at->format('d M Y, H:i') }}
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
@endif
</div>
<x-slot name="footer">
<div class="flex flex-wrap items-center gap-2">
{{-- View Detail Button --}}
@if ($detailUrl)
<x-filament::button color="gray" size="sm" icon="heroicon-m-eye" tag="a"
:href="$detailUrl" target="_blank">
Detail
</x-filament::button>
@endif
{{-- Action Buttons based on status --}}
@if ($verification->status === \App\Enums\VerificationStatus::PENDING)
{{ ($this->approveAction)(['id' => $verification->id]) }}
{{ ($this->revisionAction)(['id' => $verification->id]) }}
{{ ($this->rejectAction)(['id' => $verification->id]) }}
@elseif($verification->status === \App\Enums\VerificationStatus::NEED_REVISION)
<span
class="flex items-center gap-1 text-xs text-warning-600 dark:text-warning-400 font-medium italic">
<x-heroicon-s-clock class="w-3 h-3 animate-pulse" />
Menunggu revisi dari user...
</span>
@elseif($verification->status === \App\Enums\VerificationStatus::APPROVED)
<span
class="flex items-center gap-1 text-xs text-success-600 dark:text-success-400 font-medium">
<x-heroicon-s-check-circle class="w-3 h-3" />
Verifikasi selesai
</span>
@elseif($verification->status === \App\Enums\VerificationStatus::REJECTED)
<span
class="flex items-center gap-1 text-xs text-danger-600 dark:text-danger-400 font-medium">
<x-heroicon-s-x-circle class="w-3 h-3" />
Pengajuan ditolak
</span>
@endif
</div>
</x-slot>
</x-filament::section>
@empty
<div class="col-span-full">
<div
class="flex flex-col items-center justify-center py-16 text-gray-400 bg-gray-50 dark:bg-gray-800/50 rounded-xl border-2 border-dashed border-gray-200 dark:border-gray-700">
<x-heroicon-o-inbox class="w-16 h-16 mb-4 opacity-50" />
<p class="text-lg font-medium">Tidak ada pengajuan verifikasi</p>
<p class="text-sm text-gray-500 mt-1">
@if ($filterStatus === 'all')
Belum ada pengajuan verifikasi dari user.
@else
Tidak ada pengajuan dengan status ini.
@endif
</p>
</div>
</div>
@endforelse
</div>
{{-- Pagination --}}
@if ($this->getVerifications()->hasPages())
<div class="mt-6">
{{ $this->getVerifications()->links() }}
</div>
@endif
<x-filament-actions::modals />
</x-filament-panels::page>