simedkom/app/Filament/Pages/AdminVerification/Index.php

159 lines
7.2 KiB
PHP

<?php
namespace App\Filament\Pages\AdminVerification;
use App\Enums\VerificationStatus;
use App\Filament\Pages\AdminVerification\Concerns\HasVerificationActions;
use App\Filament\Pages\AdminVerification\Concerns\HasVerificationFilters;
use App\Filament\Pages\AdminVerification\Concerns\HasVerificationNotifications;
use App\Filament\Resources\Manage\Partners\Pages\ViewPartner;
use App\Models\VerificationRequest;
use BackedEnum;
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Pages\Page;
use Filament\Support\Icons\Heroicon;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Livewire\Attributes\Computed;
use UnitEnum;
class Index extends Page implements HasActions, HasForms
{
use HasPageShield, HasVerificationActions, HasVerificationFilters, HasVerificationNotifications, InteractsWithActions, InteractsWithForms;
protected static string|UnitEnum|null $navigationGroup = 'Kelola';
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedUserGroup;
protected static ?string $navigationLabel = 'Verifikasi Rekanan';
protected static ?int $navigationSort = 6;
protected static ?string $slug = 'manage/admin-verification';
protected static ?string $title = 'Verifikasi Rekanan';
protected string $view = 'filament.pages.admin-verification';
public static function canAccess(): bool
{
return auth()->user()->can('View:AdminVerification');
}
public static function getNavigationBadge(): ?string
{
return VerificationRequest::query()->pending()->count();
}
#[Computed]
public function verifications(): LengthAwarePaginator
{
$query = VerificationRequest::with([
'company.user',
'company.partnerMedia',
'company.partnerMedia.journalists',
'submittedBy',
'reviews.reviewer',
])
->latest('updated_at');
// Apply status filter
if ($this->filterStatus !== 'all') {
$query->where('status', $this->filterStatus);
}
return $query->paginate($this->rowsToDisplay)
->through(function (VerificationRequest $verification) {
$latestReview = $verification->reviews->first();
$status = $verification->status;
$company = $verification->company;
$media = $company?->partnerMedia;
$journalists = $media?->journalists ?? collect();
// Prepare Review classes
$reviewColor = $latestReview?->decision?->getColor() ?? 'gray';
$reviewClasses = match ($reviewColor) {
'success' => 'bg-success-50 dark:bg-success-500/10 border-success-200 dark:border-success-500/20',
'warning' => 'bg-warning-50 dark:bg-warning-500/10 border-warning-200 dark:border-warning-500/20',
'danger' => 'bg-danger-50 dark:bg-danger-500/10 border-danger-200 dark:border-danger-500/20',
'info' => 'bg-info-50 dark:bg-info-500/10 border-info-200 dark:border-info-500/20',
default => 'bg-gray-50 dark:bg-gray-500/10 border-gray-200 dark:border-gray-500/20',
};
$reviewTitleClasses = match ($reviewColor) {
'success' => 'text-success-700 dark:text-success-400',
'warning' => 'text-warning-700 dark:text-warning-400',
'danger' => 'text-danger-700 dark:text-danger-400',
'info' => 'text-info-700 dark:text-info-400',
default => 'text-gray-700 dark:text-gray-400',
};
return [
'id' => $verification->id,
'company' => [
'hashId' => $company?->user?->getHashid(),
'name' => $company?->name ?? 'Data tidak ditemukan',
'detailUrl' => ($company && $company->user_id) ? ViewPartner::getUrl(['record' => $company?->user?->getHashid()]) : null,
],
'submittedBy' => $verification->submittedBy?->name ?? 'Unknown',
'status' => [
'value' => $status,
'label' => $status->getLabel(),
'color' => $status->getColor(),
'isPending' => $status === VerificationStatus::PENDING,
'isRevision' => $status === VerificationStatus::NEED_REVISION,
'isApproved' => $status === VerificationStatus::APPROVED,
'isRejected' => $status === VerificationStatus::REJECTED,
],
'timestamps' => [
'submittedAt' => $verification->created_at->translatedFormat('l, d M Y H:i'),
'submittedAtHuman' => $verification->created_at->diffForHumans(),
'updatedAt' => $verification->updated_at->translatedFormat('l, d M Y H:i'),
'updatedAtHuman' => $verification->updated_at->diffForHumans(),
],
'summary' => [
'company' => [
'name' => $company?->name ?? 'Belum diisi',
'email' => $company?->email ?? '-',
'exists' => $company !== null,
],
'media' => [
'name' => $media?->name ?? 'Belum diisi',
'type' => $media?->type?->getLabel() ?? '-',
'exists' => $media !== null,
],
'journalists' => [
'count' => $journalists->count(),
'names' => $journalists->pluck('name')->take(3)->toArray(),
'exists' => $journalists->count() > 0,
],
],
'reviews' => [
'count' => $verification->reviews->count(),
'latest' => [
'note' => $latestReview?->note,
'reviewer' => $latestReview?->reviewer?->name ?? 'Admin',
'createdAtHuman' => $latestReview?->created_at?->diffForHumans(),
'classes' => $reviewClasses,
'titleClasses' => $reviewTitleClasses,
],
'history' => $verification->reviews->map(fn ($review) => [
'decisionLabel' => $review->decision->getLabel(),
'decisionColor' => $review->decision->getColor(),
'reviewerName' => $review->reviewer?->name ?? 'Admin',
'note' => $review->note,
'createdAt' => $review->created_at->translatedFormat('l, d M Y H:i'),
]),
],
];
});
}
}