You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
4.7 KiB
186 lines
4.7 KiB
|
1 year ago
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
|
||
|
|
import { CommonModule } from '@angular/common';
|
||
|
|
import { MatCardModule } from '@angular/material/card';
|
||
|
|
import { MatIconModule } from '@angular/material/icon';
|
||
|
|
import { MatButtonModule } from '@angular/material/button';
|
||
|
|
import { PokemonService } from '../../../core/services/pokemon.service';
|
||
|
|
import { Pokemon } from '../../../core/models/pokemon.model';
|
||
|
|
import { PokemonCellComponent } from '../pokemon-cell/pokemon-cell.component';
|
||
|
|
import { PokemonDetailsComponent } from '../pokemon-details/pokemon-details.component';
|
||
|
|
|
||
|
|
@Component({
|
||
|
|
selector: 'app-pokemon-carousel',
|
||
|
|
standalone: true,
|
||
|
|
imports: [
|
||
|
|
CommonModule,
|
||
|
|
MatCardModule,
|
||
|
|
MatIconModule,
|
||
|
|
MatButtonModule,
|
||
|
|
PokemonCellComponent,
|
||
|
|
PokemonDetailsComponent
|
||
|
|
],
|
||
|
|
template: `
|
||
|
|
<div class="carousel-container">
|
||
|
|
<button mat-icon-button class="nav-button prev"
|
||
|
|
[disabled]="currentBoxIndex === 0"
|
||
|
|
(click)="previousBox()">
|
||
|
|
<mat-icon>chevron_left</mat-icon>
|
||
|
|
</button>
|
||
|
|
|
||
|
|
<div class="pokemon-box-container">
|
||
|
|
<mat-card class="pokemon-box">
|
||
|
|
<div class="box-title">Box {{ (currentBoxIndex + 1).toString().padStart(3, '0') }}</div>
|
||
|
|
<div class="pokemon-grid">
|
||
|
|
<app-pokemon-cell
|
||
|
|
*ngFor="let pokemon of currentGroup"
|
||
|
|
[pokemon]="pokemon"
|
||
|
|
(caught)="onPokemonCaught($event)"
|
||
|
|
(selected)="onPokemonSelected($event)"
|
||
|
|
></app-pokemon-cell>
|
||
|
|
</div>
|
||
|
|
</mat-card>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<button mat-icon-button class="nav-button next"
|
||
|
|
[disabled]="currentBoxIndex === pokemonGroups.length - 1"
|
||
|
|
(click)="nextBox()">
|
||
|
|
<mat-icon>chevron_right</mat-icon>
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="box-navigation">
|
||
|
|
<span>Box {{ currentBoxIndex + 1 }} of {{ pokemonGroups.length }}</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<app-pokemon-details
|
||
|
|
*ngIf="selectedPokemon"
|
||
|
|
[pokemon]="selectedPokemon"
|
||
|
|
[isOpen]="!!selectedPokemon"
|
||
|
|
(closed)="selectedPokemon = null"
|
||
|
|
></app-pokemon-details>
|
||
|
|
`,
|
||
|
|
styles: [`
|
||
|
|
.carousel-container {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
padding: 20px;
|
||
|
|
position: relative;
|
||
|
|
height: calc(100vh - 200px);
|
||
|
|
}
|
||
|
|
|
||
|
|
.pokemon-box-container {
|
||
|
|
flex: 1;
|
||
|
|
max-width: 800px;
|
||
|
|
position: relative;
|
||
|
|
}
|
||
|
|
|
||
|
|
.pokemon-box {
|
||
|
|
background-color: white;
|
||
|
|
border: 2px solid #ccc;
|
||
|
|
border-radius: 10px;
|
||
|
|
padding: 20px;
|
||
|
|
position: relative;
|
||
|
|
width: 100%;
|
||
|
|
box-sizing: border-box;
|
||
|
|
}
|
||
|
|
|
||
|
|
.box-title {
|
||
|
|
background-color: #4CAF50;
|
||
|
|
color: white;
|
||
|
|
padding: 5px 15px;
|
||
|
|
border-radius: 15px 15px 0 0;
|
||
|
|
position: absolute;
|
||
|
|
top: -30px;
|
||
|
|
left: 20px;
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
.pokemon-grid {
|
||
|
|
display: grid;
|
||
|
|
grid-template-columns: repeat(6, 1fr);
|
||
|
|
gap: 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.nav-button {
|
||
|
|
margin: 0 20px;
|
||
|
|
&.prev { left: 0; }
|
||
|
|
&.next { right: 0; }
|
||
|
|
&:disabled {
|
||
|
|
opacity: 0.5;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.box-navigation {
|
||
|
|
text-align: center;
|
||
|
|
padding: 10px;
|
||
|
|
font-size: 1.1em;
|
||
|
|
color: #666;
|
||
|
|
}
|
||
|
|
`],
|
||
|
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||
|
|
})
|
||
|
|
export class PokemonCarouselComponent implements OnInit {
|
||
|
|
pokemonGroups: (Pokemon | null)[][] = [];
|
||
|
|
currentBoxIndex = 0;
|
||
|
|
selectedPokemon: Pokemon | null = null;
|
||
|
|
caughtPokemon = new Set<string>();
|
||
|
|
|
||
|
|
get currentGroup(): (Pokemon | null)[] {
|
||
|
|
return this.pokemonGroups[this.currentBoxIndex] || [];
|
||
|
|
}
|
||
|
|
|
||
|
|
constructor(
|
||
|
|
private pokemonService: PokemonService,
|
||
|
|
private cdr: ChangeDetectorRef
|
||
|
|
) {}
|
||
|
|
|
||
|
|
ngOnInit() {
|
||
|
|
this.loadPokemon();
|
||
|
|
}
|
||
|
|
|
||
|
|
private loadPokemon() {
|
||
|
|
this.pokemonService.getPokemonList().subscribe({
|
||
|
|
next: (groups) => {
|
||
|
|
this.pokemonGroups = groups;
|
||
|
|
this.cdr.markForCheck();
|
||
|
|
},
|
||
|
|
error: (error) => {
|
||
|
|
console.error('Error loading Pokemon:', error);
|
||
|
|
this.cdr.markForCheck();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
nextBox() {
|
||
|
|
if (this.currentBoxIndex < this.pokemonGroups.length - 1) {
|
||
|
|
this.currentBoxIndex++;
|
||
|
|
this.cdr.markForCheck();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
previousBox() {
|
||
|
|
if (this.currentBoxIndex > 0) {
|
||
|
|
this.currentBoxIndex--;
|
||
|
|
this.cdr.markForCheck();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
onPokemonCaught(pfic: string) {
|
||
|
|
this.pokemonService.toggleCatch(pfic).subscribe(
|
||
|
|
response => {
|
||
|
|
if (response.status === 'caught') {
|
||
|
|
this.caughtPokemon.add(pfic);
|
||
|
|
} else {
|
||
|
|
this.caughtPokemon.delete(pfic);
|
||
|
|
}
|
||
|
|
this.cdr.markForCheck();
|
||
|
|
}
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
onPokemonSelected(pokemon: Pokemon) {
|
||
|
|
this.selectedPokemon = pokemon;
|
||
|
|
this.cdr.markForCheck();
|
||
|
|
}
|
||
|
|
}
|