company = auth()->user()->company; $this->partnerMedia = auth()->user()->company?->partnerMedia; $this->journalist = auth()->user()->company?->partnerMedia?->journalists?->first(); // Load verification requests with reviews if ($this->company) { $this->companyVerification = $this->company->verificationRequest() ->with(['reviews.reviewer']) ->latest() ->first(); } if ($this->partnerMedia) { $this->mediaVerification = $this->partnerMedia->verificationRequest() ->with(['reviews.reviewer']) ->latest() ->first(); } if ($this->journalist) { $this->journalistVerification = $this->journalist->verificationRequest() ->with(['reviews.reviewer']) ->latest() ->first(); } } /** * Determine the current step based on status */ protected function resolveStep(?VerificationStatus $status, bool $hasData = false): int { if (! $hasData) { return 1; // No data yet } return match ($status) { VerificationStatus::PENDING, VerificationStatus::NEED_REVISION => 2, // In review or needs revision VerificationStatus::APPROVED, VerificationStatus::REJECTED => 3, // Final decision default => 1, // Draft / not submitted yet }; } /** * Check if user can submit verification for entity */ protected function canSubmit($entity, ?VerificationRequest $verification): bool { if (! $entity) { return false; } // No verification yet - can submit if (! $verification) { return true; } // Can resubmit only if status is NEED_REVISION return $verification->status === VerificationStatus::NEED_REVISION; } /** * Check if entity is approved */ protected function isApproved(?VerificationRequest $verification): bool { return $verification?->status === VerificationStatus::APPROVED; } /** * Check if entity is rejected */ protected function isRejected(?VerificationRequest $verification): bool { return $verification?->status === VerificationStatus::REJECTED; } /** * Check if entity is pending review */ protected function isPending(?VerificationRequest $verification): bool { return $verification?->status === VerificationStatus::PENDING; } /** * Check if entity needs revision */ protected function needsRevision(?VerificationRequest $verification): bool { return $verification?->status === VerificationStatus::NEED_REVISION; } /** * Get the latest review notes for an entity */ protected function getLatestReviewNotes(?VerificationRequest $verification): ?string { if (! $verification) { return null; } $latestReview = $verification->reviews() ->whereIn('decision', [DecisionAdmin::NEED_REVISION, DecisionAdmin::REJECTED]) ->latest() ->first(); return $latestReview?->note; } /** * Get all reviews history for an entity */ protected function getReviewHistory(?VerificationRequest $verification): Collection { if (! $verification) { return collect(); } return $verification->reviews() ->with('reviewer') ->latest() ->get(); } public function companyProgress(): array { $hasData = $this->company !== null; $currentStep = $this->resolveStep($this->companyVerification?->status, $hasData); return [ 'title' => 'Perusahaan', 'description' => 'Progress verifikasi perusahaan', 'icon' => 'heroicon-o-building-office-2', 'currentStep' => $currentStep, 'entity' => $this->company, 'verification' => $this->companyVerification, 'canSubmit' => $this->canSubmit($this->company, $this->companyVerification), 'isApproved' => $this->isApproved($this->companyVerification), 'isRejected' => $this->isRejected($this->companyVerification), 'isPending' => $this->isPending($this->companyVerification), 'needsRevision' => $this->needsRevision($this->companyVerification), 'latestNotes' => $this->getLatestReviewNotes($this->companyVerification), 'reviewHistory' => $this->getReviewHistory($this->companyVerification), 'editUrl' => CustomCompany::getUrl(), 'steps' => [ [ 'title' => 'Pengajuan', 'description' => $hasData ? 'Data perusahaan sudah diisi' : 'Lengkapi data perusahaan', ], [ 'title' => 'Verifikasi', 'description' => match ($this->companyVerification?->status) { VerificationStatus::NEED_REVISION => 'Perlu perbaikan data', VerificationStatus::PENDING => 'Sedang diverifikasi admin', default => 'Menunggu pengajuan', }, ], [ 'title' => 'Selesai', 'description' => match ($this->companyVerification?->status) { VerificationStatus::APPROVED => 'Perusahaan disetujui', VerificationStatus::REJECTED => 'Perusahaan ditolak', default => 'Menunggu keputusan', }, ], ], ]; } public function mediaProgress(): array { $hasData = $this->partnerMedia !== null; $currentStep = $this->resolveStep($this->mediaVerification?->status, $hasData); return [ 'title' => 'Media', 'description' => 'Progress verifikasi media', 'currentStep' => $currentStep, 'entity' => $this->partnerMedia, 'verification' => $this->mediaVerification, 'canSubmit' => $this->canSubmit($this->partnerMedia, $this->mediaVerification), 'isApproved' => $this->isApproved($this->mediaVerification), 'isRejected' => $this->isRejected($this->mediaVerification), 'isPending' => $this->isPending($this->mediaVerification), 'needsRevision' => $this->needsRevision($this->mediaVerification), 'latestNotes' => $this->getLatestReviewNotes($this->mediaVerification), 'reviewHistory' => $this->getReviewHistory($this->mediaVerification), 'editUrl' => CustomMedia::getUrl(), 'steps' => [ [ 'title' => 'Pengajuan', 'description' => $hasData ? 'Data media sudah diisi' : 'Lengkapi data media', ], [ 'title' => 'Verifikasi', 'description' => match ($this->mediaVerification?->status) { VerificationStatus::NEED_REVISION => 'Perlu perbaikan data', VerificationStatus::PENDING => 'Sedang diverifikasi admin', default => 'Menunggu pengajuan', }, ], [ 'title' => 'Selesai', 'description' => match ($this->mediaVerification?->status) { VerificationStatus::APPROVED => 'Media disetujui', VerificationStatus::REJECTED => 'Media ditolak', default => 'Menunggu keputusan', }, ], ], ]; } public function journalistProgress(): array { $hasData = $this->journalist !== null; $currentStep = $this->resolveStep($this->journalistVerification?->status, $hasData); return [ 'title' => 'Jurnalis', 'description' => 'Progress verifikasi jurnalis', 'currentStep' => $currentStep, 'entity' => $this->journalist, 'verification' => $this->journalistVerification, 'canSubmit' => $this->canSubmit($this->journalist, $this->journalistVerification), 'isApproved' => $this->isApproved($this->journalistVerification), 'isRejected' => $this->isRejected($this->journalistVerification), 'isPending' => $this->isPending($this->journalistVerification), 'needsRevision' => $this->needsRevision($this->journalistVerification), 'latestNotes' => $this->getLatestReviewNotes($this->journalistVerification), 'reviewHistory' => $this->getReviewHistory($this->journalistVerification), 'editUrl' => ManageJournalists::getUrl(), 'steps' => [ [ 'title' => 'Pengajuan', 'description' => $hasData ? 'Data jurnalis sudah diisi' : 'Lengkapi data jurnalis', ], [ 'title' => 'Verifikasi', 'description' => match ($this->journalistVerification?->status) { VerificationStatus::NEED_REVISION => 'Perlu perbaikan data', VerificationStatus::PENDING => 'Sedang diverifikasi admin', default => 'Menunggu pengajuan', }, ], [ 'title' => 'Selesai', 'description' => match ($this->journalistVerification?->status) { VerificationStatus::APPROVED => 'Jurnalis disetujui', VerificationStatus::REJECTED => 'Jurnalis ditolak', default => 'Menunggu keputusan', }, ], ], ]; } /** * Submit company verification action */ public function submitCompanyAction(): Action { return Action::make('submitCompany') ->label(fn () => $this->needsRevision($this->companyVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi') ->icon('heroicon-o-paper-airplane') ->color('primary') ->requiresConfirmation() ->modalHeading('Ajukan Verifikasi Perusahaan') ->modalDescription('Apakah Anda yakin ingin mengajukan data perusahaan untuk diverifikasi? Pastikan semua data sudah benar.') ->modalSubmitActionLabel('Ya, Ajukan') ->visible(fn () => $this->canSubmit($this->company, $this->companyVerification)) ->action(function () { $this->submitVerification('company', $this->company, $this->companyVerification); }); } /** * Submit media verification action */ public function submitMediaAction(): Action { return Action::make('submitMedia') ->label(fn () => $this->needsRevision($this->mediaVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi') ->icon('heroicon-o-paper-airplane') ->color('primary') ->requiresConfirmation() ->modalHeading('Ajukan Verifikasi Media') ->modalDescription('Apakah Anda yakin ingin mengajukan data media untuk diverifikasi? Pastikan semua data sudah benar.') ->modalSubmitActionLabel('Ya, Ajukan') ->visible(fn () => $this->canSubmit($this->partnerMedia, $this->mediaVerification)) ->action(function () { $this->submitVerification('media', $this->partnerMedia, $this->mediaVerification); }); } /** * Submit journalist verification action */ public function submitJournalistAction(): Action { return Action::make('submitJournalist') ->label(fn () => $this->needsRevision($this->journalistVerification) ? 'Kirim Ulang' : 'Ajukan Verifikasi') ->icon('heroicon-o-paper-airplane') ->color('primary') ->requiresConfirmation() ->modalHeading('Ajukan Verifikasi Jurnalis') ->modalDescription('Apakah Anda yakin ingin mengajukan data jurnalis untuk diverifikasi? Pastikan semua data sudah benar.') ->modalSubmitActionLabel('Ya, Ajukan') ->visible(fn () => $this->canSubmit($this->journalist, $this->journalistVerification)) ->action(function () { $this->submitVerification('journalist', $this->journalist, $this->journalistVerification); }); } /** * Handle verification submission */ protected function submitVerification(string $type, $entity, ?VerificationRequest $existingRequest): void { if (! $entity) { Notification::make() ->title('Error') ->body('Data tidak ditemukan. Silakan lengkapi data terlebih dahulu.') ->danger() ->send(); return; } if ($existingRequest && $existingRequest->status === VerificationStatus::NEED_REVISION) { // Resubmit - update existing request $existingRequest->update([ 'status' => VerificationStatus::PENDING, ]); $verification = $existingRequest; } else { // New submission $verification = VerificationRequest::create([ 'verifiable_type' => get_class($entity), 'verifiable_id' => $entity->id, 'submitted_by' => auth()->id(), 'status' => VerificationStatus::PENDING, ]); } // Update the local property match ($type) { 'company' => $this->companyVerification = $verification->fresh(['reviews.reviewer']), 'media' => $this->mediaVerification = $verification->fresh(['reviews.reviewer']), 'journalist' => $this->journalistVerification = $verification->fresh(['reviews.reviewer']), }; $entityName = match ($type) { 'company' => 'Perusahaan', 'media' => 'Media', 'journalist' => 'Jurnalis', }; Notification::make() ->title('Berhasil!') ->body("Data {$entityName} berhasil diajukan untuk diverifikasi.") ->success() ->send(); } public function getViewData(): array { return [ 'companyProgress' => $this->companyProgress(), 'mediaProgress' => $this->mediaProgress(), 'journalistProgress' => $this->journalistProgress(), ]; } }