feat: add transaction history to homepage (CAS-56) #137

Merged
csimonis merged 8 commits from feature/transaction-history into main 2025-04-23 10:38:31 +00:00
11 changed files with 47 additions and 24 deletions
Showing only changes of commit 35184807c0 - Show all commits

View file

@ -18,4 +18,7 @@ public interface TransactionRepository extends JpaRepository<TransactionEntity,
@Query("SELECT t FROM TransactionEntity t WHERE t.user = ?1 ORDER BY t.createdAt DESC LIMIT ?2 OFFSET ?3")
List<TransactionEntity> findByUserIdWithLimit(UserEntity userEntity, Integer limit, Integer offset);
@Query("SELECT COUNT(t) > ?2 + ?3 FROM TransactionEntity t WHERE t.user = ?1")
Boolean hasMore(UserEntity userEntity, Integer limit, Integer offset);
}

View file

@ -5,6 +5,7 @@ import de.szut.casino.deposit.TransactionRepository;
import de.szut.casino.user.UserEntity;
import de.szut.casino.user.UserService;
import de.szut.casino.user.transaction.dto.GetTransactionDto;
import de.szut.casino.user.transaction.dto.UserTransactionsDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -20,17 +21,16 @@ public class GetTransactionService {
@Autowired
private TransactionRepository transactionRepository;
public List<TransactionEntity> getUserTransactions(String authToken, Integer limit, Integer offset) {
public UserTransactionsDto getUserTransactionsDto(String authToken, Integer limit, Integer offset) {
Optional<UserEntity> user = this.userService.getCurrentUser(authToken);
if (user.isPresent()) {
if (limit != null && limit > 0) {
return this.transactionRepository.findByUserIdWithLimit(user.get(), limit, offset);
} else {
return this.transactionRepository.findAllByUserId(user.get());
}
List<TransactionEntity> transactionEntities = this.transactionRepository.findByUserIdWithLimit(user.get(), limit, offset);
Boolean hasMore = this.transactionRepository.hasMore(user.get(), limit, offset);
return new UserTransactionsDto(mapTransactionsToDtos(transactionEntities), hasMore);
}
return List.of();
return new UserTransactionsDto(List.of(), false);
}
public List<GetTransactionDto> mapTransactionsToDtos(List<TransactionEntity> transactions) {

View file

@ -2,6 +2,7 @@ package de.szut.casino.user.transaction;
import de.szut.casino.deposit.TransactionEntity;
import de.szut.casino.user.transaction.dto.GetTransactionDto;
import de.szut.casino.user.transaction.dto.UserTransactionsDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
@ -18,14 +19,14 @@ public class TransactionController {
private GetTransactionService transactionService;
@GetMapping("/user/transactions")
public ResponseEntity<List<GetTransactionDto>> getUserTransactions(
public ResponseEntity<UserTransactionsDto> getUserTransactions(
@RequestHeader("Authorization") String authToken,
@RequestParam(value = "limit", required = false) Integer limit,
@RequestParam(value = "offset", required = false) Integer offset
) {
List<TransactionEntity> transactionEntities = this.transactionService.getUserTransactions(authToken, limit, offset);
UserTransactionsDto transactionEntities = this.transactionService.getUserTransactionsDto(authToken, limit, offset);
return ResponseEntity.ok(this.transactionService.mapTransactionsToDtos(transactionEntities));
return ResponseEntity.ok(transactionEntities);
}
}

View file

@ -0,0 +1,12 @@
package de.szut.casino.user.transaction.dto;
import lombok.AllArgsConstructor;
import java.util.List;
@AllArgsConstructor
public class UserTransactionsDto {
public List<GetTransactionDto> transactions;
public Boolean hasMore;
}

View file

@ -101,7 +101,7 @@
<div class="space-y-3">
<div
class="flex justify-between items-center"
*ngFor="let transaction of recentTransactions|async"
*ngFor="let transaction of (recentTransactionData | async)?.transactions"
>
<div>
<p class="text-sm font-medium">{{ transaction.status }}</p>

View file

@ -3,13 +3,13 @@ import { AsyncPipe, CurrencyPipe, DatePipe, NgFor } from '@angular/common';
import { DepositComponent } from '../deposit/deposit.component';
import { ActivatedRoute, Router } from '@angular/router';
import { ConfirmationComponent } from '@shared/components/confirmation/confirmation.component';
import { Transaction } from 'app/model/Transaction';
import { NavbarComponent } from '@shared/components/navbar/navbar.component';
import { Game } from 'app/model/Game';
import { Observable, of } from 'rxjs';
import { Observable } from 'rxjs';
import { TransactionService } from '@service/transaction.service';
import format from 'ajv/dist/vocabularies/format';
import { TransactionHistoryComponent } from '../transaction-history/transaction-history.component';
import { TransactionData } from '../../model/TransactionData';
@Component({
selector: 'app-homepage',
@ -80,7 +80,7 @@ export default class HomeComponent implements OnInit {
allGames: Game[] = [...this.featuredGames];
recentTransactions: Observable<Transaction[]> = inject(TransactionService).getUsersTransactions(5);
recentTransactionData: Observable<TransactionData> = inject(TransactionService).getUsersTransactions(5);
openDepositModal() {
this.isDepositModalOpen = true;

View file

@ -1,9 +1,8 @@
button[disabled] {
cursor: not-allowed;
background-color: #ccc;
background-color: #077b58;
box-shadow: none;
}
button[disabled]:hover {
background-color: #ccc;
background-color: #077b58;
}

View file

@ -8,7 +8,7 @@
</button>
<h2 class="modal-heading">Transaktionen</h2>
<p class="py-2 text-text-secondary mb-4">Hier siehst du alle vergangenen Einzahlungen</p>
@for (transaction of transactions$ | async; track null) {
@for (transaction of (transactionData$ | async)?.transactions; track null) {
<div class="flex justify-between items-center mb-4">
<div>
<p class="text-sm font-medium">{{ transaction.status }}</p>
@ -25,11 +25,11 @@
</div>
</div>
}
<div class="inline inline-flex w-full">
<div class="inline inline-flex w-full gap-2">
<button type="button" (click)="back()" class="button-primary w-full py-2" [disabled]="offset <= 0">
<
</button>
<button type="button" (click)="forward()" class="button-primary w-full py-2">
<button type="button" (click)="forward()" class="button-primary w-full py-2" [disabled]="!(transactionData$|async)?.hasMore">
>
</button>
</div>

View file

@ -4,6 +4,7 @@ import { Observable } from 'rxjs';
import { Transaction } from '../../model/Transaction';
import { AsyncPipe, CurrencyPipe, DatePipe, NgForOf, NgIf } from '@angular/common';
import { AnimatedNumberComponent } from '@blackjack/components/animated-number/animated-number.component';
import { TransactionData } from '../../model/TransactionData';
const PER_PAGE = 5
@ -31,7 +32,7 @@ export class TransactionHistoryComponent {
protected offset: number = 0;
private transactionService: TransactionService = inject(TransactionService);
transactions$: Observable<Transaction[]> = this.loadTransactions();
transactionData$: Observable<TransactionData> = this.loadTransactions();
closeDialog() {
this.isOpen = false;
@ -40,12 +41,12 @@ export class TransactionHistoryComponent {
forward() {
this.offset++;
this.transactions$ = this.loadTransactions();
this.transactionData$ = this.loadTransactions();
}
back() {
this.offset--;
this.transactions$ = this.loadTransactions();
this.transactionData$ = this.loadTransactions();
}
loadTransactions() {

View file

@ -0,0 +1,6 @@
import { Transaction } from './Transaction';
export interface TransactionData {
transactions: Transaction[];
hasMore: boolean;
}

View file

@ -1,5 +1,6 @@
import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { TransactionData } from '../model/TransactionData';
@Injectable({
providedIn: 'root',
@ -18,6 +19,6 @@ export class TransactionService {
baseUrl.searchParams.append('offset', offset.toString());
}
return this.http.get<any[]>(`${baseUrl}`);
return this.http.get<TransactionData>(`${baseUrl}`);
}
}