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.'); } }