migrant-web/app/Http/Controllers/Admin/DashboardController.php
2026-06-19 16:05:22 +05:30

194 lines
7.9 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Inertia\Inertia;
class DashboardController extends Controller
{
/**
* Display the admin dashboard overview.
*/
public function index()
{
// Dynamic Database Queries
$totalWorkers = \App\Models\Worker::count();
$activeWorkers = \App\Models\Worker::where('status', 'active')->count();
$inactiveWorkers = $totalWorkers - $activeWorkers;
$totalEmployers = \App\Models\User::where('role', 'employer')->count();
$activeEmployers = \App\Models\User::where('role', 'employer')
->where(function($query) {
$query->whereHas('sponsor', function($q) {
$q->where('status', 'active');
})->orWhereDoesntHave('sponsor');
})->count();
$inactiveEmployers = $totalEmployers - $activeEmployers;
$activeSubs = \Illuminate\Support\Facades\DB::table('subscriptions')->where('status', 'active')->count();
$expiredSubs = \Illuminate\Support\Facades\DB::table('subscriptions')->where('status', 'expired')->count();
$newEmployers = \App\Models\User::where('role', 'employer')->where('created_at', '>=', now()->subDays(7))->count();
$revenueSum = \Illuminate\Support\Facades\DB::table('subscriptions')->where('status', 'active')->sum('amount_aed');
// Dynamic conversion rates
$verifiedCount = \App\Models\Worker::where('verified', true)->count();
$verificationRate = $totalWorkers > 0 ? round(($verifiedCount / $totalWorkers) * 100, 1) : 0.0;
$hiredCount = \App\Models\Worker::where('status', 'hired')->count();
$hiringConversionRate = $totalWorkers > 0 ? round(($hiredCount / $totalWorkers) * 100, 1) : 0.0;
$chatsCount = \Illuminate\Support\Facades\DB::table('conversations')->count();
$chatToHireRate = $chatsCount > 0 ? round(($hiredCount / $chatsCount) * 100, 1) : 0.0;
$activeRatio = $totalWorkers > 0 ? round(($activeWorkers / $totalWorkers) * 100) : 0;
$activeUsersRatio = $activeRatio . '% Active';
// Custom subscription trends
$months = [];
for ($i = 5; $i >= 0; $i--) {
$months[] = now()->subMonths($i);
}
$trendData = [];
foreach ($months as $date) {
$monthStart = $date->copy()->startOfMonth();
$monthEnd = $date->copy()->endOfMonth();
$basic = \Illuminate\Support\Facades\DB::table('subscriptions')
->where('plan_id', 'basic')
->whereBetween('created_at', [$monthStart, $monthEnd])
->count();
$premium = \Illuminate\Support\Facades\DB::table('subscriptions')
->where('plan_id', 'premium')
->whereBetween('created_at', [$monthStart, $monthEnd])
->count();
$vip = \Illuminate\Support\Facades\DB::table('subscriptions')
->whereIn('plan_id', ['vip', 'enterprise'])
->whereBetween('created_at', [$monthStart, $monthEnd])
->count();
$trendData[] = [
'month' => $date->format('M'),
'basic' => $basic,
'premium' => $premium,
'vip' => $vip,
];
}
// Funnel
$profilesBrowsed = \Illuminate\Support\Facades\DB::table('profile_views')->count();
$chatsInitiated = \Illuminate\Support\Facades\DB::table('conversations')->count();
$candidatesShortlisted = \Illuminate\Support\Facades\DB::table('shortlists')->count();
$workersHired = $hiredCount;
$verificationsToday = \App\Models\Worker::where('verified', true)
->where('updated_at', '>=', now()->startOfDay())
->count();
$stats = [
'total_workers' => $totalWorkers,
'active_workers' => $activeWorkers,
'inactive_workers' => $inactiveWorkers,
'total_employers' => $totalEmployers,
'active_employers' => $activeEmployers,
'inactive_employers' => $inactiveEmployers,
'active_subscriptions' => $activeSubs,
'revenue_this_month_aed' => $revenueSum,
'new_employers_this_week' => $newEmployers,
'expired_subscriptions' => $expiredSubs,
'hiring_conversion_rate' => $hiringConversionRate,
'chat_to_hire_rate' => $chatToHireRate,
'verification_rate' => $verificationRate,
'active_users_ratio' => $activeUsersRatio,
'trend_data' => $trendData,
'verifications_today' => $verificationsToday,
'verified_workers_count' => $verifiedCount,
'funnel' => [
'profiles_browsed' => $profilesBrowsed,
'chats_initiated' => $chatsInitiated,
'candidates_shortlisted' => $candidatesShortlisted,
'workers_hired' => $workersHired,
],
'worker_availability' => [
'Active' => \App\Models\Worker::where('status', 'active')->count(),
'Hidden' => \App\Models\Worker::where('status', 'hidden')->count(),
'Hired' => \App\Models\Worker::where('status', 'hired')->count()
],
];
// Process verifications automatically or fetched dynamically
$recentVerifications = \App\Models\Worker::where('verified', true)
->with(['documents' => function($q) {
$q->orderBy('created_at', 'desc');
}])
->latest('updated_at')
->take(5)
->get()
->map(function ($worker) {
$doc = $worker->documents->first();
return [
'id' => $worker->id,
'name' => $worker->name,
'type' => 'Worker',
'processed_at' => $worker->updated_at ? $worker->updated_at->diffForHumans() : 'Recently',
'document_type' => $doc ? ucfirst($doc->type) : 'Passport & Visa',
'status' => 'Auto-Approved',
];
})->toArray();
// Fetch recent subscriptions from subscriptions table
$recentSubs = \Illuminate\Support\Facades\DB::table('subscriptions')
->leftJoin('users', 'subscriptions.user_id', '=', 'users.id')
->select('subscriptions.*', 'users.name as employer_name')
->latest('subscriptions.created_at')
->take(5)
->get();
$recentSubscriptions = [];
foreach ($recentSubs as $sub) {
$planName = ucfirst($sub->plan_id) . ' Pass';
$recentSubscriptions[] = [
'id' => $sub->id,
'employer_name' => $sub->employer_name ?: 'System Guest / Sponsor',
'plan_name' => $planName,
'amount_aed' => (float)$sub->amount_aed,
'subscribed_at' => \Carbon\Carbon::parse($sub->created_at)->diffForHumans(),
];
}
return Inertia::render('Admin/Dashboard', [
'stats' => $stats,
'recent_verifications' => $recentVerifications,
'recent_subscriptions' => $recentSubscriptions,
]);
}
/**
* Approve a pending verification (Legacy/Manual Override).
*/
public function approveVerification(Request $request)
{
$validated = $request->validate([
'id' => 'required|integer',
]);
return back()->with('success', 'Verification document #' . $validated['id'] . ' has been approved manually.');
}
/**
* Reject a pending verification (Legacy/Manual Override).
*/
public function rejectVerification(Request $request)
{
$validated = $request->validate([
'id' => 'required|integer',
]);
return back()->with('success', 'Verification document #' . $validated['id'] . ' has been rejected.');
}
}