mirror of
https://codeberg.org/beerbrawl/beerbrawl.git
synced 2024-09-23 01:30:52 +02:00
feat(#35): link frontend and backend
This commit is contained in:
parent
66f58f317e
commit
a84f9059df
|
@ -3,13 +3,16 @@ package at.ac.tuwien.sepr.groupphase.backend.datagenerator;
|
|||
import at.ac.tuwien.sepr.groupphase.backend.endpoint.dto.TournamentUpdateQualificationMatchDto;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.endpoint.dto.TournamentUpdateQualificationMatchDto.DrinksPickupDto;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.endpoint.dto.TournamentUpdateQualificationMatchDto.ScoreUpdateDto;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.endpoint.dto.SharedMediaCreateDto;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.entity.ApplicationUser;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.entity.BeerPongTable;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.entity.SharedMedia;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.entity.Team;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.entity.Tournament;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.entity.domainservice.MatchDomainService;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.repository.BeerPongTableRepository;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.repository.QualificationParticipationRepository;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.repository.SharedMediaRepository;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.repository.TeamRepository;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.repository.TournamentRepository;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.repository.UserRepository;
|
||||
|
@ -23,10 +26,14 @@ import lombok.AllArgsConstructor;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
|
@ -50,6 +57,7 @@ public class TestDataGenerator {
|
|||
private final TournamentQualificationService qualificationService;
|
||||
private final TournamentKoPhaseService koPhaseService;
|
||||
private final QualificationParticipationRepository qualificationParticipationRepository;
|
||||
private final SharedMediaRepository sharedMediaRepository;
|
||||
|
||||
public void generateTestUser() {
|
||||
userRepository.deleteAll();
|
||||
|
@ -103,6 +111,48 @@ public class TestDataGenerator {
|
|||
.toList();
|
||||
beerPongTableRepository.saveAllAndFlush(tables3);
|
||||
matchDomainService.scheduleQualiMatches(tournament3.getId());
|
||||
|
||||
List<Tournament> tournaments = new ArrayList<>();
|
||||
tournaments.add(tournament);
|
||||
tournaments.add(tournament2);
|
||||
tournaments.add(tournament3);
|
||||
addTestImagesToTournaments(tournaments);
|
||||
}
|
||||
|
||||
private void addTestImagesToTournaments(List<Tournament> tournaments) {
|
||||
tournaments.forEach(tournament -> {
|
||||
try {
|
||||
uploadImageToTournament(tournament, "John Smith", "World Chess Championship", "testimage.png");
|
||||
uploadImageToTournament(tournament, "Emily Johnson", "Grand Slam Tennis Tournament", "testimage.png");
|
||||
uploadImageToTournament(tournament, "Michael Brown", "Olympic Games 2024", "testimage.png");
|
||||
uploadImageToTournament(tournament, "Jessica Martinez", "FIFA World Cup", "testimage.png");
|
||||
uploadImageToTournament(tournament, "David Garcia", "NBA Finals", "testimage.png");
|
||||
uploadImageToTournament(tournament, "Jane Doe", "Super Bowl", "testimage.png");
|
||||
uploadImageToTournament(tournament, "Andrew Wilson", "Rugby World Cup", "testimage.png");
|
||||
uploadImageToTournament(tournament, "Sophia Lee", "Australian Open", "testimage.png");
|
||||
uploadImageToTournament(tournament, "Ethan Clark", "UEFA Champions League", "testimage.png");
|
||||
uploadImageToTournament(tournament, "Olivia Scott", "Wimbledon", "testimage.png");
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Failed to upload test images to tournament {}", tournament.getName(), e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void uploadImageToTournament(Tournament tournament, String author, String title, String imagePath) throws IOException {
|
||||
SharedMediaCreateDto data = new SharedMediaCreateDto();
|
||||
data.setAuthor(author);
|
||||
data.setTitle(title);
|
||||
data.setTournamentId(tournament.getId());
|
||||
|
||||
byte[] imageBytes = Files.readAllBytes(new ClassPathResource(imagePath).getFile().toPath());
|
||||
|
||||
SharedMedia sharedMedia = new SharedMedia();
|
||||
sharedMedia.setAuthor(author);
|
||||
sharedMedia.setTitle(title);
|
||||
sharedMedia.setImage(imageBytes);
|
||||
sharedMedia.setTournament(tournament);
|
||||
|
||||
sharedMediaRepository.saveAndFlush(sharedMedia);
|
||||
}
|
||||
|
||||
private void generateTestTournamentsWithFinishedQualificationAndStartedKoPhase() {
|
||||
|
|
|
@ -8,6 +8,7 @@ import at.ac.tuwien.sepr.groupphase.backend.endpoint.dto.SharedMediaMetadataDto;
|
|||
import at.ac.tuwien.sepr.groupphase.backend.endpoint.mapper.SharedMediaMapper;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.exception.NotFoundException;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.service.SharedMediaService;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -39,6 +40,7 @@ public class SharedMediaEndpoint {
|
|||
private final SharedMediaMapper sharedMediaMapper;
|
||||
|
||||
//public for upload of images
|
||||
@PermitAll
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@PostMapping
|
||||
public SharedMediaMetadataDto createSharedMedia(
|
||||
|
|
|
@ -1,18 +1,9 @@
|
|||
package at.ac.tuwien.sepr.groupphase.backend.endpoint.dto;
|
||||
|
||||
import at.ac.tuwien.sepr.groupphase.backend.entity.SharedMedia;
|
||||
|
||||
public record SharedMediaMetadataDto(
|
||||
Long id,
|
||||
String author,
|
||||
String title,
|
||||
Long tournamentId) {
|
||||
|
||||
public static SharedMediaMetadataDto fromSharedMedia(SharedMedia e) {
|
||||
return new SharedMediaMetadataDto(
|
||||
e.getId(),
|
||||
e.getAuthor(),
|
||||
e.getTitle(),
|
||||
e.getTournament() != null ? e.getTournament().getId() : null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import jakarta.persistence.Id;
|
|||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.Lob;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
@ -17,15 +18,20 @@ import lombok.Setter;
|
|||
@Getter
|
||||
@Setter
|
||||
public class SharedMedia {
|
||||
private static final int MAX_IMAGE_SIZE = 2 * 1024 * 1024; // 2MB
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Size(max = 30, message = "Author can't be more than 30 characters long.")
|
||||
private String author;
|
||||
@Size(max = 50, message = "Title can't be more than 50 characters long.")
|
||||
private String title;
|
||||
|
||||
@Lob
|
||||
@Column(columnDefinition = "BLOB")
|
||||
@Size(max = SharedMedia.MAX_IMAGE_SIZE)
|
||||
private byte[] image;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
|
|
|
@ -16,7 +16,7 @@ spring:
|
|||
# Set this property to true if you want to see the executed queries
|
||||
show-sql: false
|
||||
hibernate:
|
||||
ddl-auto: update
|
||||
ddl-auto: create-drop
|
||||
# Allows to fetch lazy properties outside of the original transaction. Although this sounds helpful, the property
|
||||
# is disabled since it breaks the principle of least astonishment and leads to bad performance. To learn more,
|
||||
# follow this link: https://bit.ly/2LaX9ku
|
||||
|
|
BIN
backend/src/main/resources/testimage.png
Normal file
BIN
backend/src/main/resources/testimage.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 254 B |
|
@ -13,6 +13,7 @@ import at.ac.tuwien.sepr.groupphase.backend.repository.TeamRepository;
|
|||
import at.ac.tuwien.sepr.groupphase.backend.repository.TournamentRepository;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.repository.UserRepository;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.service.TournamentKoPhaseService;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.repository.*;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.service.TournamentQualificationService;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.service.TournamentService;
|
||||
import at.ac.tuwien.sepr.groupphase.backend.service.TournamentTeamService;
|
||||
|
@ -57,6 +58,7 @@ public class TestData {
|
|||
@Autowired
|
||||
private QualificationParticipationRepository qualificationParticipationRepository;
|
||||
|
||||
private SharedMediaRepository sharedMediaRepository;
|
||||
|
||||
protected String BASE_URI = "/api/v1";
|
||||
protected String TOURNAMENT_BASE_URI = BASE_URI + "/tournaments";
|
||||
|
@ -279,7 +281,8 @@ public class TestData {
|
|||
beerPongTableRepository,
|
||||
matchDomainService,
|
||||
tournamentQualificationService, this.qualificationService, this.koPhaseService,
|
||||
this.qualificationParticipationRepository);
|
||||
this.qualificationParticipationRepository,
|
||||
sharedMediaRepository);
|
||||
dataGenerator.generateTestUser();
|
||||
dataGenerator.generateTestTournaments();
|
||||
}
|
||||
|
|
|
@ -1,20 +1,25 @@
|
|||
<mat-card class="party-picture-card">
|
||||
<div class="image-container">
|
||||
<img class="images" src="{{picture?.source}}" alt="party pic" />
|
||||
<div class="image-container">
|
||||
<img class="images" src="{{ imageUrl }}" alt="party pic" />
|
||||
</div>
|
||||
<div class="middle-bar">
|
||||
<p>Author: {{ picture?.author }}</p>
|
||||
<p>{{ picture?.title }}</p>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<h5>11:00</h5>
|
||||
<div>
|
||||
<button
|
||||
mat-icon-button
|
||||
aria-label="Approve picture"
|
||||
matTooltip="Approve picture"
|
||||
(click)="openConfirmDialog()"
|
||||
>
|
||||
<mat-icon>check</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button aria-label="Reject picture" matTooltip="Reject picture">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="middle-bar">
|
||||
<p>Author: {{picture?.author}}</p>
|
||||
<p>{{picture?.title}}</p>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<h5>11:00</h5>
|
||||
<div>
|
||||
<button mat-icon-button aria-label="Approve picture" matTooltip="Approve picture" (click)="openConfirmDialog()">
|
||||
<mat-icon>check</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button aria-label="Reject picture" matTooltip="Reject picture">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-card>
|
||||
</div>
|
||||
</mat-card>
|
||||
|
|
|
@ -1,57 +1,56 @@
|
|||
.party-picture-card {
|
||||
width: 20rem;
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
padding-top: 2rem;
|
||||
box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.2);
|
||||
margin: 1rem;
|
||||
display: flex;
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
width: 20rem;
|
||||
padding-left: 2rem;
|
||||
padding-right: 2rem;
|
||||
padding-top: 2rem;
|
||||
box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.2);
|
||||
margin: 1rem;
|
||||
display: flex;
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.image-container {
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
height: 20rem; /* Fixed height for the image container */
|
||||
background-color: rgb(235, 235, 235); /* Grey background */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
height: 20rem; /* Fixed height for the image container */
|
||||
background-color: rgb(235, 235, 235); /* Grey background */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.images {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
display: block;
|
||||
object-fit: contain; /* Ensure the image is contained within the container */
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
width: auto;
|
||||
height: auto;
|
||||
display: block;
|
||||
object-fit: contain; /* Ensure the image is contained within the container */
|
||||
}
|
||||
|
||||
.bottom-bar{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.bottom-bar {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.middle-bar{
|
||||
width: 100%;
|
||||
.middle-bar {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h5 {
|
||||
color: grey
|
||||
color: grey;
|
||||
}
|
||||
|
||||
p {
|
||||
color: rgb(80, 80, 80)
|
||||
color: rgb(80, 80, 80);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,9 @@ describe('PartyPictureCardComponent', () => {
|
|||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [PartyPictureCardComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
imports: [PartyPictureCardComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(PartyPictureCardComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
|
|
@ -1,27 +1,62 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
import { Component, Input, OnInit, OnDestroy, ElementRef } from '@angular/core';
|
||||
import { MatCard } from '@angular/material/card';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { ConfirmationService } from '../../services/confirmation.service';
|
||||
import { MatIconButton } from '@angular/material/button';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
|
||||
interface PictureDTO {
|
||||
source: string;
|
||||
author: string;
|
||||
title: string;
|
||||
}
|
||||
import { SharedMediaMetadataDto } from '../../../../openapi-generated';
|
||||
import { SharedMediaEndpointService } from '@api';
|
||||
import { ConfirmationService } from '../../services/confirmation.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-party-picture-card',
|
||||
standalone: true,
|
||||
imports: [MatCard, MatIcon, MatIconButton, MatTooltip],
|
||||
templateUrl: './party-picture-card.component.html',
|
||||
styleUrl: './party-picture-card.component.scss',
|
||||
styleUrls: ['./party-picture-card.component.scss'],
|
||||
})
|
||||
export class PartyPictureCardComponent {
|
||||
@Input() picture: PictureDTO | undefined;
|
||||
export class PartyPictureCardComponent implements OnInit, OnDestroy {
|
||||
@Input() picture: SharedMediaMetadataDto | undefined;
|
||||
imageUrl: string | undefined;
|
||||
|
||||
constructor(private confirmationService: ConfirmationService) {}
|
||||
private observer: IntersectionObserver | undefined;
|
||||
|
||||
constructor(
|
||||
private confirmationService: ConfirmationService,
|
||||
private sharedMediaService: SharedMediaEndpointService,
|
||||
private element: ElementRef,
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.observer = new IntersectionObserver(entries => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting && this.picture && this.picture.id) {
|
||||
this.loadImage(this.picture.id);
|
||||
this.observer?.unobserve(this.element.nativeElement);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.observer.observe(this.element.nativeElement);
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.observer) {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
loadImage(sharedMediaId: number): void {
|
||||
this.sharedMediaService.getSharedMediaImage(sharedMediaId).subscribe(
|
||||
(response: any) => {
|
||||
// Create a blob URL from the received Blob
|
||||
this.imageUrl = URL.createObjectURL(response);
|
||||
},
|
||||
(error: any) => {
|
||||
// Handle errors
|
||||
console.error('Error fetching shared media image:', error);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async openConfirmDialog(): Promise<void> {
|
||||
if (await this.confirmationService.openConfirmationDialog('approve picture')) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<app-header-card [title]="'Approve Party Pics'">
|
||||
<button mat-raised-button color="primary" [routerLink]="'..'">Back to Overview</button>
|
||||
<button mat-raised-button color="primary" [routerLink]="'..'">Back to Overview</button>
|
||||
</app-header-card>
|
||||
|
||||
<div class="picture-grid">
|
||||
@for (picture of getPictures(); track picture) {
|
||||
<app-party-picture-card [picture]="picture"></app-party-picture-card>
|
||||
}
|
||||
@for (picture of getPictures(); track picture) {
|
||||
<app-party-picture-card [picture]="picture"></app-party-picture-card>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -1,22 +1,21 @@
|
|||
.picture-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.party-picture-card {
|
||||
width: 100%;
|
||||
padding: 2rem;
|
||||
box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.2);
|
||||
margin: 0;
|
||||
display: flex;
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: 2rem;
|
||||
box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.2);
|
||||
margin: 0;
|
||||
display: flex;
|
||||
border-radius: 0.5rem;
|
||||
overflow: hidden;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,9 @@ describe('PartyPicsApproveComponent', () => {
|
|||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [PartyPicsApproveComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
imports: [PartyPicsApproveComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(PartyPicsApproveComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
|
|
@ -1,43 +1,56 @@
|
|||
import { Component, input } from '@angular/core';
|
||||
import { HeaderCardComponent } from '../header-card/header-card.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { Component, OnInit, Input, input } from '@angular/core';
|
||||
import { MatButton } from '@angular/material/button';
|
||||
import { MatCard } from '@angular/material/card';
|
||||
import { HeaderCardComponent } from '../header-card/header-card.component';
|
||||
import { PartyPictureCardComponent } from '../party-picture-card/party-picture-card.component';
|
||||
|
||||
interface PictureDTO {
|
||||
source: string;
|
||||
author: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const pics = [
|
||||
{
|
||||
source: 'https://picsum.photos/200/300',
|
||||
author: 'John Smith',
|
||||
title: 'Sunset Over the Mountains',
|
||||
},
|
||||
{ source: 'https://picsum.photos/300/200', author: 'Jane Doe', title: 'Cityscape at Dusk' },
|
||||
{ source: 'https://picsum.photos/300/300', author: 'Alice Johnson', title: 'Forest Pathway' },
|
||||
{ source: 'https://picsum.photos/200/300', author: 'Robert Brown', title: 'Ocean Waves' },
|
||||
{ source: 'https://picsum.photos/500/200', author: 'Emily Davis', title: 'Desert Mirage' },
|
||||
{ source: 'https://picsum.photos/500/300', author: 'Michael Wilson', title: 'Winter Wonderland' },
|
||||
{ source: 'https://picsum.photos/500/300', author: 'Sarah Thompson', title: 'Spring Blossoms' },
|
||||
{ source: 'https://picsum.photos/300/200', author: 'David Martinez', title: 'Autumn Leaves' },
|
||||
{ source: 'https://picsum.photos/300/300', author: 'Laura Taylor', title: 'Night Sky' },
|
||||
];
|
||||
import { SharedMediaEndpointService, SharedMediaMetadataDto } from '@api';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-party-pics-approve',
|
||||
standalone: true,
|
||||
imports: [MatButton, MatCard, HeaderCardComponent, RouterModule, PartyPictureCardComponent],
|
||||
templateUrl: './party-pics-approve.component.html',
|
||||
styleUrl: './party-pics-approve.component.scss',
|
||||
styleUrls: ['./party-pics-approve.component.scss'],
|
||||
})
|
||||
export class PartyPicsApproveComponent {
|
||||
export class PartyPicsApproveComponent implements OnInit {
|
||||
tournamentId = input.required<number>();
|
||||
pictures: SharedMediaMetadataDto[] = [];
|
||||
|
||||
getPictures(): PictureDTO[] {
|
||||
return pics;
|
||||
constructor(
|
||||
private sharedMediaService: SharedMediaEndpointService,
|
||||
private snackBar: MatSnackBar,
|
||||
) {}
|
||||
|
||||
getPictures(): SharedMediaMetadataDto[] {
|
||||
return this.pictures;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.fetchPictures();
|
||||
}
|
||||
|
||||
fetchPictures(): void {
|
||||
this.sharedMediaService.getSharedMediaByTournament(this.tournamentId()).subscribe({
|
||||
next: (data: SharedMediaMetadataDto[]) => {
|
||||
this.pictures = data;
|
||||
},
|
||||
error: error => {
|
||||
this.defaultServiceErrorHandling(error);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private defaultServiceErrorHandling(error: any): void {
|
||||
let errorMessage = '';
|
||||
if (typeof error.error === 'object') {
|
||||
errorMessage = error.error.error;
|
||||
} else {
|
||||
errorMessage = error.error;
|
||||
}
|
||||
this.snackBar.open(errorMessage, 'OK', {
|
||||
duration: 5000,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue