Implémente le back end du panier avec l'utilisation des cookies qui ne sont pas encore liées à ces pages : import React from 'react'
import {useState} from 'react';
import { getCookie, setCookie } from '../../../../cookies/CookiesLib.tsx';

type Props = {
    typeBillet: number,
    quantite: number,
}

export default function ItemPanier(props: Props) {
  const [quantite, setQuantite] = useState(props.quantite);

  return (
    <div className="item-panier">
        <div className="container-item-panier">
            <div className="container-image">
                <img src="/images/billet.png" alt="billet" />
            </div>
            <div className="informations">
                <div className="textes">
                    <h4>Pass 1 jour - fosse</h4>
                    <h5>35,99€</h5>
                </div>
                <div className="compteur-quantitee">
                    <span className='ajout-retrait' onClick={() => setQuantite(quantite-1)}>-</span>
                    <input type="number" className='quantite' value={quantite}/>
                    <span className='ajout-retrait' onClick={() => setQuantite(quantite+1)}>+</span>
                </div>
            </div>
        </div>   
        <img className='cross' src="/icones/cross.svg" alt="croix"/>
    </div>
  )
}
import { motion } from 'framer-motion'
import React from 'react'
import { Link } from 'react-router-dom'
import {useState} from 'react';
import TextField from '../../../form/TextField';
import Button from '../../../form/Button';
import ItemPanier from './ItemPanier';

type Props = {
  isOpen: boolean;
  setIsOpen: (isOpen : boolean) => void;
}

export default function MenuConnexion(props: Props) {

  const menuVariants = {
    hidden:{
      x: "42rem",
      transition:{
        duration: 0.5,
        ease: [1, -0.02, 0,1]
      }
    },
    visible:{
      x: 0,
      transition:{
        duration: 0.5,
        ease: [1, -0.02, 0,1]
      }
    }
  }

  return (
    <motion.div className='side-menu cart'
    variants={menuVariants}
    initial="hidden"
    animate={props.isOpen ? "visible" : "hidden"}>
        <div className="cross" onClick={() => props.setIsOpen(false)}>
            <svg width="36" height="28" viewBox="0 0 36 28" fill="none" xmlns="http://www.w3.org/2000/svg">
              <rect x="6.52539" y="0.321533" width="35.8974" height="3.58974" rx="1.79487" transform="rotate(45 6.52539 0.321533)" fill="#E45A3B"/>
              <rect x="3.87891" y="25.5957" width="35.8974" height="3.58974" rx="1.79487" transform="rotate(-45 3.87891 25.5957)" fill="#E45A3B"/>
            </svg>
        </div>
        <div className="container">
          <h2>Mon panier</h2>

          <section className='le-panier'>
            <ItemPanier typeBillet={1} quantite={1}/>
            <ItemPanier typeBillet={1} quantite={1}/>
            
          </section>
          
          <div className="sous-total">
            <h4>Sous total: </h4>
            <h4>35,99€</h4>
          </div>
          <Button text="RESERVER"/>
        </div>
    </motion.div>
  )
}
import { motion } from 'framer-motion';
import { useContext, useState } from 'react';
import Button from '../components/form/Button';
import { getCookie, setCookie } from '../cookies/CookiesLib.tsx';
import { CartContext } from '../App';


const initialDays = { '20Juillet': false, '21Juillet': false, '22Juillet': false };

type Props = {
  id: number;
  title: string;
  price: number|string;
  nbTicket: number;
  isForfait?: boolean; 
};

export default function TicketCard({ id, title, price, nbTicket, isForfait }: Props) {
  const [isOpen, setIsOpen] = useState(false);
  const [tickets, setTickets] = useState(nbTicket);
  const [rotation, setRotation] = useState(0);
  const [days, setDays] = useState(initialDays);
  const { cart, setCart } = useContext(CartContext);
  
  const handleTicketChange = (newTickets: number, event: React.MouseEvent) => {
    event.stopPropagation();
    setTickets(newTickets);
    };
  const addToCartHandler = () => {
    const selectedDays = isForfait ? 
      Object.entries(days).filter(([_, isChosen]) => isChosen).map(([day, _]) => day) : 
      [];

    const itemForCart = {
      id,
      title,
      price: typeof price === 'number' ? price : 0,
      quantity: tickets,
      selectedDays,
    };

    let newCart = cart.slice(); 
    const billetIndex = newCart.findIndex(billet => billet.id === itemForCart.id);
    if (billetIndex > -1) {
      newCart[billetIndex].quantity += itemForCart.quantity;
    } else {
      newCart.push(itemForCart);
    }
    setCart(newCart); // Met à jour l'état global du panier
    setCookie('cart', newCart, { expires: 7, sameSite: 'None', secure: true }); // Met à jour le cookie

  };


  const contentVariants = {
    closed: {
      opacity: 0,
      height: 0,
      overflow: 'hidden',
      transition: {
        duration: 0.2,
        ease: 'easeInOut',
        when: 'afterChildren',
      },
    },
    open: {
      opacity: 1,
      height: title === "Forfait 2 jours" ? 150 : 120,
      transition: {
        duration: 0.2,
        ease: 'easeInOut',
        when: 'beforeChildren',
      }
    },
  };

  const cardVariants = {
    hidden: { opacity: 0, y: 50 },
    visible: {
      opacity: 1,
      y: 0,
      transition: {
        type: 'spring',
        stiffness: 120,
      },
    },
  };

  const maxSelectedDays = 2;

  const selectedDayCount = () => {
    return Object.values(days).filter(Boolean).length;
  };

  const toggleDaySelection = (day: keyof typeof initialDays) => {
    setDays(prevDays => {
      const isSelected = prevDays[day];
      const count = selectedDayCount();
  
      if (!isSelected && count >= maxSelectedDays) {
        return prevDays;
      }
      
      return { ...prevDays, [day]: !prevDays[day] };
    });
  };
  
  return (
    <motion.div
      className="ticket-card"
      layout
      initial="hidden"
      animate="visible"
      variants={cardVariants}
      onClick={() => {
        setIsOpen(!isOpen);
        setRotation(rotation === 0 ? 90 : 0);
      }}
    >
      <div className="content">
        <div className='left-part'>
          <h4>{title}</h4>
          <p>Les tickets ne sont pas remboursables.</p>
          <p>Dernière entrée à 11H.</p>
        </div>
        <div className='right-part'>
          <p>{price}€</p>
          <motion.div className="svg-container" animate={{ rotate: rotation }}>
            <svg xmlns="http://www.w3.org/2000/svg" width="13" height="20" viewBox="0 0 13 20" fill="none">
              <path d="M2 18L10 10L2 2" stroke="#4E4E4E" strokeWidth="4" />
            </svg>
          </motion.div>
        </div>
      </div>
      <motion.div
  className={`sub-menu ${title === "Forfait 2 jours" ? "forfait-2j" : ""}`}
  variants={contentVariants}
  initial="closed"
  animate={isOpen ? "open" : "closed"}
  exit="closed"
>
  <div className='top-partsubmenu'>
        <div className='left-part-sub'>
        {isForfait && (Object.keys(days) as Array<keyof typeof days>).map(day => (
          <label key={day}>
            <input 
              type="checkbox"
              checked={days[day]}
              onChange={() => toggleDaySelection(day)}
            />
            {day}
          </label>
        ))}
          <div className='sub-menu-left-part'>
          <div className ="rect">
            <img src="images/billet_pass1j.png" alt="Billet pass 1 jour" />
          </div>
          <div className='article-select'>
          <svg xmlns="http://www.w3.org/2000/svg" width="22" height="21" viewBox="0 0 22 21" fill="none">
            <path d="M22 9.03848H14.6966L19.8599 4.10947L17.6953 2.04109L12.532 6.97007V0H9.46799V6.97007L4.30475 2.04109L2.13807 4.10947L7.30131 9.03848H0V11.9615H7.30131L2.13807 16.8906L4.30475 18.9589L9.46799 14.0299V21H12.532V14.0299L17.6953 18.9589L19.8599 16.8906L14.6966 11.9615H22V9.03848Z" fill="#FFD600"/>
          </svg>
          <p>x{tickets} Article(s) sélectionné(s)</p>
          </div>
          </div>
        <div className="ticket-control">
          <button onClick={(event) => handleTicketChange(Math.max(tickets - 1, 0), event)}>-</button>
          <span>{tickets}</span>
          <button className='sommeButton' onClick={(event) => handleTicketChange(tickets + 1, event)}>+</button>
        </div>
        </div>
      </div>
      <div className='delimiter-submenu'></div>
      <div className='bottom-partsubmenu'>
        <div className='bottom-part-left'>
        <p>Sous-total</p>
          <p>{tickets * price}€</p>
        </div>
        <button onClick={addToCartHandler}>AJOUTER AU PANIER</button>
      </div>

      </motion.div>
    </motion.div>
  );
}import Cookies from 'js-cookie';

// Définition des types pour les données que vous souhaitez stocker dans les cookies
interface UserData {
  username: string;
  email: string;
  // ... autres champs
}

// Fonction pour définir un cookie
export const setCookie = (key: string, value: any, options?: Cookies.CookieAttributes) => {
  Cookies.set(key, JSON.stringify(value), options);
};

// Fonction pour récupérer un cookie
export const getCookie = (key: string): any | null => {
  const cookie = Cookies.get(key);
  return cookie ? JSON.parse(cookie) : null;
};

// Fonction pour supprimer un cookie
export const removeCookie = (key: string) => {
  Cookies.remove(key);
};

// removeCookie('cart');

type userData= {
    pseudoUser: string;
    emailUser: string;
    idUser: number;
}

export const setUserCookie = (user: userData) => {
    setCookie("Connected", user, {expires: 7});
}

export const isConnected = ():boolean => {
    const user = getCookie("Connected");
    if (user){
        return true;
    }
    return false;
}

export const getUserCookie = ():userData => {
    const user = getCookie("Connected");
    return user;
}

export const removeUserCookie = () => {
    removeCookie("Connected");
}