98 lines
3.7 KiB
PHP
98 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\User;
|
|
use App\Models\Suggestion;
|
|
use App\Models\Ticket;
|
|
use App\Models\UserSubscriber;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
class DashboardController extends Controller
|
|
{
|
|
public function index()
|
|
{
|
|
// 1. Calculate General Statistics
|
|
$totalUsers = User::count();
|
|
|
|
// 2. Safely Count Free Subscribers using the relationship
|
|
$freeSubscribers = UserSubscriber::where('expired_at', '>=', now())
|
|
->whereHas('subscribe', function (Builder $query) {
|
|
$query->where('is_free', true);
|
|
})
|
|
->distinct('user_id')
|
|
->count('user_id');
|
|
|
|
// 3. Get Paid Subscribers & Breakdown by Plan Type AND Market Provider
|
|
$paidBreakdown = UserSubscriber::where('user_subscribers.expired_at', '>=', now())
|
|
->whereHas('subscribe', function (Builder $query) {
|
|
$query->where('is_free', false);
|
|
})
|
|
->join('subscribe_plans', 'user_subscribers.subscribe_plan_id', '=', 'subscribe_plans.id')
|
|
->selectRaw('subscribe_plans.name as plan_name, user_subscribers.market_provider, count(DISTINCT user_subscribers.user_id) as total')
|
|
->groupBy('subscribe_plans.name', 'user_subscribers.market_provider')
|
|
->get();
|
|
|
|
// Format the display name to show the source clearly
|
|
$paidBreakdown->each(function ($item) {
|
|
$provider = strtolower($item->market_provider ?? '');
|
|
|
|
if ($provider === 'bazar') {
|
|
$item->display_name = $item->plan_name . ' (کافه بازار)';
|
|
} elseif ($provider === 'myket') {
|
|
$item->display_name = $item->plan_name . ' (مایکت)';
|
|
} else {
|
|
// If market_provider is null or empty, it was purchased directly from the site
|
|
$item->display_name = $item->plan_name . ' (سایت / مستقیم)';
|
|
}
|
|
});
|
|
|
|
// Total paid is the sum of the breakdown
|
|
$paidSubscribers = $paidBreakdown->sum('total');
|
|
|
|
// 4. Fetch Recent Data (Limit to 5)
|
|
$recentSuggestions = Suggestion::with('user')->latest()->take(5)->get();
|
|
|
|
// Order tickets by updated_at so newly replied tickets jump to the top
|
|
$recentTickets = Ticket::with('user')->latest('updated_at')->take(5)->get();
|
|
|
|
// 5. Prepare Chart Data (Strictly the last 7 calendar days)
|
|
$chartDates = [];
|
|
$newUsersData = [];
|
|
$paidSubsData = [];
|
|
$freeSubsData = [];
|
|
|
|
for ($i = 6; $i >= 0; $i--) {
|
|
$date = now()->subDays($i);
|
|
$dbDate = $date->format('Y-m-d');
|
|
|
|
// Format X-axis to Jalali for the chart labels
|
|
$chartDates[] = \Morilog\Jalali\Jalalian::fromCarbon($date)->format('Y/m/d');
|
|
|
|
// Count records for this specific exact date
|
|
$newUsersData[] = User::whereDate('created_at', $dbDate)->count();
|
|
|
|
$paidSubsData[] = UserSubscriber::whereDate('created_at', $dbDate)
|
|
->whereHas('subscribe', fn($q) => $q->where('is_free', false))->count();
|
|
|
|
$freeSubsData[] = UserSubscriber::whereDate('created_at', $dbDate)
|
|
->whereHas('subscribe', fn($q) => $q->where('is_free', true))->count();
|
|
}
|
|
|
|
return view('admin.dashboard.index', compact(
|
|
'totalUsers',
|
|
'paidSubscribers',
|
|
'freeSubscribers',
|
|
'paidBreakdown',
|
|
'recentSuggestions',
|
|
'recentTickets',
|
|
'chartDates',
|
|
'newUsersData',
|
|
'paidSubsData',
|
|
'freeSubsData'
|
|
));
|
|
}
|
|
}
|