diff --git a/api/app/Http/Controllers/StatisticsController.php b/api/app/Http/Controllers/StatisticsController.php index faf7d6e..ac8a078 100644 --- a/api/app/Http/Controllers/StatisticsController.php +++ b/api/app/Http/Controllers/StatisticsController.php @@ -7,6 +7,8 @@ use App\Models\Game; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; +use App\Models\CoinTransaction; +use App\Models\CoinTransactionType; class StatisticsController extends Controller { @@ -73,4 +75,63 @@ class StatisticsController extends Controller 'current_balance' => $user->coins_balance, // Extra info ]); } + + public function getAdminStats() + { + $totalPlayers = User::where('type', 'P')->count(); + $totalGames = Game::count(); + $totalBlockedUsers = User::where('blocked', true)->count(); + + $gamesByType = Game::select('type', DB::raw('count(*) as total')) + ->groupBy('type') + ->get(); + + // 3. Games Per Month (Line/Bar Chart) + $gamesPerMonth = Game::select( + DB::raw('DATE_FORMAT(began_at, "%Y-%m") as month'), + DB::raw('count(*) as total') + ) + ->whereNotNull('began_at') + ->groupBy('month') + ->orderBy('month', 'desc') + ->limit(12) + ->get(); + + // 4. Financial/Coin Stats (Using the new Tables) + // We calculate "Revenue" based on the volume of "Coin purchase" transactions + + // Calculate Total Coins Purchased (All time) + // We join with types table to filter by name "Coin purchase" + $totalCoinsPurchased = CoinTransaction::whereHas('type', function($q) { + $q->where('name', 'Coin purchase'); + }) + ->sum('coins'); + + // Calculate Purchases Per Month (Time Series) + // Groups by 'transaction_datetime' (YYYY-MM) + $purchasesPerMonth = \App\Models\CoinTransaction::join('coin_transaction_types', 'coin_transactions.coin_transaction_type_id', '=', 'coin_transaction_types.id') + ->where('coin_transaction_types.name', 'Coin purchase') + ->select( + DB::raw('DATE_FORMAT(coin_transactions.transaction_datetime, "%Y-%m") as month'), + DB::raw('SUM(coin_transactions.coins) as total_coins') + ) + ->groupBy('month') + ->orderBy('month', 'desc') + ->limit(12) + ->get(); + + return response()->json([ + 'global_counters' => [ + 'total_players' => $totalPlayers, + 'total_games' => $totalGames, + 'blocked_users' => $totalBlockedUsers, + 'total_coins_purchased' => (int) $totalCoinsPurchased, // Cast to int + ], + 'charts' => [ + 'games_by_type' => $gamesByType, + 'games_per_month' => $gamesPerMonth, + 'purchases_per_month' => $purchasesPerMonth, + ] + ]); + } } \ No newline at end of file diff --git a/api/app/Models/CoinTransaction.php b/api/app/Models/CoinTransaction.php new file mode 100644 index 0000000..024c9eb --- /dev/null +++ b/api/app/Models/CoinTransaction.php @@ -0,0 +1,40 @@ + 'datetime', + 'custom' => 'array', + ]; + + public function type() + { + return $this->belongsTo(CoinTransactionType::class, 'coin_transaction_type_id'); + } + + public function user() + { + return $this->belongsTo(User::class); + } +} \ No newline at end of file diff --git a/api/app/Models/CoinTransactionType.php b/api/app/Models/CoinTransactionType.php new file mode 100644 index 0000000..6caca4b --- /dev/null +++ b/api/app/Models/CoinTransactionType.php @@ -0,0 +1,20 @@ + 'array', + ]; +} \ No newline at end of file diff --git a/api/app/Models/Game.php b/api/app/Models/Game.php index dd65b7f..13f2865 100644 --- a/api/app/Models/Game.php +++ b/api/app/Models/Game.php @@ -3,7 +3,6 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; -use App\Http\Requests\StoreGameRequest; use Illuminate\Database\Eloquent\Factories\HasFactory; diff --git a/api/routes/api.php b/api/routes/api.php index b4991af..d15a631 100644 --- a/api/routes/api.php +++ b/api/routes/api.php @@ -39,6 +39,7 @@ Route::prefix('v1')->group(function () { UserController::class, 'getMatches', ]); + Route::get('/{user}/transactions', [UserController::class, 'getTransactions']); }); // Game Resources @@ -65,6 +66,7 @@ Route::prefix('v1')->group(function () { Route::middleware('user.type:A') ->prefix('admin') ->group(function () { + Route::get('/statistics', [StatisticsController::class, 'getAdminStats']); Route::prefix('users')->group(function () { Route::get('/', [UserController::class, 'index']); Route::post('/', [UserController::class, 'store']);