Boutique

La page Boutique (ShopPageComponent) permet aux utilisateurs d'acheter des éléments cosmétiques (avatars, profils) en utilisant la monnaie virtuelle gagnée en jouant. L'interface présente les articles disponibles dans une grille, indique lesquels sont déjà achetés, et permet des transactions sécurisées via le serveur.

ShopPageComponent

Propriétés

|| Propriété | Type | Description |
||---|---|---|
|| shopItems | ShopItem[] | Liste des articles disponibles dans la boutique |
|| userProfile | UserProfile \| null | Profil utilisateur contenant le solde et l'historique d'achats |
|| isLoading | boolean | Indique si une opération d'achat est en cours |
|| showInsufficientFundsPopup | boolean | Contrôle l'affichage du popup de fonds insuffisants |
|| insufficientFundsMessage | string | Message d'erreur à afficher pour fonds insuffisants |
|| showConfirmPurchasePopup | boolean | Contrôle l'affichage du popup de confirmation d'achat |
|| confirmPurchaseMessage | string | Message de confirmation d'achat |
|| selectedItemForPurchase | ShopItem \| null | Article sélectionné pour l'achat en attente |
|| private subscriptions | Subscription[] | Gestion des abonnements RxJS |
|| isHelpPopupActive | boolean | Contrôle l'affichage du popup d'aide |
|| helpTitle | string | Titre du popup d'aide |
|| helpContent | string | Contenu Markdown du popup d'aide |
|| showFullHelpButton | boolean | Affiche le bouton "Aide complète" dans le popup |

Méthodes

constructor(private shopService: ShopService, private userService: UserService, private authService: AuthService, private router: Router, private helpService: HelpService)

Description : Initialise le composant avec les services nécessaires.
Paramètres :

ngOnInit(): void

Description : Initialise le composant au chargement de la page.
Actions :

  1. Charge les articles disponibles via shopService.getAvailableItems()
  2. S'abonne au profil utilisateur pour les mises à jour en temps réel

Retour : void

ngOnDestroy(): void

Description : Nettoie les abonnements lors de la destruction du composant.
Retour : void

isPurchased(itemId: string): boolean

Description : Vérifie si un article a déjà été acheté.
Paramètres :

Validation : Vérifie dans userProfile.purchaseHistory
Retour : boolean (true si acheté, false sinon)

canAfford(itemPrice: number): boolean

Description : Vérifie si l'utilisateur a suffisamment de monnaie virtuelle.
Paramètres :

Validation : Compare userProfile.virtualCurrencyBalance >= itemPrice
Retour : boolean (true si suffisant, false sinon)

async onPurchaseAttempt(item: ShopItem)

Description : Gère la tentative d'achat d'un article.
Paramètres :

Flux :

  1. Vérifie si une opération est déjà en cours
  2. Récupère le token d'authentification
  3. Appelle shopService.checkFunds() pour vérifier les fonds
  4. Affiche popup de confirmation si fonds suffisants
  5. Affiche popup d'erreur si fonds insuffisants

Retour : Promise

closeInsufficientFundsPopup = (): void

Description : Ferme le popup de fonds insuffisants.
Retour : void

closeConfirmPurchasePopup = (): void

Description : Ferme le popup de confirmation d'achat et réinitialise l'article sélectionné.
Retour : void

confirmPurchase = async ()

Description : Confirme et effectue l'achat de l'article sélectionné.
Flux :

  1. Vérifie qu'un article est sélectionné
  2. Récupère le token d'authentification
  3. Appelle shopService.purchaseItem() pour effectuer l'achat
  4. Recharge le profil utilisateur via userService.loadUserProfile()
  5. Affiche message de succès ou d'erreur

Gestion d'erreurs : Affiche popup en cas d'échec
Retour : Promise

goBack(): void

Description : Retourne à la page d'accueil.
Navigation : AppRoutes.Home
Retour : void

toggleHelpPopup(): void

Description : Active/désactive le popup d'aide.
Actions : Charge le contenu d'aide via helpService.getHelpContentForRoute()
Retour : void

closeHelpPopup(): void

Description : Ferme le popup d'aide.
Retour : void

navigateToFullHelp(): void

Description : Navigue vers la page d'aide complète.
Navigation : AppRoutes.Help
Retour : void

Composants utilisés

ShopItemComponent

Composant représentant un article de la boutique avec toutes ses informations visuelles.

Propriétés @Input

|| Propriété | Type | Description |
||---|---|---|
|| item | ShopItem | Article à afficher |
|| isPurchased | boolean | Indique si l'article est déjà acheté |
|| canAfford | boolean | Indique si l'utilisateur peut se permettre l'article |

Propriétés @Output

|| Propriété | Type | Description |
||---|---|---|
|| purchase | EventEmitter<ShopItem> | Émis lors de la tentative d'achat |

OneButtonPopupComponent

Popup avec un seul bouton pour les messages d'information ou d'erreur.

Propriétés @Input

|| Propriété | Type | Description |
||---|---|---|
|| isPopupActive | boolean | Contrôle l'affichage |
|| popupMessage | string | Message à afficher |
|| closePopup | () => void | Callback de fermeture |

TwoButtonsPopupComponent

Popup avec deux boutons pour les confirmations.

Propriétés @Input

|| Propriété | Type | Description |
||---|---|---|
|| popupMessage | string | Message de confirmation |
|| validatePopup | Function | Callback de validation |
|| closePopup | () => void | Callback d'annulation |

UserViewComponent

Composant affichant le profil utilisateur.

Propriétés @Input

|| Propriété | Type | Description |
||---|---|---|
|| disableLogout | boolean | Désactive le bouton de déconnexion |

HelpButtonComponent

Bouton d'aide circulaire fixe.

Propriétés @Output

|| Propriété | Type | Description |
||---|---|---|
|| helpClicked | EventEmitter | Émis lors du clic |

HelpPopupComponent

Popup d'aide contextuelle avec contenu Markdown.

Propriétés @Input

|| Propriété | Type | Description |
||---|---|---|
|| isActive | boolean | Contrôle l'affichage |
|| title | string | Titre du popup |
|| markdownContent | string | Contenu en Markdown |
|| showFullHelpButton | boolean | Affiche bouton "Aide complète" |

Propriétés @Output

|| Propriété | Type | Description |
||---|---|---|
|| close | EventEmitter | Émis à la fermeture |
|| navigateToFullHelp | EventEmitter | Émis pour ouvrir page d'aide complète |

Services utilisés

ShopService

Service gérant les interactions avec l'API de la boutique.

Méthodes

getAvailableItems(): ShopItem[]

Description : Retourne la liste des articles disponibles dans la boutique.
Source : Défini dans @common/shop-item (partagé client/serveur)
Retour : ShopItem[] (7 articles : avatars et profils)

async checkFunds(idToken: string, itemId: string)

Description : Vérifie si l'utilisateur a suffisamment de fonds pour acheter un article.
Paramètres :

Retour : Promise<{ canAfford: boolean; currentBalance: number; itemPrice: number }>

async purchaseItem(idToken: string, itemId: string)

Description : Effectue l'achat d'un article.
Paramètres :

Retour : Promise<{ success: boolean; message?: string; newBalance?: number; purchasedItem?: string }>

UserService

Service gérant le profil utilisateur et ses données.

Propriétés

Méthodes

async loadUserProfile(idToken: string)

Description : Charge le profil utilisateur depuis le serveur.
Actions :

  1. Appelle GET /api/user/profile avec le token
  2. Met à jour userProfile$
  3. Inclut solde, historique d'achats, préférences

Retour : Promise

AuthService

Service gérant l'authentification Firebase.

Méthodes

async getIdToken()

Description : Récupère le token d'authentification Firebase ID de l'utilisateur actuel.
Retour : Promise<string | null>

HelpService

Service fournissant le contenu d'aide contextuelle.

Méthodes

getHelpContentForRoute(route: string)

Description : Retourne le contenu d'aide pour une route donnée.
Paramètres :

Retour :

Communication avec le Serveur

La boutique communique avec le serveur via HTTP REST pour les opérations d'achat :

Endpoints utilisés

GET /api/shop/check-funds/:itemId

Description : Vérifie si l'utilisateur peut acheter un article.
Headers : Authorization: Bearer {idToken}
Réponse :

{
    canAfford: boolean,
    currentBalance: number,
    itemPrice: number
}

POST /api/shop/purchase

Description : Effectue l'achat d'un article.
Headers : Authorization: Bearer {idToken}
Body :

{ itemId: string }

Réponse :

{
    success: boolean,
    message?: string,
    newBalance?: number,
    purchasedItem?: string
}

GET /api/user/profile

Description : Récupère le profil utilisateur mis à jour après achat.
Headers : Authorization: Bearer {idToken}
Réponse :

{
    firebaseUid: string,
    username: string,
    virtualCurrencyBalance: number,
    purchaseHistory: string[],
    // ... autres champs
}

Flux d'achat complet

  1. Affichage initial : Charge articles via getAvailableItems() et profil via observable
  2. Clic sur "ACHETER" : Appelle checkFunds() pour vérifier fonds
  3. Confirmation : Affiche popup de confirmation si fonds suffisants
  4. Validation : Appelle purchaseItem() pour effectuer l'achat
  5. Mise à jour : Recharge le profil utilisateur pour rafraîchir solde et historique
  6. Affichage : Met à jour l'interface (badge "ACHETÉ", nouveau solde)

Navigation

La page Boutique peut rediriger vers :

  1. Page d'Accueil (MainPageComponent) - Via bouton "RETOUR" ou logo
  2. Page d'Aide (HelpPageComponent) - Via bouton "Aide complète" du popup d'aide

Routes utilisées