Initialer Laravel Commit für BetiX
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled

This commit is contained in:
2026-04-04 18:01:50 +02:00
commit 0280278978
374 changed files with 65210 additions and 0 deletions

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