262 lines
9.5 KiB
PHP
262 lines
9.5 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Widgets\Stats;
|
|
|
|
use App\Enums\IsActive;
|
|
use App\Enums\IssueSentiment;
|
|
use App\Enums\RoleEnum;
|
|
use App\Models\Classification;
|
|
use App\Models\ContentRecap;
|
|
use App\Models\CooperationPayment;
|
|
use App\Models\DataChangeRequest;
|
|
use App\Models\Department;
|
|
use App\Models\IssueManagement;
|
|
use App\Models\Journalist;
|
|
use App\Models\Location;
|
|
use App\Models\MediaMonitoring;
|
|
use App\Models\News;
|
|
use App\Models\PartnerMedia;
|
|
use App\Models\Theme;
|
|
use App\Models\VerificationRequest;
|
|
use App\Models\Visitor;
|
|
use BezhanSalleh\FilamentShield\Traits\HasWidgetShield;
|
|
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
|
|
use Filament\Widgets\StatsOverviewWidget\Stat;
|
|
|
|
class OverviewStats extends BaseWidget
|
|
{
|
|
use HasWidgetShield;
|
|
|
|
protected static ?int $sort = 1;
|
|
|
|
protected int|string|array $columnSpan = 'full';
|
|
|
|
protected ?string $pollingInterval = null;
|
|
|
|
protected function getStats(): array
|
|
{
|
|
$user = auth()->user();
|
|
|
|
if ($user && $user->hasRole(RoleEnum::PERUSAHAAN->value)) {
|
|
return $this->getCompanyStats($user);
|
|
}
|
|
|
|
if ($user && $user->hasRole(RoleEnum::ADMIN_KEUANGAN->value)) {
|
|
return $this->getFinanceStats();
|
|
}
|
|
|
|
if ($user && $user->hasRole(RoleEnum::ADMIN_KONTEN->value)) {
|
|
return $this->getContentAdminStats();
|
|
}
|
|
|
|
if ($user && $user->hasRole(RoleEnum::ADMIN_MONITORING->value)) {
|
|
return $this->getMonitoringStats();
|
|
}
|
|
|
|
$totalJournalists = Journalist::count();
|
|
$totalMedia = PartnerMedia::count();
|
|
$average = $totalMedia > 0 ? round($totalJournalists / $totalMedia, 1) : 0;
|
|
|
|
return [
|
|
Stat::make('Total Klasifikasi', Classification::active()->count())
|
|
->description('Klasifikasi aktif')
|
|
->descriptionIcon('heroicon-o-book-open')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Total Lokus', Location::active()->count())
|
|
->description('Lokus aktif')
|
|
->descriptionIcon('heroicon-o-map-pin')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Total OPD', Department::where('is_active', IsActive::ACTIVE)->count())
|
|
->description('OPD aktif')
|
|
->descriptionIcon('heroicon-o-building-library')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Total Tema', Theme::active()->count())
|
|
->description('Tema aktif')
|
|
->descriptionIcon('heroicon-o-puzzle-piece')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Total Anggaran', 'Rp '.number_format(CooperationPayment::sum('amount'), 0, ',', '.'))
|
|
->description('Realisasi pembayaran')
|
|
->descriptionIcon('heroicon-o-banknotes')
|
|
->color('success'),
|
|
|
|
Stat::make('Rasio Jurnalis', $average.' per Media')
|
|
->description('Rata-rata jurnalis')
|
|
->descriptionIcon('heroicon-o-users')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Total Jurnalis', $totalJournalists)
|
|
->description('Jurnalis terdaftar')
|
|
->descriptionIcon('heroicon-o-identification')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Isu Kritis', IssueManagement::whereIn('issue', [IssueSentiment::NEGATIVE, IssueSentiment::CRISIS])->count())
|
|
->description('Perlu perhatian')
|
|
->descriptionIcon('heroicon-o-exclamation-triangle')
|
|
->color('danger'),
|
|
|
|
Stat::make('Antrean Verifikasi', VerificationRequest::pending()->count())
|
|
->description('Butuh tindakan')
|
|
->descriptionIcon('heroicon-o-pencil-square')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Antrean Perubahan', DataChangeRequest::pending()->count())
|
|
->description('Perubahan data')
|
|
->descriptionIcon('heroicon-o-document-text')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Total Pengunjung', Visitor::count())
|
|
->description('Total traffic')
|
|
->descriptionIcon('heroicon-o-chart-bar')
|
|
->color($this->getRandomColor()),
|
|
];
|
|
}
|
|
|
|
private array $availableColors = [
|
|
'primary',
|
|
'success',
|
|
'warning',
|
|
'danger',
|
|
'info',
|
|
'fuchsia',
|
|
'indigo',
|
|
'violet',
|
|
'orange',
|
|
'cyan',
|
|
'emerald',
|
|
'amber',
|
|
'rose',
|
|
'lime',
|
|
];
|
|
|
|
private function getRandomColor(): string
|
|
{
|
|
return $this->availableColors[array_rand($this->availableColors)];
|
|
}
|
|
|
|
private function getCompanyStats($user): array
|
|
{
|
|
$company = $user->company;
|
|
|
|
if (! $company) {
|
|
return [
|
|
Stat::make('Status Perusahaan', 'Belum Terdaftar')
|
|
->description('Silakan lengkapi profil perusahaan')
|
|
->color('danger'),
|
|
];
|
|
}
|
|
|
|
$journalistCount = $company->journalists()->count();
|
|
$cooperationCount = 0;
|
|
|
|
if ($company->partnerMedia) {
|
|
$cooperationCount = $company->partnerMedia->cooperations()->count();
|
|
}
|
|
|
|
$verificationStatus = $company->verificationRequest?->status?->getLabel() ?? 'Belum Mengajukan';
|
|
$verificationColor = $company->verificationRequest?->status?->getColor() ?? 'gray';
|
|
|
|
$dataChangeRequestsCount = $company->dataChangeRequests()->pending()->count() + $user->dataChangeRequests()->pending()->count();
|
|
|
|
return [
|
|
Stat::make('Status Verifikasi', $verificationStatus)
|
|
->description('Status verifikasi perusahaan')
|
|
->descriptionIcon('heroicon-o-shield-check')
|
|
->color($verificationColor),
|
|
|
|
Stat::make('Total Jurnalis', $journalistCount)
|
|
->description('Jurnalis terdaftar')
|
|
->descriptionIcon('heroicon-o-users')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Total Kerjasama', $cooperationCount)
|
|
->description('Kerjasama diajukan/diikuti')
|
|
->descriptionIcon('heroicon-o-hand-raised')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Antrean Perubahan Data', $dataChangeRequestsCount)
|
|
->description('Perubahan data menunggu persetujuan')
|
|
->descriptionIcon('heroicon-o-document-text')
|
|
->color($this->getRandomColor()),
|
|
];
|
|
}
|
|
|
|
private function getFinanceStats(): array
|
|
{
|
|
return [
|
|
Stat::make('Total Anggaran', 'Rp '.number_format(CooperationPayment::sum('amount'), 0, ',', '.'))
|
|
->description('Total Nilai Kerjasama')
|
|
->descriptionIcon('heroicon-o-banknotes')
|
|
->color('success'),
|
|
|
|
Stat::make('Realisasi Pembayaran', CooperationPayment::accepted()->count())
|
|
->description('Pembayaran Selesai')
|
|
->descriptionIcon('heroicon-o-check-circle')
|
|
->color('success'),
|
|
|
|
Stat::make('Menunggu Pembayaran', CooperationPayment::pending()->count())
|
|
->description('Menunggu Tindakan')
|
|
->descriptionIcon('heroicon-o-clock')
|
|
->color('warning'),
|
|
|
|
Stat::make('Pembayaran Ditolak', CooperationPayment::rejected()->count())
|
|
->description('Perlu Perhatian')
|
|
->descriptionIcon('heroicon-o-x-circle')
|
|
->color('danger'),
|
|
];
|
|
}
|
|
|
|
private function getContentAdminStats(): array
|
|
{
|
|
return [
|
|
Stat::make('Total Klasifikasi', Classification::active()->count())
|
|
->description('Klasifikasi aktif')
|
|
->descriptionIcon('heroicon-o-book-open')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Total Rekap Konten', ContentRecap::count())
|
|
->description('Konten direkap')
|
|
->descriptionIcon('heroicon-o-document-duplicate')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Total Berita', News::count())
|
|
->description('Berita dipublikasikan')
|
|
->descriptionIcon('heroicon-o-newspaper')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Berita Terpopuler', number_format(News::max('views') ?? 0, 0, ',', '.'))
|
|
->description('Views tertinggi')
|
|
->descriptionIcon('heroicon-o-star')
|
|
->color('warning'),
|
|
];
|
|
}
|
|
|
|
private function getMonitoringStats(): array
|
|
{
|
|
return [
|
|
Stat::make('Total Isu (Masalah)', IssueManagement::count())
|
|
->description('Manajemen Isu')
|
|
->descriptionIcon('heroicon-o-exclamation-circle')
|
|
->color('primary'),
|
|
|
|
Stat::make('Isu Kritis / Negatif', IssueManagement::whereIn('issue', [IssueSentiment::NEGATIVE, IssueSentiment::CRISIS])->count())
|
|
->description('Perhatian Khusus')
|
|
->descriptionIcon('heroicon-o-exclamation-triangle')
|
|
->color('danger'),
|
|
|
|
Stat::make('Total Media Monitoring', MediaMonitoring::count())
|
|
->description('Berita terpantau')
|
|
->descriptionIcon('heroicon-o-globe-alt')
|
|
->color($this->getRandomColor()),
|
|
|
|
Stat::make('Total Lokus', Location::active()->count())
|
|
->description('Lokus aktif')
|
|
->descriptionIcon('heroicon-o-map-pin')
|
|
->color($this->getRandomColor()),
|
|
];
|
|
}
|
|
}
|