159 lines
7.2 KiB
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'),
|
|
]),
|
|
],
|
|
];
|
|
});
|
|
}
|
|
}
|