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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 1x 1x 1x 1x 3x 6x 3x 1x 1x 1x | /**
* @module components/evenements/DisplayedOffre
* Module de composant DisplayedOffre pour l'affichage et la gestion des offres d'événements
*
* Ce module contient le composant DisplayedOffre qui affiche la liste des offres
* disponibles pour un événement donné avec la gestion des réservations.
* Il intègre le système de panier Redux et gère les états de chargement.
*
* ## Fonctionnalités principales
* - Affichage en grille des offres disponibles
* - Intégration avec Redux pour le panier
* - Gestion des états de chargement et d'erreur
* - Calcul des quantités réservées par offre
* - Interface responsive (1 colonne mobile, 2 colonnes desktop)
* - Actions de réservation et annulation en temps réel
*
* ## Gestion du panier
* - Synchronisation avec l'état Redux du panier
* - Calcul automatique des quantités par offre et événement
* - Mise à jour en temps réel des quantités affichées
* - Validation des réservations avec les places restantes
*
* ## États d'affichage
* - **Chargement** : Indicateur pendant la récupération des offres
* - **Erreur** : Message d'erreur si échec du chargement
* - **Données** : Grille des cartes d'offres avec interactions
*
* ## Layout responsive
* - Mobile : 1 colonne (grid-cols-1)
* - Desktop : 2 colonnes (md:grid-cols-2)
* - Espacement uniforme entre les cartes (gap-4)
*
* ## Intégration
* - Utilisé dans ModalEvenement pour l'affichage des offres
* - Connecté au hook useOffres pour les données
* - Intégré avec le système de réservation global
*
* @group Components
*/
import {useOffres} from "@/hook/useOffre";
import CardOffre from "@/components/evenements/CardOffre";
import { useSelector } from "react-redux";
import { OffrePanier } from "@/type/achat/offrePanier";
/**
* Props du composant DisplayedOffre
*/
type Props = {
/** ID de l'événement pour lequel afficher les offres */
evenementId: number;
/** Nombre de places restantes disponibles pour l'événement */
remainingTickets: number;
/** Fonction appelée pour réserver des places pour une offre */
onReservePlaces: (evenementId: number, offreId: number) => void;
/** Fonction appelée pour annuler des réservations pour une offre */
onUnReservePlaces: (evenementId: number, offreId: number) => void;
};
/**
* Composant DisplayedOffre pour l'affichage et la gestion des offres d'événements.
* Voir la documentation du module ci-dessus pour les détails complets.
*
* Le composant récupère et affiche toutes les offres disponibles sous forme de grille,
* en intégrant les fonctionnalités de réservation et la synchronisation avec le panier.
* Il gère automatiquement les états de chargement et les erreurs.
*
* @param props - Les propriétés du composant
* @param props.evenementId - ID de l'événement concerné
* @param props.remainingTickets - Places restantes pour validation
* @param props.onReservePlaces - Callback pour réserver des places
* @param props.onUnReservePlaces - Callback pour annuler des réservations
*
* @returns Grille d'offres avec gestion des réservations ou états de chargement/erreur
*
* @example
* ```tsx
* // Utilisation dans un modal d'événement
* <DisplayedOffre
* evenementId={evenement.id}
* remainingTickets={remainingTickets}
* onReservePlaces={(eventId, offerId) => reservePlaces(eventId, offerId)}
* onUnReservePlaces={(eventId, offerId) => unReservePlaces(eventId, offerId)}
* />
*
* // Avec gestion d'état de réservation
* const handleReservation = useCallback((eventId: number, offerId: number) => {
* // Logique de réservation
* updateReservations(eventId, offerId);
* }, []);
* ```
*/
export default function DisplayedOffre({evenementId, remainingTickets, onReservePlaces, onUnReservePlaces}: Props) {
const {offres, loading, error} = useOffres();
// Sélectionner le panier depuis Redux
const panierItems = useSelector((state: { panier: { items: OffrePanier[] } }) => state.panier.items);
return (
<>
{loading && <p>Chargement des offres...</p>}
{error && <p>Erreur lors du chargement des offres : {error.message}</p>}
{!loading && !error && (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{offres.map((offre) => {
// Chercher la quantité pour cette offre et cet événement
const item = panierItems.find((i: OffrePanier) => i.evenementId === evenementId && i.offreId === offre.id);
const quantityInCart = item ? item.quantity : 0;
return (
<CardOffre
key={offre.id}
offre={offre}
remainingTickets={remainingTickets}
onReservePlaces={() => onReservePlaces(evenementId,offre.id)}
onUnReservePlaces={() => onUnReservePlaces(evenementId,offre.id)}
quantityInCart={quantityInCart}
/>
);
})}
</div>
)}
</>
);
} |