├── models ├── Order.js ├── ProductSchema.js └── UserSchema.js ├── components ├── Footer │ ├── Footer.css │ └── Footer.jsx ├── sidebar │ ├── Style.module.css │ ├── static │ │ └── data.js │ └── Sidebar.jsx ├── bestseller │ ├── BestSellers.module.css │ ├── BestSellers.jsx │ └── static │ │ └── bestSellerdata.js ├── herosection │ ├── Herosection.module.css │ └── Herosection.jsx ├── productCard │ ├── Card.module.css │ └── Card.jsx ├── productcard_landscape │ ├── styles.module.css │ ├── checkUser.js │ ├── ProductCardLandscape.jsx │ └── Buttondiv.jsx ├── navbar │ ├── cartcirlce │ │ └── CartCircle.jsx │ ├── Navbar.module.css │ ├── dropdown │ │ ├── Dropdown.jsx │ │ └── Dropdown.module.css │ ├── authbutton │ │ └── AuthButton.jsx │ └── Navbar.jsx ├── productsection │ └── Product.jsx └── auth │ ├── authRegex.js │ ├── authLogic.js │ ├── Auth.module.css │ └── Auth.jsx ├── styles ├── Login.module.css ├── ProductsBanner.module.css ├── globals.css ├── SingleProduct.module.css ├── tshirts.module.css ├── Cart.module.css ├── Payment.module.css └── Home.module.css ├── public ├── cc.png ├── favicon.ico ├── fonts │ └── Poppins.ttf ├── assets │ ├── Landing │ │ ├── Cat1.png │ │ ├── Cat2.jpg │ │ ├── Cat2.png │ │ ├── Cat3.png │ │ ├── Cat1Mobile.png │ │ ├── Cat2Mobile.png │ │ ├── Cat3Mobile.png │ │ ├── linuxhoodie.png │ │ ├── LandingBanner.png │ │ ├── LandingBanner2.png │ │ ├── LandingBanner3.png │ │ ├── ShopNowButton.png │ │ ├── whitefcoder1.webp │ │ ├── ShopCodersBanner.png │ │ └── newsletterbanner1.png │ ├── auth │ │ ├── gg_logo.png │ │ ├── gh_logo.png │ │ └── authbanner.png │ ├── brands │ │ ├── logi.png │ │ ├── razer.png │ │ └── antesports.png │ ├── cart │ │ └── deleteicon.png │ ├── Products │ │ ├── monitor │ │ │ ├── m1.png │ │ │ ├── m2.png │ │ │ ├── m3.png │ │ │ ├── m4.png │ │ │ └── m5.png │ │ ├── productbg.png │ │ ├── caps │ │ │ ├── gh_cap1.webp │ │ │ ├── gh_cap2.jpg │ │ │ └── gh_cap3.webp │ │ ├── keyboards │ │ │ ├── k1.png │ │ │ ├── k2.png │ │ │ ├── k3.png │ │ │ ├── k4.png │ │ │ └── k5.png │ │ ├── Shirt │ │ │ ├── GH_shirt1.webp │ │ │ ├── GH_shirt2.webp │ │ │ ├── GH_shirt3.webp │ │ │ ├── GH_shirt4.webp │ │ │ └── GH_shirt5.webp │ │ ├── Hoodies │ │ │ ├── Gh_hoodie1.webp │ │ │ └── Gh_hoodie2.webp │ │ └── misc │ │ │ └── cart.svg │ ├── Singleproduct │ │ ├── minus.png │ │ └── plus.png │ └── navbar │ │ ├── bag.svg │ │ ├── up.svg │ │ ├── navlogo.svg │ │ └── ham.svg ├── vercel.svg ├── thirteen.svg └── next.svg ├── postcss.config.js ├── jsconfig.json ├── app ├── monitors │ ├── styles.module.css │ ├── [id] │ │ └── page.jsx │ └── page.jsx ├── swags │ ├── styles.module.css │ ├── [id] │ │ └── page.jsx │ └── page.jsx ├── keyboards │ ├── styles.module.css │ ├── [id] │ │ └── page.jsx │ └── page.jsx ├── layout.jsx ├── globals.css ├── page.jsx ├── paymentsucess │ └── page.jsx └── cart │ └── page.jsx ├── services ├── GetStripe.js └── shopApi.js ├── SECURITY.md ├── middleware ├── db.js └── toastMessage.js ├── next.config.js ├── pages └── api │ ├── user │ ├── viewalluser.js │ ├── usertest.js │ ├── loginuser.js │ ├── adduser.js │ ├── resetcart.js │ ├── removefromcart.js │ ├── reducecartitems.js │ ├── viewuserdetails.js │ └── addtocart.js │ ├── hello.js │ ├── products │ ├── bestseller.js │ ├── viewproductbyid copy.js │ ├── fetchproduct.js │ ├── viewproductbyid.js │ ├── viewallproducts.js │ ├── addproduct.js │ └── addproductstocart.js │ ├── stripe.js │ ├── auth │ └── [...nextauth].js │ └── stripecart.js ├── global ├── StoreInitializer.js └── store.js ├── .gitignore ├── tailwind.config.js ├── package.json ├── LICENSE ├── CONTRIBUTING.md ├── README.md └── CODE_OF_CONDUCT.md /models/Order.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/Footer/Footer.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/sidebar/Style.module.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/bestseller/BestSellers.module.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /styles/Login.module.css: -------------------------------------------------------------------------------- 1 | .login_mainparent { 2 | padding: 10px 80px; 3 | } -------------------------------------------------------------------------------- /public/cc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/cc.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/fonts/Poppins.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/fonts/Poppins.ttf -------------------------------------------------------------------------------- /public/assets/Landing/Cat1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/Cat1.png -------------------------------------------------------------------------------- /public/assets/Landing/Cat2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/Cat2.jpg -------------------------------------------------------------------------------- /public/assets/Landing/Cat2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/Cat2.png -------------------------------------------------------------------------------- /public/assets/Landing/Cat3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/Cat3.png -------------------------------------------------------------------------------- /public/assets/auth/gg_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/auth/gg_logo.png -------------------------------------------------------------------------------- /public/assets/auth/gh_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/auth/gh_logo.png -------------------------------------------------------------------------------- /public/assets/brands/logi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/brands/logi.png -------------------------------------------------------------------------------- /public/assets/brands/razer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/brands/razer.png -------------------------------------------------------------------------------- /public/assets/auth/authbanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/auth/authbanner.png -------------------------------------------------------------------------------- /public/assets/cart/deleteicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/cart/deleteicon.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /public/assets/brands/antesports.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/brands/antesports.png -------------------------------------------------------------------------------- /public/assets/Landing/Cat1Mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/Cat1Mobile.png -------------------------------------------------------------------------------- /public/assets/Landing/Cat2Mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/Cat2Mobile.png -------------------------------------------------------------------------------- /public/assets/Landing/Cat3Mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/Cat3Mobile.png -------------------------------------------------------------------------------- /public/assets/Landing/linuxhoodie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/linuxhoodie.png -------------------------------------------------------------------------------- /public/assets/Products/monitor/m1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/monitor/m1.png -------------------------------------------------------------------------------- /public/assets/Products/monitor/m2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/monitor/m2.png -------------------------------------------------------------------------------- /public/assets/Products/monitor/m3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/monitor/m3.png -------------------------------------------------------------------------------- /public/assets/Products/monitor/m4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/monitor/m4.png -------------------------------------------------------------------------------- /public/assets/Products/monitor/m5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/monitor/m5.png -------------------------------------------------------------------------------- /public/assets/Products/productbg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/productbg.png -------------------------------------------------------------------------------- /public/assets/Singleproduct/minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Singleproduct/minus.png -------------------------------------------------------------------------------- /public/assets/Singleproduct/plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Singleproduct/plus.png -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["./*"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /public/assets/Landing/LandingBanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/LandingBanner.png -------------------------------------------------------------------------------- /public/assets/Landing/LandingBanner2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/LandingBanner2.png -------------------------------------------------------------------------------- /public/assets/Landing/LandingBanner3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/LandingBanner3.png -------------------------------------------------------------------------------- /public/assets/Landing/ShopNowButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/ShopNowButton.png -------------------------------------------------------------------------------- /public/assets/Landing/whitefcoder1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/whitefcoder1.webp -------------------------------------------------------------------------------- /public/assets/Products/caps/gh_cap1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/caps/gh_cap1.webp -------------------------------------------------------------------------------- /public/assets/Products/caps/gh_cap2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/caps/gh_cap2.jpg -------------------------------------------------------------------------------- /public/assets/Products/caps/gh_cap3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/caps/gh_cap3.webp -------------------------------------------------------------------------------- /public/assets/Products/keyboards/k1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/keyboards/k1.png -------------------------------------------------------------------------------- /public/assets/Products/keyboards/k2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/keyboards/k2.png -------------------------------------------------------------------------------- /public/assets/Products/keyboards/k3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/keyboards/k3.png -------------------------------------------------------------------------------- /public/assets/Products/keyboards/k4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/keyboards/k4.png -------------------------------------------------------------------------------- /public/assets/Products/keyboards/k5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/keyboards/k5.png -------------------------------------------------------------------------------- /public/assets/Landing/ShopCodersBanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/ShopCodersBanner.png -------------------------------------------------------------------------------- /public/assets/Landing/newsletterbanner1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Landing/newsletterbanner1.png -------------------------------------------------------------------------------- /public/assets/Products/Shirt/GH_shirt1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/Shirt/GH_shirt1.webp -------------------------------------------------------------------------------- /public/assets/Products/Shirt/GH_shirt2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/Shirt/GH_shirt2.webp -------------------------------------------------------------------------------- /public/assets/Products/Shirt/GH_shirt3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/Shirt/GH_shirt3.webp -------------------------------------------------------------------------------- /public/assets/Products/Shirt/GH_shirt4.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/Shirt/GH_shirt4.webp -------------------------------------------------------------------------------- /public/assets/Products/Shirt/GH_shirt5.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/Shirt/GH_shirt5.webp -------------------------------------------------------------------------------- /public/assets/Products/Hoodies/Gh_hoodie1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/Hoodies/Gh_hoodie1.webp -------------------------------------------------------------------------------- /public/assets/Products/Hoodies/Gh_hoodie2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamalCodes/ShopCoders/HEAD/public/assets/Products/Hoodies/Gh_hoodie2.webp -------------------------------------------------------------------------------- /components/Footer/Footer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Footer = () => { 4 | return ( 5 |
Footer
6 | ) 7 | } 8 | 9 | export default Footer -------------------------------------------------------------------------------- /components/herosection/Herosection.module.css: -------------------------------------------------------------------------------- 1 | .shopnow_button { 2 | background: linear-gradient(90deg, #FF9966 0%, #FF5E62 100%); 3 | box-shadow: 0px 5px 10px rgba(149, 149, 149, 0.2); 4 | } -------------------------------------------------------------------------------- /app/monitors/styles.module.css: -------------------------------------------------------------------------------- 1 | .product_main { 2 | -webkit-box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 3 | -moz-box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 4 | box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 5 | } -------------------------------------------------------------------------------- /app/swags/styles.module.css: -------------------------------------------------------------------------------- 1 | .product_main { 2 | -webkit-box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 3 | -moz-box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 4 | box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 5 | } -------------------------------------------------------------------------------- /app/keyboards/styles.module.css: -------------------------------------------------------------------------------- 1 | .product_main { 2 | -webkit-box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 3 | -moz-box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 4 | box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 5 | } -------------------------------------------------------------------------------- /components/productCard/Card.module.css: -------------------------------------------------------------------------------- 1 | .product_main { 2 | -webkit-box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 3 | -moz-box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 4 | box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 5 | } -------------------------------------------------------------------------------- /components/productcard_landscape/styles.module.css: -------------------------------------------------------------------------------- 1 | .product_main { 2 | -webkit-box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 3 | -moz-box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 4 | box-shadow: 0px 0px 17px -2px rgba(255, 132, 0, 0.16); 5 | } -------------------------------------------------------------------------------- /components/productcard_landscape/checkUser.js: -------------------------------------------------------------------------------- 1 | import { useSession, signOut } from "next-auth/react"; 2 | 3 | const checkUser = () => { 4 | const { data: session, status } = useSession(); 5 | if (status === "authenticated") { 6 | return true; 7 | } 8 | }; 9 | 10 | export default checkUser; 11 | -------------------------------------------------------------------------------- /services/GetStripe.js: -------------------------------------------------------------------------------- 1 | import { loadStripe } from "@stripe/stripe-js"; 2 | 3 | let stripePromise; 4 | 5 | const getStripe = () => { 6 | if (!stripePromise) { 7 | stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY); 8 | } 9 | 10 | return stripePromise; 11 | }; 12 | 13 | export default getStripe; 14 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | ## Reporting a Vulnerability 2 | 3 | If you find a security error please **DONOT** make an issue /discussion out of it, talk about it publicly, instead report it with the most details possible to [Tamal Das](https://twitter.com/mrTamall). You can expect an update within the next **36 hours** - if not please be paitent. 4 | 5 | Thankyou. -------------------------------------------------------------------------------- /components/navbar/cartcirlce/CartCircle.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const CartCircle = () => { 4 | return ( 5 | <> 6 | 7 |
8 | 9 | 10 | ) 11 | } 12 | 13 | export default CartCircle -------------------------------------------------------------------------------- /middleware/db.js: -------------------------------------------------------------------------------- 1 | import mongoose, { connect } from "mongoose"; 2 | 3 | const connectDb = (handler) => async (req, res) => { 4 | if (mongoose.connections[0].readyState) { 5 | return handler(req, res); 6 | } 7 | 8 | await mongoose.connect(process.env.MONGO_URI); 9 | return handler(req, res); 10 | }; 11 | 12 | export default connectDb; 13 | -------------------------------------------------------------------------------- /app/swags/[id]/page.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ProductCardLandscape from '@/components/productcard_landscape/ProductCardLandscape'; 3 | 4 | 5 | 6 | const Page = async ({ params: { id } }) => { 7 | 8 | return ( 9 | <> 10 | 11 | 12 | 13 | 14 | ) 15 | } 16 | 17 | export default Page; -------------------------------------------------------------------------------- /app/keyboards/[id]/page.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ProductCardLandscape from '@/components/productcard_landscape/ProductCardLandscape'; 3 | 4 | 5 | 6 | const Page = async ({ params: { id } }) => { 7 | 8 | return ( 9 | <> 10 | 11 | 12 | 13 | 14 | ) 15 | } 16 | 17 | export default Page; -------------------------------------------------------------------------------- /app/monitors/[id]/page.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ProductCardLandscape from '@/components/productcard_landscape/ProductCardLandscape'; 3 | 4 | 5 | 6 | const Page = async ({ params: { id } }) => { 7 | 8 | return ( 9 | <> 10 | 11 | 12 | 13 | 14 | ) 15 | } 16 | 17 | export default Page; -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | experimental: { 4 | appDir: true, 5 | }, 6 | images: { 7 | domains: [ 8 | "i.ibb.co", 9 | "ibb.co", 10 | "lh3.googleusercontent.com", 11 | "avatars.githubusercontent.com", 12 | "shareicon.net", 13 | ], 14 | }, 15 | }; 16 | 17 | module.exports = nextConfig; 18 | -------------------------------------------------------------------------------- /pages/api/user/viewalluser.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Users from "../../../models/UserSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | const users = await Users.find({}); 7 | return res.status(200).json({ users }); 8 | } catch (error) { 9 | console.log(error); 10 | } 11 | }; 12 | 13 | export default connectDb(handler); 14 | -------------------------------------------------------------------------------- /pages/api/hello.js: -------------------------------------------------------------------------------- 1 | import db from "../../middleware/db"; 2 | import Products from "../../models/ProductSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | await db.connect(); 7 | const products = await Products.find(); 8 | return res.status(200).json({ products }); 9 | } catch (error) { 10 | console.log(error); 11 | } 12 | }; 13 | 14 | export default handler; 15 | -------------------------------------------------------------------------------- /global/StoreInitializer.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useRef, useState } from "react"; 4 | import { useStore } from "./store"; 5 | 6 | function StoreInitializer({ cartArray }) { 7 | const initialized = useRef(false); 8 | if (!initialized.current) { 9 | useStore.setState({ cartArray }); 10 | initialized.current = true; 11 | } 12 | return null; 13 | } 14 | 15 | export default StoreInitializer; 16 | -------------------------------------------------------------------------------- /pages/api/products/bestseller.js: -------------------------------------------------------------------------------- 1 | import connectDb from "@/middleware/db"; 2 | import Products from "@/models/ProductSchema"; 3 | 4 | const bestSellerHandler = async (req, res) => { 5 | try { 6 | const bestSellers = await Products.find(); 7 | return res.status(200).json(bestSellers); 8 | } catch (error) { 9 | console.log(error); 10 | } 11 | }; 12 | 13 | export default connectDb(bestSellerHandler); 14 | -------------------------------------------------------------------------------- /pages/api/products/viewproductbyid copy.js: -------------------------------------------------------------------------------- 1 | import connectDb from "@/middleware/db"; 2 | import Products from "@/models/ProductSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | let id = req.query.id; 7 | const product = await Products.findById(id); 8 | return res.status(200).json(product); 9 | } catch (error) { 10 | console.log(error); 11 | } 12 | }; 13 | 14 | export default connectDb(handler); 15 | -------------------------------------------------------------------------------- /pages/api/products/fetchproduct.js: -------------------------------------------------------------------------------- 1 | import connectDb from "@/middleware/db"; 2 | import Products from "@/models/ProductSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | let type = req.query.type; 7 | const product = await Products.find({ productType: type }); 8 | return res.status(200).json(product); 9 | } catch (error) { 10 | console.log(error); 11 | } 12 | }; 13 | 14 | export default connectDb(handler); 15 | -------------------------------------------------------------------------------- /pages/api/products/viewproductbyid.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Products from "../../../models/ProductSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | let id = req.query.id; 7 | const product = await Products.findById(id); 8 | return res.status(200).json({ product }); 9 | } catch (error) { 10 | console.log(error); 11 | } 12 | }; 13 | 14 | export default connectDb(handler); 15 | -------------------------------------------------------------------------------- /pages/api/products/viewallproducts.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Products from "../../../models/ProductSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | let category = req.query.category; 7 | const products = await Products.find({ category: category }); 8 | return res.status(200).json({ products }); 9 | } catch (error) { 10 | console.log(error); 11 | } 12 | }; 13 | 14 | export default connectDb(handler); 15 | -------------------------------------------------------------------------------- /services/shopApi.js: -------------------------------------------------------------------------------- 1 | import db from "../middleware/db"; 2 | 3 | export const fetchallShirts = async (req, res) => { 4 | try { 5 | await db.connect(); 6 | const res = await fetch( 7 | "http://localhost:3000/api/products/viewallproducts?category=tshirts" 8 | ); 9 | if (res.status !== 200) { 10 | throw new Error("Failed to fetch products"); 11 | return; 12 | } 13 | return res.json(); 14 | } catch (error) { 15 | console.log(error); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 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 | .env 34 | -------------------------------------------------------------------------------- /components/productsection/Product.jsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { bearStore } from '@/global/store'; 4 | import React from 'react' 5 | import Card from '../productCard/Card'; 6 | 7 | const Product = ({ products }) => { 8 | const selectedBrand = bearStore((state) => state.selectedBrand); 9 | 10 | return ( 11 |
12 | {products?.map((item, index) => ( 13 | 14 | ))} 15 | 16 | 17 |
18 | ) 19 | } 20 | 21 | export default Product -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/sidebar/static/data.js: -------------------------------------------------------------------------------- 1 | import antesports from "../../../public/assets/brands/antesports.png"; 2 | import logi from "../../../public/assets/brands/logi.png"; 3 | import razer from "../../../public/assets/brands/razer.png"; 4 | 5 | const brandData = [ 6 | { 7 | name: "Ant Esports", 8 | image: antesports, 9 | }, 10 | 11 | { 12 | name: "Logitech", 13 | image: logi, 14 | }, 15 | 16 | { 17 | name: "Razer", 18 | image: razer, 19 | }, 20 | ]; 21 | 22 | const lightingData = ["RGB", "LED", "Backlit"]; 23 | 24 | const sidebardata = { 25 | brandData, 26 | lightingData, 27 | }; 28 | 29 | export default sidebardata; 30 | -------------------------------------------------------------------------------- /public/assets/navbar/bag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /pages/api/user/usertest.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Users from "../../../models/UserSchema"; 3 | import { authOptions } from "../auth/[...nextauth]"; 4 | import { getServerSession } from "next-auth/next"; 5 | 6 | const handler = async (req, res) => { 7 | try { 8 | const session = await getServerSession(req, res, authOptions); 9 | 10 | console.log(session?.user); 11 | 12 | if (!session) { 13 | res.status(401).json({ message: "You must be logged in." }); 14 | return; 15 | } 16 | 17 | return res.status(200).json(session.user); 18 | } catch (error) { 19 | console.log(error); 20 | } 21 | }; 22 | 23 | export default connectDb(handler); 24 | -------------------------------------------------------------------------------- /pages/api/user/loginuser.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Users from "../../../models/UserSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | console.log(req.body); 7 | const { email, password } = req.body; 8 | const user = await Users.findOne({ email: email }); 9 | 10 | if (user) { 11 | if (user.password === password) { 12 | return res.status(200).json({ user }); 13 | } else { 14 | return res.status(401).json({ message: "Password is incorrect" }); 15 | } 16 | } else { 17 | return res.status(500).json({ message: "User not found" }); 18 | } 19 | } catch (error) { 20 | console.log(error); 21 | } 22 | }; 23 | 24 | export default connectDb(handler); 25 | -------------------------------------------------------------------------------- /global/store.js: -------------------------------------------------------------------------------- 1 | // import { create } from "zustand"; 2 | 3 | // export const useStore = create((set) => ({ 4 | // cartArray: [], 5 | // cartLoading: false, 6 | // })); 7 | 8 | // import { create } from "zustand"; 9 | 10 | // export const useStore = create((set) => ({ 11 | // cartArray: [], 12 | // cartLoading: false, 13 | // })); 14 | 15 | "use client"; 16 | 17 | import { create } from "zustand"; 18 | 19 | export const bearStore = create((set) => ({ 20 | openauth: false, 21 | toggleauth: () => set((state) => ({ openauth: !state.openauth })), 22 | 23 | authtype: "login", 24 | setauthtype: (type) => set((state) => ({ authtype: type })), 25 | 26 | selectedBrand: "", 27 | setSelectedBrand: (brand) => set((state) => ({ selectedBrand: brand })), 28 | })); 29 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./pages/**/*.{js,ts,jsx,tsx}", 5 | "./components/**/*.{js,ts,jsx,tsx}", 6 | "./app/**/*.{js,ts,jsx,tsx}", 7 | ], 8 | theme: { 9 | extend: { 10 | fontFamily: { 11 | poppins: ["Poppins", "sans-serif"], 12 | mont: ["Montserrat", "sans-serif"], 13 | }, 14 | colors: { 15 | orange: "#FF8400", 16 | black: "#000000", 17 | }, 18 | }, 19 | screens: { 20 | md: "1200px", 21 | max_md: { max: "1199px" }, 22 | max_th: { max: "1000px" }, 23 | tab: "800px", 24 | max_tab: { max: "799px" }, 25 | mobile: "500px", 26 | max_mobile: { max: "499px" }, 27 | }, 28 | }, 29 | plugins: [], 30 | }; 31 | -------------------------------------------------------------------------------- /pages/api/products/addproduct.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Products from "../../../models/ProductSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | let newprod = new Products({ 7 | productType: req.body.productType, 8 | productName: req.body.productName, 9 | productPrice: req.body.productPrice, 10 | productImage: req.body.productImage, 11 | productDescription: req.body.productDescription, 12 | productQty: req.body.productQty, 13 | productSize: req.body.productSize, 14 | productSlug: req.body.productSlug, 15 | 16 | }); 17 | 18 | await newprod.save(); 19 | return res.status(200).json({ newprod }); 20 | } catch (error) { 21 | console.log(error); 22 | } 23 | }; 24 | 25 | export default connectDb(handler); 26 | -------------------------------------------------------------------------------- /pages/api/products/addproductstocart.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Products from "../../../models/ProductSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | let newprod = new Products({ 7 | productType: req.body.productType, 8 | productName: req.body.productName, 9 | productPrice: req.body.productPrice, 10 | productImage: req.body.productImage, 11 | productDescription: req.body.productDescription, 12 | productQty: req.body.productQty, 13 | productSize: req.body.productSize, 14 | productSlug: req.body.productSlug, 15 | 16 | }); 17 | 18 | await newprod.save(); 19 | return res.status(200).json({ newprod }); 20 | } catch (error) { 21 | console.log(error); 22 | } 23 | }; 24 | 25 | export default connectDb(handler); 26 | -------------------------------------------------------------------------------- /middleware/toastMessage.js: -------------------------------------------------------------------------------- 1 | import { toast, ToastContainer } from "react-toastify"; 2 | import "react-toastify/dist/ReactToastify.css"; 3 | /* import { useNavigate } from "react-router-dom"; */ 4 | 5 | export const showSuccessToast = (message) => { 6 | toast.success(message, { 7 | position: "top-right", 8 | autoClose: 1200, 9 | hideProgressBar: false, 10 | closeOnClick: false, 11 | pauseOnHover: false, 12 | draggable: true, 13 | progress: undefined, 14 | closeButton: false, 15 | }); 16 | }; 17 | export const showErrorToast = (message) => { 18 | toast.error(message, { 19 | position: "top-right", 20 | autoClose: 1300, 21 | hideProgressBar: false, 22 | closeOnClick: false, 23 | pauseOnHover: false, 24 | draggable: true, 25 | progress: undefined, 26 | closeButton: false, 27 | }); 28 | }; 29 | -------------------------------------------------------------------------------- /components/bestseller/BestSellers.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import bestSellerData from "./static/bestSellerdata" 3 | import Card from '../productCard/Card' 4 | 5 | const BestSellers = () => { 6 | return ( 7 |
8 |

Best Sellers

9 |
10 | 11 |
12 | 13 | {bestSellerData.map((item, index) => { 14 | return ( 15 | 16 | 17 | ) 18 | })} 19 |
20 | 21 | 22 |
23 | ) 24 | } 25 | 26 | export default BestSellers -------------------------------------------------------------------------------- /public/assets/navbar/up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/assets/navbar/navlogo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /components/navbar/Navbar.module.css: -------------------------------------------------------------------------------- 1 | .navbar_main { 2 | background: rgba(255, 255, 255, 0.25); 3 | box-shadow: 0 8px 32px 0 rgba(255, 255, 255, 0.25); 4 | backdrop-filter: blur(11px); 5 | -webkit-backdrop-filter: blur(11px); 6 | border-radius: 10px; 7 | } 8 | 9 | /* on hovering on product_text, the .dropdown_menu must be .dropdown_menu.active */ 10 | 11 | .rotated { 12 | transform: rotate(90deg); 13 | animation: rotate 0.3s linear forwards; 14 | } 15 | 16 | @keyframes rotate { 17 | 0% { 18 | transform: rotate(0deg); 19 | } 20 | 21 | 100% { 22 | transform: rotate(180deg); 23 | } 24 | } 25 | 26 | .unrotated { 27 | transform: rotate(300deg); 28 | animation: unrotate 0.3s linear forwards; 29 | } 30 | 31 | @keyframes unrotate { 32 | 0% { 33 | transform: rotate(180deg); 34 | } 35 | 36 | 100% { 37 | transform: rotate(0deg); 38 | } 39 | } -------------------------------------------------------------------------------- /models/ProductSchema.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const ProductSchema = new mongoose.Schema( 4 | { 5 | productType: { 6 | type: String, 7 | required: true, 8 | }, 9 | productName: { 10 | type: String, 11 | required: true, 12 | }, 13 | productPrice: { 14 | type: Number, 15 | required: true, 16 | }, 17 | productDescription: { 18 | type: String, 19 | required: true, 20 | }, 21 | productImage: { 22 | type: String, 23 | required: true, 24 | }, 25 | productQty: { 26 | type: Number, 27 | required: true, 28 | }, 29 | productSize: { 30 | type: String, 31 | }, 32 | productSlug: { 33 | type: String, 34 | required: true, 35 | }, 36 | }, 37 | { timetamps: true } 38 | ); 39 | 40 | const Products = 41 | mongoose.models.product || mongoose.model("product", ProductSchema); 42 | 43 | export default Products; 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "shopcoders", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@next/font": "13.1.6", 13 | "@stripe/stripe-js": "^1.35.0", 14 | "autoprefixer": "^10.4.14", 15 | "axios": "^1.3.0", 16 | "bson": "^5.0.0", 17 | "dotenv": "^16.0.3", 18 | "eslint-config-next": "^13.2.2", 19 | "js-cookie": "^3.0.1", 20 | "mongodb": "^5.0.0", 21 | "mongoose": "^6.9.0", 22 | "next": "^13.2.2", 23 | "next-auth": "^4.19.2", 24 | "react": "^18.2.0", 25 | "react-dom": "^18.2.0", 26 | "react-icons": "^4.7.1", 27 | "react-query": "^3.39.3", 28 | "react-toastify": "^9.1.2", 29 | "stripe": "^11.9.1", 30 | "swr": "^2.0.3", 31 | "zustand": "^4.3.2" 32 | }, 33 | "devDependencies": { 34 | "tailwindcss": "^3.3.1" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pages/api/user/adduser.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Users from "../../../models/UserSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | console.log(req.body); 7 | 8 | 9 | 10 | const { 11 | name, 12 | email, 13 | password, 14 | username, 15 | address, 16 | state, 17 | pincode, 18 | city, 19 | phone, 20 | } = req.body; 21 | let newuser = new Users({ 22 | firstName: name.split(" ")[0], 23 | lastName: name.split(" ")[1], 24 | email: email, 25 | password: password, 26 | username: username, 27 | address: address, 28 | state: state, 29 | pincode: pincode, 30 | city: city, 31 | phone: phone, 32 | }); 33 | 34 | await newuser.save(); 35 | return res.status(200).json({ newuser }); 36 | } catch (error) { 37 | console.log(error); 38 | } 39 | }; 40 | 41 | export default connectDb(handler); 42 | -------------------------------------------------------------------------------- /pages/api/user/resetcart.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Users from "../../../models/UserSchema"; 3 | import { authOptions } from "../auth/[...nextauth]"; 4 | import { getServerSession } from "next-auth/next"; 5 | 6 | const handler = async (req, res) => { 7 | try { 8 | const session = await getServerSession(req, res, authOptions); 9 | const emptycart = []; 10 | 11 | if (!session) { 12 | res.status(401).json({ message: "You must be logged in." }); 13 | return; 14 | } 15 | const user = await Users.findOne({ email: session.user.email }); 16 | 17 | if (user) { 18 | user.cartproducts = emptycart; 19 | await user.save(); 20 | 21 | console.log(user); 22 | 23 | return res.status(200).json({ user }); 24 | } else { 25 | return res.status(404).json({ error: "User not found" }); 26 | } 27 | } catch (error) { 28 | console.log(error); 29 | } 30 | }; 31 | 32 | export default connectDb(handler); 33 | -------------------------------------------------------------------------------- /public/thirteen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Tamal Das 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /pages/api/user/removefromcart.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Users from "../../../models/UserSchema"; 3 | import { authOptions } from "../auth/[...nextauth]"; 4 | import { getServerSession } from "next-auth/next"; 5 | 6 | const handler = async (req, res) => { 7 | try { 8 | const session = await getServerSession(req, res, authOptions); 9 | 10 | if (!session) { 11 | res.status(401).json({ message: "You must be logged in." }); 12 | return; 13 | } 14 | const user = await Users.findOne({ email: session.user.email }); 15 | console.log(user.cartproducts); 16 | 17 | if (user) { 18 | const product = req.body; 19 | 20 | user.cartproducts = user.cartproducts.filter( 21 | (cartproduct) => !cartproduct._id.equals(product._id) 22 | ); 23 | await user.save(); 24 | 25 | console.log(user); 26 | 27 | return res.status(200).json({ user }); 28 | } else { 29 | return res.status(404).json({ error: "User not found" }); 30 | } 31 | } catch (error) { 32 | console.log(error); 33 | } 34 | }; 35 | 36 | export default connectDb(handler); 37 | -------------------------------------------------------------------------------- /public/assets/Products/misc/cart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/swags/page.jsx: -------------------------------------------------------------------------------- 1 | 2 | 3 | import Sidebar from '@/components/sidebar/Sidebar' 4 | import React from 'react' 5 | import { MongoClient } from 'mongodb'; 6 | import Product from '@/components/productsection/Product'; 7 | 8 | 9 | 10 | async function connectAndFetchDB() { 11 | const uri = process.env.MONGO_URI; 12 | const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true }); 13 | 14 | try { 15 | await client.connect(); 16 | 17 | const collection = client.db('test').collection('products'); 18 | const result = await collection.find({ productType: "swags" }).toArray(); 19 | return result; 20 | } catch (err) { 21 | console.error(err); 22 | } finally { 23 | await client.close(); 24 | 25 | } 26 | } 27 | 28 | const Page = async () => { 29 | 30 | 31 | const data = await connectAndFetchDB() 32 | 33 | return ( 34 | <> 35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | ) 45 | } 46 | 47 | export default Page -------------------------------------------------------------------------------- /app/monitors/page.jsx: -------------------------------------------------------------------------------- 1 | 2 | 3 | import Sidebar from '@/components/sidebar/Sidebar' 4 | import React from 'react' 5 | import { MongoClient } from 'mongodb'; 6 | import Product from '@/components/productsection/Product'; 7 | 8 | 9 | 10 | async function connectAndFetchDB() { 11 | const uri = process.env.MONGO_URI; 12 | const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true }); 13 | 14 | try { 15 | await client.connect(); 16 | 17 | const collection = client.db('test').collection('products'); 18 | const result = await collection.find({ productType: "monitors" }).toArray(); 19 | return result; 20 | } catch (err) { 21 | console.error(err); 22 | } finally { 23 | await client.close(); 24 | 25 | } 26 | } 27 | 28 | const Page = async () => { 29 | 30 | 31 | const data = await connectAndFetchDB() 32 | 33 | return ( 34 | <> 35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | ) 45 | } 46 | 47 | export default Page -------------------------------------------------------------------------------- /app/keyboards/page.jsx: -------------------------------------------------------------------------------- 1 | 2 | 3 | import Sidebar from '@/components/sidebar/Sidebar' 4 | import React from 'react' 5 | import { MongoClient } from 'mongodb'; 6 | import Product from '@/components/productsection/Product'; 7 | 8 | 9 | 10 | async function connectAndFetchDB() { 11 | const uri = process.env.MONGO_URI; 12 | const client = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true }); 13 | 14 | try { 15 | await client.connect(); 16 | 17 | const collection = client.db('test').collection('products'); 18 | const result = await collection.find({ productType: "keyboards" }).toArray(); 19 | return result; 20 | } catch (err) { 21 | console.error(err); 22 | } finally { 23 | await client.close(); 24 | 25 | } 26 | } 27 | 28 | const Page = async () => { 29 | 30 | 31 | const data = await connectAndFetchDB() 32 | 33 | return ( 34 | <> 35 |
36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 | 44 | ) 45 | } 46 | 47 | export default Page -------------------------------------------------------------------------------- /pages/api/user/reducecartitems.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Users from "../../../models/UserSchema"; 3 | import { authOptions } from "../auth/[...nextauth]"; 4 | import { getServerSession } from "next-auth/next"; 5 | 6 | const handler = async (req, res) => { 7 | try { 8 | const session = await getServerSession(req, res, authOptions); 9 | 10 | if (!session) { 11 | res.status(401).json({ message: "You must be logged in." }); 12 | return; 13 | } 14 | const user = await Users.findOne({ email: session.user.email }); 15 | 16 | if (user) { 17 | const product = req.body; 18 | const foundProduct = user.cartproducts.find( 19 | (cartproduct) => cartproduct.productSlug === product.productSlug 20 | ); 21 | 22 | if (foundProduct) { 23 | foundProduct.totalPrice = foundProduct.totalPrice - product.productPrice; 24 | foundProduct.purchasedQty = foundProduct.purchasedQty - 1; 25 | } 26 | 27 | await user.save(); 28 | 29 | return res.status(200).json(user); 30 | } else { 31 | return res.status(404).json({ error: "User not found" }); 32 | } 33 | } catch (error) { 34 | console.log(error); 35 | } 36 | }; 37 | 38 | export default connectDb(handler); 39 | -------------------------------------------------------------------------------- /pages/api/user/viewuserdetails.js: -------------------------------------------------------------------------------- 1 | /* import connectDb from "../../../middleware/db"; 2 | import Users from "../../../models/UserSchema"; 3 | 4 | const handler = async (req, res) => { 5 | try { 6 | let email = req.query.email; 7 | const user = await Users.findOne({ email: email }); 8 | return res.status(200).json({ user }); 9 | } catch (error) { 10 | console.log(error); 11 | } 12 | }; 13 | 14 | export default connectDb(handler); */ 15 | 16 | import connectDb from "../../../middleware/db"; 17 | import Users from "../../../models/UserSchema"; 18 | import { authOptions } from "../auth/[...nextauth]"; 19 | import { getServerSession } from "next-auth/next"; 20 | 21 | const handler = async (req, res) => { 22 | try { 23 | const session = await getServerSession(req, res, authOptions); 24 | 25 | if (!session) { 26 | res.status(401).json({ message: "You must be logged in." }); 27 | return; 28 | } 29 | 30 | const user = await Users.findOne({ email: session.user.email }); 31 | 32 | if (user) { 33 | return res.status(200).json({ user }); 34 | } else { 35 | return res.status(200).json({ user, error: "User not found" }); 36 | } 37 | } catch (error) { 38 | console.log(error); 39 | } 40 | }; 41 | 42 | export default connectDb(handler); 43 | -------------------------------------------------------------------------------- /components/productCard/Card.jsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link' 2 | import React from 'react' 3 | import styles from "./Card.module.css" 4 | import Image from 'next/image' 5 | import bag from "../../public/assets/navbar/bag.svg" 6 | 7 | const Card = ({ item }) => { 8 | return ( 9 | 10 | 11 |
12 | 13 | 14 |
15 |

{item.productName}

16 | 17 |
18 |

⭐⭐⭐⭐⭐

19 | 20 | 21 |
22 |

₹{" "} {item.productPrice}

23 | 24 |
25 |
26 |
27 |
28 | 29 | 30 | 31 | ) 32 | } 33 | 34 | export default Card -------------------------------------------------------------------------------- /app/layout.jsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { SessionProvider } from "next-auth/react"; 4 | import Navbar from '@/components/navbar/Navbar'; 5 | import "./globals.css"; 6 | 7 | export default function RootLayout({ children }) { 8 | return ( 9 | 10 | 11 | CoderCrate 12 | 13 | 14 | 15 | 16 | 17 | {/* //* Fonts */} 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {children} 32 | 33 | 34 | 35 | 36 | ) 37 | } 38 | -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /pages/api/user/addtocart.js: -------------------------------------------------------------------------------- 1 | import connectDb from "../../../middleware/db"; 2 | import Users from "../../../models/UserSchema"; 3 | import { authOptions } from "../auth/[...nextauth]"; 4 | import { getServerSession } from "next-auth/next"; 5 | 6 | const handler = async (req, res) => { 7 | try { 8 | const session = await getServerSession(req, res, authOptions); 9 | 10 | if (!session) { 11 | res.status(401).json({ message: "You must be logged in." }); 12 | return; 13 | } 14 | const user = await Users.findOne({ email: session.user.email }); 15 | 16 | 17 | if (user) { 18 | const product = req.body; 19 | console.log(product); 20 | 21 | const foundProduct = user.cartproducts.find( 22 | (cartproduct) => cartproduct.productSlug === product.productSlug 23 | ); 24 | 25 | console.log(foundProduct); 26 | 27 | if (foundProduct) { 28 | foundProduct.totalPrice = foundProduct.totalPrice + product.totalPrice; 29 | foundProduct.purchasedQty = 30 | foundProduct.purchasedQty + product.purchasedQty; 31 | } else { 32 | user.cartproducts.push(product); 33 | } 34 | 35 | await user.save(); 36 | 37 | return res.status(200).json(user); 38 | } else { 39 | return res.status(404).json({ error: "User not found" }); 40 | } 41 | } catch (error) { 42 | console.log(error); 43 | } 44 | }; 45 | 46 | export default connectDb(handler); 47 | -------------------------------------------------------------------------------- /pages/api/stripe.js: -------------------------------------------------------------------------------- 1 | import loadConfig from "next/dist/server/config"; 2 | import Stripe from "stripe"; 3 | 4 | const stripe = new Stripe(process.env.STRIPE_SECRET_KEY); 5 | 6 | export default async function handler(req, res) { 7 | if (req.method === "POST") { 8 | try { 9 | const params = { 10 | submit_type: "pay", 11 | mode: "payment", 12 | payment_method_types: ["card"], 13 | billing_address_collection: "auto", 14 | shipping_options: [{ shipping_rate: "shr_1LVfzVGVURq38X9NfyWDtQK3" }], 15 | 16 | line_items: req.body.map((item) => { 17 | return { 18 | price_data: { 19 | currency: "inr", 20 | product_data: { 21 | name: item.productName, 22 | images: [item.productImage], 23 | }, 24 | unit_amount: item.productPrice * 100, 25 | }, 26 | quantity: item.purchasedQty, 27 | }; 28 | }), 29 | success_url: `${req.headers.origin}/paymentsucess`, 30 | cancel_url: `${req.headers.origin}/canceled`, 31 | }; 32 | 33 | // Create Checkout Sessions from body params. 34 | const session = await stripe.checkout.sessions.create(params); 35 | 36 | res.status(200).json(session); 37 | } catch (err) { 38 | res.status(err.statusCode || 500).json(err.message); 39 | } 40 | } else { 41 | res.setHeader("Allow", "POST"); 42 | res.status(405).end("Method Not Allowed"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /components/navbar/dropdown/Dropdown.jsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import React from 'react' 4 | import styles from "./Dropdown.module.css" 5 | import Link from 'next/link'; 6 | 7 | const Dropdown = ({ open, setOpen }) => { 8 | function closeDropdown() { 9 | setOpen(false); 10 | } 11 | 12 | 13 | 14 | return ( 15 |
19 | { 24 | closeDropdown(); 25 | }} 26 | > 27 | Keyboards 28 | 29 | { 34 | closeDropdown(); 35 | }} 36 | > 37 | Monitors 38 | 39 | { 44 | closeDropdown(); 45 | }} 46 | > 47 | Swags 48 | 49 |
50 | ); 51 | } 52 | 53 | export default Dropdown -------------------------------------------------------------------------------- /pages/api/auth/[...nextauth].js: -------------------------------------------------------------------------------- 1 | import NextAuth from "next-auth"; 2 | import CredentialsProvider from "next-auth/providers/credentials"; 3 | import GoogleProvider from "next-auth/providers/google"; 4 | import GithubProvider from "next-auth/providers/github"; 5 | import mongoose from "mongoose"; 6 | import Users from "../../../models/UserSchema"; 7 | 8 | const dbConnect = () => { 9 | if (mongoose.connection.readyState >= 1) return; 10 | 11 | mongoose.connect(process.env.MONGO_URI); 12 | }; 13 | 14 | export const authOptions = { 15 | session: { 16 | strategy: "jwt", 17 | }, 18 | providers: [ 19 | GoogleProvider({ 20 | clientId: process.env.GOOGLE_ID, 21 | clientSecret: process.env.GOOGLE_SECRET, 22 | }), 23 | GithubProvider({ 24 | clientId: process.env.GITHUB_ID, 25 | clientSecret: process.env.GITHUB_SECRET, 26 | }), 27 | CredentialsProvider({ 28 | async authorize(credentials, req) { 29 | dbConnect(); 30 | 31 | const { email, password } = credentials; 32 | 33 | const user = await Users.findOne({ email }); 34 | 35 | if (!user) { 36 | throw new Error("Invalid Email or Password"); 37 | } 38 | 39 | if (user.password !== password) { 40 | throw new Error("Invalid Email or Password"); 41 | } 42 | 43 | return user; 44 | }, 45 | }), 46 | ], 47 | pages: { 48 | signIn: "/", 49 | }, 50 | secret: process.env.NEXTAUTH_SECRET, 51 | }; 52 | 53 | export default NextAuth(authOptions); 54 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution guidelines 🔐 2 | 3 | **Hello contributors, I want you to stick to the below-listed contribution guidelines. Happy contributing.** 4 | 5 |
6 | 7 | - Issues will be assigned on a **First-Come-First-Serve** basis and are applicable only when they have opted through GitHub. 8 | - If a contributor is unable to solve the allotted issue, the issue needs to be passed to other contenders at the discretion of the maintainer/owner. 9 | 10 | 11 | ## General 12 | 13 | - `Fork` the repo to your account. 14 | - `git clone` to clone the repo 15 | - Make a `.env` file where you put your `SERVER_URL` to be `http://localhost:3000` 16 | 17 | - Making a branch is **optional**, else contribute to the main branch of your forked repo. 18 | 19 | 20 | ## After changes : 21 | - Make sure you do `git pull` to pull the latest version of the code 22 | - `git add .` to stage for commits 23 | - `git commit -am ` for committing the code. 24 | - **NOTICE: Message will be :** 25 | - `fix: ` 26 | - `feat : ` 27 | - `docs : ` 28 | - `chore : ` 29 | 30 | 31 |
32 | 33 | - Then create a Pull Request and wait for review. 34 | - Put up a good pull request title relevant to the issue you are solving. Example `Feat: Search Bar Story added` 35 | - Don't forget to attach **`Screenshots, Proper Description and Issue Number`** 36 | - Remember to be respectful to other contributors, mentors, community 37 | - Don't raise invalid/spam issues they will be closed !! 38 | 39 |
-------------------------------------------------------------------------------- /components/herosection/Herosection.jsx: -------------------------------------------------------------------------------- 1 | import Image from 'next/image' 2 | import React from 'react' 3 | import herobanner from "../../public/assets/hero/herobanner.svg" 4 | import styles from "./Herosection.module.css" 5 | 6 | const Herosection = () => { 7 | return ( 8 | <> 9 | 10 |
11 | 12 | 13 |
14 |
15 |

16 | Revolutionize 17 |

18 |

your coding game.

19 | 20 |

Shop now at CoderCrate,
the ultimate place for your coding needs.

21 | 22 | 23 |
24 | 25 |
26 | 27 |
28 |
29 | 30 |
31 | 32 | 33 | ) 34 | } 35 | 36 | export default Herosection -------------------------------------------------------------------------------- /components/auth/authRegex.js: -------------------------------------------------------------------------------- 1 | import { showErrorToast } from "@/middleware/toastMessage"; 2 | 3 | const emailRegex = 4 | /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 5 | const phoneRegex = /^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/; 6 | const usernameRegex = /^[a-zA-Z0-9]+$/; 7 | const nameRegex = /^[a-zA-Z]+$/; 8 | 9 | export const AuthRegex = (creds) => { 10 | 11 | 12 | if (creds.firstName && !nameRegex.test(creds.firstName)) { 13 | showErrorToast("No special characters allowed in first name"); 14 | return false; 15 | } 16 | 17 | if (creds.lastName && !nameRegex.test(creds.lastName)) { 18 | showErrorToast("No special characters allowed in last name"); 19 | return false; 20 | } 21 | 22 | if (creds.firstName && creds.firstName.length < 2) { 23 | showErrorToast("First name must be bigger than 2 characters"); 24 | return false; 25 | } 26 | 27 | if (creds.lastName && creds.lastName.length < 2) { 28 | showErrorToast("Last name must be bigger than 2 characters"); 29 | return false; 30 | } 31 | 32 | if (creds.email && !emailRegex.test(creds.email)) { 33 | showErrorToast("Invalid Email"); 34 | return false; 35 | } 36 | 37 | if (creds.username && !usernameRegex.test(creds.username)) { 38 | showErrorToast("No special characters allowed in username"); 39 | return false; 40 | } 41 | 42 | if (creds.city && !usernameRegex.test(creds.city)) { 43 | showErrorToast("No special characters allowed in city name"); 44 | return false; 45 | } 46 | if (creds.phone && !phoneRegex.test(creds.phone)) { 47 | showErrorToast("Invalid Phone Number"); 48 | return false; 49 | } 50 | 51 | return true; 52 | }; 53 | -------------------------------------------------------------------------------- /pages/api/stripecart.js: -------------------------------------------------------------------------------- 1 | import loadConfig from "next/dist/server/config"; 2 | import Stripe from "stripe"; 3 | 4 | const stripe = new Stripe(process.env.STRIPE_SECRET_KEY); 5 | 6 | export default async function handler(req, res) { 7 | if (req.method === "POST") { 8 | try { 9 | const params = { 10 | submit_type: "pay", 11 | mode: "payment", 12 | payment_method_types: ["card"], 13 | billing_address_collection: "auto", 14 | shipping_options: [{ shipping_rate: "shr_1LVfzVGVURq38X9NfyWDtQK3" }], 15 | 16 | line_items: req.body.map((item) => { 17 | return { 18 | price_data: { 19 | currency: "inr", 20 | product_data: { 21 | name: item.productName, 22 | images: [item.productImage], 23 | }, 24 | unit_amount: item.productPrice * 100, 25 | }, 26 | quantity: item.purchasedQty, 27 | }; 28 | }), 29 | success_url: `${req.headers.origin}/paymentsucess`, 30 | cancel_url: `${req.headers.origin}/canceled`, 31 | }; 32 | 33 | // Create Checkout Sessions from body params. 34 | const session = await stripe.checkout.sessions.create(params); 35 | 36 | res.status(200).json(session); 37 | } catch (err) { 38 | res.status(err.statusCode || 500).json(err.message); 39 | } 40 | } else { 41 | res.setHeader("Allow", "POST"); 42 | res.status(405).end("Method Not Allowed"); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /public/assets/navbar/ham.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer components { 6 | .blackheader { 7 | @apply font-poppins text-black text-[5rem] leading-[5rem] font-[600] ml-[-4px]; 8 | } 9 | 10 | .blackheader_tab { 11 | @apply text-[4rem] leading-[4rem] break-all; 12 | } 13 | 14 | .blackheader_mobile { 15 | @apply text-[2.4rem] leading-[2.4rem] break-all; 16 | } 17 | 18 | 19 | .blackheader2 { 20 | @apply font-poppins text-black text-[4rem] leading-[5rem] font-[600] ml-[-4px] text-center; 21 | } 22 | 23 | .blackheader2_tab { 24 | @apply text-[3rem] leading-[3rem] break-all; 25 | } 26 | 27 | .blackheader2_mobile { 28 | @apply text-[2rem] leading-[2rem] break-all; 29 | } 30 | 31 | 32 | /* //* BRANDS STYLING FOR SIDEBAR */ 33 | 34 | .brands_container { 35 | @apply flex items-center gap-2 cursor-default p-[10px] rounded-[8px]; 36 | } 37 | 38 | .brands_container:hover { 39 | @apply bg-slate-100; 40 | } 41 | 42 | .brands_text { 43 | @apply font-poppins font-[400] text-[1.1rem] text-black tracking-[0.1rem] 44 | } 45 | 46 | .authinput { 47 | @apply block w-full px-3 py-2 text-gray-900 placeholder-gray-500 border border-gray-300 rounded-md shadow-sm; 48 | } 49 | 50 | .authinput:focus { 51 | @apply outline-none ring-orange border-orange; 52 | } 53 | 54 | } 55 | 56 | /* ===== Scrollbar CSS ===== */ 57 | /* Firefox */ 58 | * { 59 | scrollbar-width: auto; 60 | scrollbar-color: #FF8400 #28282b00; 61 | } 62 | 63 | /* Chrome, Edge, and Safari */ 64 | *::-webkit-scrollbar { 65 | width: 7px; 66 | } 67 | 68 | *::-webkit-scrollbar-track { 69 | background: #28282b00; 70 | } 71 | 72 | *::-webkit-scrollbar-thumb { 73 | background-color: #FF8400; 74 | border-radius: 10px; 75 | } -------------------------------------------------------------------------------- /app/page.jsx: -------------------------------------------------------------------------------- 1 | // "use client" 2 | 3 | // import React, { useEffect, useState } from "react"; 4 | // import styles from "../styles/Home.module.css"; 5 | // import Image from "next/legacy/image"; 6 | // import shoppingbtn from "../public/assets/Landing/ShopNowButton.png"; 7 | // import ProductsBanner from "./ProductsBanner"; 8 | // import { ToastContainer } from "react-toastify"; 9 | // import "react-toastify/dist/ReactToastify.css"; 10 | 11 | 12 | // const Home = () => { 13 | 14 | // return ( 15 | // <> 16 | // 29 | //
30 | 31 | //
32 | 33 | //
34 | //
35 | 36 | // Trade-in-offer 37 | //

Super value deal

38 | //

On all products

39 | 40 | //

Save more with coupons & up to 70% off for black friday sale !

41 | 42 | 43 | 44 | //
45 | 46 | // shopping button 47 | 48 | 49 | 50 | //
51 | 52 | //
53 | //
54 | 55 | // 56 | // ); 57 | // }; 58 | 59 | // export default Home; 60 | 61 | 62 | "use client"; 63 | 64 | import React from "react"; 65 | import BestSellers from "@/components/bestseller/BestSellers"; 66 | import Herosection from "@/components/herosection/Herosection"; 67 | 68 | const Page = () => { 69 | return ( 70 | <> 71 | 72 | 73 | 74 | ); 75 | }; 76 | 77 | export default Page; 78 | -------------------------------------------------------------------------------- /app/paymentsucess/page.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import Image from "next/image"; 4 | import React, { useState } from "react"; 5 | import styles from "../../styles/Payment.module.css"; 6 | import signupbanner from "../../public/assets/auth/authbanner.png"; 7 | import { useSession } from "next-auth/react" 8 | import { useSWRConfig } from 'swr' 9 | import { useRouter } from 'next/navigation' 10 | 11 | const Authcard = () => { 12 | const { mutate } = useSWRConfig() 13 | const { data: session, status } = useSession() 14 | const router = useRouter() 15 | 16 | 17 | const handleResetCart = async () => { 18 | 19 | const resetusercart = await fetch(`${process.env.NEXT_PUBLIC_URL}/api/user/resetcart`) 20 | 21 | if (resetusercart.status === 200) { 22 | mutate(`${process.env.NEXT_PUBLIC_URL}/api/user/viewuserdetails`) 23 | } 24 | 25 | router.push("/") 26 | 27 | }; 28 | 29 | return ( 30 | <> 31 | 32 | 33 |
34 |
35 | 36 |
37 | 38 | 39 |
40 | 41 | 42 |
43 |

Hi {session?.user?.name.split(" ")[0]},
your order has been made 🎉

You can track it in our { 44 | handleResetCart(); 45 | }}>orders page. Keep shopping !

46 | 54 | 55 |
56 |
57 |
58 | 59 | ); 60 | }; 61 | 62 | export default Authcard; 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Your paragraph text](https://user-images.githubusercontent.com/72851613/222189087-c794f4cb-5815-4307-b6de-6d8e8f720278.png) 2 | 3 | 4 |

What is ShopCoders ?

5 | 6 |
7 | Shopcoders is an E-Commerce platform, made by the coders for the coders. We mainly focus on selling Merchandise Swag stickers that the devs love. 8 |
9 | 10 |
11 | 12 |

Tech stack 👩‍💻

13 | 14 |
15 | 16 | ![]( https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB) ![]( https://img.shields.io/badge/NextJS%20v13-20232A?style=for-the-badge&logo=vercel&logoColor=61DAFB) ![]( https://img.shields.io/badge/CSS-239120?&style=for-the-badge&logo=css3&logoColor=white) C ![]( https://img.shields.io/badge/JavaScript-323330?style=for-the-badge&logo=javascript&logoColor=F7DF1E) ![]( https://img.shields.io/badge/MongoDB-4EA94B?style=for-the-badge&logo=mongodb&logoColor=white) ![](https://img.shields.io/badge/Vercel-000000?style=for-the-badge&logo=vercel&logoColor=white) ![React](https://img.shields.io/badge/zustand-%2320232a.svg?style=for-the-badge&logo=react&logoColor=%2361DAFB) ![](https://img.shields.io/badge/NextAuth-FD3A5C?style=for-the-badge&logo=hotjar&logoColor=white) ![](https://img.shields.io/badge/Stripe-626CD9?style=for-the-badge&logo=Stripe&logoColor=white) 17 | 18 |
19 |
20 | 21 |

Guidelines & License 📜

22 | 23 |
24 | 25 | **[Setup guidelines](https://github.com/IAmTamal/ShopCoders) 🛠**
26 | **[Contributing guidelines](https://github.com/IAmTamal/ShopCoders/blob/main/CONTRIBUTING.md) 🔐**
27 | 28 | **[License](https://github.com/IAmTamal/ShopCoders/blob/main/LICENSE) ✅**
29 | **[Code of Conduct](https://github.com/IAmTamal/ShopCoders/blob/main/CODE_OF_CONDUCT.md) ✅**
30 | 31 | 32 |
33 |
34 | 35 |

Thank you everyone! 💚

36 | 37 |
38 | A heartfelt thank you to those who have contributed to this project. We are really grateful towards your contribution. 39 | You all are amazing. Opensource for the win 🚀 40 |
41 | -------------------------------------------------------------------------------- /components/navbar/authbutton/AuthButton.jsx: -------------------------------------------------------------------------------- 1 | import { bearStore } from "@/global/store"; 2 | import React from "react"; 3 | import { signOut, useSession } from "next-auth/react"; 4 | import { showErrorToast } from "@/middleware/toastMessage"; 5 | 6 | const AuthButton = ({ showauthmodal, setshowauthmodal }) => { 7 | const setauthtype = bearStore((state) => state.setauthtype); 8 | const { data: session, status } = useSession(); 9 | 10 | return ( 11 | <> 12 |
13 | 14 | {session?.user ? ( 15 | 24 | ) : ( 25 | <> 26 | 35 | 44 | 45 | )} 46 |
47 | 48 | ); 49 | }; 50 | 51 | export default AuthButton; 52 | -------------------------------------------------------------------------------- /components/sidebar/Sidebar.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { bearStore } from "@/global/store"; 4 | import React from "react"; 5 | import sidebardata from "./static/data"; 6 | import Image from "next/image"; 7 | 8 | const Sidebar = () => { 9 | const openauth = bearStore((state) => state.openauth); 10 | const setSelectedBrand = bearStore((state) => state.setSelectedBrand); 11 | 12 | return ( 13 | <> 14 | 15 |
16 | 17 | 18 |
19 |

20 | Filter by Brands 21 |

22 | 23 |
24 | { 25 | sidebardata.brandData.map((item, index) => { 26 | return (
{ 27 | setSelectedBrand(item.name); 28 | }} > 29 | Ant Esports 36 |

{item.name}

37 |
) 38 | }) 39 | } 40 | 41 |
42 |
43 | 44 |
45 |

46 | Filter by Lighting 47 |

48 | 49 |
50 | { 51 | sidebardata.lightingData.map((item, index) => { 52 | return ( 53 |
54 |

{item}

55 |
56 | ) 57 | }) 58 | } 59 |
60 |
61 | 62 | 63 |
64 | 65 | ); 66 | }; 67 | 68 | export default Sidebar; 69 | -------------------------------------------------------------------------------- /components/navbar/dropdown/Dropdown.module.css: -------------------------------------------------------------------------------- 1 | .dropdown_menu { 2 | position: absolute; 3 | top: 50px; 4 | right: 0px; 5 | background-color: #fff; 6 | /* background-color: #1B1B1B; */ 7 | border-radius: 8px; 8 | padding: 10px 20px; 9 | width: 150px; 10 | font-family: var(--font-family); 11 | justify-content: space-evenly; 12 | font-style: normal; 13 | font-weight: 300; 14 | font-size: 15px; 15 | letter-spacing: 1.5px; 16 | text-transform: capitalize; 17 | cursor: pointer; 18 | /* color: #b0b0b0; */ 19 | border: 2px solid #FF8400; 20 | } 21 | 22 | .dropdown_menu::before { 23 | content: ''; 24 | position: absolute; 25 | top: -11px; 26 | right: 20px; 27 | height: 20px; 28 | width: 20px; 29 | background: #fff; 30 | /* background-color: #1B1B1B; */ 31 | transform: rotate(45deg); 32 | border: 2px solid #FF8400; 33 | border-right: none; 34 | border-bottom: none; 35 | } 36 | 37 | .dropdown_menu.active { 38 | opacity: 1; 39 | visibility: visible; 40 | transform: translateY(0); 41 | transition: 500ms ease; 42 | } 43 | 44 | .dropdown_menu.inactive { 45 | opacity: 0; 46 | visibility: hidden; 47 | transform: translateY(-20px); 48 | transition: 500ms ease; 49 | } 50 | 51 | 52 | 53 | .dropdown_menu ul li { 54 | padding: 10px 0; 55 | border-top: 1px solid rgba(0, 0, 0, 0.05); 56 | } 57 | 58 | .dropdown_texts:hover { 59 | color: rgb(212, 33, 9); 60 | cursor: pointer; 61 | } 62 | 63 | .dropdown_menu ul li:hover img { 64 | opacity: 1; 65 | cursor: pointer; 66 | } 67 | 68 | .dropdownItem { 69 | display: flex; 70 | margin: 10px auto; 71 | } 72 | 73 | .dropdownItem img { 74 | max-width: 20px; 75 | margin-right: 10px; 76 | opacity: 0.5; 77 | transition: 500ms; 78 | } 79 | 80 | .dropdownItem a { 81 | max-width: 100px; 82 | margin-left: 10px; 83 | transition: 500ms; 84 | } 85 | 86 | .dropdown_menu ul li { 87 | padding: 10px 0; 88 | border-top: 1px solid rgba(0, 0, 0, 0.05); 89 | } 90 | 91 | .dropdown_menu ul li:hover a { 92 | color: rgb(212, 33, 9); 93 | cursor: pointer; 94 | } 95 | 96 | .dropdown_menu ul li:hover img { 97 | opacity: 1; 98 | cursor: pointer; 99 | } 100 | 101 | .dropdownItem { 102 | display: flex; 103 | margin: 10px auto; 104 | } 105 | 106 | .dropdownItem img { 107 | max-width: 20px; 108 | margin-right: 10px; 109 | opacity: 0.5; 110 | transition: 500ms; 111 | } 112 | 113 | .dropdownItem a { 114 | max-width: 100px; 115 | margin-left: 10px; 116 | transition: 500ms; 117 | } -------------------------------------------------------------------------------- /styles/ProductsBanner.module.css: -------------------------------------------------------------------------------- 1 | .pb_main { 2 | /* height: 100vh; */ 3 | width: 100%; 4 | background-position: right 0; 5 | background-size: cover; 6 | padding: 100px 80px; 7 | } 8 | 9 | .pb_header1 { 10 | font-size: 60px; 11 | font-family: 'Montserrat', sans-serif; 12 | text-align: center; 13 | font-weight: 700; 14 | margin-bottom: 20px; 15 | width: 60%; 16 | margin: auto; 17 | } 18 | 19 | .pb_subheader1 { 20 | font-size: 22px; 21 | text-align: center; 22 | margin-top: 20px; 23 | font-family: 'Poppins', sans-serif; 24 | } 25 | 26 | .pb_cardsdiv { 27 | display: flex; 28 | justify-content: center; 29 | margin-top: 50px; 30 | flex-wrap: wrap; 31 | gap: 20px; 32 | } 33 | 34 | .pb_cardmain { 35 | background-color: whitesmoke; 36 | max-width: 15rem; 37 | min-width: 15rem; 38 | border-radius: 12px; 39 | padding: 10px 10px; 40 | cursor: pointer; 41 | max-height: 28rem; 42 | min-height: 24rem; 43 | } 44 | 45 | .pb_cardmain2 { 46 | background-color: whitesmoke; 47 | max-width: 15rem; 48 | min-width: 15rem; 49 | border-radius: 12px; 50 | padding: 10px 10px; 51 | cursor: pointer; 52 | max-height: 26rem; 53 | min-height: 26rem; 54 | } 55 | 56 | .pb_cardimgdiv { 57 | background-color: rgba(128, 128, 128, 0.407); 58 | border-radius: 12px; 59 | } 60 | 61 | .pb_cardimgdiv img { 62 | width: 100%; 63 | object-fit: cover; 64 | } 65 | 66 | .pb_cardtextdiv p { 67 | margin-bottom: 0px; 68 | } 69 | 70 | .pb_cardtextdiv p:nth-child(1) { 71 | font-size: 24px; 72 | font-weight: 600; 73 | font-family: 'Poppins', sans-serif; 74 | margin-top: 10px; 75 | margin-bottom: 15px; 76 | color: #007c73; 77 | } 78 | 79 | .pb_cardtextdiv p:nth-child(3) { 80 | 81 | margin-bottom: 5px; 82 | font-family: 'Poppins', sans-serif; 83 | font-size: 18px; 84 | margin-top: 5px; 85 | font-weight: 600; 86 | color: #007c73; 87 | 88 | } 89 | 90 | .pb_cardtextdiv p:nth-child(4) { 91 | 92 | margin-bottom: 5px; 93 | font-family: 'Poppins', sans-serif; 94 | font-size: 18px; 95 | margin-top: 5px; 96 | 97 | } 98 | 99 | 100 | @media screen and (max-width: 1025px) { 101 | 102 | .pb_header1, 103 | .pb_subheader1 { 104 | width: 100%; 105 | } 106 | 107 | } 108 | 109 | @media screen and (max-width: 769px) { 110 | 111 | .pb_header1, 112 | .pb_subheader1 { 113 | font-size: 50px; 114 | line-height: 50px; 115 | } 116 | 117 | .pb_subheader1 { 118 | font-size: 18px; 119 | } 120 | 121 | .pb_main { 122 | padding: 50px 20px; 123 | max-width: 100vw; 124 | } 125 | 126 | 127 | } -------------------------------------------------------------------------------- /models/UserSchema.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const UserSchema = new mongoose.Schema( 3 | { 4 | firstName: { 5 | type: String, 6 | required: true, 7 | }, 8 | lastName: { 9 | type: String, 10 | required: true, 11 | }, 12 | email: { 13 | type: String, 14 | required: true, 15 | }, 16 | password: { 17 | type: String, 18 | }, 19 | username: { 20 | type: String, 21 | }, 22 | cartproducts: [ 23 | { 24 | productType: { 25 | type: String, 26 | required: true, 27 | }, 28 | productName: { 29 | type: String, 30 | required: true, 31 | }, 32 | productPrice: { 33 | type: Number, 34 | required: true, 35 | }, 36 | productDescription: { 37 | type: String, 38 | required: true, 39 | }, 40 | productImage: { 41 | type: String, 42 | required: true, 43 | }, 44 | productQty: { 45 | type: Number, 46 | required: true, 47 | }, 48 | productSize: { 49 | type: String, 50 | }, 51 | productSlug: { 52 | type: String, 53 | required: true, 54 | }, 55 | purchasedQty: { 56 | type: Number, 57 | default: 0, 58 | }, 59 | totalPrice: { 60 | type: Number, 61 | }, 62 | }, 63 | ], 64 | address: { 65 | type: String, 66 | }, 67 | state: { 68 | type: String, 69 | }, 70 | pincode: { 71 | type: String, 72 | }, 73 | city: { 74 | type: String, 75 | }, 76 | phone: { 77 | type: String, 78 | }, 79 | sellproducts: [ 80 | { 81 | name: { 82 | type: String, 83 | required: true, 84 | }, 85 | qty: { 86 | type: String, 87 | required: true, 88 | }, 89 | size: { 90 | type: String, 91 | }, 92 | slug: { 93 | type: String, 94 | required: true, 95 | }, 96 | 97 | price: { 98 | type: Number, 99 | required: true, 100 | }, 101 | category: { 102 | type: String, 103 | required: true, 104 | }, 105 | 106 | desc: { 107 | type: String, 108 | required: true, 109 | }, 110 | 111 | img: { 112 | type: String, 113 | required: true, 114 | }, 115 | }, 116 | ], 117 | }, 118 | { timetamps: true } 119 | ); 120 | 121 | const Users = mongoose.models.user || mongoose.model("user", UserSchema); 122 | 123 | export default Users; 124 | -------------------------------------------------------------------------------- /components/productcard_landscape/ProductCardLandscape.jsx: -------------------------------------------------------------------------------- 1 | import Image from "next/image"; 2 | import React from "react"; 3 | import { MongoClient, ObjectId } from "mongodb"; 4 | import styles from "./styles.module.css"; 5 | import Buttondiv from "./Buttondiv"; 6 | 7 | async function fetchSingleProduct(id) { 8 | const uri = process.env.MONGO_URI; 9 | const client = new MongoClient(uri, { 10 | useNewUrlParser: true, 11 | useUnifiedTopology: true, 12 | }); 13 | 14 | try { 15 | await client.connect(); 16 | const collection = client.db("test").collection("products"); 17 | const product = await collection.findOne({ _id: new ObjectId(id) }); 18 | return product; 19 | } catch (err) { 20 | console.error(err); 21 | } finally { 22 | await client.close(); 23 | } 24 | } 25 | 26 | const ProductCardLandscape = async (id) => { 27 | const product = await fetchSingleProduct(id); 28 | 29 | return ( 30 | <> 31 | {product && ( 32 |
35 |
36 | detailed picture of the tshirt 43 | 44 |
45 |

46 | {product.productName} 47 |

48 | 49 |

50 | {product.productDescription} 51 |

52 | 53 |

54 | {" "} 55 | ₹ {product.productPrice} 56 |

57 | 58 |

59 | Available qty : {product.productQty}{" "} 60 |

61 | 62 | 63 |
64 |
65 |
66 | )} 67 | 68 | ); 69 | }; 70 | 71 | export default ProductCardLandscape; 72 | -------------------------------------------------------------------------------- /components/navbar/Navbar.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useState } from "react"; 4 | import navlogo from "../../public/assets/navbar/navlogo.svg"; 5 | import bag from "../../public/assets/navbar/bag.svg"; 6 | import Image from "next/image"; 7 | import Link from "next/link"; 8 | import CartCircle from "./cartcirlce/CartCircle"; 9 | import AuthButton from "./authbutton/AuthButton"; 10 | import ham from "../../public/assets/navbar/ham.svg"; 11 | import Dropdown from "./dropdown/Dropdown"; 12 | import Authcard from "../auth/Auth"; 13 | import styles from "./Navbar.module.css" 14 | import up from "../../public/assets/navbar/up.svg" 15 | 16 | 17 | const Navbar = () => { 18 | const [open, setOpen] = useState(false); 19 | const [showauthmodal, setshowauthmodal] = useState(false); 20 | 21 | 22 | return ( 23 | <> 24 | 25 | {showauthmodal && } 26 |
27 |
28 | 29 |

30 | CoderCrate 31 |

32 |
33 | 34 | 65 | 66 | 67 | 68 |
69 | 70 |
71 |
72 | 73 | ); 74 | }; 75 | 76 | export default Navbar; 77 | -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | padding: 0; 4 | margin: 0; 5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, 6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; 7 | } 8 | 9 | a { 10 | color: inherit; 11 | text-decoration: none; 12 | } 13 | 14 | * { 15 | box-sizing: border-box; 16 | } 17 | 18 | 19 | 20 | 21 | .success-wrapper, 22 | .cancel-wrapper { 23 | background-color: #edf2f8; 24 | min-height: 60vh; 25 | font-family: "Ubuntu", sans-serif; 26 | } 27 | 28 | .ps_btn { 29 | width: 100%; 30 | max-width: 400px; 31 | padding: 10px 12px; 32 | border-radius: 15px; 33 | border: none; 34 | font-size: 20px; 35 | margin-top: 10px; 36 | margin-top: 40px; 37 | text-transform: uppercase; 38 | background-color: #f02d34; 39 | color: #fff; 40 | cursor: pointer; 41 | transform: scale(1, 1); 42 | transition: transform 0.5s ease; 43 | font-family: "Ubuntu", sans-serif; 44 | } 45 | 46 | .success, 47 | .cancel { 48 | width: 1000px; 49 | margin: auto; 50 | margin-top: 160px; 51 | background-color: #edf2f8; 52 | padding: 50px; 53 | border-radius: 15px; 54 | display: flex; 55 | justify-content: center; 56 | align-items: center; 57 | flex-direction: column; 58 | } 59 | 60 | .success .icon { 61 | color: green; 62 | font-size: 40px; 63 | } 64 | 65 | .success h2 { 66 | text-transform: capitalize; 67 | margin-top: 15px 0px; 68 | font-weight: 900; 69 | font-size: 40px; 70 | color: #324d67; 71 | } 72 | 73 | .success .email-msg { 74 | font-size: 16px; 75 | font-weight: 600; 76 | text-align: center; 77 | } 78 | 79 | .cancel p { 80 | font-size: 20px; 81 | font-weight: 600; 82 | } 83 | 84 | .success .description { 85 | font-size: 16px; 86 | font-weight: 600; 87 | text-align: center; 88 | margin: 10px; 89 | margin-top: 30px; 90 | } 91 | 92 | .success .description .email { 93 | margin-left: 5px; 94 | color: #f02d34; 95 | } 96 | 97 | .product-max-qty { 98 | margin-top: 10px; 99 | } 100 | 101 | @media screen and (max-width: 800px) { 102 | 103 | .success-wrapper, 104 | .cancel-wrapper { 105 | min-height: 69vh; 106 | } 107 | 108 | .success, 109 | .cancel { 110 | width: 370px; 111 | margin-top: 100px; 112 | padding: 20px; 113 | } 114 | 115 | .success { 116 | height: 350px; 117 | } 118 | 119 | .success h2 { 120 | font-size: 17px; 121 | } 122 | 123 | .btn-container { 124 | width: 300px; 125 | margin: auto; 126 | } 127 | } 128 | 129 | html, 130 | body { 131 | background-color: #e8c287 !important; 132 | } 133 | 134 | /* ===== Scrollbar CSS ===== */ 135 | /* Firefox */ 136 | * { 137 | scrollbar-width: auto; 138 | scrollbar-color: #007c73 #e8c18700; 139 | } 140 | 141 | /* Chrome, Edge, and Safari */ 142 | *::-webkit-scrollbar { 143 | width: 13px; 144 | } 145 | 146 | *::-webkit-scrollbar-track { 147 | background: #e8c18700; 148 | } 149 | 150 | *::-webkit-scrollbar-thumb { 151 | background-color: #007c73; 152 | border-radius: 10px; 153 | border: 3px solid #e8c287; 154 | } -------------------------------------------------------------------------------- /styles/SingleProduct.module.css: -------------------------------------------------------------------------------- 1 | .singleproduct_main { 2 | display: flex; 3 | flex-direction: column; 4 | align-items: center; 5 | justify-content: center; 6 | width: 100%; 7 | background-color: #f5f5f500; 8 | padding: 3rem; 9 | } 10 | 11 | .productbox { 12 | display: flex; 13 | justify-content: space-between; 14 | gap: 2rem; 15 | border-radius: 8px; 16 | background-color: whitesmoke; 17 | padding: 1rem; 18 | padding-right: 0px; 19 | 20 | } 21 | 22 | .productbox img:nth-child(1) { 23 | width: 380px; 24 | height: 450px; 25 | background-color: #C5C5C5; 26 | border-radius: 8px; 27 | max-height: 450px; 28 | max-width: 380px; 29 | object-fit: contain; 30 | } 31 | 32 | .product_textdiv { 33 | padding-top: 20px; 34 | width: 50%; 35 | padding-right: 25px; 36 | } 37 | 38 | .product_textdiv h1 { 39 | font-size: 3rem; 40 | font-weight: 600; 41 | color: #000; 42 | margin-bottom: 1rem; 43 | font-family: 'Montserrat', sans-serif; 44 | } 45 | 46 | .product_textdiv p { 47 | font-size: 1.2rem; 48 | font-weight: 400; 49 | color: #000; 50 | margin-bottom: 0rem; 51 | font-family: "Poppins", sans-serif; 52 | } 53 | 54 | .product_textdiv p:nth-child(3) { 55 | color: #007c73; 56 | font-weight: 600; 57 | margin-top: 2rem; 58 | } 59 | 60 | .product_btndiv { 61 | display: flex; 62 | gap: 2rem; 63 | align-items: center; 64 | margin-top: 50px; 65 | position: relative; 66 | } 67 | 68 | .product_btndiv img { 69 | cursor: pointer; 70 | } 71 | 72 | .buybtn { 73 | background-color: #e0a246 !important; 74 | color: black; 75 | font-weight: 600; 76 | font-family: "Poppins", sans-serif; 77 | 78 | } 79 | 80 | .product_qtydiv { 81 | display: flex; 82 | gap: 1rem; 83 | align-items: center; 84 | margin-top: 20px; 85 | user-select: none; 86 | } 87 | 88 | .qtybtn { 89 | background: transparent !important; 90 | width: 30px !important; 91 | height: 30px !important; 92 | cursor: pointer; 93 | } 94 | 95 | @media screen and (max-width: 1000px) { 96 | .productbox { 97 | flex-direction: row; 98 | gap: 2rem; 99 | align-items: center; 100 | max-width: 90vw; 101 | 102 | } 103 | 104 | .product_textdiv { 105 | padding-right: 0px; 106 | } 107 | 108 | .productbox img:nth-child(1) { 109 | /* background-color: transparent; */ 110 | max-width: 50%; 111 | } 112 | 113 | } 114 | 115 | @media screen and (max-width: 660px) { 116 | .productbox { 117 | flex-direction: column; 118 | gap: 1rem; 119 | align-items: center; 120 | max-width: 85vw; 121 | min-width: 85vw; 122 | padding: 0rem; 123 | padding-top: 1rem; 124 | } 125 | 126 | .product_textdiv { 127 | padding-right: 0px; 128 | } 129 | 130 | .productbox img:nth-child(1) { 131 | width: 90%; 132 | max-width: 90%; 133 | } 134 | 135 | .product_textdiv { 136 | width: 90%; 137 | text-align: center; 138 | } 139 | 140 | .product_btndiv { 141 | width: 80%; 142 | justify-content: center; 143 | margin: auto; 144 | margin-top: 30px; 145 | margin-bottom: 10px; 146 | } 147 | } -------------------------------------------------------------------------------- /components/bestseller/static/bestSellerdata.js: -------------------------------------------------------------------------------- 1 | import k2 from "../../../public/assets/Products/keyboards/k2.png"; 2 | import k3 from "../../../public/assets/Products/keyboards/k3.png"; 3 | import k4 from "../../../public/assets/Products/keyboards/k4.png"; 4 | 5 | import m1 from "../../../public/assets/Products/monitor/m1.png"; 6 | import m2 from "../../../public/assets/Products/monitor/m2.png"; 7 | import m3 from "../../../public/assets/Products/monitor/m3.png"; 8 | 9 | 10 | 11 | const bestSellerData = [ 12 | { 13 | _id: "6446cd23b01340d35e31d71d", 14 | productType: "keyboards", 15 | productName: "EvoFox Deathray RGB Gaming Keyboard", 16 | productPrice: 899, 17 | productDescription: "EvoFox Deathray RGB Gaming Keyboard, 16 Million True Prism RGB, Backlighting Effects with Custom Setting, Silent Membrane Keys, Sturdy,19 Anti Ghosting Keys, Windows Lock Key, Braided Cable (Black)", 18 | productImage: k2, 19 | productQty: 10, 20 | productSlug: "kb2", 21 | __v: 0 22 | }, 23 | { 24 | _id: "6446cc8ab01340d35e31d711", 25 | productType: "monitors", 26 | productName: "LG Ultragear", 27 | productPrice: 899, 28 | productDescription: "LG Ultragear Gaming 24 Inch (60.3 Cm) Full HD (1920 x 1080) Pixels LCD Monitor 165Hz, 1ms, Freesync Premium, HDMI x 2, Display Port, HP Out, Reader Mode, VA, Flicker Safe - 24GQ50F (Black)", 29 | productImage: m1, 30 | productQty: 10, 31 | productSlug: "lg1", 32 | __v: 0 33 | }, { 34 | _id: "6446ccbab01340d35e31d713", 35 | productType: "monitors", 36 | productName: "LG Ultragear", 37 | productPrice: 899, 38 | productDescription: "LG Ultragear Gaming 24 Inch (60.3 Cm) Full HD (1920 x 1080) Pixels LCD Monitor 165Hz, 1ms, Freesync Premium, HDMI x 2, Display Port, HP Out, Reader Mode, VA, Flicker Safe - 24GQ50F (Black)", 39 | productImage: m2, 40 | productQty: 10, 41 | productSlug: "lg2", 42 | __v: 0 43 | }, 44 | 45 | { 46 | _id: "6446cd48b01340d35e31d721", 47 | productType: "keyboards", 48 | productName: "EvoFox Deathray RGB Gaming Keyboard", 49 | productPrice: 899, 50 | productDescription: "EvoFox Deathray RGB Gaming Keyboard, 16 Million True Prism RGB, Backlighting Effects with Custom Setting, Silent Membrane Keys, Sturdy,19 Anti Ghosting Keys, Windows Lock Key, Braided Cable (Black)", 51 | productImage: k4, 52 | productQty: 10, 53 | productSlug: "kb4", 54 | __v: 0 55 | }, { 56 | _id: "6446cd31b01340d35e31d71f", 57 | productType: "keyboards", 58 | productName: "EvoFox Deathray RGB Gaming Keyboard", 59 | productPrice: 899, 60 | productDescription: "EvoFox Deathray RGB Gaming Keyboard, 16 Million True Prism RGB, Backlighting Effects with Custom Setting, Silent Membrane Keys, Sturdy,19 Anti Ghosting Keys, Windows Lock Key, Braided Cable (Black)", 61 | productImage: k3, 62 | productQty: 10, 63 | productSlug: "kb3", 64 | __v: 0 65 | }, 66 | { 67 | _id: "6446ccccb01340d35e31d715", 68 | productType: "monitors", 69 | productName: "LG Ultragear", 70 | productPrice: 899, 71 | productDescription: "LG Ultragear Gaming 24 Inch (60.3 Cm) Full HD (1920 x 1080) Pixels LCD Monitor 165Hz, 1ms, Freesync Premium, HDMI x 2, Display Port, HP Out, Reader Mode, VA, Flicker Safe - 24GQ50F (Black)", 72 | productImage: m3, 73 | productQty: 10, 74 | productSlug: "lg3", 75 | __v: 0 76 | }, 77 | 78 | ]; 79 | 80 | export default bestSellerData; 81 | -------------------------------------------------------------------------------- /components/auth/authLogic.js: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { showErrorToast, showSuccessToast } from "@/middleware/toastMessage"; 4 | import { bearStore } from "@/global/store"; 5 | const { AuthRegex } = require("./authRegex"); 6 | import { signIn } from "next-auth/react"; 7 | 8 | const handleSignup = async (creds, setcreds, setauthtype) => { 9 | if ( 10 | creds.firstName.length < 1 || 11 | creds.lastName.length < 1 || 12 | creds.email.length < 1 || 13 | creds.password.length < 1 || 14 | creds.username.length < 1 || 15 | creds.address.length < 1 || 16 | creds.state.length < 1 || 17 | creds.pincode.length < 1 || 18 | creds.city.length < 1 || 19 | creds.phone.length < 1 20 | ) { 21 | console.log("Please fill all the fields"); 22 | showErrorToast("Please fill all the fields"); 23 | return; 24 | } 25 | 26 | if (!AuthRegex(creds)) { 27 | return; 28 | } 29 | 30 | try { 31 | const res = await fetch( 32 | `${process.env.NEXT_PUBLIC_URL}/api/user/adduser`, 33 | { 34 | method: "POST", 35 | headers: { 36 | "Content-Type": "application/json", 37 | }, 38 | body: JSON.stringify(creds), 39 | } 40 | ); 41 | 42 | if (res.status !== 200) { 43 | showErrorToast("Something went wrong"); 44 | } else { 45 | showSuccessToast("Signed you up, please login"); 46 | setauthtype("login"); 47 | setcreds({ 48 | firstName: "", 49 | lastName: "", 50 | email: "", 51 | password: "", 52 | username: "", 53 | address: "", 54 | state: "", 55 | pincode: "", 56 | city: "", 57 | phone: "", 58 | }); 59 | } 60 | } catch (error) { 61 | showErrorToast(error); 62 | } 63 | }; 64 | 65 | const handleLogin = async (creds, setcreds) => { 66 | try { 67 | 68 | if ( 69 | creds.email.length < 1 || 70 | creds.password.length < 1 71 | ) { 72 | showErrorToast("Please fill all the fields"); 73 | return; 74 | } 75 | 76 | if (!AuthRegex(creds)) { 77 | return; 78 | } 79 | 80 | 81 | const email = creds.email; 82 | const password = creds.password; 83 | const data = await signIn("credentials", { 84 | redirect: false, 85 | email, 86 | password, 87 | }); 88 | 89 | if (data.error) { 90 | showErrorToast(data.error); 91 | } 92 | 93 | console.log(data); 94 | 95 | if (data.ok) { 96 | showSuccessToast("Logged in"); 97 | 98 | setTimeout(() => { 99 | setcreds({ 100 | name: "", 101 | email: "", 102 | password: "", 103 | username: "", 104 | address: "", 105 | state: "", 106 | pincode: "", 107 | city: "", 108 | phone: "", 109 | }); 110 | setshowauthmodal(false); 111 | document.body.style.overflow = "auto"; 112 | document.body.getElementsByClassName("navbar")[0].style.pointerEvents = 113 | "auto"; 114 | }, 2200); 115 | } 116 | } catch (error) { 117 | showErrorToast(error); 118 | } 119 | }; 120 | 121 | //* Github Login 122 | async function handleGithubSignin() { 123 | try { 124 | const data = await signIn("github", { 125 | callbackUrl: `${process.env.NEXT_PUBLIC_URL}`, 126 | }); 127 | if (data.error) { 128 | showErrorToast(data.error); 129 | } 130 | } catch (error) { 131 | showErrorToast(error); 132 | } 133 | } 134 | 135 | //* Google Login 136 | async function handleGoogleSignin() { 137 | try { 138 | const data = await signIn("google", { 139 | callbackUrl: `${process.env.NEXT_PUBLIC_URL}`, 140 | }); 141 | if (data.error) { 142 | showErrorToast(data.error); 143 | } 144 | } catch (error) { 145 | showErrorToast(error); 146 | } 147 | } 148 | 149 | const authLogic = { 150 | handleSignup, 151 | handleLogin, 152 | handleGithubSignin, 153 | handleGoogleSignin, 154 | }; 155 | 156 | export default authLogic; 157 | -------------------------------------------------------------------------------- /styles/tshirts.module.css: -------------------------------------------------------------------------------- 1 | .shirtpage_main { 2 | padding: 80px 80px; 3 | } 4 | 5 | 6 | .shirtpage_main_heading { 7 | display: flex; 8 | justify-content: space-between; 9 | } 10 | 11 | .shirtpage_main_heading h1 { 12 | font-family: 'Montserrat', sans-serif; 13 | font-size: 24px; 14 | font-weight: 700; 15 | color: #212529 !important; 16 | } 17 | 18 | .searchmaindiv { 19 | max-width: 30%; 20 | margin-bottom: 0px !important; 21 | } 22 | 23 | .searchmaindiv input { 24 | font-family: "Poppins", sans-serif; 25 | background-color: transparent; 26 | border: #212529 1px solid; 27 | } 28 | 29 | .searchmaindiv input:focus { 30 | font-family: "Poppins", sans-serif; 31 | background-color: transparent; 32 | border: #212529 1px solid; 33 | box-shadow: none; 34 | } 35 | 36 | .searchmaindiv button { 37 | font-family: "Poppins", sans-serif; 38 | border: #212529 1px solid; 39 | background-color: #007c73; 40 | color: white; 41 | } 42 | 43 | .searchmaindiv button:hover { 44 | font-family: "Poppins", sans-serif; 45 | border: #212529 1px solid !important; 46 | background-color: #007c73 !important; 47 | color: white; 48 | } 49 | 50 | 51 | /* //* Product Cards */ 52 | 53 | .pb_main { 54 | /* height: 100vh; */ 55 | width: 100%; 56 | background-position: right 0; 57 | background-size: cover; 58 | padding: 100px 80px; 59 | margin-bottom: 5rem; 60 | } 61 | 62 | .pb_header1 { 63 | font-size: 60px; 64 | font-family: 'Montserrat', sans-serif; 65 | text-align: center; 66 | font-weight: 700; 67 | margin-bottom: 20px; 68 | width: 60%; 69 | margin: auto; 70 | } 71 | 72 | .pb_subheader1 { 73 | font-size: 22px; 74 | text-align: center; 75 | margin-top: 20px; 76 | font-family: 'Poppins', sans-serif; 77 | } 78 | 79 | .pb_cardsdiv { 80 | display: flex; 81 | justify-content: center; 82 | margin-top: 50px; 83 | flex-wrap: wrap; 84 | gap: 20px; 85 | } 86 | 87 | .pb_cardmain { 88 | background-color: whitesmoke; 89 | max-width: 15rem; 90 | min-width: 15rem; 91 | border-radius: 12px; 92 | padding: 10px 10px; 93 | cursor: pointer; 94 | text-decoration: none !important; 95 | position: relative; 96 | /* min-height: 26rem; */ 97 | max-height: 28rem; 98 | min-height: 25rem; 99 | } 100 | 101 | .card_cart { 102 | position: absolute; 103 | right: 20px; 104 | cursor: pointer; 105 | bottom: 20px; 106 | 107 | } 108 | 109 | 110 | .pb_cardimgdiv { 111 | background-color: rgba(128, 128, 128, 0.407); 112 | border-radius: 12px; 113 | } 114 | 115 | .pb_cardimgdiv img { 116 | width: 100%; 117 | object-fit: cover; 118 | } 119 | 120 | .pb_cardtextdiv p { 121 | margin-bottom: 0px; 122 | } 123 | 124 | .pb_cardtextdiv p:nth-child(1) { 125 | font-size: 24px; 126 | font-weight: 600; 127 | font-family: 'Poppins', sans-serif; 128 | margin-top: 10px; 129 | color: #212529 !important; 130 | margin-bottom: 15px; 131 | /* color: #007c73; */ 132 | } 133 | 134 | .pb_cardtextdiv p:nth-child(3) { 135 | 136 | margin-bottom: 5px; 137 | font-family: 'Poppins', sans-serif; 138 | font-size: 18px; 139 | margin-top: 5px; 140 | font-weight: 600; 141 | color: #007c73; 142 | 143 | } 144 | 145 | .pb_cardtextdiv p:nth-child(4) { 146 | 147 | margin-bottom: 5px; 148 | font-family: 'Poppins', sans-serif; 149 | font-size: 18px; 150 | margin-top: 5px; 151 | 152 | } 153 | 154 | 155 | @media screen and (max-width: 1025px) { 156 | 157 | .pb_header1, 158 | .pb_subheader1 { 159 | width: 100%; 160 | } 161 | 162 | .shirtpage_main_heading { 163 | flex-direction: column; 164 | justify-content: center; 165 | align-items: center; 166 | } 167 | 168 | .searchmaindiv { 169 | max-width: 100%; 170 | } 171 | 172 | } 173 | 174 | @media screen and (max-width: 769px) { 175 | 176 | .pb_header1, 177 | .pb_subheader1 { 178 | font-size: 50px; 179 | line-height: 50px; 180 | } 181 | 182 | .pb_subheader1 { 183 | font-size: 18px; 184 | } 185 | 186 | .pb_main { 187 | padding: 50px 20px; 188 | max-width: 100vw; 189 | } 190 | 191 | 192 | } -------------------------------------------------------------------------------- /styles/Cart.module.css: -------------------------------------------------------------------------------- 1 | .cart_mainparent { 2 | padding: 0px 80px; 3 | } 4 | 5 | .cart_parent h1 { 6 | font-family: "Montserrat", sans-serif; 7 | margin-top: 30px; 8 | } 9 | 10 | .cart_cardparent { 11 | display: flex; 12 | /* flex-direction: column; 13 | */ 14 | align-items: center; 15 | margin-top: 30px; 16 | flex-wrap: wrap; 17 | gap: 2rem; 18 | /* justify-content: center; */ 19 | flex-grow: 1; 20 | flex-basis: auto; 21 | 22 | } 23 | 24 | 25 | .cart_cartcard { 26 | background-color: whitesmoke; 27 | margin-bottom: 20px; 28 | border-radius: 12px; 29 | padding: 10px; 30 | padding-right: 20px; 31 | display: flex; 32 | justify-content: space-between; 33 | gap: 2rem; 34 | max-width: 550px; 35 | min-width: 550px; 36 | min-height: 364px; 37 | 38 | } 39 | 40 | .cart_cartcard img { 41 | width: 230px; 42 | height: auto; 43 | background-color: #C5C5C5; 44 | border-radius: 8px; 45 | object-fit: contain; 46 | } 47 | 48 | .cart_cardtextdiv { 49 | display: flex; 50 | flex-direction: column; 51 | justify-content: space-between; 52 | } 53 | 54 | .cart_cardtextdiv>div:nth-child(1)>p:nth-child(1) { 55 | font-size: 2.1rem; 56 | font-weight: 600; 57 | color: #000000; 58 | font-family: "Montserrat", sans-serif; 59 | 60 | } 61 | 62 | .cart_cardtextdiv>div:nth-child(1)>p:nth-child(2) { 63 | font-size: 25px; 64 | font-family: "Poppins", sans-serif; 65 | color: #1c1e20; 66 | 67 | } 68 | 69 | .cart_qtydiv { 70 | display: flex; 71 | gap: 1.5rem; 72 | align-items: center; 73 | } 74 | 75 | .cart_qtydiv p { 76 | font-size: 25px; 77 | font-family: "Poppins", sans-serif; 78 | color: #1c1e20; 79 | margin-bottom: 0px; 80 | } 81 | 82 | .qtybtn { 83 | background: transparent !important; 84 | width: 30px !important; 85 | height: 30px !important; 86 | cursor: pointer; 87 | } 88 | 89 | .cart_cardprice span { 90 | font-size: 25px; 91 | font-weight: 600; 92 | 93 | font-family: "Poppins", sans-serif; 94 | } 95 | 96 | 97 | .cart_cardhr { 98 | border: 1px solid #1c1e20; 99 | margin-top: 10px; 100 | margin-bottom: 10px; 101 | } 102 | 103 | .cart_pricediv { 104 | display: flex; 105 | justify-content: space-between; 106 | } 107 | 108 | .cart_pricediv img { 109 | width: 30px; 110 | max-width: 30px !important; 111 | height: 30px; 112 | margin-right: 10px; 113 | cursor: pointer; 114 | } 115 | 116 | .cart_cardprice { 117 | font-size: 25px; 118 | color: #007c73; 119 | font-weight: 600; 120 | font-family: "Poppins", sans-serif; 121 | } 122 | 123 | .pb_cardmain { 124 | text-decoration: none; 125 | } 126 | 127 | .cart_placeorderbtn { 128 | background-color: #007c73 !important; 129 | font-family: "Monteserrat", sans-serif !important; 130 | font-size: 20px; 131 | letter-spacing: 2px; 132 | margin-top: 10px; 133 | font-weight: 600 !important; 134 | color: white !important; 135 | margin-bottom: 50px; 136 | } 137 | 138 | .cart_placeorderbtn:hover { 139 | background-color: #007c73 !important; 140 | font-family: "Monteserrat", sans-serif !important; 141 | font-weight: 600; 142 | color: white !important; 143 | } 144 | 145 | .cart_emptydiv { 146 | display: flex; 147 | justify-content: center; 148 | align-items: center; 149 | flex-direction: column; 150 | margin-top: 5rem; 151 | } 152 | 153 | .cart_emptydiv h1 { 154 | font-family: "Montserrat", sans-serif; 155 | margin-top: 30px; 156 | /* text-align: center; */ 157 | } 158 | 159 | @media screen and (max-width: 700px) { 160 | .cart_mainparent { 161 | padding: 20px 20px; 162 | } 163 | 164 | .cart_cartcard { 165 | max-width: 80vw; 166 | min-width: 80vw; 167 | } 168 | 169 | .cart_cardtextdiv { 170 | max-width: 70vw; 171 | } 172 | } 173 | 174 | 175 | @media screen and (max-width:650px) { 176 | .cart_cardparent { 177 | justify-content: center; 178 | } 179 | 180 | .cart_cartcard { 181 | flex-direction: column; 182 | justify-content: center; 183 | align-items: center; 184 | padding: 20px; 185 | /* padding-right: 10px; */ 186 | text-align: center; 187 | } 188 | 189 | .cart_cartcard img { 190 | width: 280px; 191 | max-width: 70vw; 192 | } 193 | 194 | .cart_placeorderbtndiv { 195 | display: flex; 196 | justify-content: center; 197 | margin-top: 20px; 198 | } 199 | 200 | .carttotal { 201 | display: flex; 202 | flex-direction: column; 203 | justify-content: center; 204 | align-items: center; 205 | } 206 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | gyansujan69@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /components/auth/Auth.module.css: -------------------------------------------------------------------------------- 1 | .authparent { 2 | position: fixed; 3 | background-color: rgba(0, 0, 0, 0.475); 4 | inset: 0; 5 | backdrop-filter: blur(5px); 6 | display: flex; 7 | justify-content: center; 8 | align-items: center; 9 | overflow: scroll; 10 | height: 100vh; 11 | width: 100vw; 12 | z-index: 9900; 13 | padding: 0px 20px; 14 | } 15 | 16 | .authsub { 17 | background-color: white; 18 | overflow: hidden; 19 | border-radius: 12px; 20 | font-family: "Montserrat", sans-serif; 21 | width: auto; 22 | height: 600px; 23 | display: flex; 24 | gap: 2rem; 25 | position: relative; 26 | } 27 | 28 | .auth_leftdiv { 29 | -webkit-box-flex: 0; 30 | -webkit-flex-grow: 0; 31 | -ms-flex-positive: 0; 32 | flex-grow: 0; 33 | width: 380px; 34 | position: relative; 35 | background-color: #007c73; 36 | padding: 48px; 37 | user-select: none; 38 | } 39 | 40 | .auth_rightdiv { 41 | -webkit-box-flex: 1; 42 | -webkit-flex-grow: 1; 43 | -ms-flex-positive: 1; 44 | flex-grow: 1; 45 | width: 480px; 46 | padding: 48px; 47 | overflow: scroll; 48 | } 49 | 50 | .auth_leftdiv h1 { 51 | font-size: 2.5rem; 52 | color: white; 53 | text-align: center; 54 | padding: 0; 55 | font-weight: 200; 56 | /* font-size: 32px; */ 57 | line-height: 40px; 58 | /* margin-top: 48px; */ 59 | margin-bottom: 52px; 60 | } 61 | 62 | .auth_leftdiv p { 63 | font-size: 1.2rem; 64 | color: white; 65 | 66 | font-size: 20px; 67 | line-height: 24px; 68 | font-weight: 300; 69 | font-weight: 200; 70 | margin-top: 8px; 71 | } 72 | 73 | .auth_leftdiv p:first-of-type { 74 | text-align: center; 75 | } 76 | 77 | .auth_logodiv { 78 | display: flex; 79 | justify-content: center; 80 | gap: 1rem; 81 | } 82 | 83 | .auth_logodiv img { 84 | width: 30px !important; 85 | height: 30px !important; 86 | cursor: pointer; 87 | } 88 | 89 | .auth_imgdiv { 90 | display: flex; 91 | justify-content: center; 92 | margin-top: 50px; 93 | flex-direction: column; 94 | align-items: center; 95 | gap: 1rem; 96 | } 97 | 98 | .auth_leftdiv img { 99 | width: 200px; 100 | height: 200px; 101 | } 102 | 103 | .auth_imgdiv p { 104 | font-family: "Poppins", sans-serif; 105 | 106 | } 107 | 108 | .auth_imgdiv span { 109 | text-decoration: underline; 110 | color: rgb(244, 159, 31); 111 | cursor: pointer; 112 | } 113 | 114 | 115 | 116 | .auth_textdiv { 117 | margin-left: 2rem; 118 | margin-right: 2rem; 119 | 120 | flex-direction: column; 121 | min-height: 70vh; 122 | max-height: 70vh; 123 | 124 | 125 | } 126 | 127 | 128 | .auth_input { 129 | max-width: 100%; 130 | } 131 | 132 | .auth_input::placeholder { 133 | font-size: 1.2rem; 134 | font-weight: 500; 135 | color: #000000c5; 136 | font-family: "Montserrat", sans-serif; 137 | 138 | } 139 | 140 | .auth_textarea { 141 | min-height: 300px; 142 | } 143 | 144 | .auth_formdiv { 145 | display: flex; 146 | justify-content: space-between; 147 | } 148 | 149 | 150 | .auth_rightdiv::-webkit-scrollbar-track { 151 | /* -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); */ 152 | background-color: #f5f5f500 !important; 153 | } 154 | 155 | .auth_rightdiv::-webkit-scrollbar { 156 | width: 5px !important; 157 | 158 | background-color: #de252500 !important; 159 | } 160 | 161 | .auth_rightdiv::-webkit-scrollbar-thumb { 162 | background-color: #ff733d !important; 163 | /* border: 2px solid #555555; */ 164 | max-height: 10% !important; 165 | } 166 | 167 | .auth_btndiv { 168 | position: absolute; 169 | top: 10px; 170 | z-index: 100; 171 | right: 1%; 172 | cursor: pointer; 173 | background-color: transparent; 174 | 175 | } 176 | 177 | .auth_btndiv button { 178 | border-radius: 50% !important; 179 | border: #ff733d 1px solid; 180 | height: 30px; 181 | width: 30px; 182 | font-family: "Montserrat", sans-serif !important; 183 | font-weight: 600; 184 | } 185 | 186 | .auth_smallheader { 187 | font-family: "Montserrat", sans-serif; 188 | display: none; 189 | font-weight: 600; 190 | } 191 | 192 | .auth_smallsocialdiv { 193 | display: none; 194 | } 195 | 196 | .signup_btn { 197 | background-color: #007c73 !important; 198 | color: white !important; 199 | border: none; 200 | border-radius: 5px; 201 | padding: 10px 20px; 202 | font-size: 1.2rem; 203 | 204 | cursor: pointer; 205 | transition: all 0.3s ease-in-out; 206 | font-family: "Montserrat", sans-serif !important; 207 | 208 | font-weight: 600 !important; 209 | } 210 | 211 | .signup_btn:hover { 212 | background-color: #007c73 !important; 213 | color: white !important; 214 | border: none; 215 | border-radius: 5px; 216 | padding: 10px 20px; 217 | font-size: 1.2rem; 218 | 219 | cursor: pointer; 220 | transition: all 0.3s ease-in-out; 221 | font-family: "Montserrat", sans-serif !important; 222 | 223 | font-weight: 600 !important; 224 | } 225 | 226 | 227 | .auth_smallchecktext p { 228 | font-family: "Montserrat", sans-serif !important; 229 | margin-top: 20px; 230 | } 231 | 232 | .auth_smallchecktext span { 233 | text-decoration: underline !important; 234 | color: rgb(244, 159, 31); 235 | cursor: pointer; 236 | } 237 | 238 | @media screen and (max-width: 1000px) { 239 | 240 | 241 | .authsub { 242 | flex-direction: column; 243 | } 244 | 245 | .auth_leftdiv { 246 | display: none; 247 | } 248 | 249 | .auth_smallheader { 250 | text-align: center; 251 | margin-bottom: 0px; 252 | display: block; 253 | margin-top: 10px; 254 | } 255 | 256 | .auth_smallsocialdiv { 257 | display: block; 258 | } 259 | 260 | .auth_smallsocialdiv hr { 261 | width: 50%; 262 | margin: auto; 263 | height: 2px; 264 | border: #007c73 1px solid; 265 | background-color: #007c73; 266 | margin-top: 40px; 267 | } 268 | 269 | .auth_rightdiv { 270 | padding-top: 10px; 271 | } 272 | } 273 | 274 | @media screen and (max-width:500px) { 275 | .auth_rightdiv { 276 | -webkit-box-flex: 1; 277 | -webkit-flex-grow: 1; 278 | -ms-flex-positive: 1; 279 | flex-grow: 1; 280 | width: auto; 281 | padding: 48px; 282 | padding-top: 10px; 283 | overflow: auto; 284 | } 285 | 286 | .auth_rightdiv::-webkit-scrollbar { 287 | display: none; 288 | } 289 | } -------------------------------------------------------------------------------- /styles/Payment.module.css: -------------------------------------------------------------------------------- 1 | .authparent { 2 | position: fixed; 3 | background-color: rgba(0, 0, 0, 0.475); 4 | inset: 0; 5 | backdrop-filter: blur(5px); 6 | display: flex; 7 | justify-content: center; 8 | align-items: center; 9 | overflow: scroll; 10 | height: 100vh; 11 | width: 100vw; 12 | z-index: 9900; 13 | padding: 0px 20px; 14 | } 15 | 16 | .authsub { 17 | background-color: white; 18 | overflow: hidden; 19 | border-radius: 12px; 20 | font-family: "Montserrat", sans-serif; 21 | width: auto; 22 | height: 500px; 23 | display: flex; 24 | gap: 2rem; 25 | position: relative; 26 | } 27 | 28 | .auth_leftdiv { 29 | -webkit-box-flex: 0; 30 | -webkit-flex-grow: 0; 31 | -ms-flex-positive: 0; 32 | flex-grow: 0; 33 | width: 380px; 34 | position: relative; 35 | background-color: #007c73; 36 | padding: 48px; 37 | user-select: none; 38 | } 39 | 40 | .auth_rightdiv { 41 | -webkit-box-flex: 1; 42 | -webkit-flex-grow: 1; 43 | -ms-flex-positive: 1; 44 | flex-grow: 1; 45 | width: 480px; 46 | padding: 48px; 47 | overflow: scroll; 48 | display: flex; 49 | flex-direction: column; 50 | justify-content: center; 51 | } 52 | 53 | .auth_rightdiv p { 54 | font-size: 1.2rem; 55 | color: #000000c5; 56 | font-weight: 500; 57 | font-family: "Montserrat", sans-serif; 58 | margin-bottom: 3rem; 59 | } 60 | 61 | 62 | .auth_rightdiv p>span { 63 | font-size: 1.2rem; 64 | color: #122caac5 !important; 65 | font-weight: 600; 66 | font-family: "Montserrat", sans-serif; 67 | margin-bottom: 3rem; 68 | cursor: pointer; 69 | } 70 | 71 | .auth_leftdiv h1 { 72 | font-size: 2rem; 73 | color: white; 74 | text-align: center; 75 | padding: 0; 76 | font-weight: 200; 77 | /* font-size: 32px; */ 78 | line-height: 40px; 79 | /* margin-top: 48px; */ 80 | margin-bottom: 52px; 81 | } 82 | 83 | .auth_leftdiv p { 84 | font-size: 1.2rem; 85 | color: white; 86 | 87 | font-size: 20px; 88 | line-height: 24px; 89 | font-weight: 300; 90 | font-weight: 200; 91 | margin-top: 80px; 92 | } 93 | 94 | .auth_leftdiv p:first-of-type { 95 | text-align: center; 96 | } 97 | 98 | .auth_logodiv { 99 | display: flex; 100 | justify-content: center; 101 | gap: 1rem; 102 | } 103 | 104 | .auth_logodiv img { 105 | width: 30px !important; 106 | height: 30px !important; 107 | cursor: pointer; 108 | } 109 | 110 | .auth_imgdiv { 111 | display: flex; 112 | justify-content: center; 113 | margin-top: 50px; 114 | flex-direction: column; 115 | align-items: center; 116 | gap: 1rem; 117 | } 118 | 119 | /* .auth_leftdiv img { 120 | width: 200px; 121 | height: 200px; 122 | } */ 123 | 124 | .auth_imgdiv p { 125 | font-family: "Poppins", sans-serif; 126 | 127 | } 128 | 129 | .auth_imgdiv span { 130 | text-decoration: underline; 131 | color: rgb(244, 159, 31); 132 | cursor: pointer; 133 | } 134 | 135 | 136 | 137 | .auth_textdiv { 138 | margin-left: 2rem; 139 | margin-right: 2rem; 140 | 141 | flex-direction: column; 142 | min-height: 70vh; 143 | max-height: 70vh; 144 | 145 | 146 | } 147 | 148 | 149 | .auth_input { 150 | max-width: 100%; 151 | } 152 | 153 | .auth_input::placeholder { 154 | font-size: 1.2rem; 155 | font-weight: 500; 156 | color: #000000c5; 157 | font-family: "Montserrat", sans-serif; 158 | 159 | } 160 | 161 | .auth_textarea { 162 | min-height: 300px; 163 | } 164 | 165 | .auth_formdiv { 166 | display: flex; 167 | justify-content: space-between; 168 | } 169 | 170 | 171 | .auth_rightdiv::-webkit-scrollbar-track { 172 | /* -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); */ 173 | background-color: #f5f5f500 !important; 174 | } 175 | 176 | .auth_rightdiv::-webkit-scrollbar { 177 | width: 5px !important; 178 | 179 | background-color: #de252500 !important; 180 | } 181 | 182 | .auth_rightdiv::-webkit-scrollbar-thumb { 183 | background-color: #ff733d !important; 184 | /* border: 2px solid #555555; */ 185 | max-height: 10% !important; 186 | } 187 | 188 | .auth_btndiv { 189 | position: absolute; 190 | top: 10px; 191 | z-index: 100; 192 | right: 1%; 193 | cursor: pointer; 194 | background-color: transparent; 195 | 196 | } 197 | 198 | .auth_btndiv button { 199 | border-radius: 50% !important; 200 | border: #ff733d 1px solid; 201 | height: 30px; 202 | width: 30px; 203 | font-family: "Montserrat", sans-serif !important; 204 | font-weight: 600; 205 | } 206 | 207 | .auth_smallheader { 208 | font-family: "Montserrat", sans-serif; 209 | display: none; 210 | font-weight: 600; 211 | } 212 | 213 | .signup_btn { 214 | background-color: #ff8400 !important; 215 | color: white !important; 216 | border: none; 217 | border-radius: 5px; 218 | padding: 10px 20px; 219 | font-size: 1.2rem; 220 | 221 | cursor: pointer; 222 | transition: all 0.3s ease-in-out; 223 | font-family: "Montserrat", sans-serif !important; 224 | 225 | font-weight: 600 !important; 226 | } 227 | 228 | .signup_btn:hover { 229 | background-color: #007c73 !important; 230 | color: white !important; 231 | border: none; 232 | border-radius: 5px; 233 | padding: 10px 20px; 234 | font-size: 1.2rem; 235 | 236 | cursor: pointer; 237 | transition: all 0.3s ease-in-out; 238 | font-family: "Montserrat", sans-serif !important; 239 | 240 | font-weight: 600 !important; 241 | } 242 | 243 | 244 | .auth_smallchecktext p { 245 | font-family: "Montserrat", sans-serif !important; 246 | margin-top: 20px; 247 | } 248 | 249 | .auth_smallchecktext span { 250 | text-decoration: underline !important; 251 | color: rgb(244, 159, 31); 252 | cursor: pointer; 253 | } 254 | 255 | @media screen and (max-width: 1000px) { 256 | 257 | 258 | .authsub { 259 | flex-direction: column; 260 | } 261 | 262 | .auth_leftdiv { 263 | display: none; 264 | } 265 | 266 | .auth_smallheader { 267 | text-align: center; 268 | margin-bottom: 0px; 269 | display: block; 270 | margin-top: 10px; 271 | } 272 | 273 | .auth_rightdiv { 274 | padding-top: 10px; 275 | } 276 | } 277 | 278 | @media screen and (max-width:500px) { 279 | .auth_rightdiv { 280 | -webkit-box-flex: 1; 281 | -webkit-flex-grow: 1; 282 | -ms-flex-positive: 1; 283 | flex-grow: 1; 284 | width: auto; 285 | padding: 48px; 286 | padding-top: 10px; 287 | overflow: auto; 288 | } 289 | 290 | .auth_rightdiv::-webkit-scrollbar { 291 | display: none; 292 | } 293 | } -------------------------------------------------------------------------------- /components/productcard_landscape/Buttondiv.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import Image from "next/image"; 4 | import React, { useState } from "react"; 5 | import cart from "../../public/assets/Products/misc/cart.svg"; 6 | import { AiOutlinePlusSquare, AiOutlineMinusSquare } from "react-icons/ai"; 7 | import { showErrorToast, showSuccessToast } from "@/middleware/toastMessage"; 8 | import { ToastContainer } from "react-toastify"; 9 | import "react-toastify/dist/ReactToastify.css"; 10 | import getStripe from "../../services/GetStripe"; 11 | import { useSWRConfig } from 'swr' 12 | import { useSession } from "next-auth/react" 13 | 14 | const Buttondiv = ({ product }) => { 15 | const { mutate } = useSWRConfig() 16 | const { data: session, status } = useSession() 17 | const [creds, setcreds] = useState({ 18 | name: "", 19 | email: "", 20 | }); 21 | const [purchasedQty, setpurchasedQty] = useState(1); 22 | 23 | 24 | //* STRIPE PAYMENT 25 | 26 | const stripeCheckout = async () => { 27 | 28 | if (purchasedQty > 0) { 29 | product.totalPrice = product.productPrice * purchasedQty; 30 | product.purchasedQty = purchasedQty; 31 | } else { 32 | product.totalPrice = product.productPrice; 33 | product.purchasedQty = 1; 34 | } 35 | 36 | const stripe = await getStripe(); 37 | 38 | const response = await fetch("/api/stripe", { 39 | method: "POST", 40 | headers: { 41 | "Content-Type": "application/json", 42 | }, 43 | body: JSON.stringify([ 44 | product 45 | ]), 46 | }); 47 | 48 | if (response.status === 500) { 49 | return; 50 | } 51 | 52 | const data = await response.json(); 53 | const { error } = data; 54 | if (error) { 55 | return; 56 | } 57 | 58 | stripe.redirectToCheckout({ 59 | sessionId: data.id, 60 | }); 61 | }; 62 | 63 | //* ADDING TO CART 64 | 65 | const handleCart = async () => { 66 | 67 | 68 | const user = await fetch(`${process.env.NEXT_PUBLIC_URL}/api/user/viewuserdetails`) 69 | const userData = await user.json(); 70 | 71 | if (userData.user === null) { 72 | creds.name = session.user.name; 73 | creds.email = session.user.email; 74 | try { 75 | const res = await fetch( 76 | `${process.env.NEXT_PUBLIC_URL}/api/user/adduser`, 77 | { 78 | method: "POST", 79 | headers: { 80 | "Content-Type": "application/json", 81 | }, 82 | body: JSON.stringify(creds), 83 | } 84 | ); 85 | 86 | if (res.status !== 200) { 87 | showErrorToast("Something went wrong"); 88 | 89 | } else { 90 | setcreds({ 91 | name: "", 92 | email: "", 93 | }) 94 | } 95 | } catch (error) { 96 | showErrorToast(error); 97 | } 98 | } 99 | 100 | if (purchasedQty > 0) { 101 | product.totalPrice = product.productPrice * purchasedQty; 102 | product.purchasedQty = purchasedQty; 103 | } else { 104 | product.totalPrice = product.productPrice; 105 | product.purchasedQty = 1; 106 | } 107 | 108 | console.log(product); 109 | 110 | 111 | const cart = await fetch( 112 | `${process.env.NEXT_PUBLIC_URL}/api/user/addtocart`, 113 | { 114 | method: "POST", 115 | headers: { 116 | "Content-Type": "application/json", 117 | }, 118 | body: JSON.stringify(product), 119 | } 120 | ); 121 | 122 | if (cart.status !== 200) { 123 | showErrorToast("Something went wrong"); 124 | } else { 125 | showSuccessToast("Added to cart"); 126 | mutate(`${process.env.NEXT_PUBLIC_URL}/api/user/viewuserdetails`) 127 | } 128 | }; 129 | 130 | const addQty = () => { 131 | 132 | setpurchasedQty(currentQty => { 133 | return currentQty + 1; 134 | }) 135 | 136 | if (purchasedQty >= product.productQty) { 137 | setpurchasedQty(product.productQty); 138 | } 139 | }; 140 | 141 | const removeQty = () => { 142 | setpurchasedQty(currentQty => { 143 | return currentQty - 1; 144 | }) 145 | if (purchasedQty <= 0) { 146 | setpurchasedQty(0); 147 | } 148 | }; 149 | 150 | 151 | 152 | return ( 153 | <> 154 | 167 | 168 |
169 | 170 | 171 | 172 |

{purchasedQty}

173 | 174 | 175 | 176 | 177 |
178 |
179 | 191 | 192 | 210 |
211 | 212 | ); 213 | }; 214 | 215 | export default Buttondiv; 216 | -------------------------------------------------------------------------------- /styles/Home.module.css: -------------------------------------------------------------------------------- 1 | .mainparent { 2 | display: flex; 3 | } 4 | 5 | .herobanner { 6 | height: 100vh; 7 | width: 100%; 8 | background-position: right 0; 9 | background-size: cover; 10 | background-image: url("../public/assets/Landing/LandingBanner.png"); 11 | 12 | padding: 0 80px; 13 | display: flex; 14 | flex-direction: column; 15 | justify-content: center; 16 | 17 | } 18 | 19 | .hb_textdiv { 20 | margin-bottom: 3rem; 21 | } 22 | 23 | .hb_textdiv h1, 24 | .hb_textdiv h2 { 25 | font-family: 'Montserrat', sans-serif; 26 | font-size: 70px; 27 | font-weight: 700; 28 | line-height: 70px; 29 | } 30 | 31 | .hb_textdiv h2 { 32 | color: #007c73; 33 | } 34 | 35 | .hb_textdiv span { 36 | font-family: 'Poppins', sans-serif; 37 | font-size: 20px; 38 | letter-spacing: 0.1rem; 39 | } 40 | 41 | .hb_textdiv p { 42 | font-family: 'Poppins', sans-serif; 43 | font-size: 24px; 44 | width: 40%; 45 | margin-top: 2rem; 46 | letter-spacing: 0.1rem; 47 | 48 | } 49 | 50 | @media screen and (max-width: 1025px) { 51 | .herobanner { 52 | background-image: none; 53 | background-color: #e8c287; 54 | align-items: center; 55 | text-align: center; 56 | } 57 | 58 | .hb_textdiv p { 59 | width: 100%; 60 | 61 | } 62 | 63 | } 64 | 65 | @media screen and (max-width: 769px) { 66 | 67 | .hb_textdiv h1, 68 | .hb_textdiv h2 { 69 | font-size: 50px; 70 | line-height: 50px; 71 | } 72 | 73 | .hb_textdiv p { 74 | font-size: 18px; 75 | } 76 | 77 | .hb_textdiv span { 78 | display: none; 79 | } 80 | 81 | .herobanner { 82 | padding: 0 20px; 83 | } 84 | } 85 | 86 | 87 | .shopcoderbanner2 { 88 | background-image: url("../public/assets/Landing/LandingBanner2.png"); 89 | height: 50vh; 90 | background-position: center; 91 | background-size: cover; 92 | display: flex; 93 | flex-direction: column; 94 | justify-content: center; 95 | padding-left: 90px; 96 | } 97 | 98 | .shopcoderbanner2 p:nth-child(1) { 99 | font-family: 'Montserrat', sans-serif; 100 | font-size: 60px; 101 | font-weight: 700; 102 | line-height: 70px; 103 | letter-spacing: 0.1rem; 104 | margin-top: 30px; 105 | margin-bottom: 30px; 106 | color: black; 107 | } 108 | 109 | .shopcoderbanner2 span { 110 | font-family: 'Montserrat', sans-serif; 111 | font-size: 24px; 112 | font-weight: 700; 113 | color: black; 114 | width: 40%; 115 | } 116 | 117 | @media screen and (max-width: 769px) { 118 | .shopcoderbanner2 { 119 | background-image: url("../public/assets/Landing/LandingBanner3.png"); 120 | background-position: center; 121 | background-size: cover; 122 | text-align: center; 123 | padding-left: 20px; 124 | padding-right: 20px; 125 | height: auto !important; 126 | padding-bottom: 10px; 127 | max-width: 100vw; 128 | } 129 | 130 | .shopcoderbanner2 p:nth-child(1) { 131 | font-family: 'Montserrat', sans-serif; 132 | font-size: 50px; 133 | font-weight: 700; 134 | line-height: 50px; 135 | letter-spacing: 0.1rem; 136 | margin-top: 30px; 137 | margin-bottom: 30px; 138 | color: black; 139 | } 140 | 141 | .shopcoderbanner2 span { 142 | font-size: 18px; 143 | width: 100%; 144 | } 145 | } 146 | 147 | .categorydiv, 148 | .categorydiv2 { 149 | display: flex; 150 | padding: 100px 0px 100px 0px; 151 | gap: 20px; 152 | justify-content: space-evenly; 153 | flex-wrap: wrap; 154 | } 155 | 156 | .categorydiv2 { 157 | padding-top: 0px; 158 | justify-content: center; 159 | } 160 | 161 | .category_banner1, 162 | .category_banner2, 163 | .category_banner3 { 164 | background-image: url("../public/assets/Landing/Cat1.png"); 165 | 166 | background-position: center; 167 | background-size: cover; 168 | min-width: 600px; 169 | max-width: 600px; 170 | height: 400px; 171 | display: flex; 172 | flex-direction: column; 173 | align-items: flex-end; 174 | padding-right: 20px; 175 | padding-top: 20px; 176 | border-radius: 8px; 177 | 178 | } 179 | 180 | .category_banner2 { 181 | background-image: url("../public/assets/Landing/Cat2.png"); 182 | } 183 | 184 | .category_banner3 { 185 | background-image: url("../public/assets/Landing/Cat3.png"); 186 | align-items: flex-start; 187 | padding-left: 20px; 188 | padding-right: 0px; 189 | min-width: 720px; 190 | 191 | max-width: 720px; 192 | 193 | } 194 | 195 | .category_banner1 div, 196 | .category_banner2 div { 197 | width: 58%; 198 | text-align: right; 199 | word-break: normal; 200 | 201 | } 202 | 203 | .category_banner1 div p:nth-child(1), 204 | .category_banner2 div p:nth-child(1), 205 | .category_banner3 div p:nth-child(1) { 206 | font-size: 12px; 207 | text-transform: uppercase; 208 | color: #1c1e20; 209 | font-family: "Poppins", sans-serif; 210 | line-height: 12px; 211 | font-weight: 600; 212 | letter-spacing: 0.1rem; 213 | margin-bottom: 40px; 214 | } 215 | 216 | .category_banner1 div p:nth-child(2), 217 | .category_banner2 div p:nth-child(2), 218 | .category_banner3 div p:nth-child(2) { 219 | font-size: 38px; 220 | color: black; 221 | font-family: 'Montserrat', sans-serif; 222 | line-height: 38px; 223 | font-weight: 700 !important; 224 | letter-spacing: 0.1rem; 225 | color: #007c73; 226 | 227 | } 228 | 229 | .category_banner2 div p:nth-child(2) { 230 | color: #662A44; 231 | } 232 | 233 | .category_banner3 div p:nth-child(2) { 234 | margin-top: 3.5rem; 235 | color: #1c1e20; 236 | max-width: 54%; 237 | } 238 | 239 | .category_banner1 div button, 240 | .category_banner2 div button, 241 | .category_banner3 div button { 242 | 243 | font-family: 'Poppins', sans-serif; 244 | font-weight: 600; 245 | letter-spacing: 0.1rem; 246 | margin-top: 10px; 247 | cursor: pointer; 248 | padding: 7px 20px; 249 | border-radius: 5px; 250 | animation: ease-in-out 0.5s; 251 | background-color: #007c73; 252 | color: white; 253 | } 254 | 255 | .category_banner1 div button:hover, 256 | .category_banner2 div button:hover, 257 | .category_banner3 div button:hover { 258 | border: 1px solid #007c73; 259 | /* background-color: rgba(255, 255, 255, 0); */ 260 | background: transparent; 261 | color: black; 262 | font-family: 'Poppins', sans-serif; 263 | font-weight: 600; 264 | letter-spacing: 0.1rem; 265 | animation: ease-in-out 0.5s; 266 | } 267 | 268 | 269 | 270 | @media screen and (max-width: 1025px) { 271 | 272 | .categorydiv, 273 | .categorydiv2 { 274 | padding: 100px 0px 15px 0px; 275 | gap: 10px; 276 | justify-content: center; 277 | align-items: center; 278 | flex-wrap: wrap; 279 | } 280 | 281 | .categorydiv2 { 282 | padding-top: 0px; 283 | justify-content: center; 284 | } 285 | 286 | .category_banner1, 287 | .category_banner2, 288 | .category_banner3 { 289 | background-image: url("../public/assets/Landing/Cat1Mobile.png"); 290 | 291 | background-position: center; 292 | background-size: cover; 293 | /* min-width: 600px; */ 294 | max-width: 90vw; 295 | min-width: 90vw; 296 | width: auto; 297 | height: auto; 298 | display: flex; 299 | flex-direction: column; 300 | align-items: center; 301 | padding: 20px 20px; 302 | border-radius: 8px; 303 | background-repeat: no-repeat; 304 | } 305 | 306 | .category_banner2 { 307 | background-image: url("../public/assets/Landing/Cat2Mobile.png"); 308 | } 309 | 310 | .category_banner3 { 311 | background-image: url("../public/assets/Landing/Cat3Mobile.png"); 312 | align-items: flex-start; 313 | padding: 20px 20px; 314 | 315 | text-align: center; 316 | } 317 | 318 | .category_banner1 div, 319 | .category_banner2 div { 320 | width: 100%; 321 | text-align: center; 322 | word-break: normal; 323 | 324 | } 325 | 326 | .category_banner1 div p:nth-child(1), 327 | .category_banner2 div p:nth-child(1), 328 | .category_banner3 div p:nth-child(1) { 329 | font-size: 12px; 330 | text-transform: uppercase; 331 | color: #1c1e20; 332 | font-family: "Poppins", sans-serif; 333 | line-height: 12px; 334 | font-weight: 600; 335 | letter-spacing: 0.1rem; 336 | margin-bottom: 40px; 337 | } 338 | 339 | .category_banner1 div p:nth-child(2), 340 | .category_banner2 div p:nth-child(2), 341 | .category_banner3 div p:nth-child(2) { 342 | font-size: 38px; 343 | color: black; 344 | font-family: 'Montserrat', sans-serif; 345 | line-height: 38px; 346 | font-weight: 700 !important; 347 | letter-spacing: 0.1rem; 348 | color: #007c73; 349 | 350 | } 351 | 352 | .category_banner2 div p:nth-child(2) { 353 | color: #662A44; 354 | } 355 | 356 | .category_banner3 div p:nth-child(2) { 357 | margin-top: 3.5rem; 358 | color: #1c1e20; 359 | max-width: 100%; 360 | } 361 | 362 | .category_banner1 div button, 363 | .category_banner2 div button, 364 | .category_banner3 div button { 365 | 366 | font-family: 'Poppins', sans-serif; 367 | font-weight: 600; 368 | letter-spacing: 0.1rem; 369 | margin-top: 10px; 370 | cursor: pointer; 371 | padding: 7px 20px; 372 | border-radius: 5px; 373 | animation: ease-in-out 0.5s; 374 | background-color: #007c73; 375 | color: white; 376 | } 377 | 378 | .category_banner1 div button:hover, 379 | .category_banner2 div button:hover, 380 | .category_banner3 div button:hover { 381 | border: 1px solid #007c73; 382 | /* background-color: rgba(255, 255, 255, 0); */ 383 | background: transparent; 384 | color: black; 385 | font-family: 'Poppins', sans-serif; 386 | font-weight: 600; 387 | letter-spacing: 0.1rem; 388 | animation: ease-in-out 0.5s; 389 | } 390 | } -------------------------------------------------------------------------------- /app/cart/page.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React, { useEffect } from "react"; 4 | import Image from "next/image"; 5 | import Link from "next/link"; 6 | import styles from "../../styles/Cart.module.css"; 7 | import useSWR from "swr"; 8 | import { showErrorToast, showSuccessToast } from "@/middleware/toastMessage"; 9 | import { useRouter } from "next/navigation"; 10 | import { toast, ToastContainer } from "react-toastify"; 11 | import "react-toastify/dist/ReactToastify.css"; 12 | import { useSession } from "next-auth/react"; 13 | import getStripe from "../../services/GetStripe"; 14 | import deleteicon from "../../public/assets/cart/deleteicon.png"; 15 | import { useSWRConfig } from "swr"; 16 | import { AiOutlineMinusSquare } from "react-icons/ai"; 17 | 18 | const fetcher = (...args) => fetch(...args).then((res) => res.json()); 19 | const Cart = () => { 20 | const router = useRouter(); 21 | const { mutate } = useSWRConfig(); 22 | 23 | const { status } = useSession({ 24 | required: true, 25 | onUnauthenticated() { 26 | showErrorToast("Please login to view your cart"); 27 | setTimeout(() => { 28 | router.push("/"); 29 | }, 2000); 30 | }, 31 | }); 32 | 33 | const { data, error } = useSWR( 34 | `${process.env.NEXT_PUBLIC_URL}/api/user/viewuserdetails`, 35 | fetcher, 36 | { 37 | revalidateOnFocus: false, 38 | } 39 | ); 40 | 41 | if (!data) 42 | return ( 43 |
44 |

Your cart is loading

45 |
46 | ); 47 | if (error) return "there is an error"; 48 | 49 | //* Stripe checkout 50 | const stripeCheckout = async () => { 51 | const stripe = await getStripe(); 52 | 53 | const response = await fetch("/api/stripecart", { 54 | method: "POST", 55 | headers: { 56 | "Content-Type": "application/json", 57 | }, 58 | body: JSON.stringify(data?.user?.cartproducts), 59 | }); 60 | 61 | if (response.status === 500) { 62 | return; 63 | } 64 | 65 | const stripeData = await response.json(); 66 | const { error } = stripeData; 67 | if (error) { 68 | return; 69 | } 70 | 71 | stripe.redirectToCheckout({ 72 | sessionId: stripeData.id, 73 | }); 74 | }; 75 | 76 | //* Remove from cart 77 | const removeFromCart = async (product) => { 78 | const cart = await fetch( 79 | `${process.env.NEXT_PUBLIC_URL}/api/user/removefromcart`, 80 | { 81 | method: "POST", 82 | headers: { 83 | "Content-Type": "application/json", 84 | }, 85 | body: JSON.stringify(product), 86 | } 87 | ); 88 | 89 | console.log(cart.status); 90 | 91 | if (cart.status !== 200) { 92 | showErrorToast("Something went wrong"); 93 | } else { 94 | showSuccessToast("Removed from cart"); 95 | mutate(`${process.env.NEXT_PUBLIC_URL}/api/user/viewuserdetails`); 96 | } 97 | }; 98 | 99 | //* Reduce cart 100 | const reduceCart = async (product) => { 101 | const cart = await fetch( 102 | `${process.env.NEXT_PUBLIC_URL}/api/user/reducecartitems`, 103 | { 104 | method: "POST", 105 | headers: { 106 | "Content-Type": "application/json", 107 | }, 108 | body: JSON.stringify(product), 109 | } 110 | ); 111 | 112 | if (cart.status !== 200) { 113 | showErrorToast("Something went wrong"); 114 | } else { 115 | mutate(`${process.env.NEXT_PUBLIC_URL}/api/user/viewuserdetails`); 116 | } 117 | }; 118 | 119 | return ( 120 | <> 121 | 134 | 135 |
136 |
137 | {data?.user?.cartproducts.length > 0 ? ( 138 | <> 139 | {/*

Here's your cart

*/} 140 | 141 |
142 | {data?.user?.cartproducts.map((product, index) => { 143 | 144 | return ( 145 | <> 146 |
147 |
148 | detailed picture of the tshirt 149 | 150 |
151 |

{product.productName}

152 | 153 | {/*

{product.productDescription}

*/} 154 | 155 |

Unit price:{" "} 156 | ₹ {product.productPrice} 157 |

158 | 159 |
160 |

Quantity: {product.purchasedQty}

161 | {product.purchasedQty > 1 && ( 162 | { 165 | reduceCart(product); 166 | }} 167 | /> 168 | )} 169 |
170 | 171 |
172 |
173 |
174 | 175 | 176 |

₹ {product.totalPrice}

177 | 178 | { 182 | removeFromCart(product); 183 | }} 184 | /> 185 |
186 |
187 | 188 | 189 | 190 |
191 |
192 |
193 | {/* */} 194 | 195 | ); 196 | })} 197 | 198 |
199 |
200 | 201 | 202 |
203 |

Thanks for shopping with us

204 | 205 | 206 | 207 |

208 | {" "} 209 | Your cart total is
210 | 211 | 212 | ₹{" "} 213 | {data?.user && 214 | data?.user?.cartproducts.reduce((acc, curr) => { 215 | return acc + curr.totalPrice; 216 | }, 0)} 217 | 218 | 219 |

220 | 221 |
222 | 234 |
235 | 236 | 237 | 238 |
239 |
240 |
241 |
242 |
243 |
244 | 245 |
246 | 247 | {/**/} 248 | 249 | 250 | 251 | ) : ( 252 |
253 |

Your cart is empty

254 | 255 | 261 | 262 |
263 | )} 264 |
265 |
266 | 267 | ); 268 | }; 269 | 270 | export default Cart; 271 | -------------------------------------------------------------------------------- /components/auth/Auth.jsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import Image from "next/image"; 4 | import React, { useRef, useState } from "react"; 5 | import authbanner from "../../public/assets/auth/authbanner.png"; 6 | import { ToastContainer, toast } from 'react-toastify'; 7 | import 'react-toastify/dist/ReactToastify.css'; 8 | import gh_logo from "../../public/assets/auth/gh_logo.png"; 9 | import gg_logo from "../../public/assets/auth/gg_logo.png"; 10 | import { bearStore } from "@/global/store"; 11 | import authLogic from "./authLogic"; 12 | 13 | const Authcard = ({ showauthmodal, setshowauthmodal }) => { 14 | 15 | 16 | const myRef = useRef(null); 17 | const authtype = bearStore((state) => state.authtype); 18 | const setauthtype = bearStore((state) => state.setauthtype); 19 | const [creds, setcreds] = useState({ 20 | firstName: "", 21 | lastName: "", 22 | email: "", 23 | password: "", 24 | username: "", 25 | address: "", 26 | state: "", 27 | pincode: "", 28 | city: "", 29 | phone: "", 30 | }); 31 | 32 | const handleChange = (e) => { 33 | setcreds({ ...creds, [e.target.name]: e.target.value }); 34 | }; 35 | 36 | const scrollToRef = () => { 37 | myRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' }); 38 | }; 39 | 40 | return ( 41 | <> 42 | 55 | 56 |
57 | 58 |
59 | 60 |
61 | 71 |
72 | 73 | 74 | 75 |
76 | 77 |
78 | 79 |
80 |
81 | 82 | 83 |

{authtype === "login" ? "Login" : "Signup"}

84 | 85 | 86 |
87 | { 88 | 89 | authLogic.handleGithubSignin(); 90 | }} /> 91 | { 92 | authLogic.handleGoogleSignin(); 93 | }} /> 94 | 95 |
96 | 97 |

OR

98 | 99 | {authtype === "signup" && ( 100 |
101 |
102 | 105 | 115 |
116 |
117 | 120 | 128 |
129 |
130 | )} 131 | 132 |
133 | 136 | 146 | {authtype === "signup" &&
147 | We'll never share your email with anyone else. 148 |
} 149 |
150 | 151 |
152 | 155 | 163 |
164 | 165 | {authtype === "signup" && ( 166 | <> 167 | 168 |
169 | 172 | 181 |
182 | 183 |
184 | 187 |