Merge branch 'react-version' of https://github.com/MarcEricMartel/420-5DW-HY-TP into react-version

This commit is contained in:
Victor Turgeon 2022-11-07 23:34:50 -05:00
commit fba4921a56
6 changed files with 314 additions and 115 deletions

View File

@ -0,0 +1,94 @@
import { createContext, useState } from "react";
export const CartContext = createContext({
items: [],
getProductQuantity: () => { },
addOneToCart: () => { },
removeOneFromCart: () => { },
deleteFromCart: () => { },
getTotalCost: () => { },
addToCart: () => { }
});
export function CartProvider({ children }) {
const [cartProducts, setCartProducts] = useState([]);
function addToCart(product, qty) {
setCartProducts([...cartProducts, {...product, quantity: parseFloat(qty)}]);
}
function getProductQuantity(id) {
const quantity = cartProducts.find(product => product.id === id)?.quantity;
if (quantity === undefined) {
return 0;
}
return quantity;
};
function addOneToCart(id, qty) {
const currentQty = getProductQuantity(id);
if (qty > currentQty) {
setCartProducts(
cartProducts.map(
product => product.id === id
? { ...product, quantity: parseFloat(product.quantity) + 1 }
: product
)
);
}
};
function removeOneFromCart(id) {
const currentQty = getProductQuantity(id);
if (currentQty === 1)
deleteFromCart();
else
setCartProducts(
cartProducts.map(
product => product.id === id
? { ...product, quantity: parseFloat(product.quantity) - 1 }
: product
)
);
};
function deleteFromCart(id) {
setCartProducts(
cartProducts => cartProducts.filter(currentProduct => {
return currentProduct.id != id;
})
);
};
function getTotalCost() {
let totalCost = 0;
cartProducts.map((cartItem) => {
totalCost += (cartItem.Price * cartItem.quantity);
});
return totalCost;
};
const contextValue = {
items: cartProducts,
getProductQuantity,
addOneToCart,
removeOneFromCart,
deleteFromCart,
getTotalCost,
addToCart
};
return (
<CartContext.Provider value={contextValue}>
{children}
</CartContext.Provider>
);
}
export default CartProvider;

View File

@ -1,14 +1,42 @@
import { Button } from "react-bootstrap"; import { Button } from "react-bootstrap";
import { faCartShopping } from "@fortawesome/free-solid-svg-icons"; import { faCartShopping } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Modal, ModalBody, ModalHeader } from "react-bootstrap";
import { useState, useContext } from "react";
import { CartCard } from './CartCard';
import { CartContext } from './Cart';
const CartButton = () =>{ const CartButton = () => {
return( const [show, setShow] = useState(false);
<Button id="cart-button"> const handleClose = () => setShow(false);
<FontAwesomeIcon icon={faCartShopping}/> const handleShow = () => setShow(true);
<div id="cart-count">3</div> const cart = useContext(CartContext);
</Button>
const productsCount = cart.items.reduce((sum, product) => sum + product.quantity, 0)
return (
<>
<Button id="cart-button" onClick={handleShow}>
<FontAwesomeIcon icon={faCartShopping} />
<div id="cart-count">{productsCount}</div>
</Button>
<Modal show={show} onHide={handleClose} className="carosse">
<ModalHeader closeButton>
<Modal.Title>Carosse</Modal.Title>
</ModalHeader>
<ModalBody>
{productsCount > 0 ?
<>
<p></p>
{cart.items.map((item) => <CartCard product={item}></CartCard>)}
</>
:
<h1>C'est vide! Rempli le hi hi!</h1>
}
</ModalBody>
</Modal>
</>
) )
} }

View File

@ -0,0 +1,43 @@
import { Card, Button, Form, Row, Col } from 'react-bootstrap';
import { useContext, useState, useEffect } from 'react';
import { CartContext } from './Cart';
const CartCard = ({ product }) => {
const cart = useContext(CartContext);
const productQuantity = cart.getProductQuantity(product.id);
const [imageSrc, setImageSrc] = useState(null);
useEffect(() => {
fetch(`https://localhost:7292/api/Image?id=${product.id}&thumbnail=true`)
.then(response => response.blob())
.then(blob => {
const imageUrl = URL.createObjectURL(blob);
setImageSrc(imageUrl);
})
}, []);
return (
<>
<Card>
<Card.Body>
<div className={!imageSrc ? "cat-load" : "d-none cat-load"} />
<Card.Img className="item-img" variant="top" src={imageSrc} />
<Card.Title>{product.Title}</Card.Title>
<Card.Text>{product.Price}$ CA</Card.Text>
<Form as={Row}>
<Form.Label column="true" sm="6">Dans l'carosse: {productQuantity}</Form.Label>
<Col sm="6">
<Button sm="6" className='mx-2' onClick={() => cart.addOneToCart(product.id, product.quantity)}>+</Button>
<Button sm="6" className='mx-2' onClick={() => cart.removeOneFromCart(product.id)}>-</Button>
</Col>
</Form>
<Button variant="danger" className='my-2' onClick={() => cart.deleteFromCart(product.id)}>Supprimer</Button>
</Card.Body>
</Card>
</>
)
}
export default CartCard;

View File

@ -12,6 +12,8 @@ const Topbar = () => {
const [cookies, setCookie, removeCookie] = useCookies(['name']); const [cookies, setCookie, removeCookie] = useCookies(['name']);
const [user, setLogin] = useState(null); const [user, setLogin] = useState(null);
useEffect(() => { useEffect(() => {
async function reset() { async function reset() {
await setLogin(await cookies.GMGM ?? null); await setLogin(await cookies.GMGM ?? null);
@ -29,103 +31,103 @@ const Topbar = () => {
} }
return ( return (
<Navbar expand="sm" className="topbar-container"> <>
<Container> <Navbar expand="sm" className="topbar-container">
<Link className="navbar-brand" to="/"> <Container>
<img src="/images/LesGrossesMitaines.png" alt="" height="45" /> <Link className="navbar-brand" to="/">
</Link> <img src="/images/LesGrossesMitaines.png" alt="" height="45" />
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Link className="nav-link" to="/" >
Maison
</Link>
<Link className="nav-link" to="/morceaux" >
Morceaux
</Link>
<Link className="nav-link" to="/aboutUs" >
À propos de nous
</Link>
<Link className="nav-link" to="/contactUs" >
Contactez-nous
</Link>
<Link className="nav-link" to="/privacy" >
Vie privée
</Link>
{(user === null || user.LoggedIn === false) &&
<Link className="nav-link" to="/login" >
Connexion
</Link>
}
{(user === null || user.LoggedIn === false) &&
<Link className="nav-link" to="/register">
S'inscrire
</Link>
}
{user !== null && user.LoggedIn &&
<Dropdown className="dropdown-gestion-container">
<Dropdown.Toggle className="dropdown-gestion" >
Bonjour, {user.firstName} {user.lastName}!
</Dropdown.Toggle>
<Dropdown.Menu className="dropdown-gestion-menu">
<Dropdown.Item>
<Link className="nav-link" to="/myaccount" >
Mon Compte
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Link className="nav-link" to="/myaddresses" >
Mes Addresses
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Link className="nav-link" to="/myinvoices" >
Mes Commandes
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Button className="nav-link" onClick={() => logOut()}>
Déconnexion
</Button>
</Dropdown.Item>
{user.role === "Administrateur" &&
<Container>
<Dropdown.Divider />
<Dropdown.ItemText>
Gestion
</Dropdown.ItemText>
<Dropdown.Item>
<Link className="nav-link" to="/inventaire" >
Inventaire
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Link className="nav-link" to="/invoices" >
Commandes
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Link className="nav-link" to="/clients" >
Clients
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Link className="nav-link" to="/addresses" >
Adresses
</Link>
</Dropdown.Item>
</Container>
}
</Dropdown.Menu>
</Dropdown>
}
</Nav>
<Link className="nav-link" to="/formulaire" >
<CartButton />
</Link> </Link>
</Navbar.Collapse> <Navbar.Toggle aria-controls="basic-navbar-nav" />
</Container> <Navbar.Collapse id="basic-navbar-nav">
</Navbar> <Nav className="me-auto">
<Link className="nav-link" to="/" >
Maison
</Link>
<Link className="nav-link" to="/morceaux" >
Morceaux
</Link>
<Link className="nav-link" to="/aboutUs" >
À propos de nous
</Link>
<Link className="nav-link" to="/contactUs" >
Contactez-nous
</Link>
<Link className="nav-link" to="/privacy" >
Vie privée
</Link>
{(user === null || user.LoggedIn === false) &&
<Link className="nav-link" to="/login" >
Connexion
</Link>
}
{(user === null || user.LoggedIn === false) &&
<Link className="nav-link" to="/register">
S'inscrire
</Link>
}
{user !== null && user.LoggedIn &&
<Dropdown className="dropdown-gestion-container">
<Dropdown.Toggle className="dropdown-gestion" >
Bonjour, {user.firstName} {user.lastName}!
</Dropdown.Toggle>
<Dropdown.Menu className="dropdown-gestion-menu">
<Dropdown.Item>
<Link className="nav-link" to="/myaccount" >
Mon Compte
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Link className="nav-link" to="/myaddresses" >
Mes Addresses
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Link className="nav-link" to="/myinvoices" >
Mes Commandes
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Button className="nav-link" onClick={() => logOut()}>
Déconnexion
</Button>
</Dropdown.Item>
{user.role === "Administrateur" &&
<Container>
<Dropdown.Divider />
<Dropdown.ItemText>
Gestion
</Dropdown.ItemText>
<Dropdown.Item>
<Link className="nav-link" to="/inventaire" >
Inventaire
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Link className="nav-link" to="/invoices" >
Commandes
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Link className="nav-link" to="/clients" >
Clients
</Link>
</Dropdown.Item>
<Dropdown.Item>
<Link className="nav-link" to="/addresses" >
Adresses
</Link>
</Dropdown.Item>
</Container>
}
</Dropdown.Menu>
</Dropdown>
}
</Nav>
<CartButton/>
</Navbar.Collapse>
</Container>
</Navbar>
</>
); );
} }

View File

@ -2,13 +2,16 @@ import React from "react";
import { Outlet } from "react-router-dom"; import { Outlet } from "react-router-dom";
import Topbar from "../components/Topbar"; import Topbar from "../components/Topbar";
import Footer from "../components/Footer"; import Footer from "../components/Footer";
import CartProvider from "../components/Cart";
const Layout = () => { const Layout = () => {
return ( return (
<> <>
<Topbar /> <CartProvider>
<Outlet /> <Topbar />
<Footer /> <Outlet />
<Footer />
</CartProvider>
</> </>
); );
}; };

View File

@ -1,8 +1,10 @@
import { useEffect } from "react"; import { useEffect } from "react";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { useState } from "react"; import { useState } from "react";
import { Button } from "react-bootstrap"; import { Button, Form, Row} from 'react-bootstrap';
import QtySelect from "../components/QtySelect"; import QtySelect from "../components/QtySelect";
import { CartContext } from "../components/Cart";
import { useContext } from "react";
const MorceauDetail = () => { const MorceauDetail = () => {
@ -12,11 +14,14 @@ const MorceauDetail = () => {
const [itemQty, setItemQty] = useState(0); const [itemQty, setItemQty] = useState(0);
const [currentQty, setCurrentQty] = useState(1); const [currentQty, setCurrentQty] = useState(1);
const cart = useContext(CartContext);
const inCartQuantity = cart.getProductQuantity(item.id)
const isNoStock = () => { const isNoStock = () => {
return item.status == 1 || item.status == 2 || item.status == 5; return item.status == 1 || item.status == 2 || item.status == 5;
} }
const currentQtyChange = (newQty) =>{ const currentQtyChange = (newQty) => {
setCurrentQty(newQty); setCurrentQty(newQty);
} }
@ -139,14 +144,38 @@ const MorceauDetail = () => {
<p className="detail-description">{item.description}</p> <p className="detail-description">{item.description}</p>
</div> </div>
<div className="detail-container-controls"> <div className="detail-container-controls">
<QtySelect {inCartQuantity > 0 ?
qty={isNoStock() ? 0 : itemQty} <>
onChange={currentQtyChange} <Form as={Row}>
/> <Form.Label sm="6">Dans l'carosse: {inCartQuantity}</Form.Label>
<Button disabled={isNoStock()} className="add-to-cart"> <Button disabled={isNoStock()} className="add-to-cart"
Ajouter au panier onClick={() => cart.addOneToCart(item.id, item.quantity)}
</Button> sm="6">
+
</Button >
<Button disabled={isNoStock()} className="add-to-cart"
onClick={() => cart.removeOneFromCart(item.id)}
sm="6">
-
</Button >
</Form>
<Button disabled={isNoStock()} className="add-to-cart"
onClick={() => cart.deleteFromCart(item.id)} variant="danger"
column="true" sm="6" >
Sortir du carosse
</Button>
</>
:
<>
<QtySelect
qty={isNoStock() ? 0 : itemQty}
onChange={currentQtyChange}
/>
<Button disabled={isNoStock()} className="add-to-cart" onClick={() => cart.addToCart(item, currentQty)}>
Ajouter au carosse
</Button>
</>
}
</div> </div>
</div> </div>
</> </>