react-version #1
@ -84,13 +84,18 @@ const InvoiceItem = ({ invoice }) => {
|
||||
|
||||
<div className="invoice-item-container">
|
||||
<div className="invoice-item-info">
|
||||
{invoice.status != null ?
|
||||
<div>
|
||||
#{invoice.id} ({getStatus(invoice.status)})
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
<div className="invoice-item-expedition">
|
||||
<b>Adresse d'expédition:</b><br />
|
||||
{invoice.firstName} {invoice.lastName}<br />
|
||||
{invoice.shippingAddress.civicNumber} {invoice.shippingAddress.street} <br />
|
||||
{invoice.shippingAddress.appartment != null ? <>App: {invoice.shippingAddress.appartment} <br /></> : null}
|
||||
{invoice.shippingAddress.city}, {invoice.shippingAddress.province} {invoice.shippingAddress.postalCode}<br />
|
||||
{invoice.shippingAddress.country}<br />
|
||||
</div>
|
||||
|
@ -1,8 +1,13 @@
|
||||
const ReviewProdItem = ({ pq, onAddOne, onRemoveOne, onRemoveProduct }) => {
|
||||
return (
|
||||
<div className="review-prod-item-container">
|
||||
export function ReviewProdItem({ pq, /*onAddOne, onRemoveOne, onRemoveProduct*/ }) {
|
||||
|
||||
const productTotal = (p) => {
|
||||
return (p.quantity * (p.status == 3 || p.status == 4 ? p.promoPrice : p.price))
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
<div className="invoice-item-product" key={pq.id}>{pq.quantity} x {pq.title} <br /> <b>{productTotal(pq).toFixed(2)} $ CA</b></div>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,25 @@
|
||||
import ReviewProdItem from "./ReviewProdItem";
|
||||
import { CartContext } from './Cart';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export function ReviewProdList(/*{ products , onAddOne, onRemoveOne, onRemoveProduct }*/) {
|
||||
const cart = useContext(CartContext);
|
||||
|
||||
const ReviewProdList = ({ products, onAddOne, onRemoveOne, onRemoveProduct }) => {
|
||||
return (
|
||||
<div>
|
||||
{products.map((p) => (
|
||||
<div className="invoice-item-products">
|
||||
<h3>Produits</h3>
|
||||
<div className="invoice-item-product-list">
|
||||
{cart.items.map((p) => (
|
||||
<ReviewProdItem
|
||||
key={p.product.id}
|
||||
key={p.id}
|
||||
pq={p}
|
||||
onAddOne={onAddOne}
|
||||
onRemoveOne={onRemoveOne}
|
||||
onRemoveProduct={onRemoveProduct}
|
||||
//onAddOne={onAddOne}
|
||||
//onRemoveOne={onRemoveOne}
|
||||
//onRemoveProduct={onRemoveProduct}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
|
@ -1,38 +1,45 @@
|
||||
const TotalProductsPrice = ({ products }) => {
|
||||
import { CartContext } from './Cart';
|
||||
import { useContext } from 'react';
|
||||
|
||||
const productTotal = (p) => {
|
||||
return (p.quantity * (p.product.status == 3 || p.product.status == 4 ? p.product.promoPrice : p.product.price))
|
||||
}
|
||||
export function TotalProductsPrice(/*{ products }*/) {
|
||||
|
||||
const getPriceHTML = (prods) => {
|
||||
const cart = useContext(CartContext);
|
||||
|
||||
// const productTotal = (p) => {
|
||||
// return (p.quantity * (p.product.status == 3 || p.product.status == 4 ? p.product.promoPrice : p.product.price))
|
||||
// }
|
||||
|
||||
const getPriceHTML = (/*prods*/) => {
|
||||
|
||||
const tpsRate = 5;
|
||||
const tvqRate = 9.975;
|
||||
|
||||
var price = 0;
|
||||
var price = cart.getTotalCost();
|
||||
var tps = 0;
|
||||
var tvq = 0;
|
||||
var total;
|
||||
|
||||
prods.map((p) => {
|
||||
price += productTotal(p);
|
||||
});
|
||||
// prods.map((p) => {
|
||||
// price += productTotal(p);
|
||||
// });
|
||||
|
||||
tps = price * (tpsRate / 100);
|
||||
tvq = price * (tvqRate / 100);
|
||||
total = price + tps + tvq;
|
||||
|
||||
return (
|
||||
<div className="invoice-item-price">
|
||||
Sous-total = {price.toFixed(2)} $ CA<br />
|
||||
+ TPS ({tpsRate}%) = {tps.toFixed(2)} $ CA<br />
|
||||
+ TVQ ({tvqRate}%) = {tvq.toFixed(2)} $ CA<br />
|
||||
<b>Total = {(price + tps + tvq).toFixed(2)} $ CA</b>
|
||||
<b>Total = {total.toFixed(2)} $ CA</b>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{getPriceHTML(products)}
|
||||
{getPriceHTML(/*products*/)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,55 +1,69 @@
|
||||
import { useState } from "react";
|
||||
import { useEffect } from "react";
|
||||
import { useState, useContext, useEffect } from "react";
|
||||
import Cookies from "universal-cookie";
|
||||
import ReviewProdList from "../components/ReviewProdList";
|
||||
import TotalProductsPrice from "../components/TotalProductsPrice";
|
||||
import { Row, Col, Button } from "react-bootstrap";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import Swal from "sweetalert2";
|
||||
import withReactContent from "sweetalert2-react-content";
|
||||
import CartProvider from "../components/Cart";
|
||||
|
||||
const ReviewInvoice = () => {
|
||||
|
||||
const cookies = new Cookies();
|
||||
const navigate = useNavigate();
|
||||
const mySwal = withReactContent(Swal);
|
||||
|
||||
const [products, setProducts] = useState([]);
|
||||
const cart = useContext(CartProvider);
|
||||
|
||||
const [firstName, setFirstName] = useState("");
|
||||
const [lastName, setLastName] = useState("");
|
||||
const [phoneNumber, setPhoneNumber] = useState("");
|
||||
const [emailAddress, setEmailAddress] = useState("");
|
||||
const [civicNumber, setCivicNumber] = useState(0);
|
||||
const [appartment, setAppartment] = useState("");
|
||||
const [street, setStreet] = useState("");
|
||||
const [city, setCity] = useState("");
|
||||
const [province, setProvince] = useState("");
|
||||
const [country, setCountry] = useState("");
|
||||
const [postalCode, setPostalCode] = useState("");
|
||||
const [prodQuant, setProdQuant] = useState({});
|
||||
//const [products, setProducts] = useState([]);
|
||||
|
||||
const [thisInvoice, setThisInvoice] = useState({
|
||||
firstName: "",
|
||||
lastName: "",
|
||||
phoneNumber: "",
|
||||
emailAddress: "",
|
||||
civicNumber: "",
|
||||
appartment: "",
|
||||
street: "",
|
||||
city: "",
|
||||
province: "",
|
||||
country: "",
|
||||
postalCode: "",
|
||||
prodQuant: []
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const thisInvoice = cookies.get('invoice');
|
||||
if (thisInvoice != null) {
|
||||
setFirstName(thisInvoice.firstName);
|
||||
setLastName(thisInvoice.lastName);
|
||||
setPhoneNumber(thisInvoice.phoneNumber);
|
||||
setEmailAddress(thisInvoice.emailAddress);
|
||||
setCivicNumber(thisInvoice.civicNumber);
|
||||
setAppartment(thisInvoice.appartment);
|
||||
setStreet(thisInvoice.street);
|
||||
setCity(thisInvoice.city);
|
||||
setProvince(thisInvoice.province);
|
||||
setCountry(thisInvoice.country);
|
||||
setPostalCode(thisInvoice.postalCode);
|
||||
setProdQuant(thisInvoice.prodQuant);
|
||||
|
||||
var prods = [];
|
||||
|
||||
Object.keys(thisInvoice.prodQuant).map((k) => {
|
||||
fetch(`https://localhost:7292/api/Product?id=${k}`)
|
||||
.then(async (response) => {
|
||||
prods.push({ product: await response.json(), quantity: thisInvoice.prodQuant[k] });
|
||||
}).then(() => {
|
||||
setProducts(prods.sort((a, b) => a.product.id - b.product.id));
|
||||
setThisInvoice((e) => {
|
||||
return {
|
||||
...e,
|
||||
firstName: thisInvoice.firstName,
|
||||
lastName: thisInvoice.lastName,
|
||||
phoneNumber: thisInvoice.phoneNumber,
|
||||
emailAddress: thisInvoice.emailAddress,
|
||||
civicNumber: thisInvoice.civicNumber,
|
||||
appartment: thisInvoice.appartment,
|
||||
street: thisInvoice.street,
|
||||
city: thisInvoice.city,
|
||||
province: thisInvoice.province,
|
||||
country: thisInvoice.country,
|
||||
postalCode: thisInvoice.postalCode,
|
||||
prodQuant: thisInvoice.prodQuant
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
//var prods = [];
|
||||
// Object.keys(thisInvoice.prodQuant).map((k) => {
|
||||
// fetch(`https://localhost:7292/api/Product?id=${k}`)
|
||||
// .then(async (response) => {
|
||||
// prods.push({ product: await response.json(), quantity: thisInvoice.prodQuant[k] });
|
||||
// }).then(() => {
|
||||
// setProducts(prods.sort((a, b) => a.product.id - b.product.id));
|
||||
// })
|
||||
// });
|
||||
}
|
||||
else {
|
||||
console.log("No invoice to review!");
|
||||
@ -57,109 +71,161 @@ const ReviewInvoice = () => {
|
||||
}, []);
|
||||
|
||||
|
||||
const handleAddOne = (id) => {
|
||||
// const handleAddOne = (id) => {
|
||||
|
||||
var modifiedPQ = prodQuant.filter((pq) => pq.id == id);
|
||||
var modifiedProd = prodQuant.filter((pq) => pq.product.id == id);
|
||||
// var modifiedPQ = prodQuant.filter((pq) => pq.id == id);
|
||||
// var modifiedProd = prodQuant.filter((pq) => pq.product.id == id);
|
||||
|
||||
modifiedPQ.quantity++;
|
||||
modifiedProd.quantity = modifiedPQ.quantity;
|
||||
// modifiedPQ.quantity++;
|
||||
// modifiedProd.quantity = modifiedPQ.quantity;
|
||||
|
||||
setProdQuant([...(prodQuant.filter((pq) => pq.id !== id)), { ...modifiedPQ }].sort((a, b) => a.id - b.id));
|
||||
setProducts([...(products.filter((pq) => pq.product.id !== id)), { ...modifiedProd }].sort((a, b) => a.product.id - b.product.id));
|
||||
// setProdQuant([...(prodQuant.filter((pq) => pq.id !== id)), { ...modifiedPQ }].sort((a, b) => a.id - b.id));
|
||||
// setProducts([...(products.filter((pq) => pq.product.id !== id)), { ...modifiedProd }].sort((a, b) => a.product.id - b.product.id));
|
||||
|
||||
|
||||
// }
|
||||
|
||||
// const handleRemoveOne = (id) => {
|
||||
// var modifiedPQ = prodQuant.filter((pq) => pq.id == id);
|
||||
// var modifiedProd = prodQuant.filter((pq) => pq.product.id == id);
|
||||
|
||||
// if (modifiedPQ.quantity - 1 <= 0) {
|
||||
// setProdQuant([...(prodQuant.filter((pq) => pq.id !== id))].sort((a, b) => a.id - b.id));
|
||||
// setProducts([...(products.filter((pq) => pq.product.id !== id))].sort((a, b) => a.product.id - b.product.id));
|
||||
// }
|
||||
// else {
|
||||
// modifiedPQ.quantity--;
|
||||
// modifiedProd.quantity = modifiedPQ.quantity;
|
||||
// setProdQuant([...(prodQuant.filter((pq) => pq.id !== id)), { ...modifiedPQ }].sort((a, b) => a.id - b.id));
|
||||
// setProducts([...(products.filter((pq) => pq.product.id !== id)), { ...modifiedProd }].sort((a, b) => a.product.id - b.product.id));
|
||||
// }
|
||||
// }
|
||||
|
||||
// const handleRemoveProduct = (id) => {
|
||||
|
||||
// setProdQuant([...(prodQuant.filter((pq) => pq.id !== id))].sort((a, b) => a.id - b.id));
|
||||
// setProducts([...(products.filter((pq) => pq.product.id !== id))].sort((a, b) => a.product.id - b.product.id));
|
||||
// }
|
||||
|
||||
const handleModify = () => {
|
||||
navigate("/formulaire")
|
||||
}
|
||||
|
||||
const handleRemoveOne = (id) => {
|
||||
var modifiedPQ = prodQuant.filter((pq) => pq.id == id);
|
||||
var modifiedProd = prodQuant.filter((pq) => pq.product.id == id);
|
||||
const handleConfirmer = async () => {
|
||||
console.log(thisInvoice);
|
||||
|
||||
if (modifiedPQ.quantity - 1 <= 0) {
|
||||
setProdQuant([...(prodQuant.filter((pq) => pq.id !== id))].sort((a, b) => a.id - b.id));
|
||||
setProducts([...(products.filter((pq) => pq.product.id !== id))].sort((a, b) => a.product.id - b.product.id));
|
||||
}
|
||||
else {
|
||||
modifiedPQ.quantity--;
|
||||
modifiedProd.quantity = modifiedPQ.quantity;
|
||||
setProdQuant([...(prodQuant.filter((pq) => pq.id !== id)), { ...modifiedPQ }].sort((a, b) => a.id - b.id));
|
||||
setProducts([...(products.filter((pq) => pq.product.id !== id)), { ...modifiedProd }].sort((a, b) => a.product.id - b.product.id));
|
||||
}
|
||||
}
|
||||
// let formData = new FormData();
|
||||
// Object.keys(thisInvoice).map((k) => {
|
||||
// formData.set(k, thisInvoice[k]);
|
||||
// });
|
||||
|
||||
const handleRemoveProduct = (id) => {
|
||||
// console.log(formData);
|
||||
const json = JSON.stringify(thisInvoice);
|
||||
|
||||
setProdQuant([...(prodQuant.filter((pq) => pq.id !== id))].sort((a, b) => a.id - b.id));
|
||||
setProducts([...(products.filter((pq) => pq.product.id !== id))].sort((a, b) => a.product.id - b.product.id));
|
||||
const response = await fetch(`https://localhost:7292/api/Invoice`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'accept': 'application/json',
|
||||
},
|
||||
body: json
|
||||
})
|
||||
console.log(json);
|
||||
|
||||
if (response.ok) {
|
||||
mySwal.fire({
|
||||
title: 'Commande envoyée avec succès!',
|
||||
timer: 2000,
|
||||
icon: "success"
|
||||
})
|
||||
cart.items = [];
|
||||
navigate('./myinvoices');
|
||||
}
|
||||
else
|
||||
console.log("Erreur de creation la commande #" + thisInvoice.id);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className="review-invoice-container">
|
||||
<Row>
|
||||
<h2 className="confirmer-infos">Veuillez confirmer les informations ci-dessous!</h2>
|
||||
<Col xs={6} md={4}>
|
||||
|
||||
<div className="review-invoice-info">
|
||||
<div>
|
||||
<label>Prénom: </label>
|
||||
<input value={firstName} onChange={(e) => setFirstName(e.target.value)} />
|
||||
<label className="bold">Prénom: </label> <label>{thisInvoice.firstName}</label>
|
||||
{/* <input value={firstName} onChange={(e) => setFirstName(e.target.value)} /> */}
|
||||
</div>
|
||||
<div>
|
||||
<label>Nom: </label>
|
||||
<input value={lastName} onChange={(e) => setLastName(e.target.value)} />
|
||||
<label className="bold">Nom: </label> <label>{thisInvoice.lastName}</label>
|
||||
{/* <input value={lastName} onChange={(e) => setLastName(e.target.value)} /> */}
|
||||
</div>
|
||||
<div>
|
||||
<label>Téléphone: </label>
|
||||
<input value={phoneNumber} onChange={(e) => setPhoneNumber(e.target.value)} />
|
||||
<label className="bold">Téléphone: </label> <label>{thisInvoice.phoneNumber}</label>
|
||||
{/* <input value={phoneNumber} onChange={(e) => setPhoneNumber(e.target.value)} /> */}
|
||||
</div>
|
||||
<div>
|
||||
<label>Courriel: </label>
|
||||
<input value={emailAddress} onChange={(e) => setEmailAddress(e.target.value)} />
|
||||
<label className="bold">Courriel: </label> <label>{thisInvoice.emailAddress}</label>
|
||||
{/* <input value={emailAddress} onChange={(e) => setEmailAddress(e.target.value)} /> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="review-invoice-address-container">
|
||||
<div>
|
||||
<label>Numéro civique: </label>
|
||||
<input type="number" min="0" value={civicNumber} onChange={(e) => setCivicNumber(e.target.value)} />
|
||||
<label className="bold">Numéro civique: </label> <label>{thisInvoice.civicNumber}</label>
|
||||
{/* <input type="number" min="0" value={civicNumber} onChange={(e) => setCivicNumber(e.target.value)} /> */}
|
||||
</div>
|
||||
{thisInvoice.appartment != null ?
|
||||
<div>
|
||||
<label className="bold">Numéro d'appartement: </label> <label>{thisInvoice.appartment}</label>
|
||||
{/* <input value={appartment} onChange={(e) => setAppartment(e.target.value)} /> */}
|
||||
</div>
|
||||
: null
|
||||
}
|
||||
<div>
|
||||
<label className="bold">Rue: </label> <label>{thisInvoice.street}</label>
|
||||
{/* <input value={street} onChange={(e) => setStreet(e.target.value)} /> */}
|
||||
</div>
|
||||
<div>
|
||||
<label>Numéro d'appartement: </label>
|
||||
<input value={appartment} onChange={(e) => setAppartment(e.target.value)} />
|
||||
<label className="bold">Ville: </label> <label>{thisInvoice.city}</label>
|
||||
{/* <input value={city} onChange={(e) => setCity(e.target.value)} /> */}
|
||||
</div>
|
||||
<div>
|
||||
<label>Rue: </label>
|
||||
<input value={street} onChange={(e) => setStreet(e.target.value)} />
|
||||
<label className="bold">Province (abréviation): </label> <label>{thisInvoice.province}</label>
|
||||
{/* <input value={province} onChange={(e) => setProvince(e.target.value)} /> */}
|
||||
</div>
|
||||
<div>
|
||||
<label>Ville: </label>
|
||||
<input value={city} onChange={(e) => setCity(e.target.value)} />
|
||||
<label className="bold">Pays: </label> <label>{thisInvoice.country}</label>
|
||||
{/* <input value={country} onChange={(e) => setCountry(e.target.value)} /> */}
|
||||
</div>
|
||||
<div>
|
||||
<label>Province (abréviation): </label>
|
||||
<input value={province} onChange={(e) => setProvince(e.target.value)} />
|
||||
</div>
|
||||
<div>
|
||||
<label>Pays: </label>
|
||||
<input value={country} onChange={(e) => setCountry(e.target.value)} />
|
||||
</div>
|
||||
<div>
|
||||
<label>Code postal: </label>
|
||||
<input value={postalCode} onChange={(e) => setPostalCode(e.target.value)} />
|
||||
<label className="bold">Code postal: </label> <label>{thisInvoice.postalCode}</label>
|
||||
{/* <input value={postalCode} onChange={(e) => setPostalCode(e.target.value)} /> */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ReviewProdList
|
||||
products={products}
|
||||
onAddOne={handleAddOne}
|
||||
onRemoveOne={handleRemoveOne}
|
||||
onRemoveProduct={handleRemoveProduct}
|
||||
/>
|
||||
<div className="review-invoice-info">
|
||||
<TotalProductsPrice
|
||||
products={products}
|
||||
//products={cart.items}
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<Row className="invoice-buttons">
|
||||
<Col xs={6}>
|
||||
<Button className="invoice-button confirmer" onClick={handleConfirmer}>Confirmer</Button>
|
||||
</Col>
|
||||
<Col xs={6}>
|
||||
<Button className="invoice-button modifier" onClick={handleModify}>Modifier</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col xs={6} md={8}>
|
||||
<ReviewProdList
|
||||
//products={cart.items}
|
||||
//onAddOne={handleAddOne}
|
||||
//onRemoveOne={handleRemoveOne}
|
||||
//onRemoveProduct={handleRemoveProduct}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -762,13 +762,30 @@ a {
|
||||
|
||||
.invoice-item-products {
|
||||
color: white;
|
||||
width: 40%;
|
||||
width: 75%;
|
||||
margin: auto;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.invoice-item-products h3 {
|
||||
text-align: center !important;
|
||||
color:purple;
|
||||
font-weight: bold;
|
||||
background-color: beige;
|
||||
width: auto;
|
||||
border: 3px solid purple;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.invoice-item-products li {
|
||||
padding: 5px;
|
||||
/* border: white 1px solid; */
|
||||
background-color: black;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.invoice-item-product {
|
||||
padding: 5px;
|
||||
background-color: black;
|
||||
border-radius: 3px;
|
||||
margin-bottom: 2px;
|
||||
@ -787,10 +804,53 @@ a {
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.review-invoice-address-container{
|
||||
border:black 1px solid;
|
||||
.review-invoice-info {
|
||||
border: black 5px solid;
|
||||
margin: 5px;
|
||||
padding: 2%;
|
||||
border-radius: 10px;
|
||||
background-color: purple;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.review-invoice-address-container {
|
||||
border: purple 5px solid;
|
||||
margin: 5px;
|
||||
padding: 2%;
|
||||
border-radius: 10px;
|
||||
background-color: beige;
|
||||
}
|
||||
|
||||
.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.invoice-buttons {
|
||||
display:flex;
|
||||
margin:5%;
|
||||
}
|
||||
|
||||
.invoice-button {
|
||||
margin:2%;
|
||||
width: 100%;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.confirmer {
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.modifier {
|
||||
background-color: firebrick;
|
||||
}
|
||||
|
||||
.confirmer-infos {
|
||||
text-align: center;
|
||||
color:white;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------- */
|
||||
/* specification pour les moyennes écrans
|
||||
/* -------------------------------------------------------- */
|
||||
|
Loading…
Reference in New Issue
Block a user