Skip to content

Commit

Permalink
Merge pull request #241 from alwinsimon/v1
Browse files Browse the repository at this point in the history
V1
  • Loading branch information
alwinsimon authored Oct 28, 2023
2 parents 4aa5391 + f100ce1 commit 115ae20
Show file tree
Hide file tree
Showing 19 changed files with 356 additions and 32 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/CI - Tests - Auth Service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# ========================================= 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
3 changes: 2 additions & 1 deletion auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
8 changes: 5 additions & 3 deletions client/components/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) => {
Expand Down
4 changes: 2 additions & 2 deletions client/hooks/use-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
32 changes: 31 additions & 1 deletion client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
"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-dom": "^18.2.0",
"react-stripe-checkout": "^2.6.3"
}
}
10 changes: 8 additions & 2 deletions client/pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ const AppComponent = ({ Component, pageProps, currentUser }) => {
return (
<div>
<Header currentUser={currentUser} />
<Component {...pageProps} />
<div className="container">
<Component currentUser={currentUser} {...pageProps} />
</div>
</div>
);
};
Expand All @@ -20,7 +22,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,
response.data.currentUser
);
}

return { pageProps, currentUser: response.data.currentUser };
Expand Down
50 changes: 36 additions & 14 deletions client/pages/index.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,56 @@
import buildClient from "../api/build-client";
import Link from 'next/link';

const IndexPage = ({ currentUser }) => {
const IndexPage = ({ currentUser, tickets }) => {
if (!currentUser) {
return (
<>
<h1>Landing Page</h1>
<br/>
<br />
<h5>Signed Out</h5>
</>
);
}

let ticketList;
if (currentUser) {
ticketList = tickets.map((ticket) => {
return (
<tr key={ticket.id}>
<td>{ticket.title}</td>
<td>{ticket.price}</td>
<td>
<Link href="/tickets/[ticketId]" as={`/tickets/${ticket.id}`}>
View
</Link>
</td>
</tr>
);
});
}

return (
<>
<h1>Landing Page</h1>
<br />
<h5>Welcome {currentUser.email}</h5>

<h1>Tickets</h1>
<table className="table table-striped">
<thead>
<tr>
<th>Title</th>
<th>Price</th>
<th>Action</th>
</tr>
</thead>

<tbody>{currentUser && ticketList}</tbody>
</table>
</>
);
};

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 };
}
IndexPage.getInitialProps = async (context, client, currentUser) => {
const { data } = await client.get("/api/tickets");
return { tickets: data };
};

export default IndexPage;
66 changes: 66 additions & 0 deletions client/pages/orders/[orderId].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
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("/orders");
},
});

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]);

if (timeLeft < 0) {
return (
<div>
<h3 className="text text-danger">Order Expired !!!</h3>
</div>
);
}

return (
<div>
Time left to complete payment: {timeLeft} seconds.
<StripeCheckout
token={(token) => {
makeRequest({ token: token.id });
}}
stripeKey="pk_test_51O53zRSJtuYafghXhYNZzaJqYAh6afqRduQ3UAMs6Wm4vkv30ayq09gBPgU3jYkQPXrofQa9aRbIlb4uuCp3FC6O000J86xaKc"
amount={order.ticket.price * 100}
email={currentUser.email}
/>
{errors}
</div>
);
};

OrderShow.getInitialProps = async (context, client) => {
const { orderId } = context.query;
const { data } = await client.get(`/api/orders/${orderId}`);

return { order: data };
};

export default OrderShow;
23 changes: 23 additions & 0 deletions client/pages/orders/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const OrderIndex = ({ orders }) => {
return (
<>
<ul>
{orders.map((order) => {
return (
<li key={orders.id}>
{order.ticket.title} - {order.status}
</li>
);
})}
</ul>
</>
);
};

OrderIndex.getInitialProps = async (context, client) => {
const response = await client.get("/api/orders");

return { orders: response.data };
};

export default OrderIndex;
40 changes: 40 additions & 0 deletions client/pages/tickets/[ticketId].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Router from "next/router";
import useRequest from "../../hooks/use-request";

const TicketShow = ({ ticket }) => {
const [makeRequest, errors] = useRequest({
url: "/api/orders",
method: "post",
body: {
ticketId: ticket.id,
},
onSuccess: (orderData) => {
Router.push("/orders/[orderId]", `/orders/${orderData.id}`);
},
});

const handleClick = async () => {
makeRequest();
};

return (
<div>
<h1>{ticket.title}</h1>
<h4>Price: {ticket.price} INR</h4>
{errors}
<button className="btn btn-primary" onClick={handleClick}>
Purchase
</button>
</div>
);
};

TicketShow.getInitialProps = async (context, client) => {
const { ticketId } = context.query;

const { data } = await client.get(`/api/tickets/${ticketId}`);

return { ticket: data };
};

export default TicketShow;
Loading

0 comments on commit 115ae20

Please sign in to comment.