From d0963bc42264e30c341a3dd64cf3bb7560ba44f0 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Thu, 26 Oct 2023 00:29:21 +0530 Subject: [PATCH 01/33] Updated common module. --- payments/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/payments/package-lock.json b/payments/package-lock.json index 8a16caf..16e2b08 100644 --- a/payments/package-lock.json +++ b/payments/package-lock.json @@ -1369,9 +1369,9 @@ "dev": true }, "node_modules/@bookmyseat/common": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@bookmyseat/common/-/common-1.0.11.tgz", - "integrity": "sha512-1DI2vS8fTTnsvsl5N1IfMvGdVJs5WGEVNCTuyzISaf3B1UoE/qLHKrvCrallawXk4bTOLyr6MTo1DcWyS0xYfQ==", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@bookmyseat/common/-/common-1.0.12.tgz", + "integrity": "sha512-HuKJrOIAQagz/ax8ZeV5og7ms8qhTUH5jXVW9B29e7h3izP91DUSmh9KBrxNQpTyI93RUgh6DhZ31InuIREViw==", "dependencies": { "@types/cookie-session": "^2.0.45", "@types/express": "^4.17.18", From 146fd8ef7a194e840af47bdb909801546d837f42 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Thu, 26 Oct 2023 00:37:49 +0530 Subject: [PATCH 02/33] Updated common module. --- tickets/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tickets/package-lock.json b/tickets/package-lock.json index 2bf402a..400690f 100644 --- a/tickets/package-lock.json +++ b/tickets/package-lock.json @@ -1368,9 +1368,9 @@ "dev": true }, "node_modules/@bookmyseat/common": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/@bookmyseat/common/-/common-1.0.10.tgz", - "integrity": "sha512-+uQeZIU6BcJ5YDOCiWoVY2xB2Qc0oa3EZgHRSZt9guUHq0oSE7nKA3OX/iE+R9vee7ffOvQUWWjNfSTuRTwYlA==", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@bookmyseat/common/-/common-1.0.12.tgz", + "integrity": "sha512-HuKJrOIAQagz/ax8ZeV5og7ms8qhTUH5jXVW9B29e7h3izP91DUSmh9KBrxNQpTyI93RUgh6DhZ31InuIREViw==", "dependencies": { "@types/cookie-session": "^2.0.45", "@types/express": "^4.17.18", From 0bc0911352264f4431fd9cb625453df25a740c9e Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Thu, 26 Oct 2023 00:53:06 +0530 Subject: [PATCH 03/33] Added a new publisher. --- .../src/events/publishers/payment-created-publisher.ts | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 payments/src/events/publishers/payment-created-publisher.ts diff --git a/payments/src/events/publishers/payment-created-publisher.ts b/payments/src/events/publishers/payment-created-publisher.ts new file mode 100644 index 0000000..2753caf --- /dev/null +++ b/payments/src/events/publishers/payment-created-publisher.ts @@ -0,0 +1,9 @@ +import { + Publisher, + EventSubjects, + PaymentCreatedEvent, +} from "@bookmyseat/common"; + +export class PaymentCreatedPublisher extends Publisher { + readonly subject = EventSubjects.PaymentCreated; +} From 4aa5391ee1d4bec6d2317fbb26d94ab21572debf Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Thu, 26 Oct 2023 01:03:42 +0530 Subject: [PATCH 04/33] Configured publisher to publish payment created event and respond back with a payment ID. --- payments/src/routes/new.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/payments/src/routes/new.ts b/payments/src/routes/new.ts index 7fa2428..f1239bb 100644 --- a/payments/src/routes/new.ts +++ b/payments/src/routes/new.ts @@ -11,6 +11,8 @@ import { import { Order } from "../models/order"; import { stripe } from "../stripe-config"; import { Payment } from "../models/payment"; +import { PaymentCreatedPublisher } from "../events/publishers/payment-created-publisher"; +import { natsClient } from "../nats-client"; const router = express.Router(); @@ -53,7 +55,17 @@ router.post( await paymentRecord.save(); - res.status(201).send({ chargeCreation: "Success" }); + // Publish Event Indicating the payment success + await new PaymentCreatedPublisher(natsClient.client).publish({ + id: paymentRecord.id, + version: paymentRecord.version, + orderId: paymentRecord.orderId, + stripeId: paymentRecord.stripeId, + }); + + res + .status(201) + .send({ chargeCreation: "Success", paymentId: paymentRecord.id }); } ); From 308f92b971768d16ea4d6294a06a8dc29f026487 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 12:40:21 +0530 Subject: [PATCH 05/33] Added a additional props to pass down current user to all child component - so that child component can avoid making seperate network call for current user fetching. --- client/pages/_app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pages/_app.js b/client/pages/_app.js index 187ad3d..7eb87b5 100644 --- a/client/pages/_app.js +++ b/client/pages/_app.js @@ -7,7 +7,7 @@ const AppComponent = ({ Component, pageProps, currentUser }) => { return (
- +
); }; From 8ee9d2262e92cea96e8d7f8c791357f6313aebc2 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 12:41:02 +0530 Subject: [PATCH 06/33] Modified to remove fetching current user. --- client/pages/index.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/client/pages/index.js b/client/pages/index.js index 6163abf..1db6e52 100644 --- a/client/pages/index.js +++ b/client/pages/index.js @@ -1,11 +1,9 @@ -import buildClient from "../api/build-client"; - const IndexPage = ({ currentUser }) => { if (!currentUser) { return ( <>

Landing Page

-
+
Signed Out
); @@ -21,14 +19,7 @@ const IndexPage = ({ currentUser }) => { }; IndexPage.getInitialProps = async (context) => { - try { - const client = buildClient(context); - const response = await client.get("/api/users/currentuser"); - return response.data; - } catch (err) { - console.error("Error in making request to get current user:", err.message); - return { currentUser: null }; - } + return {}; }; export default IndexPage; From 57f8af3702071c3cf04f9708cec95b1a5ff6e061 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 12:47:55 +0530 Subject: [PATCH 07/33] Added two new arguments to child components getInitial props function to pass axios client and currentUser. --- client/pages/_app.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/pages/_app.js b/client/pages/_app.js index 7eb87b5..69d040c 100644 --- a/client/pages/_app.js +++ b/client/pages/_app.js @@ -20,7 +20,11 @@ AppComponent.getInitialProps = async (appContext) => { // If the child component has getInitialProps method, then execute it manually from here. let pageProps = {}; if (appContext.Component.getInitialProps) { - pageProps = await appContext.Component.getInitialProps(appContext.ctx); + pageProps = await appContext.Component.getInitialProps( + appContext.ctx, + client, + data.currentUser + ); } return { pageProps, currentUser: response.data.currentUser }; From 15a7fead9b2b4706e7e7896006d9ac3ea6308e26 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 12:48:44 +0530 Subject: [PATCH 08/33] Modified to receive client and current user. --- client/pages/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pages/index.js b/client/pages/index.js index 1db6e52..ab924c5 100644 --- a/client/pages/index.js +++ b/client/pages/index.js @@ -18,7 +18,7 @@ const IndexPage = ({ currentUser }) => { ); }; -IndexPage.getInitialProps = async (context) => { +IndexPage.getInitialProps = async (context, client, currentUser) => { return {}; }; From aadad8764efc4dd38039c9c04185225b19d7c7d8 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 14:57:08 +0530 Subject: [PATCH 09/33] Created a container div to align the component contents. --- client/pages/_app.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/pages/_app.js b/client/pages/_app.js index 69d040c..ad0dd0c 100644 --- a/client/pages/_app.js +++ b/client/pages/_app.js @@ -7,7 +7,9 @@ const AppComponent = ({ Component, pageProps, currentUser }) => { return (
- +
+ +
); }; From 65666591c61c38888674384f9f0b9a0104b4806e Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 15:16:12 +0530 Subject: [PATCH 10/33] Added a Ticket Creation Form. --- client/pages/tickets/new.js | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 client/pages/tickets/new.js diff --git a/client/pages/tickets/new.js b/client/pages/tickets/new.js new file mode 100644 index 0000000..c95517b --- /dev/null +++ b/client/pages/tickets/new.js @@ -0,0 +1,46 @@ +import { useState } from "react"; + +const NewTicket = () => { + const [title, setTitle] = useState(""); + const [price, setPrice] = useState(""); + + const roundOff = () => { + const roundedPrice = parseFloat(price); + + if (isNaN(roundedPrice)) { + // If price is not a number + return; + } + + setPrice(roundedPrice.toFixed(2)); + }; + return ( +
+

Create A Ticket

+
+
+ + setTitle(e.target.value)} + /> +
+
+ + setPrice(e.target.value)} + /> +
+ +
+
+ ); +}; + +export default NewTicket; From 6d2d2ed717ec3795cf69b5036c24692f825544c4 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 15:41:30 +0530 Subject: [PATCH 11/33] Added api call for form submission. --- client/pages/tickets/new.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/client/pages/tickets/new.js b/client/pages/tickets/new.js index c95517b..97853ae 100644 --- a/client/pages/tickets/new.js +++ b/client/pages/tickets/new.js @@ -1,8 +1,30 @@ import { useState } from "react"; +import useRequest from "../../hooks/use-request"; const NewTicket = () => { const [title, setTitle] = useState(""); const [price, setPrice] = useState(""); + const [makeRequest, errors] = useRequest({ + url: "/api/tickets", + method: "post", + body: { + title: title, + price: price, + }, + onSuccess: (ticket) => { + console.log(ticket); + }, + }); + + const handleSubmit = (event) => { + event.preventDefault(); + + if(!title || !price){ + return; + } + + makeRequest(); + }; const roundOff = () => { const roundedPrice = parseFloat(price); @@ -17,7 +39,7 @@ const NewTicket = () => { return (

Create A Ticket

-
+
{ onChange={(e) => setPrice(e.target.value)} />
+ {errors}
From d19b4a9df369f67311db7e98ddef0f35b71d38c2 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 16:08:59 +0530 Subject: [PATCH 12/33] Adder re-routing after ticket creation. --- client/pages/tickets/new.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/pages/tickets/new.js b/client/pages/tickets/new.js index 97853ae..1a2a197 100644 --- a/client/pages/tickets/new.js +++ b/client/pages/tickets/new.js @@ -1,4 +1,5 @@ import { useState } from "react"; +import Router from "next/router"; import useRequest from "../../hooks/use-request"; const NewTicket = () => { @@ -11,15 +12,15 @@ const NewTicket = () => { title: title, price: price, }, - onSuccess: (ticket) => { - console.log(ticket); + onSuccess: () => { + Router.push("/"); }, }); const handleSubmit = (event) => { event.preventDefault(); - if(!title || !price){ + if (!title || !price) { return; } From 796aea5dc976c3f83d465a4d14e8509effcf0f23 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 16:47:46 +0530 Subject: [PATCH 13/33] Fixed a reassignment bug. --- client/pages/_app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pages/_app.js b/client/pages/_app.js index ad0dd0c..c7c8c7c 100644 --- a/client/pages/_app.js +++ b/client/pages/_app.js @@ -25,7 +25,7 @@ AppComponent.getInitialProps = async (appContext) => { pageProps = await appContext.Component.getInitialProps( appContext.ctx, client, - data.currentUser + response.data.currentUser ); } From 61e76fc119a2918f6637508a85ff989f3d3b2d8f Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 17:07:06 +0530 Subject: [PATCH 14/33] Configured Landing page to display created tickets. --- client/pages/index.js | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/client/pages/index.js b/client/pages/index.js index ab924c5..c77a92a 100644 --- a/client/pages/index.js +++ b/client/pages/index.js @@ -1,4 +1,4 @@ -const IndexPage = ({ currentUser }) => { +const IndexPage = ({ currentUser, tickets }) => { if (!currentUser) { return ( <> @@ -9,17 +9,40 @@ const IndexPage = ({ currentUser }) => { ); } + let ticketList; + if (currentUser) { + ticketList = tickets.map((ticket) => { + return ( + + {ticket.title} + {ticket.price} + + ); + }); + } + return ( <> -

Landing Page

-
Welcome {currentUser.email}
+ +

Tickets

+ + + + + + + + + {currentUser && ticketList} +
TitlePrice
); }; IndexPage.getInitialProps = async (context, client, currentUser) => { - return {}; + const { data } = await client.get("/api/tickets"); + return { tickets: data }; }; export default IndexPage; From 1513bd8a1652528fead91f06b127aca9105183c9 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 17:20:28 +0530 Subject: [PATCH 15/33] Added a single ticket details page. --- client/pages/tickets/[ticketId].js | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 client/pages/tickets/[ticketId].js diff --git a/client/pages/tickets/[ticketId].js b/client/pages/tickets/[ticketId].js new file mode 100644 index 0000000..3811b52 --- /dev/null +++ b/client/pages/tickets/[ticketId].js @@ -0,0 +1,5 @@ +const TicketShow = () => { + return
TicketShow
; +}; + +export default TicketShow; From 0705ed72880dd28690983d01126127bbb844af3c Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 17:21:06 +0530 Subject: [PATCH 16/33] Modified to provide wild-card route to show single ticket information. --- client/pages/index.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/pages/index.js b/client/pages/index.js index c77a92a..2401514 100644 --- a/client/pages/index.js +++ b/client/pages/index.js @@ -1,3 +1,5 @@ +import Link from 'next/link'; + const IndexPage = ({ currentUser, tickets }) => { if (!currentUser) { return ( @@ -16,6 +18,11 @@ const IndexPage = ({ currentUser, tickets }) => { {ticket.title} {ticket.price} + + + View + + ); }); @@ -31,6 +38,7 @@ const IndexPage = ({ currentUser, tickets }) => { Title Price + Action From 6e8c1685df6043435cdb6322db323050fb28c92d Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 18:30:08 +0530 Subject: [PATCH 17/33] Added purchase button. --- client/pages/tickets/[ticketId].js | 38 ++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/client/pages/tickets/[ticketId].js b/client/pages/tickets/[ticketId].js index 3811b52..d04e192 100644 --- a/client/pages/tickets/[ticketId].js +++ b/client/pages/tickets/[ticketId].js @@ -1,5 +1,39 @@ -const TicketShow = () => { - return
TicketShow
; +import useRequest from "../../hooks/use-request"; + +const TicketShow = ({ ticket }) => { + const [makeRequest, errors] = useRequest({ + url: "/api/orders", + method: "post", + body: { + ticketId: ticket.id, + }, + onSuccess: (data) => { + console.log(data); + }, + }); + + const handleClick = async () => { + makeRequest(); + }; + + return ( +
+

{ticket.title}

+

Price: {ticket.price} INR

+ {errors} + +
+ ); +}; + +TicketShow.getInitialProps = async (context, client) => { + const { ticketId } = context.query; + + const { data } = await client.get(`/api/tickets/${ticketId}`); + + return { ticket: data }; }; export default TicketShow; From 44bea0c2d9547c0e979a5d9f953a6160393fe948 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 21:16:32 +0530 Subject: [PATCH 18/33] Added a single order page. --- client/pages/orders/[orderId].js | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 client/pages/orders/[orderId].js diff --git a/client/pages/orders/[orderId].js b/client/pages/orders/[orderId].js new file mode 100644 index 0000000..624b5da --- /dev/null +++ b/client/pages/orders/[orderId].js @@ -0,0 +1,5 @@ +const OrderShow = () => { + return
OrderShow
; +}; + +export default OrderShow; From 0ca3376f7b7c6166612fb0366b3e15d1a3c44f54 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 21:17:07 +0530 Subject: [PATCH 19/33] Configured routing to orders page from tickets page. --- client/pages/tickets/[ticketId].js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/pages/tickets/[ticketId].js b/client/pages/tickets/[ticketId].js index d04e192..212f31f 100644 --- a/client/pages/tickets/[ticketId].js +++ b/client/pages/tickets/[ticketId].js @@ -1,3 +1,4 @@ +import Router from "next/router"; import useRequest from "../../hooks/use-request"; const TicketShow = ({ ticket }) => { @@ -7,8 +8,8 @@ const TicketShow = ({ ticket }) => { body: { ticketId: ticket.id, }, - onSuccess: (data) => { - console.log(data); + onSuccess: (orderData) => { + Router.push("/orders/[orderId]", `/orders/${orderData.id}`); }, }); From 9a61a40207a4fa45a9d29e593e8cb752ebe5b5b6 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 21:47:56 +0530 Subject: [PATCH 20/33] Added order expiration Timer. --- client/pages/orders/[orderId].js | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/client/pages/orders/[orderId].js b/client/pages/orders/[orderId].js index 624b5da..ddb3703 100644 --- a/client/pages/orders/[orderId].js +++ b/client/pages/orders/[orderId].js @@ -1,5 +1,32 @@ -const OrderShow = () => { - return
OrderShow
; +import { useEffect, useState } from "react"; + +const OrderShow = ({ order }) => { + const [timeLeft, setTimeLeft] = useState(""); + + useEffect(() => { + const findTimeLeft = () => { + const milliSecondsLeft = new Date(order.expiresAt) - new Date(); + const secondsLeft = Math.round(milliSecondsLeft / 1000); + + setTimeLeft(secondsLeft); + }; + + findTimeLeft(); + const timer = setInterval(findTimeLeft, 1000); + + return () => { + clearInterval(timer); + }; + }, [order]); + + return
Time left to complete payment: {timeLeft} seconds.
; +}; + +OrderShow.getInitialProps = async (context, client) => { + const { orderId } = context.query; + const { data } = await client.get(`/api/orders/${orderId}`); + + return { order: data }; }; export default OrderShow; From 9a9555368b5a2500ce8cd4fe89c53251fa91f094 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 21:56:02 +0530 Subject: [PATCH 21/33] Added Timer expiration logic. --- client/pages/orders/[orderId].js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/client/pages/orders/[orderId].js b/client/pages/orders/[orderId].js index ddb3703..e865cc7 100644 --- a/client/pages/orders/[orderId].js +++ b/client/pages/orders/[orderId].js @@ -1,7 +1,7 @@ import { useEffect, useState } from "react"; const OrderShow = ({ order }) => { - const [timeLeft, setTimeLeft] = useState(""); + const [timeLeft, setTimeLeft] = useState(0); useEffect(() => { const findTimeLeft = () => { @@ -19,6 +19,14 @@ const OrderShow = ({ order }) => { }; }, [order]); + if (timeLeft < 0) { + return ( +
+

Order Expired !!!

+
+ ); + } + return
Time left to complete payment: {timeLeft} seconds.
; }; From 940757c08ed43fb4fb03a43d03bf8853c6cde0ad Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 22:58:50 +0530 Subject: [PATCH 22/33] Installed react-stripe-checkout in clients service. --- client/package-lock.json | 8 +++++++- client/package.json | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index 950faf0..0a17a58 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -13,7 +13,8 @@ "bootstrap": "^5.3.2", "next": "^13.5.4", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-stripe-checkout": "^2.6.3" } }, "node_modules/@next/env": { @@ -460,6 +461,11 @@ "react": "^18.2.0" } }, + "node_modules/react-stripe-checkout": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/react-stripe-checkout/-/react-stripe-checkout-2.6.3.tgz", + "integrity": "sha512-lnsCaAdlmwPGGMbQoI8FXtQUgEm+ktzPZ/ipAw4j0HYf80kef7CivGx6QitmgEn99/aa5hI/dmVXwfVZW/Mzfg==" + }, "node_modules/scheduler": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", diff --git a/client/package.json b/client/package.json index af83111..11b3d1d 100644 --- a/client/package.json +++ b/client/package.json @@ -14,6 +14,7 @@ "bootstrap": "^5.3.2", "next": "^13.5.4", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-stripe-checkout": "^2.6.3" } } From 7d5372b8a0a8eb928716d8b665fd82477323e419 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 23:20:48 +0530 Subject: [PATCH 23/33] Installed prop-types for Stripe module support. --- client/package-lock.json | 24 ++++++++++++++++++++++++ client/package.json | 1 + 2 files changed, 25 insertions(+) diff --git a/client/package-lock.json b/client/package-lock.json index 0a17a58..d8288fc 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -12,6 +12,7 @@ "axios": "^1.5.1", "bootstrap": "^5.3.2", "next": "^13.5.4", + "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-stripe-checkout": "^2.6.3" @@ -401,6 +402,14 @@ } } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -433,6 +442,16 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -461,6 +480,11 @@ "react": "^18.2.0" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/react-stripe-checkout": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/react-stripe-checkout/-/react-stripe-checkout-2.6.3.tgz", diff --git a/client/package.json b/client/package.json index 11b3d1d..4ff3d98 100644 --- a/client/package.json +++ b/client/package.json @@ -13,6 +13,7 @@ "axios": "^1.5.1", "bootstrap": "^5.3.2", "next": "^13.5.4", + "prop-types": "^15.8.1", "react": "^18.2.0", "react-dom": "^18.2.0", "react-stripe-checkout": "^2.6.3" From 23a902c732272a673b668782cd3c9ca1c0c24bbb Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 23:21:48 +0530 Subject: [PATCH 24/33] Configured card checkout with Stripe module. --- client/pages/orders/[orderId].js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/client/pages/orders/[orderId].js b/client/pages/orders/[orderId].js index e865cc7..3cf46b1 100644 --- a/client/pages/orders/[orderId].js +++ b/client/pages/orders/[orderId].js @@ -1,6 +1,7 @@ import { useEffect, useState } from "react"; +import StripeCheckout from "react-stripe-checkout"; -const OrderShow = ({ order }) => { +const OrderShow = ({ order, currentUser }) => { const [timeLeft, setTimeLeft] = useState(0); useEffect(() => { @@ -27,7 +28,19 @@ const OrderShow = ({ order }) => { ); } - return
Time left to complete payment: {timeLeft} seconds.
; + return ( +
+ Time left to complete payment: {timeLeft} seconds. + { + console.log(token); + }} + stripeKey="pk_test_51O53zRSJtuYafghXhYNZzaJqYAh6afqRduQ3UAMs6Wm4vkv30ayq09gBPgU3jYkQPXrofQa9aRbIlb4uuCp3FC6O000J86xaKc" + amount={order.ticket.price * 100} + email={currentUser.email} + /> +
+ ); }; OrderShow.getInitialProps = async (context, client) => { From 931a5d024380b051ce4e42c73986e8bc7b6aef67 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 23:47:08 +0530 Subject: [PATCH 25/33] Modified useRequest hook to send additional data into request body if required. --- client/hooks/use-request.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/hooks/use-request.js b/client/hooks/use-request.js index 8d528d4..ed28ccb 100644 --- a/client/hooks/use-request.js +++ b/client/hooks/use-request.js @@ -4,11 +4,11 @@ import axios from "axios"; export default ({ url, method, body, onSuccess }) => { const [errors, setErrors] = useState(null); - const makeRequest = async () => { + const makeRequest = async (props={}) => { try { setErrors(null); // Setting error to null initially to prevent errors from being displayed always. - const response = await axios[method](url, body); + const response = await axios[method](url, {...body, ...props}); // If the call back exist, then return the call back with response data. if (onSuccess) { From 04c6566f3296c55a0941e4728c7cc2755cf3dec2 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Fri, 27 Oct 2023 23:58:20 +0530 Subject: [PATCH 26/33] Configured to make api call to complete payment with received token for payment request. --- client/pages/orders/[orderId].js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/client/pages/orders/[orderId].js b/client/pages/orders/[orderId].js index 3cf46b1..347ff66 100644 --- a/client/pages/orders/[orderId].js +++ b/client/pages/orders/[orderId].js @@ -1,8 +1,20 @@ import { useEffect, useState } from "react"; +import Router from "next/router"; import StripeCheckout from "react-stripe-checkout"; +import useRequest from "../../hooks/use-request"; const OrderShow = ({ order, currentUser }) => { const [timeLeft, setTimeLeft] = useState(0); + const [makeRequest, errors] = useRequest({ + url: "/api/payments", + method: "post", + body: { + orderId: order.id, + }, + onSuccess: (payment) => { + Router.push("/"); + }, + }); useEffect(() => { const findTimeLeft = () => { @@ -33,12 +45,13 @@ const OrderShow = ({ order, currentUser }) => { Time left to complete payment: {timeLeft} seconds. { - console.log(token); + makeRequest({ token: token.id }); }} stripeKey="pk_test_51O53zRSJtuYafghXhYNZzaJqYAh6afqRduQ3UAMs6Wm4vkv30ayq09gBPgU3jYkQPXrofQa9aRbIlb4uuCp3FC6O000J86xaKc" amount={order.ticket.price * 100} email={currentUser.email} /> + {errors} ); }; From c004a940e03f90b3d4b4edb34692d0e98b5b07cb Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Sat, 28 Oct 2023 00:17:18 +0530 Subject: [PATCH 27/33] Modified API response to return tickets that are available to book (unreserved Tickets). --- tickets/src/routes/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tickets/src/routes/index.ts b/tickets/src/routes/index.ts index 600d265..525b07b 100644 --- a/tickets/src/routes/index.ts +++ b/tickets/src/routes/index.ts @@ -4,7 +4,9 @@ import { Ticket } from "../models/ticket"; const router = express.Router(); router.get("/api/tickets", async (req: Request, res: Response) => { - const tickets = await Ticket.find({}); + + // Fetch all Tickets that are available to make a booking (ie, which are not reserved by any order) + const tickets = await Ticket.find({orderId: undefined}); res.send(tickets); }); From 91cbbee84550d50df10df35605daaaf1e6117d2b Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Sat, 28 Oct 2023 00:38:48 +0530 Subject: [PATCH 28/33] Added two new options in the Header. --- client/components/header.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/components/header.js b/client/components/header.js index b9dac96..77471a3 100644 --- a/client/components/header.js +++ b/client/components/header.js @@ -2,9 +2,11 @@ import Link from "next/link"; export default ({ currentUser }) => { const Links = [ - !currentUser && { label: "Sign Up", href: "auth/signup" }, - !currentUser && { label: "Sign In", href: "auth/signin" }, - currentUser && { label: "Sign Out", href: "auth/signout" }, + !currentUser && { label: "Sign Up", href: "/auth/signup" }, + !currentUser && { label: "Sign In", href: "/auth/signin" }, + currentUser && { label: "Sell Tickets", href: "/tickets/new" }, + currentUser && { label: "My Orders", href: "/orders" }, + currentUser && { label: "Sign Out", href: "/auth/signout" }, ] .filter((validLinks) => validLinks) .map(({ label, href }) => { From c56758fda027fafd8b5d545f46926e067158ef32 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Sat, 28 Oct 2023 01:01:03 +0530 Subject: [PATCH 29/33] Added orders listing page to list order history of user. --- client/pages/orders/index.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 client/pages/orders/index.js diff --git a/client/pages/orders/index.js b/client/pages/orders/index.js new file mode 100644 index 0000000..22f886b --- /dev/null +++ b/client/pages/orders/index.js @@ -0,0 +1,23 @@ +const OrderIndex = ({ orders }) => { + return ( + <> + + + ); +}; + +OrderIndex.getInitialProps = async (context, client) => { + const response = await client.get("/api/orders"); + + return { orders: response.data }; +}; + +export default OrderIndex; From 1cfecd5d0e4abc7178e7638731e26e32466d7175 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Sat, 28 Oct 2023 01:02:15 +0530 Subject: [PATCH 30/33] Modified the redirection - redirection configured to show orders page after payment success. --- client/pages/orders/[orderId].js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/pages/orders/[orderId].js b/client/pages/orders/[orderId].js index 347ff66..de0588a 100644 --- a/client/pages/orders/[orderId].js +++ b/client/pages/orders/[orderId].js @@ -12,7 +12,7 @@ const OrderShow = ({ order, currentUser }) => { orderId: order.id, }, onSuccess: (payment) => { - Router.push("/"); + Router.push("/orders"); }, }); From 9f30b4ce2488fac4ef9cd221b6d6e6ea4d3a5d80 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <87621111+alwinsimon@users.noreply.github.com> Date: Sat, 28 Oct 2023 18:47:10 +0530 Subject: [PATCH 31/33] Create CI - Tests - Auth Service.yml --- .github/workflows/CI - Tests - Auth Service.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/workflows/CI - Tests - Auth Service.yml diff --git a/.github/workflows/CI - Tests - Auth Service.yml b/.github/workflows/CI - Tests - Auth Service.yml new file mode 100644 index 0000000..c98b5ea --- /dev/null +++ b/.github/workflows/CI - Tests - Auth Service.yml @@ -0,0 +1,3 @@ +# ===================================================== Main Branch CI Configuration ===================================================== + +name: CI - Tests - Auth Service From da4fc7b59620a929cd2d2d4db82d062b14f528b8 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Sat, 28 Oct 2023 18:58:04 +0530 Subject: [PATCH 32/33] Configured CI Workflow for auth service tests. --- .github/workflows/CI - Tests - Auth Service.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CI - Tests - Auth Service.yml b/.github/workflows/CI - Tests - Auth Service.yml index c98b5ea..c33ab5f 100644 --- a/.github/workflows/CI - Tests - Auth Service.yml +++ b/.github/workflows/CI - Tests - Auth Service.yml @@ -1,3 +1,13 @@ -# ===================================================== Main Branch CI Configuration ===================================================== +# ========================================= Main Branch ::: CI - Tests - Auth Service ========================================= name: CI - Tests - Auth Service + +on: pull_request + +jobs: + Production-Branch-Pre-Integration-Tests: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - run: cd auth && npm install && npm run test:ci From 9f78a3a3a1fe8c3a0d37fe1fae6f1b87b264e206 Mon Sep 17 00:00:00 2001 From: "Dr. Alwin Simon" <003alwin@gmail.com> Date: Sat, 28 Oct 2023 19:10:55 +0530 Subject: [PATCH 33/33] Added Test Script for CI Testing. --- auth/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/auth/package.json b/auth/package.json index 604068e..b1cfa63 100644 --- a/auth/package.json +++ b/auth/package.json @@ -5,7 +5,8 @@ "main": "index.js", "scripts": { "start": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' src/index.ts", - "test": "jest --watchAll --no-cache" + "test": "jest --watchAll --no-cache", + "test:ci": "jest" }, "jest": { "preset": "ts-jest",