Initialer Laravel Commit für BetiX
This commit is contained in:
146
app/Http/Controllers/TrophyController.php
Normal file
146
app/Http/Controllers/TrophyController.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\GameBet;
|
||||
use App\Models\User;
|
||||
use App\Models\UserAchievement;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class TrophyController extends Controller
|
||||
{
|
||||
/**
|
||||
* All available achievements with their unlock conditions (for display).
|
||||
*/
|
||||
public static array $definitions = [
|
||||
'first_bet' => ['title' => 'First Bet', 'desc' => 'Place your very first bet.', 'icon' => '🎲'],
|
||||
'first_win' => ['title' => 'First Win', 'desc' => 'Win your first game.', 'icon' => '🏆'],
|
||||
'big_winner' => ['title' => 'Big Winner', 'desc' => 'Land a 10× or higher multiplier.', 'icon' => '💥'],
|
||||
'high_roller' => ['title' => 'High Roller', 'desc' => 'Wager 100+ BTX in total.', 'icon' => '💎'],
|
||||
'frequent_player' => ['title' => 'Frequent Player', 'desc' => 'Place 50+ bets.', 'icon' => '🔥'],
|
||||
'hundred_bets' => ['title' => 'Centurion', 'desc' => 'Place 100+ bets.', 'icon' => '⚡'],
|
||||
'vault_user' => ['title' => 'Vault Guardian', 'desc' => 'Make your first vault deposit.', 'icon' => '🔒'],
|
||||
'vip_level2' => ['title' => 'Rising Star', 'desc' => 'Reach VIP Level 2.', 'icon' => '⭐'],
|
||||
'vip_level5' => ['title' => 'Elite', 'desc' => 'Reach VIP Level 5.', 'icon' => '👑'],
|
||||
'guild_member' => ['title' => 'Team Player', 'desc' => 'Join a guild.', 'icon' => '🛡️'],
|
||||
'promo_user' => ['title' => 'Promo Hunter', 'desc' => 'Redeem your first promo code.', 'icon' => '🎁'],
|
||||
];
|
||||
|
||||
/**
|
||||
* Trophy room page — show user's achievements + locked ones.
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
abort_unless($user, 403);
|
||||
|
||||
// Sync achievements before showing
|
||||
$this->syncAchievements($user);
|
||||
|
||||
$unlocked = UserAchievement::where('user_id', $user->id)
|
||||
->pluck('unlocked_at', 'achievement_key');
|
||||
|
||||
$achievements = [];
|
||||
foreach (self::$definitions as $key => $def) {
|
||||
$achievements[] = [
|
||||
'key' => $key,
|
||||
'title' => $def['title'],
|
||||
'description' => $def['desc'],
|
||||
'icon' => $def['icon'],
|
||||
'unlocked' => isset($unlocked[$key]),
|
||||
'unlocked_at' => isset($unlocked[$key]) ? $unlocked[$key]->toIso8601String() : null,
|
||||
];
|
||||
}
|
||||
|
||||
// Sort: unlocked first, then locked
|
||||
usort($achievements, fn($a, $b) => ($b['unlocked'] <=> $a['unlocked']));
|
||||
|
||||
return Inertia::render('Trophy', [
|
||||
'achievements' => $achievements,
|
||||
'total' => count(self::$definitions),
|
||||
'unlocked' => $unlocked->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trophy room for a specific user (public profiles only).
|
||||
*/
|
||||
public function show(Request $request, string $username)
|
||||
{
|
||||
$user = User::where('username', $username)->firstOrFail();
|
||||
|
||||
// Only show trophies for public profiles (or own profile)
|
||||
if (!$user->is_public && Auth::id() !== $user->id) {
|
||||
abort(403, 'This profile is private.');
|
||||
}
|
||||
|
||||
$this->syncAchievements($user);
|
||||
|
||||
$unlocked = UserAchievement::where('user_id', $user->id)
|
||||
->pluck('unlocked_at', 'achievement_key');
|
||||
|
||||
$achievements = [];
|
||||
foreach (self::$definitions as $key => $def) {
|
||||
$achievements[] = [
|
||||
'key' => $key,
|
||||
'title' => $def['title'],
|
||||
'description' => $def['desc'],
|
||||
'icon' => $def['icon'],
|
||||
'unlocked' => isset($unlocked[$key]),
|
||||
'unlocked_at' => isset($unlocked[$key]) ? $unlocked[$key]->toIso8601String() : null,
|
||||
];
|
||||
}
|
||||
|
||||
usort($achievements, fn($a, $b) => ($b['unlocked'] <=> $a['unlocked']));
|
||||
|
||||
return Inertia::render('Trophy', [
|
||||
'achievements' => $achievements,
|
||||
'total' => count(self::$definitions),
|
||||
'unlocked' => $unlocked->count(),
|
||||
'profileUser' => ['username' => $user->username, 'avatar' => $user->avatar],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and unlock achievements for the given user.
|
||||
*/
|
||||
public function syncAchievements(\App\Models\User $user): void
|
||||
{
|
||||
$bets = GameBet::where('user_id', $user->id);
|
||||
$betCount = $bets->count();
|
||||
$totalWager = $bets->sum('wager_amount');
|
||||
$maxMulti = $bets->max('payout_multiplier') ?? 0;
|
||||
$hasWin = $bets->where('payout_amount', '>', 0)->exists();
|
||||
|
||||
$toUnlock = [];
|
||||
|
||||
if ($betCount >= 1) $toUnlock[] = 'first_bet';
|
||||
if ($hasWin) $toUnlock[] = 'first_win';
|
||||
if ($maxMulti >= 10) $toUnlock[] = 'big_winner';
|
||||
if ($totalWager >= 100) $toUnlock[] = 'high_roller';
|
||||
if ($betCount >= 50) $toUnlock[] = 'frequent_player';
|
||||
if ($betCount >= 100) $toUnlock[] = 'hundred_bets';
|
||||
if ($user->vip_level >= 2) $toUnlock[] = 'vip_level2';
|
||||
if ($user->vip_level >= 5) $toUnlock[] = 'vip_level5';
|
||||
if ($user->guildMember()->exists()) $toUnlock[] = 'guild_member';
|
||||
|
||||
// Vault usage
|
||||
if (\App\Models\WalletTransfer::where('user_id', $user->id)->where('type', 'deposit')->exists()) {
|
||||
$toUnlock[] = 'vault_user';
|
||||
}
|
||||
// Promo usage
|
||||
if (\App\Models\PromoUsage::where('user_id', $user->id)->exists()) {
|
||||
$toUnlock[] = 'promo_user';
|
||||
}
|
||||
|
||||
foreach ($toUnlock as $key) {
|
||||
UserAchievement::firstOrCreate(
|
||||
['user_id' => $user->id, 'achievement_key' => $key],
|
||||
['unlocked_at' => now()]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user