Skip to content

Commit 534ef9a

Browse files
Merge pull request #475 from Adarsh07rai/main
ecommerce web application
2 parents e5745b1 + fe329b0 commit 534ef9a

36 files changed

+7823
-0
lines changed

ecommerce/.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["@babel/preset-react"]
3+
}

ecommerce/.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": ["next/babel", "next/core-web-vitals"]
3+
}

ecommerce/.gitignore

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
.pnpm-debug.log*
27+
28+
# local env files
29+
.env*.local
30+
31+
# vercel
32+
.vercel
33+
34+
# typescript
35+
*.tsbuildinfo
36+
next-env.d.ts

ecommerce/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2+
3+
## Getting Started
4+
5+
First, run the development server:
6+
7+
```bash
8+
npm run dev
9+
# or
10+
yarn dev
11+
```
12+
13+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14+
15+
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16+
17+
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
18+
19+
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20+
21+
## Learn More
22+
23+
To learn more about Next.js, take a look at the following resources:
24+
25+
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26+
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27+
28+
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29+
30+
## Deploy on Vercel
31+
32+
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33+
34+
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

ecommerce/components/Cart.jsx

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import React, { useRef } from "react";
2+
import Link from "next/link";
3+
import {
4+
AiOutlineMinus,
5+
AiOutlinePlus,
6+
AiOutlineLeft,
7+
AiOutlineShopping,
8+
} from "react-icons/ai";
9+
import { TiDeleteOutline } from "react-icons/ti";
10+
import toast from "react-hot-toast";
11+
12+
import { useStateContext } from "../context/StateContext";
13+
import { urlFor } from "../lib/client";
14+
import getStripe from "../lib/getStripe";
15+
16+
const Cart = () => {
17+
const cartRef = useRef();
18+
const {
19+
totalPrice,
20+
totalQuantities,
21+
cartItems,
22+
setShowCart,
23+
toggleCartItemQuanitity,
24+
onRemove,
25+
} = useStateContext();
26+
27+
const handleCheckout = async () => {
28+
const stripe = await getStripe();
29+
30+
const response = await fetch("/api/stripe", {
31+
method: "POST",
32+
headers: {
33+
"Content-Type": "application/json",
34+
},
35+
body: JSON.stringify(cartItems),
36+
});
37+
38+
if (response.statusCode === 500) return;
39+
40+
const data = await response.json();
41+
42+
toast.loading("Redirecting...");
43+
44+
stripe.redirectToCheckout({ sessionId: data.id });
45+
};
46+
47+
return (
48+
<div className="cart-wrapper" ref={cartRef}>
49+
<div className="cart-container">
50+
<button
51+
type="button"
52+
className="cart-heading"
53+
onClick={() => setShowCart(false)}
54+
>
55+
<AiOutlineLeft />
56+
<span className="heading">Your Cart</span>
57+
<span className="cart-num-items">({totalQuantities} items)</span>
58+
</button>
59+
60+
{cartItems.length < 1 && (
61+
<div className="empty-cart">
62+
<AiOutlineShopping size={150} />
63+
<h3>Your shopping bag is empty</h3>
64+
<Link href="/">
65+
<button
66+
type="button"
67+
onClick={() => setShowCart(false)}
68+
className="btn"
69+
>
70+
Continue Shopping
71+
</button>
72+
</Link>
73+
</div>
74+
)}
75+
76+
<div className="product-container">
77+
{cartItems.length >= 1 &&
78+
cartItems.map((item) => (
79+
<div className="product" key={item._id}>
80+
<img
81+
src={urlFor(item?.image[0])}
82+
className="cart-product-image"
83+
/>
84+
<div className="item-desc">
85+
<div className="flex top">
86+
<h5>{item.name}</h5>
87+
<h4>{item.price}</h4>
88+
</div>
89+
<div className="flex bottom">
90+
<div>
91+
<p className="quantity-desc">
92+
<span
93+
className="minus"
94+
onClick={() =>
95+
toggleCartItemQuanitity(item._id, "dec")
96+
}
97+
>
98+
<AiOutlineMinus />
99+
</span>
100+
<span className="num" onClick="">
101+
{item.quantity}
102+
</span>
103+
<span
104+
className="plus"
105+
onClick={() =>
106+
toggleCartItemQuanitity(item._id, "inc")
107+
}
108+
>
109+
<AiOutlinePlus />
110+
</span>
111+
</p>
112+
</div>
113+
<button
114+
type="button"
115+
className="remove-item"
116+
onClick={() => onRemove(item)}
117+
>
118+
<TiDeleteOutline />
119+
</button>
120+
</div>
121+
</div>
122+
</div>
123+
))}
124+
</div>
125+
{cartItems.length >= 1 && (
126+
<div className="cart-bottom">
127+
<div className="total">
128+
<h3>Subtotal:</h3>
129+
<h3>{totalPrice}</h3>
130+
</div>
131+
<div className="btn-container">
132+
<button type="button" className="btn" onClick={handleCheckout}>
133+
Pay with Stripe
134+
</button>
135+
</div>
136+
</div>
137+
)}
138+
</div>
139+
</div>
140+
);
141+
};
142+
143+
export default Cart;

ecommerce/components/Footer.jsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from "react";
2+
import { AiFillInstagram, AiOutlineTwitter } from "react-icons/ai";
3+
const Footer = () => {
4+
return (
5+
<div className="footer-container">
6+
<p>SAS Store All rights reserverd</p>
7+
<p className="icons">
8+
<AiFillInstagram />
9+
<AiOutlineTwitter />
10+
</p>
11+
</div>
12+
);
13+
};
14+
15+
export default Footer;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import React from "react";
2+
import Link from "next/link";
3+
4+
import { urlFor } from "../lib/client";
5+
6+
const FooterBanner = ({
7+
footerBanner: {
8+
discount,
9+
largeText1,
10+
largeText2,
11+
saleTime,
12+
smallText,
13+
midText,
14+
desc,
15+
product,
16+
buttonText,
17+
image,
18+
},
19+
}) => {
20+
return (
21+
<div className="footer-banner-container">
22+
<div className="banner-desc">
23+
<div className="left">
24+
<p>{discount}</p>
25+
<h3>{largeText1}</h3>
26+
<h3>{largeText2}</h3>
27+
<p>{saleTime}</p>
28+
</div>
29+
<div className="right">
30+
<p>{smallText}</p>
31+
<h3>{midText}</h3>
32+
<p>{desc}</p>
33+
<Link href={`/product/${product}`}>
34+
<button type="button">{buttonText}</button>
35+
</Link>
36+
</div>
37+
38+
<img
39+
src={urlFor(image)}
40+
className="footer-banner-image"
41+
width={200}
42+
height={200}
43+
/>
44+
</div>
45+
</div>
46+
);
47+
};
48+
49+
export default FooterBanner;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from "react";
2+
import Link from "next/link";
3+
4+
import { urlFor } from "../lib/client";
5+
6+
const HeroBanner = ({ heroBanner }) => {
7+
return (
8+
<div className="hero-banner-container">
9+
<div>
10+
<p className="beats-solo">{heroBanner.smallText}</p>
11+
<h3>{heroBanner.midText}</h3>
12+
<h1>{heroBanner.largeText1}</h1>
13+
<img
14+
src={urlFor(heroBanner.image)}
15+
alt="headphones"
16+
className="hero-banner-image"
17+
/>
18+
19+
<div>
20+
<Link href={`/product/${heroBanner.product}`}>
21+
<button type="button">{heroBanner.buttonText}</button>
22+
</Link>
23+
<div className="desc">
24+
<h5>Description</h5>
25+
<p>{heroBanner.desc}</p>
26+
</div>
27+
</div>
28+
</div>
29+
</div>
30+
);
31+
};
32+
33+
export default HeroBanner;

ecommerce/components/Layout.jsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from "react";
2+
import Head from "next/head";
3+
import Navbar from "./Navbar";
4+
import { Footer } from ".";
5+
export const Layout = ({ children }) => {
6+
return (
7+
<div className="layout">
8+
<Head>
9+
<title>SAS Group Store</title>
10+
</Head>
11+
<header>
12+
<Navbar />
13+
</header>
14+
<main className="main-container">{children}</main>
15+
<footer>
16+
<Footer />
17+
</footer>
18+
</div>
19+
);
20+
};
21+
export default Layout;

ecommerce/components/Navbar.jsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from "react";
2+
import { AiOutlineShopping } from "react-icons/ai";
3+
import { Cart } from "./";
4+
import { useStateContext } from "../context/StateContext";
5+
const Navbar = () => {
6+
const { showCart, setShowCart, totalQuantities } = useStateContext();
7+
return (
8+
<div className="navbar-container">
9+
<p className="logo">
10+
<a href="/">SAS Store</a>
11+
</p>
12+
<div className="App">
13+
<input type="text" placeholder="search..." />
14+
</div>
15+
<button
16+
type="button"
17+
className="cart-icon"
18+
onClick={() => setShowCart(true)}
19+
>
20+
<AiOutlineShopping />
21+
<span className="cart-item-qty">{totalQuantities}</span>
22+
</button>
23+
{showCart && <Cart />}
24+
</div>
25+
);
26+
};
27+
export default Navbar;

0 commit comments

Comments
 (0)