Added achievements in profil page

This commit is contained in:
2026-04-15 12:18:00 +01:00
parent ce5cc5880b
commit d9af61889a
8 changed files with 123 additions and 5 deletions
@@ -0,0 +1,18 @@
<div class="rounded-lg px-2 m-3 bg-white border border-gray-200 items-center h-full max-h-48 overflow-scroll">
<ion-list lines="none" class="flex flex-col gap-3 pt-1 pb-1">
@for (challenge of userChallenges(); track challenge.challengeTitle) {
<ion-item class="border border-gray-200 rounded-xl" style="--inner-padding-end: 0; --padding-start: 0;">
<div class="grid grid-cols-[1fr_auto] gap-2 items-start w-full px-3 py-2">
<div>
<p class="m-0 text-sm font-medium text-gray-900">{{ challenge.challengeTitle }}</p>
<p class="m-0 mt-1 text-xs text-gray-500 leading-relaxed">{{ challenge.challengeDescription }}</p>
</div>
<div class="text-right shrink-0">
<p class="m-0 text-xs text-gray-500">{{ converterHours(challenge.challengeDuration) }}</p>
<p class="m-0 mt-1 text-xs text-gray-400">{{ challenge.challengeStartDate }}</p>
</div>
</div>
</ion-item>
}
</ion-list>
</div>
@@ -0,0 +1,39 @@
import {Component, input} from '@angular/core';
import {IonicModule} from "@ionic/angular";
import {GetUserChallengeDto} from "../../services/api";
@Component({
selector: 'app-challenges-accomplished',
templateUrl: './challenges-accomplished.component.html',
styleUrls: ['./challenges-accomplished.component.scss'],
imports: [
IonicModule
]
})
export class ChallengesAccomplishedComponent {
userChallenges = input.required<GetUserChallengeDto[]>();
converterHours(hours: number) {
const day = Math.floor(hours / 24);
const week = Math.floor(day / 7);
const month = Math.floor(week / 4);
const year = Math.floor(month / 12);
switch (true) {
case year > 0:
return `${year} an${year > 1 ? 's' : ''}`;
case month > 0:
return `${month} mois`;
case week > 0:
return `${week} semaine${week > 1 ? 's' : ''}`;
case day > 0:
return `${day} jour${day > 1 ? 's' : ''}`;
default:
return `${hours} heure${hours > 1 ? 's' : ''}`;
}
}
}
@@ -0,0 +1,31 @@
<div class="rounded-lg m-3 bg-white border border-gray-200 items-center h-full max-h-48 overflow-scroll">
@if (achievements().length > 0) {
@for (achievement of achievements(); track achievement.id) {
<ion-item lines="none" class="border border-gray-300 rounded-xl m-2"
style="--inner-padding-end: 0; --padding-start: 0; --background: #F0FAF3;">
<div class="flex items-center gap-4 px-3 py-1">
<div class="flex items-center justify-center">
<ion-icon class="text-[18px] text-green-700" name="check"></ion-icon>
</div>
<div>
<p class="m-0 text-sm font-medium" style="color:#2d4a35;">{{ achievement.label }}</p>
<p class="m-0 mt-1 text-xs leading-relaxed"
style="color:#5a7a62;">{{ achievement.description }}</p>
</div>
</div>
</ion-item>
}
} @else {
<ion-item lines="none" class="border border-stone-200 rounded-xl m-3" style="--background: #fafaf8;">
<div class="flex flex-col items-center w-full px-5 py-8 gap-3">
<div class="w-10 h-10 rounded-full bg-stone-100 border border-stone-200 flex items-center justify-center">
<ion-icon name="trophy" style="color:#a8a090; font-size:20px;"></ion-icon>
</div>
<div class="text-center">
<p class="m-0 text-sm font-medium text-stone-400">Pas encore de succès</p>
<p class="m-0 mt-1 text-xs text-stone-300 leading-relaxed">Vos premiers succès apparaîtront ici</p>
</div>
</div>
</ion-item>
}
</div>
@@ -0,0 +1,22 @@
import {Component, input} from '@angular/core';
import {IonicModule} from "@ionic/angular";
import {checkmarkCircleOutline, trophyOutline} from "ionicons/icons";
import {addIcons} from "ionicons";
import {GetAchievementDto} from "../../services/api";
addIcons({
'check': checkmarkCircleOutline,
'trophy': trophyOutline
});
@Component({
selector: 'app-user-achievements',
templateUrl: './user-achievements.component.html',
styleUrls: ['./user-achievements.component.scss'],
imports: [
IonicModule
]
})
export class UserAchievementsComponent {
achievements = input.required<GetAchievementDto[]>();
}
+3 -4
View File
@@ -50,13 +50,12 @@
<app-title-part textInfo="Mes participations"></app-title-part>
<app-challenges-accomplished [userChallenges]="userChallenge()"></app-challenges-accomplished>
</div>
<div class="mt-4">
<app-title-part textInfo="Succès"></app-title-part>
<div class="rounded-lg px-5 m-3 bg-white border border-gray-200 grid grid-cols-6 items-center">
<p class="col-span-5">Vous n'avez pas encore débloqué de succès</p>
<p class="col-span-1">Test</p>
</div>
<app-user-achievements [achievements]="userAchievement()"></app-user-achievements>
</div>
<div class="mt-4">
<app-title-part textInfo="Paramètres de compte"></app-title-part>
<app-settings-options></app-settings-options>
+10 -1
View File
@@ -5,6 +5,8 @@ import {personOutline, addOutline, settingsOutline} from "ionicons/icons";
import {TitlePartComponent} from "../../components/title-part/title-part.component";
import {ChallengeCardComponent} from "../../components/challenge-card/challenge-card.component";
import {
AchievementsService,
GetAchievementDto,
GetRandomChallengeDto,
GetUserChallengeDto,
GetUserDetailsDto,
@@ -17,6 +19,7 @@ import {GenericUserInfoComponent} from "../../components/generic-user-info/gener
import {
ChallengesAccomplishedComponent
} from "../../components/challenges-accomplished/challenges-accomplished.component";
import {UserAchievementsComponent} from "../../components/user-achievements/user-achievements.component";
addIcons({
'profile': personOutline,
@@ -34,7 +37,8 @@ addIcons({
ChallengeCardComponent,
SettingsOptionsComponent,
GenericUserInfoComponent,
ChallengesAccomplishedComponent
ChallengesAccomplishedComponent,
UserAchievementsComponent
]
})
export class HomeComponent implements OnInit {
@@ -42,10 +46,12 @@ export class HomeComponent implements OnInit {
private toastCtrl = inject(ToastController);
private usersService = inject(UsersService);
private loadCtrl = inject(LoadingController);
private achievementsService = inject(AchievementsService);
randomChallenge = signal<GetRandomChallengeDto>({});
user = signal<GetUserDetailsDto>({})
userChallenge = signal<GetUserChallengeDto[]>([]);
userAchievement = signal<GetAchievementDto[]>([])
isModalOpen = false;
@@ -73,8 +79,11 @@ export class HomeComponent implements OnInit {
try {
const userInfo = await firstValueFrom(this.usersService.getUserDetailsEndpoint());
const userChallenge = await firstValueFrom(this.usersService.getAllUserChallengesEndpoint());
const userAchievement = await firstValueFrom((this.achievementsService.getUserAchievementsEndpoint()));
this.user.set(userInfo);
this.userChallenge.set(userChallenge);
this.userAchievement.set(userAchievement);
} catch {
const toast = await this.toastCtrl.create({
message: 'Impossible de charger les données du joueur',