['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()] ); } } }