Appearance
question:fait en sorte que je puisse récupèrer le prix et l'intitulé des billets depuis le cart dans la page itemPanier : import React from 'react' import {useState} from 'react'; import { getCookie, setCookie } from '../../../../cookies/CookiesLib.tsx'; import { useEffect } from 'react'; type Props = { typeBillet: number, quantite: number, } export default function ItemPanier(props: Props) { const [quantite, setQuantite] = useState(props.quantite); const updateCartCookie = (typeBillet: number, newQuantite: number) =>{ const cart = getCookie("cart"); const itemIndex = cart.findIndex((item: { typeBillet: number; }) => item.typeBillet === typeBillet); if(itemIndex > -1){ cart[itemIndex].quantite = newQuantite; }else{ cart.push({typeBillet, quantite: newQuantite}); } const filteredCart = cart.filter((item: { quantite: number; }) => item.quantite > 0); setCookie('cart', filteredCart, {expires: 7, sameSite: 'None', secure: true}); useEffect(() => { updateCartCookie(props.typeBillet, quantite); }, [quantite]); console.log(cart); } const removeFromCart = () => { const cart = getCookie('cart'); const newCart = cart.filter((item: { typeBillet: number; }) => item.typeBillet !== props.typeBillet); setCookie('cart', newCart, { expires: 7 }); }; 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>Information</h4> <h5>Prix : </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" onClick={removeFromCart}/> </div> ) } import './index.css' import './components/nav/Navbar' import Navbar from './components/nav/Navbar' import { AnimatePresence } from 'framer-motion' import { Route, Routes, useLocation } from 'react-router-dom' import Accueil from './pages/Accueil/Accueil' import { createContext, useEffect, useState } from 'react' import Programmation from './pages/Programmation/Programmation' import PageArtiste from './pages/Artiste/PageArtiste' import Billeterie from './pages/Billeterie/Billeterie' import Faq from './pages/faq/Faq' import { getCookie } from './cookies/CookiesLib' interface cartContext{ cart: any[], setCart: (cart: any[]) => void, } export const CartContext = createContext<cartContext>({ cart: [], setCart: () => {}, }) function App() { const [cart, setCart] = useState<any[]>(() => getCookie('cart') || []); const [isNavInFocus, setIsNavInFocus] = useState(false) const[isNavTransparent, setIsNavTransparent] = useState(true); const location = useLocation(); useEffect(() => { }, []); return ( <CartContext.Provider value = {{cart, setCart}}> <Navbar setNavInFocus={setIsNavInFocus} isTransparent={isNavTransparent}/> <AnimatePresence> <Routes location={location} key={location.key}> <Route path="/" element={<Accueil isNavInFocus={isNavInFocus} setIsNavTransparent={setIsNavTransparent} />} /> <Route path="/programmation" element={<Programmation isNavInFocus={isNavInFocus} setIsNavTransparent={setIsNavTransparent} />} /> <Route path="/billeterie" element={<Billeterie isNavInFocus={isNavInFocus} setIsNavTransparent={setIsNavTransparent} />} /> <Route path="/faq" element={<Faq isNavInFocus={isNavInFocus} setIsNavTransparent={setIsNavTransparent} />}/> <Route path="/artiste" element={<PageArtiste />}/> </Routes> </AnimatePresence> </CartContext.Provider> ) } export default App import { motion } from 'framer-motion' import { Link } from 'react-router-dom' import {useState} from 'react'; import TextField from '../../../form/TextField'; import Button from '../../../form/Button'; import ItemPanier from './ItemPanier'; import { CartContext } from '../../../../App'; import { useContext } from 'react'; type Props = { isOpen: boolean; setIsOpen: (isOpen : boolean) => void; } export default function MenuConnexion(props: Props) { const { cart, setCart } = useContext(CartContext); console.log(cart) 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'> {cart.map((item, index) => ( <ItemPanier key={index} typeBillet={item.typeBillet} quantite={item.quantite}/> ))} </section> <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> ); }
answer:To retrieve the price and the title of the tickets from the cart in the `ItemPanier` page, you need to pass these properties along with `typeBillet` and `quantite`. You need to update the `CartItem` type to include these properties and modify the `TicketCard` and `ItemPanier` components accordingly. First, define a proper `CartItem` type: ```tsx // Define a type for the cart item type CartItem = { id: number, title: string, price: number | string, quantity: number, selectedDays?: string[] // Optional property if you have days associated with the ticket }; ``` Now, let's update the `TicketCard` component's `addToCartHandler` to use this `CartItem` type: ```tsx // TicketCard.tsx // ... const addToCartHandler = () => { const selectedDays = isForfait ? Object.entries(days).filter(([_, isChosen]) => isChosen).map(([day, _]) => day) : []; // Cast the price to a number if it's not already one const priceNumber = typeof price === 'number' ? price : parseFloat(price.replace(/[^0-9.-]+/g, "")); const itemForCart: CartItem = { id, title, price: priceNumber, quantity: tickets, selectedDays, }; // ... the rest of your code }; // ... ``` Pass the title and the price to `ItemPanier` when mapping the cart in `MenuConnexion`: ```tsx // MenuConnexion.tsx // ... <section className='le-panier'> {cart.map((item: CartItem, index: number) => ( <ItemPanier key={index} typeBillet={item.id} quantite={item.quantity} title={item.title} price={item.price} /> ))} </section> // ... ``` And finally, update the `ItemPanier` component to accept `title` and `price` props and use them: ```tsx // ItemPanier.tsx type Props = { typeBillet: number, quantite: number, title: string, // Include title in props price: number | string, // Include price in props }; export default function ItemPanier({ typeBillet, quantite, title, price }: Props) { // ... // Display title and formatted price in your component return ( <div className="item-panier"> <div className="container-item-panier"> // ... <div className="informations"> <div className="textes"> <h4>{title}</h4> {/* Use title */} <h5>{typeof price === 'number' ? `{price.toFixed(2)}€` : price}</h5> {/* Format and display price */} </div> // Rest of your component </div> </div> // ... </div> ); } ``` Make sure your `cart` context state and cookie updates handle this new structure, and you've migrated all uses of the old `cart` structure to the new `CartItem` type. By making these changes, the `ItemPanier` component will correctly display the title and price of each ticket added to the cart.
question:[{ "resource": "/C:/Users/alexa/Desktop/sae-fest-iuto-front/src/components/TicketCard.tsx", "owner": "typescript", "code": "2552", "severity": 8, "message": "Cannot find name 'CartItem'. Did you mean 'Artiste'?", "source": "ts", "startLineNumber": 37, "startColumn": 26, "endLineNumber": 37, "endColumn": 34 }]
answer:The TypeScript error you are seeing, "Cannot find name 'CartItem'. Did you mean 'Artiste'?", suggests that TypeScript is unable to find a definition for the `CartItem` type in your `TicketCard.tsx` file. This could be because the `CartItem` type hasn't been defined or imported into the file where you're trying to use it. To fix this, you need to ensure that the `CartItem` type is defined and that it is visible to the `TicketCard.tsx` file. There are a couple of ways to do this. 1. **Define the `CartItem` type in the file where it's used**: If the `CartItem` type is only used in `TicketCard.tsx`, you could define it directly in that file. ```tsx // TicketCard.tsx type CartItem = { id: number; title: string; price: number | string; quantity: number; selectedDays?: string[]; }; // ... rest of your TicketCard component ``` 2. **Define the `CartItem` type in a shared types file and import it**: If the `CartItem` type is used in multiple components, it's a good practice to define it in a separate file for types and interfaces and then import it wherever needed. First, create a new file for shared types, e.g., `types.ts`. ```tsx // types.ts export type CartItem = { id: number; title: string; price: number | string; quantity: number; selectedDays?: string[]; }; ``` Then, import the `CartItem` type in your `TicketCard.tsx` file. ```tsx // TicketCard.tsx import { CartItem } from './path/to/types'; // Adjust the path accordingly // ... rest of your TicketCard component ``` Remember to replace `'./path/to/types'` with the actual relative path to your newly created types file. By following one of these approaches, you will have defined the `CartItem` type so that it can be used in your `TicketCard.tsx` component, and the TypeScript error should be resolved. Make sure that all files using the `CartItem` type are updated to import it from its definition.
question:comment je peux vider les input au préalable : <!-- Modale pour ajouter un utilisateur --> <div id="modal-ajouter" class="modal"> <div class="modal-content"> <span class="close-button">x</span> <form action="/ajouter_user" method="POST"> <label for "pseudo_user">Pseudo:</label> <input type="text" name="pseudo_user" id="pseudo_user_ajouter" required> <label for "mdp_user">Mot de passe:</label> <input type="password" name="mdp_user" id="mdp_user_ajouter" required> <label for "email_user">Email:</label> <input type="email" name="email_user" id="email_user_ajouter" required> <label for "statut_user">Statut:</label> <select name="statut_user" id="statut_user_ajouter" required> <option value="admin">admin</option> <option value="user">user</option> </select> <button class="btn-ajouter" type="submit">Ajouter</button> </form> </div> </div>
answer:Pour vider les champs de saisie (les éléments `input` et `select`) au sein de votre modale, vous pouvez utiliser JavaScript. Ci-dessous, je vous montre comment vous pouvez le faire en ajoutant un événement qui se déclenche lorsque le modal est ouvert. Supposons que vous avez un bouton ou quelque chose qui déclenche l'ouverture du modal, vous pouvez lier une fonction qui vide les champs à cet événement. Voici un exemple de code JavaScript qui le fait: ```javascript // Fonction pour vider les champs du modal function viderChamps() { document.getElementById('pseudo_user_ajouter').value = ''; document.getElementById('mdp_user_ajouter').value = ''; document.getElementById('email_user_ajouter').value = ''; document.getElementById('statut_user_ajouter').selectedIndex = 0; // Remet le premier élément sélectionné } // Supposons que vous avez un bouton pour ouvrir votre modal var btnOpenModal = document.getElementById('btn-open-modal'); // Ajoutez un écouteur d'évènement pour vider les champs lors de l'ouverture du modal btnOpenModal.addEventListener('click', function() { viderChamps(); // Code pour ouvrir le modal }); ``` Si vous voulez que les champs soient nettoyés lorsque le modal est fermé, vous pouvez ajouter la fonction `viderChamps()` à un écouteur d'événements sur la croix (le span avec la classe "close-button") qui ferme le modal : ```javascript // Sélectionnez le span avec la classe "close-button" var closeButton = document.querySelector('.close-button'); // Ajoutez un écouteur d'évènement pour fermer le modal et vider les champs closeButton.addEventListener('click', function() { viderChamps(); // Code pour fermer le modal }); ``` N'oubliez pas d'inclure le JavaScript sur la même page où se trouve votre code HTML ou de le référencer en tant que fichier externe.
question:{% block styles %} <link rel="stylesheet" href=" {{ url_for('static', filename='admin_users.css')}}"> {% endblock %} {% block content %} <a id="retour" href="{{ url_for('menu_admin') }}" class="btn-retour">Retour</a> <h1>Les comptes de l'application</h1> <table> <thead> <tr> <th>id User</th> <th>Pseudo</th> <th>Mdp</th> <th>Email</th> <th>Statut</th> <th>Actions</th> </tr> </thead> <tbody> {% for user in liste_users %} <tr> <td>{{ user.get_idUser() }}</td> <td>{{ user.get_pseudoUser() }}</td> <td>{{ user.get_mdpUser() }}</td> <td>{{ user.get_emailUser() }}</td> <td>{{ user.get_statutUser() }}</td> <td> <button class="btn-supprimer" data-id=" {{ user.get_idUser() }}">Supprimer</button> <button class="btn-modifier" data-id=" {{ user.get_idUser() }}" data-pseudo=" {{ user.get_pseudoUser() }}" data-mdp=" {{ user.get_mdpUser() }}" data-email=" {{ user.get_emailUser() }}">Modifier</button> </td> </tr> {% endfor %} </tbody> </table> <button id="ajouter">Ajouter</button> <!-- Modale pour ajouter un compte --> <div id="modal-ajouter" class="modal"> <div class="modal-content"> <span class="close-button">x</span> <form action="/ajouter_user" method="POST"> <label for "pseudo_user">Pseudo:</label> <input type="text" name="pseudo_user" id="pseudo_user_ajouter" required> <label for "mdp_user">Mot de passe:</label> <input type="text" name="mdp_user" id="mdp_user_ajouter" required> <label for "email_user">Email:</label> <input type="email" name="email_user" id="email_user_ajouter"> <label for "statut_user">Statut:</label> <select name="statut_user" id="statut_user_ajouter" required> <option disabled selected value> Choisir un statut </option> <option value="admin">admin</option> <option value="user">user</option> </select> <button class="btn-ajouter" type="submit">Ajouter</button> </form> </div> </div> <!-- Modale pour supprimer un compte --> <div id ="modal-supprimer" class="modal"> <div class="modal-content"> <span class="close-button">x</span> <form action="/supprimer_user" method="POST"> <input type="hidden" name="id_user" id="id_user_supprimer"> <p>Êtes-vous sûr de vouloir supprimer cet utilisateur ?</p> <button id="supprimer" type="submit">Supprimer</button> </form> </div> </div> <!-- Modale pour modifier un compte --> <div id="modal-modifier" class="modal"> <div class="modal-content"> <span class="close-button">x</span> <form action="/modifier_user" method="POST"> <input type="hidden" name="id_user" id="id_user_modifier"> <label for "pseudo_user">Pseudo:</label> <input type="text" name="pseudo_user" id="pseudo_user_modifier" required> <label for "mdp_user">Mot de passe:</label> <input type="text" name="mdp_user" id="mdp_user_modifier" required> <label for "email_user">Email:</label> <input type="email" name="email_user" id="email_user_modifier"> <button class="btn-modifier" type="submit">Modifier</button> </form> </div> <script> document.addEventListener("DOMContentLoaded", function() { var modalAjouter = document.getElementById("modal-ajouter"); var modalSupprimer = document.getElementById("modal-supprimer"); var modalModifier = document.getElementById("modal-modifier"); var btnClose = document.querySelectorAll(".close-button"); btnClose.forEach(function(btn) { btn.onclick = function() { btn.closest(".modal").style.display ="none"; }; }); document.querySelectorAll(".btn-modifier").forEach(function(btn) { btn.onclick = function() { document.getElementById("id_user_modifier").value = btn.getAttribute("data-id"); document.getElementById("pseudo_user_modifier").value = btn.getAttribute("data-pseudo"); document.getElementById("mdp_user_modifier").value = btn.getAttribute("data-mdp"); document.getElementById("email_user_modifier").value = btn.getAttribute("data-email"); modalModifier.style.display = "block"; }; }); document.getElementById("ajouter").onclick = function() { modalAjouter.style.display = "block"; document.getElementById("pseudo_user_ajouter").value = ""; document.getElementById("mdp_user_ajouter").value = ""; document.getElementById("email_user_ajouter").value = ""; document.getElementById("pseudo_user_ajouter").focus(); }; document.querySelectorAll(".btn-supprimer").forEach(function(btn) { btn.onclick = function() { document.getElementById("id_user_supprimer").value = btn.getAttribute("data-id"); modalSupprimer.style.display = "block"; }; }); window.onclick = function(event) { if (event.target.classList.contains("modal")) { event.target.style.display = "none"; } } }); </script> {% endblock %} quand je veux modifier un user ça vide tous les champs et je ne comprends pas pourquoi
answer:D'après le code que vous avez fourni, il semble que la fonction qui se déclenche lorsqu'on clique sur le bouton "modifier" récupère correctement les données de l'utilisateur à partir des attributs `data-*` et les place dans les champs appropriés. C'est le comportement attendu. Cependant, le problème peut venir d'un conflit ou d'une erreur pas immédiatement visible dans le code partagé. Vérifiez les éléments suivants pour diagnostiquer le problème : 1. Assurez-vous qu'aucun autre script n'est en cours d'exécution et qui pourrait interférer avec cette partie du code. 2. Vérifiez que les noms des attributs `data-*` correspondent exactement aux données qu'ils sont sensés contenir. Par exemple, `data-pseudo` doit contenir le pseudo de l'utilisateur, `data-mdp` le mot de passe, etc. 3. Assurez-vous qu'il n'y a pas d'autres événements `onclick` attachés aux boutons "modifier" qui pourraient entraîner la suppression des valeurs des champs de formulaire. 4. Confirmez que le code ne contient pas d'instructions JavaScript supplémentaires inattendues qui pourraient réinitialiser les champs du formulaire après le remplissage des valeurs. 5. Vérifiez que vous n'avez pas de gestionnaires d'événements globaux qui interceptent les clics et manipulent les éléments du DOM de manière imprévue. 6. Si votre formulaire est en fait soumis et la page est rechargée après le clic du bouton "modifier" (il se peut que la réponse du serveur soit une page avec un formulaire vide), les champs seront naturellement vides. Pour éviter cela, assurez-vous que le bouton "modifier" ne soumet pas le formulaire ou empêchez le comportement par défaut en utilisant `event.preventDefault()`. En dernier recours, vous pouvez ajouter des `console.log` pour déboguer et afficher les valeurs que vous récupérez et placez dans les champs de formulaire : ```javascript document.querySelectorAll(".btn-modifier").forEach(function(btn) { btn.onclick = function() { var id = btn.getAttribute("data-id"); var pseudo = btn.getAttribute("data-pseudo"); var mdp = btn.getAttribute("data-mdp"); var email = btn.getAttribute("data-email"); console.log("Modifier utilisateur:", id, pseudo, mdp, email); document.getElementById("id_user_modifier").value = id; document.getElementById("pseudo_user_modifier").value = pseudo; document.getElementById("mdp_user_modifier").value = mdp; document.getElementById("email_user_modifier").value = email; modalModifier.style.display = "block"; }; }); ``` Cela vous permettra de voir si les bonnes valeurs sont récupérées avant de les affecter aux champs de formulaire. Si les valeurs sont correctes dans la console mais que vos champs de formulaire sont vides, l'erreur est probablement ailleurs dans le code ou avec les éléments de formulaire eux-mêmes.