user(); $this->company = $user->company; // Load unified verification request if ($this->company) { $this->verificationRequest = $this->company->verificationRequest() ->with(['reviews.reviewer']) ->latest() ->first(); } } /** * Get unified verification progress */ public function getVerificationProgress(): array { $isComplete = $this->isDataComplete(); $missingData = $this->getMissingData(); $status = $this->verificationRequest?->status; $progress = [ 'currentStep' => $this->resolveStep(), 'isDataComplete' => $isComplete, 'missingData' => $missingData, 'canSubmit' => $this->canSubmit(), 'verification' => $this->verificationRequest, 'status' => [ 'label' => $status?->getLabel() ?? 'Belum Mengajukan', 'color' => $status?->getColor() ?? 'gray', ], 'isApproved' => $status === VerificationStatus::APPROVED, 'isRejected' => $status === VerificationStatus::REJECTED, 'isPending' => $status === VerificationStatus::PENDING, 'needsRevision' => $status === VerificationStatus::NEED_REVISION, 'latestNotes' => $this->getLatestReviewNotes(), 'reviewHistory' => $this->getReviewHistory(), 'company' => $this->company, 'partnerMedia' => $this->company?->partnerMedia, 'journalists' => $this->company?->partnerMedia?->journalists ?? collect(), 'steps' => $this->getSteps($isComplete), ]; // Add additional data for view $progress['missingDataButtons'] = $this->getMissingDataButtons(); $progress['alert'] = $this->getAlertData(); $progress['lastSubmittedAt'] = $this->verificationRequest?->updated_at?->translatedFormat('l, d M Y H:i'); return $progress; } /** * Submit unified verification action */ public function submitVerificationAction(): Action { $progress = $this->getVerificationProgress(); return Action::make('submitVerification') ->label(fn (): string => $this->verificationRequest && $this->verificationRequest->status === VerificationStatus::NEED_REVISION ? 'Kirim Ulang' : 'Ajukan Verifikasi') ->icon('heroicon-o-paper-airplane') ->color('primary') ->requiresConfirmation() ->modalHeading('Ajukan Verifikasi Sekarang? 🚀✨') ->modalDescription(function () use ($progress): string { if (! $progress['isDataComplete']) { return 'Aduh, data belum lengkap nih! 😅 Silakan lengkapi dulu bagian: '.implode(', ', $progress['missingData']).' ya!'; } if ($this->verificationRequest && $this->verificationRequest->status === VerificationStatus::NEED_REVISION) { return 'Ayo kirim ulang perbaikannya! Pastikan semuanya sudah sesuai catatan admin biar langsung gaspol! 💪✨'; } return 'Apakah Anda yakin ingin mengajukan verifikasi? Pastikan semua data sudah benar dan lengkap ya! Pasti bisa! 😊👍'; }) ->modalSubmitActionLabel('Ya, Ajukan') ->visible(fn (): bool => $progress['canSubmit']) ->disabled(fn (): bool => ! $progress['isDataComplete']) ->action(function () use ($progress): void { if (! $progress['isDataComplete']) { CheerfulNotification::danger( 'Data Belum Lengkap! 😅', 'Silakan lengkapi data terlebih dahulu sebelum mengajukan verifikasi ya: '.implode(', ', $progress['missingData']) )->send(); return; } $isRevision = $this->verificationRequest && $this->verificationRequest->status === VerificationStatus::NEED_REVISION; $this->verificationRequest = $this->submitVerification(); CheerfulNotification::success( 'Berhasil Diajukan! 🚀', 'Yeay! Pengajuan verifikasi Anda sudah terkirim ke Admin. Mohon ditunggu ya, semoga hasilnya memuaskan! ✨' )->send(); User::superAdmin() ->get() ->each(function ($admin) use ($isRevision): void { $user = auth()->user(); $admin->notify(new BroadcastNotification([ 'title' => $isRevision ? 'Pembaruan Data Verifikasi ✨' : 'Ada Pengajuan Verifikasi Baru! 🚀', 'body' => $isRevision ? "Cihuy! {$user->name} baru saja memperbarui data verifikasi untuk perusahaan {$user->company->name}. Yuk, cek perubahannya!" : "Halo Admin! {$user->name} baru saja mengajukan verifikasi data untuk perusahaan {$user->company->name}. Segera diproses ya! 😊", 'action' => [ Action::make('view') ->label('Lihat') ->url(PartnerResource::getUrl('view', ['record' => $user])), ], ])); }); }); } /** * Check if all required data is complete for verification */ protected function isDataComplete(): bool { return $this->company !== null && $this->company->partnerMedia !== null && $this->company->partnerMedia?->journalists !== null && $this->company->partnerMedia->journalists->count() > 0; } /** * Get missing data items for verification */ protected function getMissingData(): array { $missing = []; if (! $this->company) { $missing[] = 'Data Perusahaan'; } if ($this->company && ! $this->company->partnerMedia) { $missing[] = 'Data Media'; } if ($this->company && $this->company->partnerMedia && ($this->company->partnerMedia?->journalists === null || $this->company->partnerMedia?->journalists?->count() === 0)) { $missing[] = 'Data Jurnalis (minimal 1)'; } return $missing; } /** * Check if user can submit verification */ protected function canSubmit(): bool { if (! $this->isDataComplete()) { return false; } // No verification yet - can submit if (! $this->verificationRequest) { return true; } // Can resubmit only if status is NEED_REVISION return $this->verificationRequest->status === VerificationStatus::NEED_REVISION; } /** * Determine the current step based on status */ protected function resolveStep(): int { if (! $this->isDataComplete()) { return 1; // Data belum lengkap } if (! $this->verificationRequest) { return 1; // Belum submit } return match ($this->verificationRequest->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 }; } /** * Get the latest review notes */ protected function getLatestReviewNotes(): ?string { if (! $this->verificationRequest) { return null; } $latestReview = $this->verificationRequest->reviews() ->where(fn ($q) => $q->needRevision()->orWhere(fn ($q) => $q->rejected())) ->latest() ->first(); return $latestReview?->note; } /** * Get all reviews history */ protected function getReviewHistory(): Collection { if (! $this->verificationRequest) { return collect(); } return $this->verificationRequest->reviews() ->with('reviewer') ->latest() ->get(); } /** * Submit unified verification */ protected function submitVerification(): VerificationRequest { if ($this->verificationRequest && $this->verificationRequest->status === VerificationStatus::NEED_REVISION) { // Resubmit - update existing request $this->verificationRequest->update([ 'status' => VerificationStatus::PENDING, ]); return $this->verificationRequest->fresh(['reviews.reviewer']); } // New submission return VerificationRequest::create([ 'company_id' => $this->company->id, 'submitted_by' => auth()->id(), 'status' => VerificationStatus::PENDING, ])->load(['reviews.reviewer']); } /** * Get alert data for verification status */ protected function getAlertData(): ?array { if (! $this->verificationRequest) { return null; } $status = $this->verificationRequest->status; $latestNotes = $this->getLatestReviewNotes(); if ($status === VerificationStatus::NEED_REVISION && $latestNotes) { return [ 'type' => 'revision', 'icon' => 'exclamation-triangle', 'title' => 'Catatan Revisi dari Admin', 'message' => $latestNotes, 'color' => 'warning', ]; } if ($status === VerificationStatus::REJECTED && $latestNotes) { return [ 'type' => 'rejected', 'icon' => 'x-circle', 'title' => 'Pengajuan Ditolak', 'message' => $latestNotes, 'color' => 'danger', ]; } if ($status === VerificationStatus::APPROVED) { return [ 'type' => 'approved', 'icon' => 'check-circle', 'title' => 'Verifikasi Diterima', 'message' => 'Verifikasi Anda telah diterima dan disetujui oleh admin. Sekarang Anda sudah resmi terverifikasi dan bekerja sama dengan kami!', 'color' => 'success', ]; } if ($status === VerificationStatus::PENDING) { return [ 'type' => 'pending', 'icon' => 'clock', 'title' => 'Menunggu Verifikasi', 'message' => 'Data Anda sedang dalam proses verifikasi oleh admin. Mohon tunggu.', 'color' => 'info', 'animate' => true, ]; } return null; } /** * Get missing data buttons configuration */ protected function getMissingDataButtons(): array { $buttons = []; if (! $this->company) { $buttons[] = [ 'label' => 'Lengkapi Data Perusahaan', 'url' => PagesCompany::getUrl(), 'icon' => 'building-office-2', 'color' => 'warning', ]; } if ($this->company && ! $this->company->partnerMedia) { $buttons[] = [ 'label' => 'Lengkapi Data Media', 'url' => Media::getUrl(), 'icon' => 'newspaper', 'color' => 'warning', ]; } if ($this->company && $this->company->partnerMedia && ($this->company->partnerMedia->journalists === null || $this->company->partnerMedia->journalists->count() === 0)) { $buttons[] = [ 'label' => 'Lengkapi Data Jurnalis', 'url' => ManageJournalists::getUrl(), 'icon' => 'user-circle', 'color' => 'warning', ]; } return $buttons; } /** * Get steps array for stepper */ protected function getSteps(bool $isComplete): array { $status = $this->verificationRequest?->status; return [ [ 'title' => 'Pengajuan', 'description' => $isComplete ? 'Data sudah lengkap, silakan ajukan verifikasi' : 'Silakan lengkapi data', ], [ 'title' => 'Verifikasi', 'description' => match ($status) { VerificationStatus::NEED_REVISION => 'Perlu perbaikan data', VerificationStatus::PENDING => 'Sedang diverifikasi admin', default => 'Menunggu pengajuan', }, ], [ 'title' => 'Selesai', 'description' => match ($status) { VerificationStatus::APPROVED => 'Verifikasi disetujui', VerificationStatus::REJECTED => 'Verifikasi ditolak', default => 'Menunggu keputusan', }, ], ]; } public function getViewData(): array { return [ 'verificationProgress' => $this->getVerificationProgress(), ]; } }