Some checks failed
CI / Get Changed Files (pull_request) Successful in 11s
Label PRs based on size / Check PR size (pull_request) Successful in 20s
Pull Request Labeler / labeler (pull_request_target) Successful in 9s
CI / Backend Tests (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
CI / oxlint (pull_request) Successful in 31s
CI / prettier (pull_request) Successful in 35s
CI / eslint (pull_request) Successful in 42s
CI / test-build (pull_request) Successful in 53s
CI / Docker frontend validation (pull_request) Successful in 57s
CI / Docker backend validation (pull_request) Has been skipped
CI / Playwright (pull_request) Failing after 2m45s
Claude PR Review / claude-code (pull_request) Successful in 11m9s
168 lines
4.1 KiB
TypeScript
168 lines
4.1 KiB
TypeScript
import { ChangeDetectorRef, Component, OnInit, inject } from '@angular/core';
|
|
import { CommonModule } from '@angular/common';
|
|
import { LootboxService } from '../services/lootbox.service';
|
|
import { LootBox } from 'app/model/LootBox';
|
|
import { Router } from '@angular/router';
|
|
import { timeout } from 'rxjs';
|
|
import { User } from 'app/model/User';
|
|
import { AuthService } from '@service/auth.service';
|
|
import { UserService } from '@service/user.service';
|
|
|
|
@Component({
|
|
selector: 'app-lootbox-selection',
|
|
standalone: true,
|
|
imports: [CommonModule],
|
|
templateUrl: './lootbox-selection.component.html',
|
|
styleUrls: ['./lootbox-selection.component.css'],
|
|
})
|
|
export default class LootboxSelectionComponent implements OnInit {
|
|
lootboxes: LootBox[] = [];
|
|
isLoading = true;
|
|
error = '';
|
|
currentUser: User | null = null;
|
|
|
|
// Fallback data in case the API call fails
|
|
fallbackLootboxes: LootBox[] = [
|
|
{
|
|
id: 1,
|
|
name: 'Basic LootBox',
|
|
price: 2.0,
|
|
rewards: [
|
|
{
|
|
id: 1,
|
|
value: 0.5,
|
|
probability: 0.7,
|
|
},
|
|
{
|
|
id: 5,
|
|
value: 5.0,
|
|
probability: 0.3,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 2,
|
|
name: 'Premium LootBox',
|
|
price: 5.0,
|
|
rewards: [
|
|
{
|
|
id: 4,
|
|
value: 2.0,
|
|
probability: 0.6,
|
|
},
|
|
{
|
|
id: 5,
|
|
value: 5.0,
|
|
probability: 0.3,
|
|
},
|
|
{
|
|
id: 6,
|
|
value: 15.0,
|
|
probability: 0.1,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 3,
|
|
name: 'Legendäre LootBox',
|
|
price: 15.0,
|
|
rewards: [
|
|
{
|
|
id: 4,
|
|
value: 2.0,
|
|
probability: 0.6,
|
|
},
|
|
{
|
|
id: 5,
|
|
value: 5.0,
|
|
probability: 0.3,
|
|
},
|
|
{
|
|
id: 6,
|
|
value: 15.0,
|
|
probability: 0.1,
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
private lootboxService = inject(LootboxService);
|
|
private router = inject(Router);
|
|
private cdr = inject(ChangeDetectorRef);
|
|
private authService = inject(AuthService);
|
|
private userService = inject(UserService);
|
|
|
|
ngOnInit(): void {
|
|
this.loadLootboxes();
|
|
this.authService.userSubject.subscribe((user) => {
|
|
this.currentUser = user;
|
|
this.cdr.detectChanges();
|
|
});
|
|
}
|
|
|
|
loadLootboxes(): void {
|
|
this.isLoading = true;
|
|
this.lootboxService
|
|
.getAllLootBoxes()
|
|
.pipe(timeout(5000))
|
|
.subscribe({
|
|
next: (data) => {
|
|
console.log('Received lootboxes:', data);
|
|
this.lootboxes = data;
|
|
this.isLoading = false;
|
|
this.cdr.detectChanges();
|
|
},
|
|
error: (err) => {
|
|
this.error = 'Konnte keine Verbindung zum Backend herstellen. Zeige Demo-Daten.';
|
|
this.lootboxes = this.fallbackLootboxes;
|
|
this.isLoading = false;
|
|
this.cdr.detectChanges();
|
|
console.error('Failed to load lootboxes:', err);
|
|
},
|
|
});
|
|
}
|
|
|
|
getBoxImage(id: number): string {
|
|
return `/images/${id}-box.png`;
|
|
}
|
|
|
|
openLootbox(lootboxId: number): void {
|
|
const lootbox = this.lootboxes.find((box) => box.id === lootboxId);
|
|
|
|
if (!lootbox) {
|
|
return;
|
|
}
|
|
|
|
if (!this.currentUser || this.currentUser.balance < lootbox.price) {
|
|
this.error = 'Nicht genug Guthaben, um diese Lootbox zu öffnen.';
|
|
// Scroll to top to see the error message
|
|
window.scrollTo(0, 0);
|
|
this.cdr.detectChanges();
|
|
setTimeout(() => {
|
|
this.error = '';
|
|
this.cdr.detectChanges();
|
|
}, 5000);
|
|
return;
|
|
}
|
|
|
|
this.router.navigate(['/game/lootboxes/open', lootboxId]);
|
|
}
|
|
|
|
getRarityClass(probability: number): string {
|
|
if (probability <= 0.1) {
|
|
return 'text-yellow-400'; // Legendary
|
|
} else if (probability <= 0.3) {
|
|
return 'text-purple-400'; // Rare
|
|
} else {
|
|
return 'text-blue-400'; // Common
|
|
}
|
|
}
|
|
|
|
formatProbability(probability: number): string {
|
|
return (probability * 100).toFixed(0) + '%';
|
|
}
|
|
|
|
hasEnoughBalance(price: number): boolean {
|
|
return !!this.currentUser && this.currentUser.balance >= price;
|
|
}
|
|
}
|