Skip to content

Instantly share code, notes, and snippets.

@ShariqAnsari88
Last active March 9, 2024 13:06
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save ShariqAnsari88/797a9c25918a8ffcf9b910c8d00243b1 to your computer and use it in GitHub Desktop.
Save ShariqAnsari88/797a9c25918a8ffcf9b910c8d00243b1 to your computer and use it in GitHub Desktop.
Online Shoe Store
{
"extends": "next/core-web-vitals",
"rules": {
"react/no-unescaped-entities": "off",
"@next/next/no-page-custom-font": "off"
}
}
import React from "react";
import Wrapper from "@/components/Wrapper";
import Link from "next/link";
const Failed = () => {
return (
<div className="min-h-[650px] flex items-center">
<Wrapper>
<div className="max-w-[600px] rounded-lg p-5 border border-black mx-auto flex flex-col">
<div className="text-2xl font-bold">Payment failed!</div>
<div className="text-base mt-5">
For any product related query, drop an email to
</div>
<div className="underline">shoeshopcontact@shop.com</div>
<Link href="/" className="font-bold mt-5">
Continue Shopping
</Link>
</div>
</Wrapper>
</div>
);
};
export default Failed;
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossOrigin="true"
/>
<link
href="https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400;500;600;700&family=Urbanist:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet"
/>
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
font-family: "Urbanist", sans-serif;
font-weight: 400;
font-size: 16px;
line-height: 24px;
color: rgba(0, 0, 0, 1);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
letter-spacing: 1px;
}
/* PRODUCT DETAILS CAROUSEL STYLING CUSTOMIZATION START */
.productCarousel.carousel-root {
display: flex;
flex-direction: row-reverse;
gap: 15px;
}
.productCarousel.carousel-root .carousel {
width: auto;
}
.productCarousel.carousel-root .carousel.carousel-slider {
width: 100%;
}
.productCarousel.carousel-root .carousel.carousel-slider .slider-wrapper {
border-radius: 10px;
}
.productCarousel.carousel-root .carousel .thumbs-wrapper {
margin: 0;
}
.productCarousel.carousel-root .carousel .thumb {
height: 60px;
border-radius: 6px;
overflow: hidden;
position: relative;
}
.productCarousel.carousel-root .carousel .thumb img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: center;
}
.productCarousel.carousel-root .carousel .thumb:after {
content: "";
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background-color: black;
opacity: 0;
}
.productCarousel.carousel-root .carousel .thumb.selected,
.productCarousel.carousel-root .carousel .thumb:hover {
border: 0;
}
.productCarousel.carousel-root .carousel .thumb:hover:after,
.productCarousel.carousel-root .carousel .thumb.selected:after {
opacity: 0.2;
}
.productCarousel .control-arrow {
display: none;
}
@media screen and (max-width: 767px) {
.productCarousel.carousel-root {
flex-direction: column;
}
.productCarousel.carousel-root .carousel .thumb {
border: 0;
padding: 0;
}
}
@media screen and (min-width: 768px) {
.productCarousel.carousel-root .carousel .thumbs {
transform: none !important;
flex-direction: column;
display: flex;
gap: 10px;
}
.productCarousel.carousel-root .carousel .thumb {
border: 0;
padding: 0;
margin: 0;
}
}
/* PRODUCT DETAILS CAROUSEL STYLING CUSTOMIZATION END */
.markdown ul {
margin: 0;
padding: 0;
list-style-type: disc;
margin: 20px 0;
}
.markdown ul li {
margin: 10px 0;
}
const data = [
{ id: 1, name: "Home", url: "/" },
{ id: 2, name: "About", url: "/about" },
{ id: 3, name: "Categories", subMenu: true },
{ id: 4, name: "Contact", url: "/contact" },
];
const subMenuData = [
{ id: 1, name: "Jordan", doc_count: 11 },
{ id: 2, name: "Sneakers", doc_count: 8 },
{ id: 3, name: "Running shoes", doc_count: 64 },
{ id: 4, name: "Football shoes", doc_count: 107 },
];
("use strict");
const stripe = require("stripe")(process.env.STRIPE_KEY);
/**
* order controller
*/
const { createCoreController } = require("@strapi/strapi").factories;
module.exports = createCoreController("api::order.order", ({ strapi }) => ({
async create(ctx) {
const { products } = ctx.request.body;
try {
const lineItems = await Promise.all(
products.map(async (product) => {
const item = await strapi
.service("api::product.product")
.findOne(product.id);
console.log("this is item------->", item);
console.log("this is product------->", product);
return {
price_data: {
currency: "inr",
product_data: {
name: item.name,
},
unit_amount: Math.round(item.price * 100),
},
quantity: product.quantity,
};
})
);
const session = await stripe.checkout.sessions.create({
shipping_address_collection: { allowed_countries: ["IN"] },
payment_method_types: ["card"],
mode: "payment",
success_url: process.env.CLIENT_URL + `/success`,
cancel_url: process.env.CLIENT_URL + "/failed",
line_items: lineItems,
});
await strapi
.service("api::order.order")
.create({ data: { products, stripeId: session.id } });
return { stripeSession: session };
} catch (error) {
ctx.response.status = 500;
return { error };
}
},
}));
{
"@next/font": "13.1.6",
"@reduxjs/toolkit": "^1.9.3",
"@stripe/react-stripe-js": "^1.16.5",
"@stripe/stripe-js": "^1.48.0",
"eslint": "8.34.0",
"eslint-config-next": "13.1.6",
"next": "13.1.6",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.7.1",
"react-markdown": "^8.0.5",
"react-multi-carousel": "^2.8.2",
"react-redux": "^8.0.5",
"react-responsive-carousel": "^3.2.23",
"react-toastify": "^9.1.1",
"swr": "^2.1.0"
}
{/* PAGINATION BUTTONS START */}
{data.meta.pagination.total > maxResultCount && (
<div className="flex gap-3 items-center justify-center my-16 md:my-0">
<button
className={`rounded py-2 px-4 bg-black text-white disabled:bg-gray-200 disabled:text-gray-500`}
disabled={pageIndex === 1}
onClick={() => setPageIndex(pageIndex - 1)}
>
Previous
</button>
<span className="font-bold">{`${pageIndex} of ${
data && data.meta.pagination.pageCount
}`}</span>
<button
className={`rounded py-2 px-4 bg-black text-white disabled:bg-gray-200 disabled:text-gray-500`}
disabled={
pageIndex ===
(data && data.meta.pagination.pageCount)
}
onClick={() => setPageIndex(pageIndex + 1)}
>
Next
</button>
</div>
)}
{/* PAGINATION BUTTONS END */}
{isLoading && (
<div className="absolute top-0 left-0 w-full h-full bg-white/[0.5] flex flex-col gap-5 justify-center items-center">
<img src="/logo.svg" width={150} />
<span className="text-2xl font-medium">Loading...</span>
</div>
)}
{
"data": [
{
"size": "UK 6",
"enabled": true
},
{
"size": "UK 6.5",
"enabled": true
},
{
"size": "UK 7",
"enabled": true
},
{
"size": "UK 7.5",
"enabled": true
},
{
"size": "UK 8",
"enabled": true
},
{
"size": "UK 8.5",
"enabled": true
},
{
"size": "UK 9",
"enabled": true
},
{
"size": "UK 9.5",
"enabled": true
},
{
"size": "UK 10",
"enabled": true
},
{
"size": "UK 10.5",
"enabled": true
},
{
"size": "UK 11",
"enabled": false
},
{
"size": "UK 11.5",
"enabled": false
}
]
}
import React from "react";
import Wrapper from "@/components/Wrapper";
import Link from "next/link";
const Success = () => {
return (
<div className="min-h-[650px] flex items-center">
<Wrapper>
<div className="max-w-[600px] rounded-lg p-5 border border-black mx-auto flex flex-col">
<div className="text-2xl font-bold">
Thanks for shopping with us!
</div>
<div className="text-lg font-bold mt-2">
Your order has been placed successfully.
</div>
<div className="text-base mt-5">
For any product related query, drop an email to
</div>
<div className="underline">shoeshopcontact@shop.com</div>
<Link href="/" className="font-bold mt-5">
Continue Shopping
</Link>
</div>
</Wrapper>
</div>
);
};
export default Success;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment