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.
227 lines
6.6 KiB
227 lines
6.6 KiB
import { Component, Input, Output, EventEmitter, SimpleChanges } from '@angular/core';
|
|
import { CommonModule } from '@angular/common';
|
|
import { PokemonFamilyEntry } from '../../../core/models/plan.model';
|
|
import { Pokemon } from '../../../core/models/pokemon.model';
|
|
import { PokemonService } from '../../../core/services/pokemon.service';
|
|
import { MatChipsModule } from '@angular/material/chips';
|
|
|
|
@Component({
|
|
selector: 'app-plan-pokemon-details',
|
|
standalone: true,
|
|
imports: [
|
|
CommonModule,
|
|
MatChipsModule
|
|
],
|
|
template: `
|
|
<div class="targets-grid" *ngIf="hasTargets">
|
|
<ng-container *ngIf="evolve_to.length > 0">
|
|
<div class="target-section">
|
|
<h4>Evolution Targets</h4>
|
|
<div class="target-cards">
|
|
<div
|
|
*ngFor="let target of evolve_to"
|
|
class="target-card"
|
|
[class.completed]="isTargetCompleted(target.PFIC)"
|
|
>
|
|
<img
|
|
lazyImg
|
|
[src]="pokemonService.getPokemonImageUrl(target)"
|
|
[alt]="target.Name"
|
|
class="target-image"
|
|
[class.grayscale]="isTargetCompleted(target.PFIC)"
|
|
>
|
|
<div class="target-details">
|
|
<div class="target-name">
|
|
{{ target.Name }}
|
|
<span *ngIf="target.Form">({{ target.Form }})</span>
|
|
</div>
|
|
<span *ngIf="target.EvolutionMethod">{{target?.EvolutionMethod}}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</ng-container>
|
|
|
|
<ng-container *ngIf="pokemon_family.breed_for.length > 0">
|
|
<div class="target-section">
|
|
<h4>Breeding Targets</h4>
|
|
<div class="target-cards">
|
|
<div
|
|
*ngFor="let target of breed_for"
|
|
class="target-card"
|
|
[class.completed]="isTargetCompleted(target.PFIC)"
|
|
>
|
|
<img
|
|
lazyImg
|
|
[src]="pokemonService.getPokemonImageUrl(target)"
|
|
[alt]="target.Name"
|
|
class="target-image"
|
|
[class.grayscale]="isTargetCompleted(target.PFIC)"
|
|
>
|
|
<div class="target-details">
|
|
<div class="target-name">
|
|
{{ target.Name }}
|
|
<span *ngIf="target.Form">({{ target.Form }})</span>
|
|
</div>
|
|
<mat-chip-listbox>
|
|
<mat-chip>Breed</mat-chip>
|
|
</mat-chip-listbox>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</ng-container>
|
|
</div>
|
|
`,
|
|
styles: [`
|
|
.targets-grid {
|
|
padding: 16px 8px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 24px;
|
|
}
|
|
|
|
.target-cards {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
|
gap: 16px;
|
|
}
|
|
|
|
.target-card {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
padding: 8px;
|
|
border: 1px solid #eee;
|
|
border-radius: 8px;
|
|
transition: background-color 0.3s ease;
|
|
|
|
&:hover {
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
&.completed {
|
|
background-color: #f0f0f0;
|
|
}
|
|
}
|
|
|
|
.target-image {
|
|
width: 64px;
|
|
height: 64px;
|
|
object-fit: contain;
|
|
}
|
|
|
|
.target-details {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.target-name {
|
|
font-weight: 500;
|
|
|
|
span {
|
|
color: #666;
|
|
font-size: 0.9em;
|
|
}
|
|
}
|
|
`]
|
|
})
|
|
export class PlanPokemonDetailsComponent {
|
|
@Input() pokemon_family!: PokemonFamilyEntry;
|
|
evolve_to: Pokemon[] = [];
|
|
breed_for: Pokemon[] = [];
|
|
|
|
constructor(
|
|
public pokemonService: PokemonService
|
|
) {}
|
|
|
|
ngOnInit() {
|
|
this.evolve_to = []
|
|
this.breed_for = []
|
|
|
|
this.loadPokemonFamilyInfo(this.pokemon_family);
|
|
}
|
|
|
|
ngOnChanges(changes: SimpleChanges) {
|
|
if (changes['pokemon_family']) {
|
|
const currentFamily = changes['pokemon_family'].currentValue;
|
|
const previousFamily = changes['pokemon_family'].previousValue;
|
|
|
|
// Check if there's a meaningful change
|
|
if (currentFamily && currentFamily !== previousFamily) {
|
|
// Your logic here, e.g., re-fetch data or reset states
|
|
this.loadPokemonFamilyInfo(currentFamily);
|
|
}
|
|
}
|
|
}
|
|
|
|
loadPokemonFamilyInfo(newFamily: PokemonFamilyEntry) {
|
|
const evolveToArray: Pokemon[] = [];
|
|
newFamily.evolve_to.forEach((target) => {
|
|
this.pokemonService.getPokemonFromPFIC(target).subscribe({
|
|
next: (pokemon) => {
|
|
if (pokemon) {
|
|
evolveToArray.push(pokemon);
|
|
}
|
|
},
|
|
complete: () => {
|
|
this.customSort(evolveToArray);
|
|
this.evolve_to = [...evolveToArray]; // Assign once all have completed
|
|
},
|
|
error: (error) => {
|
|
console.error('Error loading Pokémon:', error);
|
|
}
|
|
});
|
|
});
|
|
|
|
const breedForArray: Pokemon[] = [];
|
|
newFamily.breed_for.forEach((target) => {
|
|
this.pokemonService.getPokemonFromPFIC(target).subscribe({
|
|
next: (pokemon) => {
|
|
if (pokemon) {
|
|
breedForArray.push(pokemon);
|
|
}
|
|
},
|
|
complete: () => {
|
|
this.customSort(breedForArray);
|
|
this.breed_for = [...breedForArray]; // Assign once all have completed
|
|
},
|
|
error: (error) => {
|
|
console.error('Error loading Pokémon:', error);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
parsePfic(pfic: string): (number | string)[] {
|
|
const parts = pfic.split('-');
|
|
return parts.map(part => /^\d+$/.test(part) ? parseInt(part) : part);
|
|
}
|
|
|
|
customSort(arr: Pokemon[]): Pokemon[] {
|
|
return arr.sort((a, b) => {
|
|
const parsedA = this.parsePfic(a.PFIC);
|
|
const parsedB = this.parsePfic(b.PFIC);
|
|
|
|
for (let i = 0; i < Math.min(parsedA.length, parsedB.length); i++) {
|
|
if (parsedA[i] !== parsedB[i]) {
|
|
if (typeof parsedA[i] === 'number' && typeof parsedB[i] === 'number') {
|
|
return (parsedA[i] as number) - (parsedB[i] as number);
|
|
}
|
|
return (parsedA[i] as string).localeCompare(parsedB[i] as string);
|
|
}
|
|
}
|
|
|
|
return parsedA.length - parsedB.length;
|
|
});
|
|
}
|
|
|
|
get hasTargets(): boolean {
|
|
return this.pokemon_family.evolve_to.length > 0 || this.pokemon_family.breed_for.length > 0;
|
|
}
|
|
|
|
isTargetCompleted(pfic: string): boolean {
|
|
return this.pokemonService.isTargetCompleted(pfic);
|
|
}
|
|
}
|