Version 1.0 #102
@@ -7,6 +7,7 @@ use App\Models\Game;
|
|||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use App\Models\CoinTransaction;
|
||||||
|
|
||||||
class StatisticsController extends Controller
|
class StatisticsController extends Controller
|
||||||
{
|
{
|
||||||
@@ -73,4 +74,56 @@ class StatisticsController extends Controller
|
|||||||
'current_balance' => $user->coins_balance, // Extra info
|
'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();
|
||||||
|
|
||||||
|
|
||||||
|
$gamesPerMonth = Game::select(
|
||||||
|
DB::raw("strftime('%Y-%m', began_at) as month"),
|
||||||
|
DB::raw('count(*) as total')
|
||||||
|
)
|
||||||
|
->whereNotNull('began_at')
|
||||||
|
->groupBy('month')
|
||||||
|
->orderBy('month', 'desc')
|
||||||
|
->limit(12)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$totalCoinsPurchased = \App\Models\CoinTransaction::whereHas('type', function($q) {
|
||||||
|
$q->where('name', 'Coin purchase');
|
||||||
|
})
|
||||||
|
->sum('coins');
|
||||||
|
|
||||||
|
$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("strftime('%Y-%m', coin_transactions.transaction_datetime) 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,
|
||||||
|
],
|
||||||
|
'charts' => [
|
||||||
|
'games_by_type' => $gamesByType,
|
||||||
|
'games_per_month' => $gamesPerMonth,
|
||||||
|
'purchases_per_month' => $purchasesPerMonth,
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -219,4 +219,37 @@ class UserController extends Controller
|
|||||||
|
|
||||||
return response()->json(['message' => 'User unblocked successfully']);
|
return response()->json(['message' => 'User unblocked successfully']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTransactions(Request $request, User $user)
|
||||||
|
{
|
||||||
|
if ($request->user()->id !== $user->id && $request->user()->type !== 'A') {
|
||||||
|
return response()->json(['message' => 'Forbidden'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
$query = $user->transactions()->with('type');
|
||||||
|
|
||||||
|
if ($request->has('type')) {
|
||||||
|
$query->whereHas('type', function ($q) use ($request) {
|
||||||
|
$q->where('name', $request->type);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('date_from')) {
|
||||||
|
$query->whereDate('transaction_datetime', '>=', $request->date_from);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->has('date_to')) {
|
||||||
|
$query->whereDate('transaction_datetime', '<=', $request->date_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
$transactions = $query->orderBy('transaction_datetime', 'desc')
|
||||||
|
->paginate(10);
|
||||||
|
|
||||||
|
return response()->json($transactions);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMyTransactions(Request $request)
|
||||||
|
{
|
||||||
|
return $this->getTransactions($request, $request->user());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class CoinTransaction extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $table = 'coin_transactions';
|
||||||
|
|
||||||
|
public $timestamps = false;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'transaction_datetime',
|
||||||
|
'user_id',
|
||||||
|
'match_id',
|
||||||
|
'game_id',
|
||||||
|
'coin_transaction_type_id',
|
||||||
|
'coins',
|
||||||
|
'custom'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'transaction_datetime' => 'datetime',
|
||||||
|
'custom' => 'array',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function type()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(CoinTransactionType::class, 'coin_transaction_type_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class CoinTransactionType extends Model
|
||||||
|
{
|
||||||
|
use HasFactory, SoftDeletes;
|
||||||
|
|
||||||
|
protected $table = 'coin_transaction_types';
|
||||||
|
|
||||||
|
protected $fillable = ['name', 'type', 'custom'];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'custom' => 'array',
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use App\Http\Requests\StoreGameRequest;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -58,4 +58,9 @@ class User extends Authenticatable
|
|||||||
{
|
{
|
||||||
return $this->hasMany(Game::class, 'player1_user_id')->orWhere('player2_user_id', $this->id);
|
return $this->hasMany(Game::class, 'player1_user_id')->orWhere('player2_user_id', $this->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function transactions()
|
||||||
|
{
|
||||||
|
return $this->hasMany(CoinTransaction::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ Route::prefix('v1')->group(function () {
|
|||||||
'updatePassword',
|
'updatePassword',
|
||||||
]);
|
]);
|
||||||
Route::post('/avatar', [ProfileController::class, 'uploadAvatar']);
|
Route::post('/avatar', [ProfileController::class, 'uploadAvatar']);
|
||||||
|
Route::get('/transactions', [UserController::class, 'getMyTransactions']);
|
||||||
});
|
});
|
||||||
|
|
||||||
// User Resources
|
// User Resources
|
||||||
@@ -40,6 +41,7 @@ Route::prefix('v1')->group(function () {
|
|||||||
UserController::class,
|
UserController::class,
|
||||||
'getMatches',
|
'getMatches',
|
||||||
]);
|
]);
|
||||||
|
Route::get('/{user}/transactions', [UserController::class, 'getTransactions']);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Game Resources
|
// Game Resources
|
||||||
@@ -66,6 +68,7 @@ Route::prefix('v1')->group(function () {
|
|||||||
Route::middleware('user.type:A')
|
Route::middleware('user.type:A')
|
||||||
->prefix('admin')
|
->prefix('admin')
|
||||||
->group(function () {
|
->group(function () {
|
||||||
|
Route::get('/statistics', [StatisticsController::class, 'getAdminStats']);
|
||||||
Route::prefix('users')->group(function () {
|
Route::prefix('users')->group(function () {
|
||||||
Route::get('/', [UserController::class, 'index']);
|
Route::get('/', [UserController::class, 'index']);
|
||||||
Route::post('/', [UserController::class, 'store']);
|
Route::post('/', [UserController::class, 'store']);
|
||||||
|
|||||||
Reference in New Issue
Block a user