verificationService = app(VerificationService::class); } public static function getNavigationBadge(): ?string { return VerificationRequest::query()->pending()->count(); } public function getVerifications(): 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(12); } public function setFilter(string $status): void { $this->filterStatus = $status; } public function getStatusCounts(): array { return [ 'all' => VerificationRequest::count(), 'pending' => VerificationRequest::pending()->count(), 'revision' => VerificationRequest::needRevision()->count(), 'approved' => VerificationRequest::approved()->count(), 'rejected' => VerificationRequest::rejected()->count(), ]; } /** * Get company name from verification request */ public function getCompanyName(VerificationRequest $request): string { return $this->verificationService->getCompanyName($request); } /** * Get detail URL for the company */ public function getDetailUrl(VerificationRequest $request): ?string { if (! $request->company || ! $request->company->user_id) { return null; } return ViewPartner::getUrl(['record' => $request->company->user_id]); } /** * Get verification summary data */ public function getVerificationSummary(VerificationRequest $request): array { return $this->verificationService->getVerificationSummary($request); } /** * Get card data for verification request */ public function getCardData(VerificationRequest $verification): array { $latestReview = $verification->reviews->first(); $summary = $this->getVerificationSummary($verification); $status = $verification->status; return [ 'companyName' => $this->getCompanyName($verification), 'detailUrl' => $this->getDetailUrl($verification), 'status' => $status, 'statusLabel' => $status->getLabel(), 'statusColor' => $status->getColor(), 'summary' => $summary, 'latestReview' => $latestReview, 'latestReviewNote' => $latestReview?->note, 'latestReviewDecision' => $latestReview?->decision, 'latestReviewDecisionLabel' => $latestReview?->decision?->getLabel(), 'latestReviewDecisionColor' => $latestReview?->decision?->getColor(), 'latestReviewReviewer' => $latestReview?->reviewer?->name ?? 'Admin', 'latestReviewCreatedAt' => $latestReview?->created_at, 'submittedBy' => $verification->submittedBy?->name ?? 'Unknown', 'reviewsCount' => $verification->reviews->count(), 'canApprove' => $status === VerificationStatus::PENDING, 'isPending' => $status === VerificationStatus::PENDING, 'isRevision' => $status === VerificationStatus::NEED_REVISION, 'isApproved' => $status === VerificationStatus::APPROVED, 'isRejected' => $status === VerificationStatus::REJECTED, ]; } /** * 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? Pastikan data sudah benar dan lengkap.') ->modalSubmitActionLabel('Ya, Setujui') ->action(function (array $arguments, array $data): void { $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('Pengguna akan diminta untuk memperbaiki data sesuai catatan yang diberikan.') ->schema([ Textarea::make('note') ->label('Catatan Revisi') ->required() ->placeholder('Jelaskan bagian yang perlu diperbaiki (Perusahaan, Media, atau Jurnalis)...') ->autocomplete(false) ->autofocus(), ]) ->action(function (array $arguments, array $data): void { $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. Pengguna tidak dapat mengajukan ulang untuk data ini.') ->modalSubmitActionLabel('Ya, Tolak') ->schema([ Textarea::make('note') ->label('Alasan Penolakan') ->required() ->placeholder('Jelaskan alasan pengajuan ditolak...') ->autocomplete(false) ->autofocus(), ]) ->action(function (array $arguments, array $data): void { $this->processReview($arguments['id'], DecisionAdmin::REJECTED, $data['note']); }); } /** * Process review decision */ protected function processReview(int $requestId, DecisionAdmin $decision, ?string $note): void { $verificationRequest = VerificationRequest::with(['company.partnerMedia.journalists'])->find($requestId); if (! $verificationRequest) { Notification::make() ->title('Error') ->body('Data verifikasi tidak ditemukan.') ->danger() ->send(); return; } try { $this->verificationService->processReview($verificationRequest, $decision, $note); $actionLabel = match ($decision) { DecisionAdmin::APPROVED => 'disetujui', DecisionAdmin::NEED_REVISION => 'diminta revisi', DecisionAdmin::REJECTED => 'ditolak', }; CheerfulNotification::success( 'Berhasil Diproses! ✨', "Mantap! Verifikasi telah {$actionLabel} dan notifikasi sudah dikirim ke user. Kerja bagus, Admin! 💪" ) ->send(); // Notify User $partnerUser = $verificationRequest->company?->user; if ($partnerUser) { $statusTitle = match ($decision) { DecisionAdmin::APPROVED => 'Horee! Verifikasi Disetujui 🎉', DecisionAdmin::NEED_REVISION => 'Yah, Ada Yang Perlu Direvisi nih 📝', DecisionAdmin::REJECTED => 'Maaf, Verifikasi Ditolak 😔', }; $body = match ($decision) { DecisionAdmin::APPROVED => 'Yeay! Pengajuan verifikasi perusahaan Anda telah disetujui. Sekarang Anda sudah resmi terverifikasi dan bekerja sama dengan kami! 🎊', DecisionAdmin::NEED_REVISION => 'Ayo sedikit lagi! Admin meminta beberapa perbaikan pada pengajuan Anda agar bisa segera disetujui. 💪', DecisionAdmin::REJECTED => 'Yah, maaf banget... pengajuan verifikasi perusahaan Anda belum bisa kami terima saat ini. 💔', }; if ($note) { $body .= "\n\nCatatan Admin: {$note}"; } $partnerUser->notify(new BroadcastNotification([ 'title' => $statusTitle, 'body' => $body, 'action' => [ Action::make('view') ->label('Lihat') ->url(Verification::getUrl()), ], ])); } } catch (\Exception $e) { Notification::make() ->title('Error') ->body('Terjadi kesalahan saat memproses verifikasi: '.$e->getMessage()) ->danger() ->send(); } } }