74 lines
2.9 KiB
PHP
74 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Enums\PressReleaseStatus;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Company;
|
|
use App\Models\Contact;
|
|
use App\Models\NewsletterSubscription;
|
|
use App\Models\PressRelease;
|
|
use App\Models\User;
|
|
use App\Services\Admin\AdminPerformanceCache;
|
|
use Illuminate\Contracts\View\View;
|
|
use stdClass;
|
|
|
|
class DashboardController extends Controller
|
|
{
|
|
public function __invoke(): View
|
|
{
|
|
$stats = app(AdminPerformanceCache::class)->remember(AdminPerformanceCache::DashboardStats, AdminPerformanceCache::StatsTtl, fn (): array => $this->stats());
|
|
|
|
return view('admin.dashboard', [
|
|
'stats' => $stats,
|
|
'recentPRs' => PressRelease::withoutGlobalScopes()
|
|
->with(['company:id,name', 'user:id,name'])
|
|
->latest('created_at')
|
|
->limit(8)
|
|
->get(['id', 'title', 'status', 'portal', 'company_id', 'user_id', 'created_at']),
|
|
'pendingReviews' => PressRelease::withoutGlobalScopes()
|
|
->with(['company:id,name'])
|
|
->where('status', PressReleaseStatus::Review->value)
|
|
->latest('created_at')
|
|
->limit(5)
|
|
->get(['id', 'title', 'company_id', 'portal', 'created_at']),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @return array{press_releases: array{total: int, published: int, review: int, draft: int}, companies: int, contacts: int, users: int, newsletter: int}
|
|
*/
|
|
private function stats(): array
|
|
{
|
|
$pressReleaseStats = PressRelease::withoutGlobalScopes()
|
|
->toBase()
|
|
->selectRaw('COUNT(*) as total')
|
|
->selectRaw('SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as published', [PressReleaseStatus::Published->value])
|
|
->selectRaw('SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as review', [PressReleaseStatus::Review->value])
|
|
->selectRaw('SUM(CASE WHEN status = ? THEN 1 ELSE 0 END) as draft', [PressReleaseStatus::Draft->value])
|
|
->first();
|
|
|
|
return [
|
|
'press_releases' => $this->normalizePressReleaseStats($pressReleaseStats),
|
|
'companies' => Company::withoutGlobalScopes()->count(),
|
|
'contacts' => Contact::withoutGlobalScopes()->count(),
|
|
'users' => User::query()->toBase()->count('*'),
|
|
'newsletter' => NewsletterSubscription::withoutGlobalScopes()
|
|
->where('is_confirmed', true)
|
|
->count(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @return array{total: int, published: int, review: int, draft: int}
|
|
*/
|
|
private function normalizePressReleaseStats(?stdClass $stats): array
|
|
{
|
|
return [
|
|
'total' => (int) ($stats->total ?? 0),
|
|
'published' => (int) ($stats->published ?? 0),
|
|
'review' => (int) ($stats->review ?? 0),
|
|
'draft' => (int) ($stats->draft ?? 0),
|
|
];
|
|
}
|
|
}
|