├── src ├── App.scss ├── components │ ├── SingleProduct │ │ ├── RelatedProducts │ │ │ ├── RelatedProducts.scss │ │ │ └── RelatedProducts.jsx │ │ ├── SingleProduct.jsx │ │ └── SingleProduct.scss │ ├── Home │ │ ├── Home.scss │ │ ├── Category │ │ │ ├── Category.scss │ │ │ └── Category.jsx │ │ ├── Banner │ │ │ ├── Banner.jsx │ │ │ └── Banner.scss │ │ └── Home.jsx │ ├── Category │ │ ├── Category.scss │ │ └── Category.jsx │ ├── Products │ │ ├── Products.jsx │ │ ├── Product │ │ │ ├── Product.jsx │ │ │ └── Product.scss │ │ └── Products.scss │ ├── Footer │ │ ├── Newsletter │ │ │ ├── Newsletter.jsx │ │ │ └── Newsletter.scss │ │ ├── Footer.scss │ │ └── Footer.jsx │ ├── header │ │ ├── Header.jsx │ │ └── Header.scss │ ├── Cart │ │ ├── CartItem │ │ │ ├── CartItem.scss │ │ │ └── CartItem.jsx │ │ ├── Cart.jsx │ │ └── Cart.scss │ └── Header │ │ └── Search │ │ ├── Search.jsx │ │ └── Search.scss ├── assets │ ├── payments.png │ ├── banner-img.png │ └── newsletter-bg.jpeg ├── index.js ├── index.scss ├── hooks │ └── useFetch.js ├── css-config │ └── mixins.scss ├── utils │ ├── api.js │ └── context.js └── App.js ├── public ├── favicon.ico └── index.html ├── .gitignore ├── .env ├── package.json └── README.md /src/App.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/components/SingleProduct/RelatedProducts/RelatedProducts.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShariqAnsari88/strapi-simple-one-client/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/assets/payments.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShariqAnsari88/strapi-simple-one-client/HEAD/src/assets/payments.png -------------------------------------------------------------------------------- /src/assets/banner-img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShariqAnsari88/strapi-simple-one-client/HEAD/src/assets/banner-img.png -------------------------------------------------------------------------------- /src/assets/newsletter-bg.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShariqAnsari88/strapi-simple-one-client/HEAD/src/assets/newsletter-bg.jpeg -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom/client"; 3 | import "./index.scss"; 4 | import App from "./App"; 5 | 6 | const root = ReactDOM.createRoot(document.getElementById("root")); 7 | root.render(); 8 | -------------------------------------------------------------------------------- /src/components/Home/Home.scss: -------------------------------------------------------------------------------- 1 | @import "../../css-config/mixins.scss"; 2 | .main-content { 3 | .layout { 4 | max-width: calc(100% - 20px); 5 | margin: 0 auto; 6 | @include md { 7 | max-width: 1200px; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/index.scss: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Cabin:wght@400;500;600;700&display=swap"); 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | box-sizing: border-box; 6 | font-family: "Cabin", sans-serif; 7 | } 8 | body { 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | font-size: 16px; 12 | line-height: 22px; 13 | font-weight: 500; 14 | } 15 | -------------------------------------------------------------------------------- /.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 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | package-lock.json 26 | -------------------------------------------------------------------------------- /src/hooks/useFetch.js: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | import { fetchDataFromApi } from "../utils/api"; 3 | const useFetch = (endpoint) => { 4 | const [data, setData] = useState(); 5 | 6 | useEffect(() => { 7 | makeApiCall(); 8 | }, [endpoint]); 9 | 10 | const makeApiCall = async () => { 11 | const res = await fetchDataFromApi(endpoint); 12 | setData(res); 13 | }; 14 | 15 | return { data }; 16 | }; 17 | export default useFetch; 18 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | JSDEV | STORE 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /src/css-config/mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin sm { 2 | @media only screen and (min-width: 640px) { 3 | @content; 4 | } 5 | } 6 | 7 | @mixin md { 8 | @media only screen and (min-width: 768px) { 9 | @content; 10 | } 11 | } 12 | 13 | @mixin lg { 14 | @media only screen and (min-width: 1024px) { 15 | @content; 16 | } 17 | } 18 | 19 | @mixin xl { 20 | @media only screen and (min-width: 1280px) { 21 | @content; 22 | } 23 | } 24 | 25 | @mixin xxl { 26 | @media only screen and (min-width: 1536px) { 27 | @content; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/components/Category/Category.scss: -------------------------------------------------------------------------------- 1 | @import "../../css-config/mixins.scss"; 2 | .category-main-content { 3 | margin: 30px 0; 4 | @include md { 5 | margin: 75px 0; 6 | } 7 | .layout { 8 | max-width: calc(100% - 20px); 9 | margin: 0 auto; 10 | @include md { 11 | max-width: 1200px; 12 | } 13 | } 14 | .category-title { 15 | font-size: 24px; 16 | @include md { 17 | font-size: 34px; 18 | } 19 | } 20 | .products-container { 21 | margin: 20px 0; 22 | @include md { 23 | margin: 50px 0; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/components/SingleProduct/RelatedProducts/RelatedProducts.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import useFetch from "../../../hooks/useFetch"; 3 | import Products from "../../Products/Products"; 4 | 5 | const RelatedProducts = ({ categoryId, productId }) => { 6 | const { data } = useFetch( 7 | `/api/products?populate=*&filters[id][$ne]=${productId}&filters[categories][id]=${categoryId}&pagination[start]=0&pagination[limit]=4` 8 | ); 9 | 10 | return ( 11 |
12 | 13 |
14 | ); 15 | }; 16 | 17 | export default RelatedProducts; 18 | -------------------------------------------------------------------------------- /src/components/Products/Products.jsx: -------------------------------------------------------------------------------- 1 | import "./Products.scss"; 2 | import Product from "./Product/Product"; 3 | 4 | const Products = ({ products, innerPage, headingText }) => { 5 | return ( 6 |
7 | {!innerPage &&
{headingText}
} 8 |
9 | {products?.data?.map((item) => ( 10 | 15 | ))} 16 |
17 |
18 | ); 19 | }; 20 | 21 | export default Products; 22 | -------------------------------------------------------------------------------- /src/utils/api.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | const params = { 4 | headers: { 5 | Authorization: "bearer " + process.env.REACT_APP_STRIPE_DEV_APP_KEY, 6 | }, 7 | }; 8 | 9 | export const fetchDataFromApi = async (url) => { 10 | try { 11 | const { data } = await axios.get( 12 | process.env.REACT_APP_STRIPE_APP_DEV_URL + url, 13 | params 14 | ); 15 | return data; 16 | } catch (err) { 17 | console.log(err); 18 | return err; 19 | } 20 | }; 21 | 22 | export const makePaymentRequest = axios.create({ 23 | baseURL: process.env.REACT_APP_STRIPE_APP_DEV_URL, 24 | headers: { 25 | Authorization: "bearer " + process.env.REACT_APP_STRIPE_DEV_APP_KEY, 26 | }, 27 | }); 28 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | REACT_APP_STRIPE_DEV_APP_KEY=8ac76b5f08e1cd814b14ef20b1e803ceaa169511eaca96acc091ee756efa6c870fb7575dd255dd38b17c6b68074712d5e0b0a28fa36fe498192fb612411d585aeee726f2a137467bbc80157b233293aeecef5ca7c318e83da3d9fe7398ce68e30755990b0b40777364f88d2f5906812c74b988bec429fc742007dab46d2d7f8a 2 | 3 | REACT_APP_STRIPE_PROD_APP_KEY=027bb7c34b9a60c3c79ab8eada87aaed2f1e85de301b4c48167d1905b46d0f3197dfb7bbea315049dd451a24ae489843083825c2eb4f5ab328a9c82bdab3b8725ebaa182c1fdebfc1363b3243820395e17417e50536e6105bb152bc1fcb80e8e411adba6f6bd92f80c864207ab0cb6f6d2915659a69a5c8433ec3ba90898b43f 4 | 5 | REACT_APP_STRIPE_APP_DEV_URL=http://localhost:1337 6 | REACT_APP_STRIPE_APP_PROD_URL=https://strapi-simple-one-production.up.railway.app 7 | 8 | REACT_APP_STRIPE_PUBLISHABLE_KEY=pk_test_51MDp33SD8BxA31DW0RfZehhQP0BqgUiYliXnGZkE4jA4bUjtzwirmGhz7ngpp7RZLM3EHdpjX0UUKWNllRlPROC800l7vtgVb1 -------------------------------------------------------------------------------- /src/components/Home/Category/Category.scss: -------------------------------------------------------------------------------- 1 | @import "../../../css-config/mixins.scss"; 2 | .shop-by-category { 3 | margin: 25px 0; 4 | @include md { 5 | margin: 50px 0; 6 | } 7 | .categories { 8 | display: flex; 9 | flex-flow: wrap; 10 | gap: 10px; 11 | .category { 12 | background-color: black; 13 | width: calc(50% - 5px); 14 | cursor: pointer; 15 | overflow: hidden; 16 | @include md { 17 | width: calc(25% - 10px); 18 | } 19 | img { 20 | width: 100%; 21 | display: block; 22 | transition: all ease 0.3s; 23 | } 24 | &:hover { 25 | img { 26 | transform: scale(1.2); 27 | } 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/components/Category/Category.jsx: -------------------------------------------------------------------------------- 1 | import { useParams } from "react-router-dom"; 2 | import useFetch from "../../hooks/useFetch"; 3 | import Products from "../Products/Products"; 4 | import "./Category.scss"; 5 | const Category = () => { 6 | const { id } = useParams(); 7 | const { data } = useFetch( 8 | `/api/products?populate=*&[filters][categories][id]=${id}` 9 | ); 10 | return ( 11 |
12 |
13 |
14 | { 15 | data?.data?.[0]?.attributes?.categories?.data?.[0] 16 | ?.attributes?.title 17 | } 18 |
19 | 20 |
21 |
22 | ); 23 | }; 24 | 25 | export default Category; 26 | -------------------------------------------------------------------------------- /src/components/Products/Product/Product.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useNavigate } from "react-router-dom"; 3 | import "./Product.scss"; 4 | 5 | const Product = ({ data, id }) => { 6 | const navigate = useNavigate(); 7 | return ( 8 |
navigate("/product/" + id)} 11 | > 12 |
13 | 19 |
20 |
21 | {data.title} 22 | ₹{data.price} 23 |
24 |
25 | ); 26 | }; 27 | 28 | export default Product; 29 | -------------------------------------------------------------------------------- /src/components/Products/Products.scss: -------------------------------------------------------------------------------- 1 | @import "../../css-config/mixins.scss"; 2 | .products-container { 3 | margin: 50px 0; 4 | @include md { 5 | margin: 75px 0; 6 | } 7 | .sec-heading { 8 | margin-bottom: 20px; 9 | font-size: 18px; 10 | font-weight: 500; 11 | text-transform: uppercase; 12 | @include md { 13 | margin-bottom: 35px; 14 | font-size: 24px; 15 | } 16 | &:after { 17 | content: ""; 18 | display: block; 19 | margin-top: 5px; 20 | width: 50px; 21 | height: 3px; 22 | background-color: #8e2de2; 23 | @include md { 24 | margin-top: 10px; 25 | } 26 | } 27 | } 28 | .products { 29 | display: flex; 30 | flex-flow: wrap; 31 | gap: 10px; 32 | @include md { 33 | gap: 20px; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/components/Home/Category/Category.jsx: -------------------------------------------------------------------------------- 1 | import { useNavigate } from "react-router-dom"; 2 | import "./Category.scss"; 3 | 4 | const Category = ({ categories }) => { 5 | const navigate = useNavigate(); 6 | return ( 7 |
8 |
9 | {categories?.data?.map((item) => ( 10 |
navigate(`/category/${item.id}`)} 14 | > 15 | 21 |
22 | ))} 23 |
24 |
25 | ); 26 | }; 27 | 28 | export default Category; 29 | -------------------------------------------------------------------------------- /src/components/Home/Banner/Banner.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import "./Banner.scss"; 4 | import BannerImg from "../../../assets/banner-img.png"; 5 | 6 | const Banner = () => { 7 | return ( 8 |
9 |
10 |
11 |

SALES

12 |

13 | Convallis interdum purus adipiscing dis parturient 14 | posuere ac a quam a eleifend montes parturient posuere 15 | curae tempor 16 |

17 |
18 |
Read More
19 |
Shop Now
20 |
21 |
22 | 23 |
24 |
25 | ); 26 | }; 27 | 28 | export default Banner; 29 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import { BrowserRouter, Routes, Route } from "react-router-dom"; 2 | import "./App.scss"; 3 | 4 | import Header from "./components/Header/Header"; 5 | import Footer from "./components/Footer/Footer"; 6 | import Home from "./components/Home/Home"; 7 | import Category from "./components/Category/Category"; 8 | import SingleProduct from "./components/SingleProduct/SingleProduct"; 9 | import Newsletter from "./components/Footer/Newsletter/Newsletter"; 10 | import AppContext from "./utils/context"; 11 | 12 | function App() { 13 | return ( 14 | 15 | 16 |
17 | 18 | } /> 19 | } /> 20 | } /> 21 | 22 | 23 |