simedkom/app/Filament/Pages/AdminVerification.php

259 lines
8.3 KiB
PHP

<?php
namespace App\Filament\Pages;
use App\Enums\DecisionAdmin;
use App\Enums\VerificationStatus;
use App\Filament\Resources\Manage\Journalists\Pages\ManageJournalists;
use App\Filament\Resources\Manage\Partners\Pages\ViewPartner;
use App\Models\VerificationRequest;
use App\Models\VerificationReview;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Actions\Concerns\InteractsWithActions;
use Filament\Actions\Contracts\HasActions;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Notifications\Notification;
use Filament\Pages\Page;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Auth;
use UnitEnum;
class AdminVerification extends Page implements HasActions, HasForms
{
use InteractsWithActions, InteractsWithForms;
protected static string|BackedEnum|null $navigationIcon = 'heroicon-o-user-group';
protected static ?string $title = 'Verifikasi Rekanan';
protected static ?string $navigationLabel = 'Verifikasi Rekanan';
protected static string|UnitEnum|null $navigationGroup = 'Kelola';
protected static ?string $slug = 'manage/admin-verification';
protected string $view = 'filament.pages.admin-verification';
public string $filterStatus = 'all';
public function getVerifications(): LengthAwarePaginator
{
$query = VerificationRequest::with([
'verifiable',
'submittedBy',
'reviews.reviewer',
])
->latest('updated_at');
// Apply status filter
if ($this->filterStatus !== 'all') {
$query->where('status', $this->filterStatus);
}
return $query->paginate(12);
}
public function setFilter(string $status): void
{
$this->filterStatus = $status;
}
public function getStatusCounts(): array
{
return [
'all' => VerificationRequest::count(),
'pending' => VerificationRequest::where('status', VerificationStatus::PENDING)->count(),
'revision' => VerificationRequest::where('status', VerificationStatus::NEED_REVISION)->count(),
'approved' => VerificationRequest::where('status', VerificationStatus::APPROVED)->count(),
'rejected' => VerificationRequest::where('status', VerificationStatus::REJECTED)->count(),
];
}
/**
* Get the entity type label
*/
public function getEntityTypeLabel(VerificationRequest $request): string
{
$type = class_basename($request->verifiable_type);
return match ($type) {
'Company' => 'Perusahaan',
'PartnerMedia' => 'Media',
'Journalist' => 'Jurnalis',
default => $type,
};
}
/**
* Get the entity name
*/
public function getEntityName(VerificationRequest $request): string
{
$entity = $request->verifiable;
if (! $entity) {
return 'Data tidak ditemukan';
}
return $entity->name ?? 'Tanpa Nama';
}
/**
* Get detail URL based on entity type
*/
public function getDetailUrl(VerificationRequest $request): ?string
{
$entity = $request->verifiable;
$type = class_basename($request->verifiable_type);
if (! $entity) {
return null;
}
return match ($type) {
'Company' => ViewPartner::getUrl(['record' => $entity->user_id]),
'PartnerMedia' => ViewPartner::getUrl(['record' => $entity->company?->user_id]),
'Journalist' => ManageJournalists::getUrl(),
default => null,
};
}
/**
* Approve verification action
*/
public function approveAction(): Action
{
return Action::make('approve')
->label('Setujui')
->color('success')
->icon('heroicon-o-check')
->size('sm')
->requiresConfirmation()
->modalHeading('Setujui Verifikasi')
->modalDescription('Apakah Anda yakin ingin menyetujui verifikasi ini?')
->modalSubmitActionLabel('Ya, Setujui')
->form([
Textarea::make('note')
->label('Catatan (Opsional)')
->placeholder('Tambahkan catatan jika diperlukan...'),
])
->action(function (array $arguments, array $data) {
$this->processReview($arguments['id'], DecisionAdmin::APPROVED, $data['note'] ?? null);
});
}
/**
* Revision verification action
*/
public function revisionAction(): Action
{
return Action::make('revision')
->label('Minta Revisi')
->color('warning')
->icon('heroicon-o-pencil-square')
->size('sm')
->modalHeading('Minta Revisi')
->modalDescription('User akan diminta untuk memperbaiki data sesuai catatan yang diberikan.')
->form([
Textarea::make('note')
->label('Catatan Revisi')
->required()
->placeholder('Jelaskan bagian yang perlu diperbaiki...')
->helperText('Catatan ini akan ditampilkan kepada user.'),
])
->action(function (array $arguments, array $data) {
$this->processReview($arguments['id'], DecisionAdmin::NEED_REVISION, $data['note']);
});
}
/**
* Reject verification action
*/
public function rejectAction(): Action
{
return Action::make('reject')
->label('Tolak')
->color('danger')
->icon('heroicon-o-x-mark')
->size('sm')
->requiresConfirmation()
->modalHeading('Tolak Verifikasi')
->modalDescription('Pengajuan akan ditolak secara permanen. User tidak dapat mengajukan ulang untuk data ini.')
->modalSubmitActionLabel('Ya, Tolak')
->form([
Textarea::make('note')
->label('Alasan Penolakan')
->required()
->placeholder('Jelaskan alasan pengajuan ditolak...')
->helperText('Alasan ini akan ditampilkan kepada user.'),
])
->action(function (array $arguments, array $data) {
$this->processReview($arguments['id'], DecisionAdmin::REJECTED, $data['note']);
});
}
/**
* Process review decision
*/
protected function processReview(int $requestId, DecisionAdmin $decision, ?string $note): void
{
$verificationRequest = VerificationRequest::find($requestId);
if (! $verificationRequest) {
Notification::make()
->title('Error')
->body('Data verifikasi tidak ditemukan.')
->danger()
->send();
return;
}
// Create review record
VerificationReview::create([
'verification_request_id' => $verificationRequest->id,
'reviewer_id' => Auth::id(),
'decision' => $decision,
'note' => $note,
]);
// Update verification request status
$newStatus = match ($decision) {
DecisionAdmin::APPROVED => VerificationStatus::APPROVED,
DecisionAdmin::NEED_REVISION => VerificationStatus::NEED_REVISION,
DecisionAdmin::REJECTED => VerificationStatus::REJECTED,
};
$verificationRequest->update([
'status' => $newStatus,
]);
// Update the related entity status if needed
$entity = $verificationRequest->verifiable;
if ($entity && method_exists($entity, 'update')) {
$entity->update(['status' => $newStatus]);
}
$actionLabel = match ($decision) {
DecisionAdmin::APPROVED => 'disetujui',
DecisionAdmin::NEED_REVISION => 'diminta revisi',
DecisionAdmin::REJECTED => 'ditolak',
};
$color = match ($decision) {
DecisionAdmin::APPROVED => 'success',
DecisionAdmin::NEED_REVISION => 'info',
DecisionAdmin::REJECTED => 'danger',
};
Notification::make()
->title('Berhasil')
->body("Verifikasi telah {$actionLabel}.")
->color($color)
->send();
}
}