From 5ece2baea99fcacbee9a30b70d03ec043c400aa7 Mon Sep 17 00:00:00 2001
From: Victor Turgeon <76506447+Medenos@users.noreply.github.com>
Date: Sun, 27 Nov 2022 12:02:00 -0500
Subject: [PATCH] Front-end pour Stripe
---
.../grosses-mitaines-ui/package-lock.json | 33 +++
.../grosses-mitaines-ui/package.json | 2 +
.../src/components/PaymentForm.js | 105 ++++++++++
.../src/components/StripeContainer.js | 19 ++
.../src/components/TotalProductsPrice.js | 6 -
.../src/pages/ReviewInvoice.js | 188 +++++++-----------
.../src/stylesheets/site.css | 54 ++++-
7 files changed, 284 insertions(+), 123 deletions(-)
create mode 100644 GrossesMitaines/grosses-mitaines-ui/src/components/PaymentForm.js
create mode 100644 GrossesMitaines/grosses-mitaines-ui/src/components/StripeContainer.js
diff --git a/GrossesMitaines/grosses-mitaines-ui/package-lock.json b/GrossesMitaines/grosses-mitaines-ui/package-lock.json
index 8cc8053..83ccff9 100644
--- a/GrossesMitaines/grosses-mitaines-ui/package-lock.json
+++ b/GrossesMitaines/grosses-mitaines-ui/package-lock.json
@@ -11,6 +11,8 @@
"@fortawesome/fontawesome-svg-core": "^6.2.0",
"@fortawesome/free-solid-svg-icons": "^6.2.0",
"@fortawesome/react-fontawesome": "^0.2.0",
+ "@stripe/react-stripe-js": "^1.15.0",
+ "@stripe/stripe-js": "^1.44.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
@@ -3395,6 +3397,24 @@
"@sinonjs/commons": "^1.7.0"
}
},
+ "node_modules/@stripe/react-stripe-js": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-1.15.0.tgz",
+ "integrity": "sha512-nqIOuAbbAN1p/zj2d2vykMzd097ZiHbu0+EpPRcfiswBRQIQIZaPrUwmj6HGD8BRA6Wp89mZen1UJbqtsfc3ZA==",
+ "dependencies": {
+ "prop-types": "^15.7.2"
+ },
+ "peerDependencies": {
+ "@stripe/stripe-js": "^1.44.1",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@stripe/stripe-js": {
+ "version": "1.44.1",
+ "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.44.1.tgz",
+ "integrity": "sha512-DKj3U6tS+sCNsSXsoZbOl5gDrAVD3cAZ9QCiVSykLC3iJo085kkmw/3BAACRH54Bq2bN34yySuH6G1SLh2xHXA=="
+ },
"node_modules/@surma/rollup-plugin-off-main-thread": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
@@ -21007,6 +21027,19 @@
"@sinonjs/commons": "^1.7.0"
}
},
+ "@stripe/react-stripe-js": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/@stripe/react-stripe-js/-/react-stripe-js-1.15.0.tgz",
+ "integrity": "sha512-nqIOuAbbAN1p/zj2d2vykMzd097ZiHbu0+EpPRcfiswBRQIQIZaPrUwmj6HGD8BRA6Wp89mZen1UJbqtsfc3ZA==",
+ "requires": {
+ "prop-types": "^15.7.2"
+ }
+ },
+ "@stripe/stripe-js": {
+ "version": "1.44.1",
+ "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-1.44.1.tgz",
+ "integrity": "sha512-DKj3U6tS+sCNsSXsoZbOl5gDrAVD3cAZ9QCiVSykLC3iJo085kkmw/3BAACRH54Bq2bN34yySuH6G1SLh2xHXA=="
+ },
"@surma/rollup-plugin-off-main-thread": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz",
diff --git a/GrossesMitaines/grosses-mitaines-ui/package.json b/GrossesMitaines/grosses-mitaines-ui/package.json
index 22107dd..484939e 100644
--- a/GrossesMitaines/grosses-mitaines-ui/package.json
+++ b/GrossesMitaines/grosses-mitaines-ui/package.json
@@ -6,6 +6,8 @@
"@fortawesome/fontawesome-svg-core": "^6.2.0",
"@fortawesome/free-solid-svg-icons": "^6.2.0",
"@fortawesome/react-fontawesome": "^0.2.0",
+ "@stripe/react-stripe-js": "^1.15.0",
+ "@stripe/stripe-js": "^1.44.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
diff --git a/GrossesMitaines/grosses-mitaines-ui/src/components/PaymentForm.js b/GrossesMitaines/grosses-mitaines-ui/src/components/PaymentForm.js
new file mode 100644
index 0000000..072ee4f
--- /dev/null
+++ b/GrossesMitaines/grosses-mitaines-ui/src/components/PaymentForm.js
@@ -0,0 +1,105 @@
+import React, { useState } from "react"
+import { CardElement, useElements, useStripe } from "@stripe/react-stripe-js"
+import { Button } from "react-bootstrap"
+
+const CARD_OPTIONS = {
+ iconStyle: "solid",
+ style: {
+ base: {
+ iconColor: "black",
+ color: "white",
+ fontWeight: 500,
+ fontFamily: "Roboto, Open Sans, Segoe UI, sans-serif",
+ fontSize: "16px",
+ fontSmoothing: "antialiased",
+ ":-webkit-autofill": { color: "beige" },
+ "::placeholder": { color: "lightgray" }
+ },
+ invalid: {
+ iconColor: "red",
+ color: "red"
+ }
+ }
+}
+
+
+
+const PaymentForm = ({ cost }) => {
+
+ const [success, setSuccess] = useState(false);
+ const stripe = useStripe();
+ const elements = useElements();
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ const { error, paymentMethod } = await stripe.createPaymentMethod({
+ type: "card",
+ card: elements.getElement(CardElement)
+ })
+
+ if (cost <= 0) {
+ console.log("Coût invalide: ", cost);
+ return;
+ }
+
+ if (!error) {
+ const { id } = paymentMethod;
+
+ const json = JSON.stringify({ amount: cost, stripeId: id });
+
+
+ fetch(`https://localhost:7292/api/Payment`, {
+ method: 'POST',
+ credentials: 'include',
+ mode: 'cors',
+ headers: {
+ 'Accept': 'application/json',
+ 'Content-Type': 'application/json'
+ },
+ body: json
+ }).then((response) => {
+ if (response.ok) {
+ console.log("Successful payment");
+ setSuccess(true);
+ }
+ else {
+ console.log(response);
+ }
+ }).catch((error) => {
+ console.log("Error: ", error);
+ })
+
+ }
+ else {
+ console.log(error.message);
+ }
+ }
+
+
+
+ return (
+ <>
+ {!success ?
+
+ :
+
+
+ L'achat s'est déroulé avec succès
+
+
+ }
+ >
+ )
+
+}
+
+export default PaymentForm;
\ No newline at end of file
diff --git a/GrossesMitaines/grosses-mitaines-ui/src/components/StripeContainer.js b/GrossesMitaines/grosses-mitaines-ui/src/components/StripeContainer.js
new file mode 100644
index 0000000..c5d2b93
--- /dev/null
+++ b/GrossesMitaines/grosses-mitaines-ui/src/components/StripeContainer.js
@@ -0,0 +1,19 @@
+import React from "react";
+import { loadStripe } from "@stripe/stripe-js"
+import { Elements } from "@stripe/react-stripe-js"
+import PaymentForm from "./PaymentForm";
+
+const PUBLIC_KEY = "pk_test_51M8mzOEerenEZcQIUmJIrmsaZeeNlOil2G1JcMvvO68w50MJr8rDwUjVO44a8dDhSlsRH4GdzH9rDqtkg4Rtbzco00NqkHdn3H";
+
+const stripeTestPromise = loadStripe(PUBLIC_KEY);
+
+const StripeContainer = ({cost}) => {
+ return (
+
+
+
+ )
+}
+
+
+export default StripeContainer;
\ No newline at end of file
diff --git a/GrossesMitaines/grosses-mitaines-ui/src/components/TotalProductsPrice.js b/GrossesMitaines/grosses-mitaines-ui/src/components/TotalProductsPrice.js
index 400de19..75e3052 100644
--- a/GrossesMitaines/grosses-mitaines-ui/src/components/TotalProductsPrice.js
+++ b/GrossesMitaines/grosses-mitaines-ui/src/components/TotalProductsPrice.js
@@ -5,9 +5,6 @@ export function TotalProductsPrice(/*{ products }*/) {
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*/) => {
@@ -19,9 +16,6 @@ export function TotalProductsPrice(/*{ products }*/) {
var tvq = 0;
var total;
- // prods.map((p) => {
- // price += productTotal(p);
- // });
tps = price * (tpsRate / 100);
tvq = price * (tvqRate / 100);
diff --git a/GrossesMitaines/grosses-mitaines-ui/src/pages/ReviewInvoice.js b/GrossesMitaines/grosses-mitaines-ui/src/pages/ReviewInvoice.js
index 7ad297e..255f975 100644
--- a/GrossesMitaines/grosses-mitaines-ui/src/pages/ReviewInvoice.js
+++ b/GrossesMitaines/grosses-mitaines-ui/src/pages/ReviewInvoice.js
@@ -7,6 +7,7 @@ import { useNavigate } from "react-router-dom";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import { CartContext } from "../components/Cart";
+import StripeContainer from "../components/StripeContainer"
const ReviewInvoice = () => {
@@ -28,26 +29,38 @@ const ReviewInvoice = () => {
province: "",
country: "",
postalCode: "",
- prodQuant: []
+ prodQuant: [],
});
+ const [total, setTotal] = useState(-1);
+
useEffect(() => {
const cookies = new Cookies();
const thisInvoice = cookies.get('invoice');
if (thisInvoice != null) {
var dic = {};
if (cart.items.length > 0) {
- cart.items.forEach((item) =>
- dic[item.id] = item.quantity
+ cart.items.forEach((item) => {
+ dic[item.id] = item.quantity;
+ }
)
}
- async function test() {
+ const tpsRate = 5;
+ const tvqRate = 9.975;
- const json = JSON.stringify(dic);
- console.log(await json);
- }
- test();
+ var price = cart.getTotalCost();
+ var tps = 0;
+ var tvq = 0;
+ var totalCost;
+
+ tps = price * (tpsRate / 100);
+ tvq = price * (tvqRate / 100);
+ totalCost = price + tps + tvq;
+ totalCost = totalCost * 100;
+ totalCost = totalCost.toFixed(0);
+
+ setTotal(totalCost);
setThisInvoice((e) => {
@@ -73,65 +86,12 @@ const ReviewInvoice = () => {
}
}, [cart]);
-
- // const handleAddOne = (id) => {
-
- // var modifiedPQ = prodQuant.filter((pq) => pq.id == id);
- // var modifiedProd = prodQuant.filter((pq) => pq.product.id == id);
-
- // 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 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 handleConfirmer = async () => {
-
- // var dic = {};
- // if (cart.items.length > 0) {
- // cart.items.forEach((item) =>
- // dic[item.id] = item.quantity
- // )
- // }
- // const json = JSON.stringify(dic);
- // console.log(await json);
-
- // const json1 = JSON.stringify(cart.items);
- // console.log(await json1);
-
- //setThisInvoice({ ...thisInvoice, prodQuant: dic });
-
const json = JSON.stringify(thisInvoice);
- console.log(json);
const response = await fetch(`https://localhost:7292/api/Invoice`, {
method: 'POST',
@@ -167,69 +127,73 @@ const ReviewInvoice = () => {
}
return (
-
- Veuillez confirmer les informations ci-dessous!
-
+ <>
+
+ Veuillez confirmer les informations ci-dessous!
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {thisInvoice.appartment != null ?
+
-
+
+
+
+
+
+
+
+
+
+
- : null
- }
-
-
-
-
+
+
+
+
+
+ {thisInvoice.appartment != null ?
+
+
+
+ : null
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+ {/*
-
-
-
-
-
-
+ */}
+
+
+
+
+
+
+ >
+
);
}
diff --git a/GrossesMitaines/grosses-mitaines-ui/src/stylesheets/site.css b/GrossesMitaines/grosses-mitaines-ui/src/stylesheets/site.css
index b1504b5..83721da 100644
--- a/GrossesMitaines/grosses-mitaines-ui/src/stylesheets/site.css
+++ b/GrossesMitaines/grosses-mitaines-ui/src/stylesheets/site.css
@@ -20,6 +20,44 @@ a {
text-decoration: none;
}
+.Payment-btn-container {
+ display: flex;
+}
+
+.Payment-btn {
+ margin: auto;
+ width: 20%;
+}
+
+.FormGroup {
+ margin: 20px 15px 20px;
+ padding: 0;
+ border-style: none;
+ color: beige !important;
+ background-color: purple;
+ will-change: opacity, transform;
+ border-radius: 4px;
+}
+
+.FormRow {
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-align: center;
+ align-items: center;
+ margin-left: 15px;
+}
+
+.StripeElement--webkit-autofill {
+ background: transparent !important;
+}
+
+.StripeElement {
+ width: 100%;
+ padding: 11px 15px 11px 0;
+}
+
+
+
.Contact {
background-color: beige;
text-align: center;
@@ -770,7 +808,7 @@ a {
.invoice-item-products h3 {
text-align: center !important;
- color:purple;
+ color: purple;
font-weight: bold;
background-color: beige;
width: auto;
@@ -831,12 +869,12 @@ a {
}
.invoice-buttons {
- display:flex;
- margin:5%;
+ display: flex;
+ margin: 5%;
}
.invoice-button {
- margin:2%;
+ margin: 2%;
width: 100%;
align-content: center;
}
@@ -851,7 +889,7 @@ a {
.confirmer-infos {
text-align: center;
- color:white;
+ color: white;
font-weight: bold;
}
@@ -861,6 +899,12 @@ a {
/* -------------------------------------------------------- */
@media(max-width:900px) {
+ .Payment-btn {
+ margin-top: 10px;
+ height: 70px;
+ width: 80%;
+ }
+
.invoice-item-container {
display: block;
}