All files / components/billet billetCard.tsx

92.3% Statements 12/13
100% Branches 8/8
66.66% Functions 2/3
100% Lines 11/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                                                              1x 1x                                                                       1x 6x 6x 6x 6x 6x   6x 6x   6x                                                            
/**
 * Module de composant BilletCard pour l'affichage des billets des Jeux Olympiques
 *
 * Ce module contient le composant BilletCard qui présente visuellement un ticket d'événement sportif
 * avec toutes les informations essentielles :
 * - Informations du client (nom, prénom)
 * - Détails de l'événement (description, lieu, date)
 * - Informations de l'offre (libellé, nombre de personnes, montant, description)
 * - Statut du billet (valide/invalide) avec codes couleur appropriés
 * - Bouton d'accès au QR code pour validation à l'entrée
 *
 * ## Fonctionnalités principales
 * Le composant adapte automatiquement son apparence selon le statut :
 * - **Billet valide** : fond vert clair avec badge vert
 * - **Billet invalide** : fond rouge clair avec badge rouge
 *
 * ## Interactions utilisateur
 * - Clic sur le bouton "QrCode" ouvre un modal avec le QR code scannable
 * - Interface responsive adaptée aux différentes tailles d'écran
 * - Gestion d'état pour l'ouverture/fermeture du modal QR code
 *
 * ## Logique interne
 * - Calcul automatique des classes CSS selon le statut du billet
 * - Gestion de l'état du modal QR code avec useState
 * - Rendu conditionnel du modal selon l'état d'ouverture
 *
 * @module components/billet/billetCard
 * @group Components
 */
 
import { Ticket } from "@/type/achat/ticket";
import { useState } from "react";
import QRCodeModal from "@/components/billet/qrCodeModal";
 
/**
 * Props du composant BilletCard
 */
export type BilletCardProps = {
  /** Ticket à afficher dans la carte */
  ticket: Ticket;
  /** Type du billet - détermine l'apparence visuelle */
  type: "valide" | "invalide";
};
 
/**
 * Composant BilletCard pour l'affichage des billets des Jeux Olympiques.
 * Voir la documentation du module ci-dessus pour les détails complets.
 *
 * @param props - Les propriétés du composant
 * @returns Carte de billet interactive avec modal QR code intégré
 *
 * @example
 * ```tsx
 * // Affichage d'un billet valide
 * <BilletCard
 *   ticket={{
 *     id: 123,
 *     client: { nom: "Dupont", prenom: "Jean" },
 *     evenement: { description: "Finale 100m" },
 *     offre: { libelle: "Catégorie A", nb_personne: 2, montant: 150 }
 *   }}
 *   type="valide"
 * />
 *
 * // Affichage d'un billet invalide
 * <BilletCard ticket={expiredTicket} type="invalide" />
 * ```
 */
export default function BilletCard({ ticket, type }: BilletCardProps) {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const isValide = type === "valide";
  const bgColor = isValide ? "bg-green-50" : "bg-red-50";
  const badgeColor = isValide ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800";
  const badgeText = isValide ? "Billet Valide" : "Billet Non Valide";
 
  const handleOpenModal = () => setIsModalOpen(true);
  const handleCloseModal = () => setIsModalOpen(false);
 
  return (
    <>
      <div className={`w-full max-w-md ${bgColor} m-0 p-4 border rounded-lg shadow-md`}>
        <div className="flex justify-between items-center mb-2">
          <p className="text-sm text-gray-500">{ticket.client.nom} - {ticket.client.prenom}</p>
          <span className={`text-xs font-semibold py-1 px-2 rounded-full ${badgeColor}`}>{badgeText}</span>
        </div>
        <h2 className="text-lg font-semibold">{ticket.evenement.description}</h2>
        <p className="text-sm text-gray-700">Offre : {ticket.offre.libelle}</p>
        <p className="text-sm text-gray-700">Nombre de personnes : {ticket.offre.nb_personne}</p>
        <p className="text-sm text-gray-700">Montant : {ticket.offre.montant} €</p>
        <p className="text-sm text-gray-700 mb-4">Description : {ticket.offre.description}</p>
        <button
          className="w-full bg-blue-500 text-white py-2 px-4 rounded-lg hover:bg-blue-600 transition-all duration-200"
          onClick={handleOpenModal}
        >
          QrCode
        </button>
      </div>
 
      {isModalOpen && (
        <div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
          <div className="bg-white rounded-lg p-4 max-w-sm w-full shadow-lg relative">
            <QRCodeModal handleCloseModal={handleCloseModal} ticket_id={ticket.id} />
          </div>
        </div>
      )}
    </>
  );
}