Open In App

Online Handicrafts Store using React

Last Updated : 27 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we are going to discuss the steps involved in building an online E-commerce platform. For example, I’ve taken a platform that houses DIY and handicraft products made by local artisans. It provides a platform for them to showcase their usually neglected sector.

The name of the website is Kalakaari and it is built using React and SASS. It shows dummy data as of now as this is essentially a frontend-only project implemented using the React framework, which will provide readers insights into how to build the frontend for their e-commerce projects and how to style their React pages using the SASS framework.

Output Preview: Let’s have a look at what our final project will look like.

Kalakari-GoogleChrome2024-03-2407-44-14-ezgifcom-video-to-gif-converter

Preview of website

Prerequisites:

Approach to Create E-Commerce Website:

  • We are going to initialize the react application using the following files:
    • index.js – main entry point for the application on the client side.
    • App.js – Point where routes are defined and all the main components are called.
  • We are going to use React components to create various pages.
    • About.jsx – This page basically describes the purpose of the website. It is optional.
    • Home.jsx – The home page provides a snapshot of things that can be done on the ecommerce platform.
    • Login.jsx and Register.jsx – They are meant for logging in/registering the user.
    • Product.jsx – This is the page to view the details of a single product.
    • Products.jsx – These pages are the category pages where products of different categories are rendered along with filter options.
    • Wishlist.jsx – The wishlist page houses the users wishlisted products.
  • We are going to create components that will be reusable across all the pages.
    • Card.jsx – This is the component used accross the entire website to display products.
    • Cart.jsx – The Cart component houses a popup for facilitating users to view the items present in the cart.
    • Categories.jsx – This proposes a stylish collage that is displayed on the home page. Various category pages are linked via this collage.
    • Contact.jsx – Is used to contact the owners of the website, by dropping an email or connecting via social media handles.
    • FeaturedProducts.jsx – Shows a selected few products that may be trending or new in collection.
    • Footer.jsx – The footer is the point of contact for people who want to reach out to the owners’. It consists of dummy data currently.
    • List.jsx – The list component is used on the Products page to render list of items based on the page we are present on.
    • Navbar.jsx – This is the main centre for navigation accross the website.
    • ProductCard.jsx – This component is rendered as many times as the number of wishlisted products on wishlist page.
    • Slider.jsx -This is the hero carousel that appears on the home page.
  • index.css – A central css file houses the root colors that can be reused across all pages for styling.
  • Material UI icons will be used for icons.
  • Sass framework has been used for styling the components. The advantage of using Sass framework for styling is its ability to streamline and enhance CSS development with features like variables, nesting, mixins, and inheritance, ultimately improving code organization and maintainability.

Steps to Create a React Application:

Step 1: Create a client folder and initialize the react app by writing the following command in the terminal.

npx create-react-app client

Step 2: Navigate to the client folder using the following command.

cd client

Step 3: Install the required dependencies using the following command:

npm install react-router-hash-link react-router-dom react-scroll sass @mui/material @mui/icons-material @emotion/react @babel/plugin-proposal-private-property-in-object

Step 4: Add this in the index.html file present in the public folder. The index.html file is already set up react.

<link href=”https://fonts.googleapis.com/css2?family=Quicksand:wght@300;400;500;600;700&display=swap” rel=”stylesheet”>

Project Structure:

Screenshot-2024-02-26-111323-(1)

Project Structure

The updated dependencies in package.json file will look like:

"dependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.14.16",
"@mui/material": "^5.14.16",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.18.0",
"react-router-hash-link": "^2.4.3",
"react-scroll": "^1.9.0",
"sass": "^1.69.5",
},

Step 5: Create the index.css, index.js and App.js files.

Step 6: Create all the components and style them.

The following are the files card.scss, cart.scss, categories.scss, contact.scss, featuredProducts.scss, footer.scss, list.scss, navbar.scss, productCard.scss, slider.scss, Card.jsx, Cart.jsx, Categories.jsx, Contact.jsx, FeaturedProducts.jsx, FeaturedProducts/data.js (this means that in the folder FeaturedProducts we have another file by the name data.js that contains dummy data for FeaturedProducts.jsx component), Footer.jsx, List.jsx, List/data.js, Navbar.jsx, ProductCard.jsx and Slider.jsx.

Step 7: Create all the page components, import previously created components, and style them.

The following are the codes for login.scss, about.scss, home.scss, product.scss, products.scss, wishlist.scss, register.scss, Login.jsx, About.jsx, Home.jsx, Product.jsx, Products.jsx, Wishlist.jsx and Register.jsx.

CSS
/* src/components/Card/card.scss */

.link {
    text-decoration: none;
    color: var(--mehendi);
}

.card{
    width: 280px;
    display: flex;
    flex-direction: column;
    margin-bottom: 50px;
    transition: all 100ms ease-in-out;

    &:hover {
      transform: translateY(-10px);
    }

    .image{
      width: 100%;
      height: 400px;
      overflow: hidden;
      position: relative;
      background-color: var(--grey-green);
      transition: all 0.5s ease-in-out;
  
      &:hover{
        .secondImg{
          z-index: 2;
        }
      }
  
      img{
        width: 200px;
        height: 200px;
        // object-fit: cover;
        position: absolute;
        top: 50%;
        left: 50%;
        border: none;
        transform: translate(-50%, -50%);
      }
  
      .mainImg{
        z-index: 1;
      }
  
      span{
        position: absolute;
        top: 5px;
        left: 5px;
        background-color: white;
        color: var(--brown);
        padding: 3px 5px;
        z-index: 3;
        font-weight: 700;
        font-size: 12px;
      }
    }
  
    h2{
      font-size: 18px;
      font-weight: 400;
    }
  
    .prices{
      display: flex;
      gap: 20px;
      line-height: 1px;
  
      h3{
        font-size: 18px;
        font-weight: 500;
  
        &:first-child{
          color: var(--brown);
          text-decoration: line-through;
        }
      }
    }
  }
CSS
/* src/components/Cart/cart.scss */

.cart {
    position: absolute;
    right: 20px;
    top: 80px;
    z-index: 999;
    background-color: var(--dried-leaf);
    padding: 20px;
    -webkit-box-shadow: 0px 0px 7px -5px rgba(0, 0, 0, 0.5);
    box-shadow: 0px 0px 7px -5px rgba(0, 0, 0, 0.5);
  
    h1 {
      margin-bottom: 30px;
      color: var(--bush-green);
      font-weight: 600;
      text-transform: capitalize;
      font-size: 24px;
    }
  
    .item {
      display: flex;
      align-items: center;
      gap: 20px;
      margin-bottom: 30px;
      img {
        width: 80px;
        height: 100px;
        object-fit: cover;
      }
  
      .details {
        h1 {
          font-size: 18px;
          font-weight: 500;
        }
  
        p {
          color: gray;
          margin-bottom: 10px;
          font-size: 14px;
          width: 300px;
        }
  
        .price {
          color: var(--mehendi);
        }
      }
  
      .delete {
        color: var(--brown);
        font-size: 30px;
        cursor: pointer;
      }
    }
  
    .total {
      display: flex;
      justify-content: flex-start;
      color: var(--mehendi);
      font-weight: 500;
      font-size: 18px;
      margin-bottom: 20px;
      gap: 30px;
    }
  
    button {
      width: 250px;
      padding: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 20px;
      cursor: pointer;
      border: none;
      background-color: var(--grass);
      color: white;
      font-weight: 500;
      margin-bottom: 20px;
    }
  
    .reset{
      color:var(--bush-green);
      font-size: 12px;
      cursor: pointer;
    }
  }
CSS
/* src/components/Categories/categories.scss */

.categories {
    display: flex;
    height: 80vh;
    gap: 10px;
    margin: 10px;
  
    .col {
      flex: 1;
      display: flex;
      flex-direction: column;
      gap: 10px;
    }
  
    .col-l {
      flex: 2;
    }
  
    .row{
      flex:1;
      display: flex;
      gap: 10px;
      position: relative;
      overflow: hidden;
  
      button{
        position: absolute;
        min-width: 100px;
        width: fit-content;
        height: 50px;
        padding: 10px;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        margin: auto;
        cursor: pointer;
        border: none;
        background-color: white;
        text-transform: uppercase;
        font-weight: 600;
        transition: all 500ms ease-in-out;

        &:hover {
          background-color: var(--cream);
        }
      }
  
      img{
        width: 100%;
        height: 100%;
        object-fit: cover;
        transition: all 0.5s ease;

        &:hover {
          transform: scale(1.2);
        }
      }
    }
  }
CSS
/* src/components/Contact/contact.scss */

.contact{
    background-color: var(--brown);
    color: white;
    padding: 15px;
    display: flex;
    justify-content: center;
    font-weight: 600;
  
    .wrapper{
      width: 50%;
      display: flex;
      align-items: center;
      justify-content: space-between;
  
      input{
        padding: 10px;
        border: none;
        border-radius: 5px 0 0  5px;
        outline: none;
        font-family: 'Quicksand', sans-serif;
        color: var(--bush-green);
      }
  
      button{
        padding: 10px;
        color: white;
        background: var(--mehendi);
        border-radius: 0 5px 5px 0;
        border: none;
        cursor: pointer;
      }
  
      .icons{
        display: flex;
        gap: 10px;
      }
    }
  }
CSS
/* src/components/FeaturedProducts/featuredProducts.scss */

.featuredProducts {
    margin: 100px 200px;
  
    .top {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 50px;
  
      h1 {
        flex: 2;
        text-transform: capitalize;
        color:var(--mehendi);
      }
  
      p{
        flex:3;
        color:var(--mehendi);
      }
    }
  
    .bottom{
      display: flex;
      justify-content: center;
      gap: 50px;
    }
  }
CSS
/* src/components/Footer/footer.scss */

.footer {
    padding: 100px 200px 20px 200px;
    background-color: var(--grey-green);
  
    .top {
      display: flex;
      gap: 50px;
  
      .item {
        flex: 1;
        display: flex;
        flex-direction: column;
        gap: 10px;
        text-align: justify;
        font-size: 14px;
  
        h1{
          font-size: 18px;
          font-weight: 500;
          color: var(--black);
        }
  
        span{
          color: var(--mehendi);
        }
      }
    }
  
    .bottom {
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-top: 50px;
      .left {
        display: flex;
        align-items: center;
  
        .logo{
          color: var(--mehendi);
          font-weight: bold;
          font-size: 24px;
        }
  
        .copyright{
          margin-left: 20px;
          font-size: 12px;
          color: var(--bush-green);
        }
      }
      .right {
  
        img{
          height: 50px;
        }
      }
    }
  }
CSS
/* src/components/List/list.scss */

.list{
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
  }
CSS
/* src/components/Navbar/navbar.scss */

.navbar {
    height: 60px;
    padding: 10px 0;
    top: 0;
    position: fixed;
    z-index: 100;
    width: 100%;
    background-color: var(--grey-green);
  
    .wrapper {
      padding: 10px 30px;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .india {
        height: 20px;
      }

      .link {
        text-decoration: none;
        color: inherit;
      }
  
      .item {
        display: flex;
        align-items: center;
        font-size: 18px;
      }
  
      .left {
        display: flex;
        align-items: center;
        gap: 25px;
      }
      .center {
        font-size: 30px;
        letter-spacing: 2px;
      }
      .right {
        display: flex;
        align-items: center;
        gap: 25px;
  
        .icons {
          display: flex;
          gap: 15px;
          color: #777;
          cursor: pointer;
  
          .cartIcon {
            position: relative;
  
            span {
              font-size: 12px;
              width: 20px;
              height: 20px;
              border-radius: 50%;
              background-color: var(--bush-green);
              color: white;
              position: absolute;
              right: -10px;
              top: -10px;
              display: flex;
              align-items: center;
              justify-content: center;
            }
          }
        }
      }
    }
  }
CSS
/* src/components/ProductCard/productCard.scss */

.productCard {

    .product-card {
        max-width: 200px;
        flex-basis: 180px;
        flex-grow: 1;
        background-color: var(--white);
    
        @media screen and (max-width: 440px) {
            max-width: 100%;
        }
    
        /* Top part of the card */
        &__images {
            cursor: pointer;
            position: relative;
    
            /* Show the 'see more' button on hover */
            &:hover,
            &:focus {
                .product-card__btn {
                    display: block;
                }
            }
        }
    
        &__img {
            &--hidden {
                width: 100%;
                opacity: 0;
                position: absolute;
                left: 0;
                top: 0;
                transition: 0.3s;
    
                &:hover {
                    opacity: 1;
                }
            }
        }
    
        /* Bottom part of the card */
        &__info {
            padding: 10px;
            text-align: center;
        }
    
        &__name {
            font-size: 16px;
            font-weight: normal;
            text-transform: capitalize;
        }
    
        &__price {
            color: var(--mehendi);
            font-size: 14px;
            font-weight: 600;
            margin: 10px 0;
        }
    
        &__promo {
            color: var(--brown);
            margin-left: 5px;
            text-decoration: line-through;
        }
    
        &__stars {
            display: flex;
            gap: 5px;
            align-items: center;
            justify-content: center;
            color: var(--grass);
        }
    
        &__review-count {
            color: var(--bush-green);
            font-size: 13px;
            font-weight: 300;
        }
    
        /* Like button */
        &__like {
            color: var(--skin-color);
            cursor: pointer;
            font-size: 30px;
            left: 15px;
            position: absolute;
            top: 15px;
        }
    
        /* Hide the checkbox and the filled heart by default */
        &__like-check,
        &__heart--filled {
            display: none;
        }
    
        /* Toggle hearts display w/CSS */
        &__like-check {
            &:checked + .product-card__heart {
                display: none;
                + .product-card__heart--filled {
                    display: inline;
                }
            }
        }

        /* See more button */
        .product-card__btn {
            background-color: var(--grass);
            border-radius: 5px;
            border: none;
            color: var(--skin-color);
            cursor: pointer;
            display: none;
            font-size: 14px;
            font-weight: bold;
            left: 50%;
            padding: 10px 15px;
            position: absolute;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 50%;
            
            
    
            &:hover {
                background-color: var(--bush-green);
            }
        }
    }
}
CSS
/* src/pages/Login/login.scss */

.loginPage {
    display: grid;
    place-items: center;
    background-color: var(--dried-leaf);
    height: 100vh;
    width: 100vw;

    .title {
        color: var(--mehendi);
        margin-bottom: 50px;
        text-align: center;
    }

    .icon {
        block-size: 1em;
        display: inline-block;
        fill: var(--bush-green);
        inline-size: 1em;
        vertical-align: middle;
    }

    .grid {
        inline-size: 90%;
        margin-inline: auto;
        max-inline-size: 20rem;


        .form {
            display: grid;
            gap: var(--formGap);
        }

        .form input[type="password"],
        .form input[type="text"],
        .form input[type="submit"] {
            inline-size: 100%;
        }

        .login {
            color: var(--mehendi);
        }

        .login label,
        .login input[type="text"],
        .login input[type="password"],
        .login input[type="submit"] {
            border-radius: 0.25rem;
            padding: 1rem;
        }

        .login label {
            background-color: var(--grass);
            border-bottom-right-radius: 0;
            border-top-right-radius: 0;
            padding-inline: 1.25rem;
        }

        .login input[type="password"],
        .login input[type="text"] {
            background-color: var(--grass);
            border-bottom-left-radius: 0;
            border-top-left-radius: 0;
        }

        .login input[type="password"]:focus,
        .login input[type="password"]:hover,
        .login input[type="text"]:focus,
        .login input[type="text"]:hover {
            background-color: var(--dried-grass);
        }

        .login input[type="submit"] {
            background-color: var(--brown);
            color: white;
            font-weight: 700;
            text-transform: uppercase;
        }

        .login input[type="submit"]:focus,
        .login input[type="submit"]:hover {
            background-color: var(--med-brown);
        }

        .form__field {

            display: flex;


            .form__input {
                flex: 1;
            }

            .hidden {
                border: 0;
                clip: rect(0 0 0 0);
                height: 1px;
                margin: -1px;
                overflow: hidden;
                padding: 0;
                position: absolute;
                width: 1px;
            }

            input {
                background-image: none;
                border: 0;
                font: inherit;
                margin: 0;
                outline: 0;
                padding: 0;
                transition: background-color 0.3s;

                &::placeholder {
                    color: var(--cream);
                }
            }

            input[type="submit"] {
                cursor: pointer;
            }
        }

    }

    .icons {
        display: none;
    }

    a {
        color: var(--mehendi);
        outline: 0;
        text-decoration: none;
    }

    a:focus,
    a:hover {
        color: var(--brown);
    }

    p {
        margin-block: 1.5rem;
    }

    .text--center {
        text-align: center;
    }
}

/* modules/form.css */

:root {
    --formGap: 0.875rem;
}
CSS
/* src/pages/About/about.scss */

.about {

    margin-top: 80px;

    .container {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        width: 100%;

        .header {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 100%;
            position: relative;

            .bg-about {
                width: 100%;
                height: 600px;
                object-fit: cover;
                background-color: #C2A78A;
            }

            .details {
                position: absolute;
                text-align: center;
                width: 80%;

                h1 {
                    font-size: 48px;
                    color: var(--mehendi);
                }

                p {
                    color: white;
                    font-size: 24px;
                    font-weight: 500;
                }
            }

        }

        .middle {

            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 80%;
            color: var(--mehendi);

            .upper-row {
                display: flex;
                justify-content: space-between;
                gap: 150px;
                align-items: center;

                h1 {
                    color: var(--grass);
                }
            }

            .lower-row {
                display: flex;
                justify-content: space-between;
                align-items: center;
                gap: 150px;
            }

        }

        .explore {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 100%;
            margin-top: 50px;
            position: relative;

            .bg-explore {
                width: 100%;
                height: 600px;
                object-fit: cover;
                filter: sepia(50%);
                background-color: #B63A36;
            }

            .buttons {
                position: absolute;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: center;

                button {
                    font-family: 'Quicksand', sans-serif;
                    outline: none;
                    border: none;
                    padding: 10px 20px;
                    margin: 20px;
                    font-size: 20px;
                    font-weight: 400;
                    cursor: pointer;
                    color: var(--mehendi);
                    transition: all 0.3s ease-in-out;

                    &:hover {
                        transform: translateY(-2px);
                        background-color: var(--dried-leaf);
                    }
                }

                .focus-button {
                    button {
                        background-color: #555843d1;
                        border: 3px var(--skin-color) solid;
                        color: white;
                        font-weight: 600;

                        &:hover {
                            background-color: var(--mehendi);
                        }
                    }
                }

                .category-button {
                    width: 70%;
                    display: flex;
                    flex-wrap: wrap;
                    justify-content: center;
                }
            }
        }
    }
}
CSS
/* src/pages/Home/home.scss */

.home {
    overflow: hidden;
}
CSS
/* src/pages/Product/product.scss */

.product {
    padding: 20px 50px;
    display: flex;
    margin-top: 80px;
    gap: 50px;

    .left {
        flex: 1;
        display: flex;
        gap: 20px;

        .images {
            flex: 1;

            img {
                width: 100%;
                height: 150px;
                object-fit: cover;
                cursor: pointer;
                margin-bottom: 10px;
            }
        }

        .mainImg {
            flex: 5;

            img {
                width: 100%;
                max-height: 600px;
                object-fit: cover;
            }
        }
    }

    .right {
        flex: 1;
        display: flex;
        flex-direction: column;
        gap: 20px;

        h1 {
            font-weight: 500;
            line-height: 20px;
        }

        .price {
            font-size: 30px;
            color: var(--grass);
            font-weight: 700;
        }

        p {
            font-size: 15px;
            font-weight: 400;
            text-align: justify;
        }

        .quantity {
            display: flex;
            align-items: center;
            gap: 10px;

            button {
                width: 50px;
                height: 50px;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                border: none;
                background-color: var(--skin-color);

                &:hover {
                    background-color: var(--cream);
                }
            }
        }

        .add {
            width: 250px;
            padding: 10px;
            background-color: var(--grass);
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 20px;
            cursor: pointer;
            border: none;
            font-weight: 500;
            transition: all 0.5ms ease-in-out;

            &:hover {
                background-color: var(--bush-green);
            }
        }

        .links {
            display: flex;
            gap: 20px;

            .item {
                cursor: pointer;
                display: flex;
                align-items: center;
                gap: 10px;
                color: var(--bush-green);
                font-size: 14px;

                &:hover {
                    color: var(--grass);
                }
            }
        }

        .info {
            display: flex;
            flex-direction: column;
            gap: 10px;
            color: var(--mehendi);
            font-size: 14px;
            margin-top: 20px;

            hr {
                width: 200px;
                border: 1px solid rgb(238, 237, 237);
            }

        }

        .details {
            color: var(--bush-green);
            font-weight: 600;
            margin-top: 20px;
        }

        hr {
            border: 1px solid rgb(238, 237, 237);
        }

    }
}
CSS
/* src/pages/Products/products.scss */

.products {
    margin-top: 50px;
    padding: 30px 50px;
    display: flex;
  
    .left {
      flex: 1;
      position: sticky;
      height: 100%;
      top: 100px;
      color: var(--mehendi);
  
      .filterItem{
        margin-bottom: 30px;
  
        h2{
          font-weight: 400;
          margin-bottom: 20px;
        }
  
        .inputItem{
          margin-bottom: 10px;
          label{
            margin-left: 10px;
          }
        }
      }
    }
    
    .right {
      flex: 3;
  }
      .catImg{
        width: 100%;
        height: 150px;
        filter: sepia(50%);
        object-fit: cover;
        margin-bottom: 50px;
        text-align: center;
        font-size: 2.5rem;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        background-color: var(--brown);
        color: white;
        font-weight: bold;
        font-style: italic;
      }
    }
  }
CSS
/* src/pages/Wishlist/wishlist.scss */

.wishlist {

    margin-top: 100px;
}

img {
    width: 100%;
    vertical-align: top;
    height: 300px;
    object-fit: cover;
}

.container {
    width: 100%;
    max-width: 1000px;
    margin-top: 50px;
    margin-bottom: 100px;
    margin-left: auto;
    margin-right: auto;
    padding: 0 20px;

    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 40px;
}
CSS
/* src/pages/Register/register.scss */

.registerPage {
    display: grid;
    place-items: center;
    background-color: var(--dried-leaf);
    height: 100vh;
    width: 100vw;
}

.title {
    color: var(--mehendi);
    margin-bottom: 50px;
    text-align: center;
}

.icon {
    block-size: 1em;
    display: inline-block;
    fill: var(--bush-green);
    inline-size: 1em;
    vertical-align: middle;
}

.grid {
    inline-size: 90%;
    margin-inline: auto;
    max-inline-size: 20rem;


    .form {
        display: grid;
        gap: var(--formGap);
    }

    .form input[type="password"],
    .form input[type="text"],
    .form input[type="submit"] {
        inline-size: 100%;
    }

    .login {
        color: var(--mehendi);
    }

    .login label,
    .login input[type="text"],
    .login input[type="password"],
    .login input[type="submit"] {
        border-radius: 0.25rem;
        padding: 1rem;
    }

    .login label {
        background-color: var(--grass);
        border-bottom-right-radius: 0;
        border-top-right-radius: 0;
        padding-inline: 1.25rem;
    }

    .login input[type="password"],
    .login input[type="text"] {
        background-color: var(--grass);
        border-bottom-left-radius: 0;
        border-top-left-radius: 0;
    }

    .login input[type="password"]:focus,
    .login input[type="password"]:hover,
    .login input[type="text"]:focus,
    .login input[type="text"]:hover {
        background-color: var(--dried-grass);
    }

    .login input[type="submit"] {
        background-color: var(--brown);
        color: white;
        font-weight: 700;
        text-transform: uppercase;
    }

    .login input[type="submit"]:focus,
    .login input[type="submit"]:hover {
        background-color: var(--med-brown);
    }

    .form__field {

        display: flex;


        .form__input {
            flex: 1;
        }

        .hidden {
            border: 0;
            clip: rect(0 0 0 0);
            height: 1px;
            margin: -1px;
            overflow: hidden;
            padding: 0;
            position: absolute;
            width: 1px;
        }

        input {
            background-image: none;
            border: 0;
            font: inherit;
            margin: 0;
            outline: 0;
            padding: 0;
            transition: background-color 0.3s;

            &::placeholder {
                color: var(--cream);
            }
        }

        input[type="submit"] {
            cursor: pointer;
        }
    }

}

.icons {
    display: none;
}

a {
    color: var(--mehendi);
    outline: 0;
    text-decoration: none;
}

a:focus,
a:hover {
    color: var(--brown);
}

p {
    margin-block: 1.5rem;
}

.text--center {
    text-align: center;
}
/* modules/form.css */

:root {
    --formGap: 0.875rem;
}
CSS
/*src/index.css*/

body {
  margin: 0;
  font-family: 'Quicksand', sans-serif;
}

:root {
  --black: #001524;
  --skin-color: #fbefe6;
  --dried-grass: #D6CC99;
  --bush-green: #445D48;
  --dried-leaf: #e9ead7;
  --light-brown: #D6C7AE;
  --med-brown: #BFB29E;
  --brown: #B3A492;
  --grass: #8caf7e;
  --cream: #F5EEC8;
  --grey-green: #D0D4CA;
  --mehendi: #555843;
}
Javascript
// src/components/Card/Card.jsx

import React from "react";
import "./card.scss";
import { Link } from "react-router-dom";

const Card = ({ item }) => {
  return (
    <Link className="link" to={`/product/${item.id}`}>
      <div className="card">
        <div className="image">
            {item.isNew && <span>New Season</span>}
         <img src={item.img} alt="" className="mainImg" />
         <img src={item.img2} alt="" className="secondImg" />
        </div>
        <h2>{item.title}</h2>
        <div className="prices">
          <h3>₹{item.oldPrice}</h3>
          <h3>₹{item.newPrice}</h3>
        </div>
      </div>
    </Link>
  );
};

export default Card;
Javascript
// src/components/Cart/Cart.jsx

import React from 'react'
import DeleteOutlinedIcon from "@mui/icons-material/DeleteOutlined";
import "./cart.scss"

const Cart = () => {

    const data = [
        {
            id: 1,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323181121/jar_8517434.png",
            title: "Embellished Jar",
            desc: "Adorned with delicate embellishments and hand-painted designs, this jar exudes timeless elegance, making it a perfect addition to your home decor or a cherished gift for a loved one",
            isNew: true,
            price: 1100,
        },
        {
            id: 2,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323175534/bracelets_6439096.png",
            title: "Ethnic Bangles",
            desc: "These exquisite pieces of handcrafted jewelry capture the essence of Indian culture and craftsmanship, adding a touch of elegance to any ensemble.",
            isNew: true,
            price: 500,
        },
    ]

  return (
    <div className='cart'>
        <h1>Products in Your Cart</h1>
        {
            data.map(item=> (
                <div className="item" key={item.id}>
                    <img src={item.img} alt="" />
                    <div className="details">
                        <h1>{item.title}</h1>
                        <p>{item.desc.substring(0, 100)}...</p>
                        <div className="price">1 x ₹{item.price}</div>
                    </div>
                    <DeleteOutlinedIcon className='delete'/>
                </div>
            ))
        }
        <div className="total">
            <span>SUBTOTAL</span>
            <span>:</span>
            <span>₹1050</span>
        </div>
        <button>PROCEED TO CHECKOUT</button>
        <span className='reset'>Reset Cart</span>
    </div>
  )
}

export default Cart
Javascript
// src/components/Categories/Categories.jsx

import React from "react";
import "./categories.scss";
import { Link } from "react-router-dom";

const Categories = () => {
  return (
    <div className="categories">
      <div className="col">
        <div className="row">
          <img
            src="https://media.geeksforgeeks.org/wp-content/uploads/20240323181431/hanging-colorful-eid-festival-lamps-beautiful-background_1017-24849.jpg"
            alt=""
          />
          <button>
            <Link to="/products/sale" className="link">
              Sale
            </Link>
          </button>
        </div>
        <div className="row">
          <img
            src="https://media.geeksforgeeks.org/wp-content/uploads/20240323181623/seamless-hand-drawn-mandala-pattern-vintage-elements-orienta_173207-1940-compressed.jpg"
            alt=""
          />
          <button>
            <Link to="/products/text" className="link">
              TEXTILES
            </Link>
          </button>
        </div>
      </div>
      <div className="col">
        <div className="row">
          {" "}
          <img
            src="https://media.geeksforgeeks.org/wp-content/uploads/20240323181726/christmas-background-with-candle-theme_52683-31153.jpg"
            alt=""
          />
          <button>
            <Link to="/products/new" className="link">
              New Season
            </Link>
          </button>
        </div>
      </div>
      <div className="col col-l">
        <div className="row">
          <div className="col">
            <div className="row">
              <img
                src="https://media.geeksforgeeks.org/wp-content/uploads/20240323182037/hobby-crafts-isometric-with-woman-painting-cup-3d_1284-27899-compressed.jpg"
                alt=""
              />
              <button>
                <Link to="/products/diy" className="link">
                  DIY
                </Link>
              </button>
            </div>
          </div>
          <div className="col">
            <div className="row">
              {" "}
              <img
                src="https://media.geeksforgeeks.org/wp-content/uploads/20240323182202/vintage-flowers-illustration-design_53876-17304.jpg"
                alt=""
              />
              <button>
                <Link to="/products/acc" className="link">
                  Accessories
                </Link>
              </button>
            </div>
          </div>
        </div>
        <div className="row">
          <img
            src="https://media.geeksforgeeks.org/wp-content/uploads/20240323181914/flat-akshaya-tritiya-illustration_23-2149352957-compressed.jpg"
            alt=""
          />
          <button>
            <Link to="/products/handi" className="link">
              Handicrafts
            </Link>
          </button>
        </div>
      </div>
    </div>
  );
};

export default Categories;
Javascript
// src/components/Contact/Contact.jsx

import React from "react";
import "./contact.scss";
import FacebookIcon from "@mui/icons-material/Facebook";
import InstagramIcon from "@mui/icons-material/Instagram";
import TwitterIcon from "@mui/icons-material/Twitter";
import GoogleIcon from "@mui/icons-material/Google";
import PinterestIcon from "@mui/icons-material/Pinterest";

const Contact = () => {
  return (
    <div className="contact" id="contact">
      <div className="wrapper">
        <span>BE IN TOUCH WITH US:</span>
        <div className="mail">
          <input type="text" placeholder="Enter your e-mail..." />
          <button>JOIN US</button>
        </div>
        <div className="icons">
          <FacebookIcon />
          <InstagramIcon />
          <TwitterIcon />
          <GoogleIcon />
          <PinterestIcon />
        </div>
      </div>
    </div>
  );
};

export default Contact;
Javascript
// src/components/FeaturedProducts/FeaturedProducts.jsx

import React from "react";
import Card from "../Card/Card";
import "./featuredProducts.scss";
import { data } from "./data";

const FeaturedProducts = ({ type }) => {

  return (
    <div className="featuredProducts">
      <div className="top">
        <h1>{type} products</h1>
        {
          type === "featured" ? (
            <p>Explore our handpicked selection of extraordinary creations from local artisans and craftsmen. These featured products showcase the finest craftsmanship and artistic expressions that India has to offer. Each item is a masterpiece, a testament to the skill and passion of our talented artisans. Discover unique jewelry, clothing, home decor, and more, all crafted with love and care.</p>
          ) : (
            <p>Stay in the know with our trending products that are captivating the hearts of our customers. These items are the talk of the town, loved by shoppers for their exceptional quality and style. From the latest fashion trends to innovative home decor, our trending products offer a glimpse into what's hot in the world of Indian artisanal craftsmanship. Don't miss out on these popular gems!</p>
          )
        }
      </div>
      <div className="bottom">
        {data[type].map(item => (
            <Card item={item} key={item.id}/>
        ))}
      </div>
    </div>
  );
};

export default FeaturedProducts;
Javascript
// src/components/FeaturedProducts/data.js

export const data = {
    featured: 
        [
            {
                id: 1,
                img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323175534/bracelets_6439096.png",
                title: "Ethnic Bangles",
                isNew: true,
                oldPrice: 500,
                newPrice: 450
            },
            {
                id: 2,
                img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180001/label_9456363.png",
                title: "DIY Keychains",
                isNew: true,
                oldPrice: 160,
                newPrice: 80
            },
            {
                id: 3,
                img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180101/horse_1943770.png",
                title: "Handmade Clay Horse",
                oldPrice: 300,
                newPrice: 200
            },
            {
                id: 4,
                img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180247/case_12920819.png",
                title: "Colorful Trays",
                oldPrice: 300,
                newPrice: 280
            },
    ],
    trending: [
        {
            id: 1,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180835/light_13745972.png",
            title: "Handmade Diya",
            oldPrice: 100,
            newPrice: 80
        },
        {
            id: 2,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180834/led-strip_2605824.png",
            title: "Diwali LED Decor",
            isNew: true,
            oldPrice: 750,
            newPrice: 500
        },
        {
            id: 3,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180834/holi_14779521.png",
            title: "Homestitched DIY Lantern",
            oldPrice: 300,
            newPrice: 280
        },
        {
            id: 4,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180833/candle_5907782.png",
            title: "Candle Diyas Pack of 10",
            isNew: true,
            oldPrice: 150,
            newPrice: 125
        }
    ]
}
Javascript
// src/components/Footer/Footer.jsx

import React from "react";
import "./footer.scss";
import { Link } from "react-router-dom";

const Footer = () => {
  return (
    <div className="footer">
      <div className="top">
        <div className="item">
          <h1>Categories</h1>
          <span>Handicrafts</span>
          <span>Textiles</span>
          <span>Accessories</span>
          <span>DIY</span>
          <span>New Arrivals</span>
        </div>
        <div className="item">
          <h1>Links</h1>
          <span>FAQ</span>
          <span>Pages</span>
          <span>Stores</span>
          <span>Compare</span>
          <span>Cookies</span>
        </div>
          <div className="item">
        <Link to="/about" style={{textDecoration: "none"}}>
            <h1>About</h1>
            <span>
            At Kalakari, we are on a mission to empower local Indian artisans, craftsmen, small shop owners, and DIY enthusiasts by providing them with a thriving platform to showcase and sell their exceptional creations.
            </span>
        </Link>
          </div>
        <div className="item">
          <h1>Contact</h1>
          <span>Email: support@craftvillageindia.com</span>
          <span>Phone: +91-123-456-7890</span>
          <span>Address</span>
          <span>CraftVillageIndia, 123, Artisan's Lane</span>
          <span>Craftsville, India 56789</span>
        </div>
      </div>
      <div className="bottom">
        <div className="left">
          <span className="logo">Kalakari</span>
          <span className="copyright">
            © Copyright 2023. All Rights Reserved
          </span>
        </div>
        <div className="right">
          <img src="https://media.geeksforgeeks.org/wp-content/uploads/20240307113354/payment.png" alt="" />
        </div>
      </div>
    </div>
  );
};

export default Footer;
Javascript
// src/components/List/List.jsx

import React from 'react'
import "./list.scss"
import Card from "../Card/Card"
import { data } from './data'

const List = ({catId}) => {


  return (
    <div className='list'>
        {
            data[catId].map(item => (
                <Card item={item} key={item.id} />
            ))
        }
    </div>
  )
}

export default List
Javascript
// src/components/List/data.js

export const data = {
    acc: [
        {
            id: 1,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323215040/earrings_4366739.png",
            title: "Vaidehi Earrings",
            isNew: true,
            oldPrice: 1100,
            newPrice: 800
        },
        {
            id: 2,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323215040/necklace_4917724.png",
            title: "Silver Jewellery Set",
            oldPrice: 500,
            newPrice: 480
        },
        {
            id: 3,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323215039/necklace_332044.png",
            title: "DIY Ethnic Set",
            oldPrice: 300,
            newPrice: 280
        },
        {
            id: 4,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323215039/balls_6577551.png",
            title: "Floral Parandi Earchain",
            oldPrice: 120,
            newPrice: 100
        },
    ],
    text: [
        {
            id: 1,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323215654/veil_7093443.png",
            title: "Panna Baluchi Cape",
            isNew: true,
            oldPrice: 1500,
            newPrice: 1350
        },
        {
            id: 2,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323215653/needles_4126713.png",
            title: "June Blooms Handwoven Fabric",
            oldPrice: "500 per m",
            newPrice: "400 per m"
        },
        {
            id: 3,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323215652/fabrics_7879060.png",
            title: "Bulchari Silk",
            oldPrice: "500 per m",
            newPrice: "450 per m"
        },
        {
            id: 4,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323215652/women_14083054.png",
            title: "Embroidered Panna Lehenga",
            oldPrice: 2500,
            newPrice: 2400
        },
    ],
    handi: [
            {
                id: 1,
                img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323181121/jar_8517434.png",
                title: "Embellished Jar",
                isNew: true,
                oldPrice: 1100,
                newPrice: 800
            },
            {
                id: 2,
                img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180101/horse_1943770.png",
                title: "Handmade Clay Horse",
                oldPrice: 300,
                newPrice: 200
            },
            {
                id: 3,
                img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323220138/decoration_8577236.png",
                title: "Wall Hangings",
                oldPrice: 300,
                newPrice: 280
            },
            {
                id: 4,
                img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323220137/dromedary_1498979.png",
                title: "Wooden Camel Decor Piece",
                oldPrice: 400,
                newPrice: 350
            },
            {
                id: 5,
                img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323220137/dromedary_1498979.png",
                title: "Handcrafted Fans Set of 3",
                oldPrice: 450,
                newPrice: 300
            },
        ],
    diy: [
        {
            id: 1,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323220539/frame_1438709.png",
            title: "Handmade Frames",
            isNew: true,
            oldPrice: 1100,
            newPrice: 800
        },
        {
            id: 2,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323220538/purse_9548577.png",
            title: "DIY Crafted Pouches",
            isNew: true,
            oldPrice: 250,
            newPrice: 200
        },
        {
            id: 3,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323220537/painting_9584029.png",
            title: "Painted Wall Hangings",
            oldPrice: 280,
            newPrice: 250
        },
        {
            id: 4,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180834/holi_14779521.png",
            title: "DIY Diwali Lanterns",
            oldPrice: 300,
            newPrice: 280
        },
        {
            id: 5,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323220537/kitchen-equipment_14666921.png",
            title: "Handpainted Plate",
            oldPrice: 560,
            newPrice: 500
        },
    ],
    new: [
        {
            id: 1,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240324074142/lakshmi_5922459.png",
            title: "Lakshmi Murti",
            isNew: true,
            oldPrice: 1500,
            newPrice: 1400
        },
        {
            id: 2,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240324074142/aromatherapy_8613226.png",
            title: "Tealight & Candle Owners",
            isNew: true,
            oldPrice: 300,
            newPrice: 240
        },
        {
            id: 3,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240324074141/lantern_4889452.png",
            title: "Handmade Diwali Lantern",
            oldPrice: 600,
            newPrice: 580
        },
        {
            id: 4,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240324074141/diwali_1283791.png",
            title: "Painted Diyas",
            oldPrice: 300,
            newPrice: 280
        },
    ],
    sale: [
        {
            id: 1,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240324074140/magic-mirror_7674541.png",
            title: "Decorated Mirror",
            isNew: true,
            oldPrice: 120,
            newPrice: 80
        },
        {
            id: 2,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240324074139/dishwashing_2771474.png",
            title: "Handpainted Kitchen Set",
            oldPrice: 550,
            newPrice: 300
        },
        {
            id: 3,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240324074139/street-lamp_9541534.png",
            title: "Colorful Wall Sconce",
            oldPrice: 250,
            newPrice: 220
        },
        {
            id: 4,
            img: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180247/case_12920819.png",
            title: "Painted Trays",
            oldPrice: 100,
            newPrice: 80
        },
    ],
}
Javascript
// src/components/Navbar/Navbar.jsx

import React from 'react'
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import SearchIcon from "@mui/icons-material/Search";
import PersonOutlineOutlinedIcon from "@mui/icons-material/PersonOutlineOutlined";
import FavoriteBorderOutlinedIcon from "@mui/icons-material/FavoriteBorderOutlined";
import ShoppingCartOutlinedIcon from "@mui/icons-material/ShoppingCartOutlined";
import { Link } from "react-router-dom";
import { HashLink } from 'react-router-hash-link';
import { useState } from 'react';
import Cart from '../Cart/Cart';
import "./navbar.scss"

const Navbar = () => {

  const [open,setOpen] = useState(false)

  return (
    <div className="navbar">
      <div className="wrapper">
        <div className="left">
          <div className="item">
            <img className="india" src="https://media.geeksforgeeks.org/wp-content/uploads/20240307113354/india.png" alt="" />
            <KeyboardArrowDownIcon />
          </div>
          <div className="item">
            <span>RUP</span>
            <KeyboardArrowDownIcon />
          </div>
          <div className="item">
            <Link className ="link" to="/products/acc">Accessories</Link>
          </div>
          <div className="item">
            <Link className ="link" to="/products/text">Textiles</Link>
          </div>
          <div className="item">
            <Link className ="link" to="/products/handi">Handicrafts</Link>
          </div>
          <div className="item">
            <Link className ="link" to="/products/diy">DIY</Link>
          </div>
        </div>

        <div className="center">
          <Link className='link' to="/">Kalakari</Link>
        </div>
        
        <div className="right">
        <div className="item">
            <Link className ="link" to="/">Homepage</Link>
          </div>
          <div className="item">
            <Link className ="link" to="/about">About</Link>
          </div>
          <div className="item">
            <HashLink className ="link" to="#contact" smooth={true} duration={500}>Contact</HashLink>
          </div>
          <div className="item">
            <Link className ="link" to="/">Stores</Link>
          </div>
          <div className="icons">
            <SearchIcon/>
            <Link to="/login" className='link'>
              <PersonOutlineOutlinedIcon/>
            </Link>
            <Link to="/wishlist" className='link'>
              <FavoriteBorderOutlinedIcon/>
            </Link>
            <div className="cartIcon" onClick={()=>setOpen(!open)}>
              <ShoppingCartOutlinedIcon/>
              <span>2</span>
            </div>
          </div>
        </div>
      </div>
      {open && <Cart />}
    </div>
  )
}

export default Navbar
Javascript
// src/components/ProductCard/ProductCard.jsx

import React from 'react'
import StarIcon from '@mui/icons-material/Star';
import FavoriteIcon from '@mui/icons-material/Favorite';
import "./productCard.scss"
import StarHalf from '@mui/icons-material/StarHalf';

const ProductCard = ( {item} ) => {
  return (
    <div className='productCard'>
        <div class="product-card">
          <div class="product-card__images">
            <div class="product-card__img">
              <img class="img-1" src={item.img1} alt=''/>
            </div>

            {item.img2 && <div class="product-card__img--hidden">
              <img class="img-2" src={item.img2} alt='' />
            </div>}

            <label class="product-card__like">
              <FavoriteIcon />
            </label>

            <button class="product-card__btn">See more</button>
          </div>

          <div class="product-card__info">
            <h3 class="product-card__name">{item.title}</h3>

            <div class="product-card__price">
              <span>₹{item.newPrice}</span>
              <span class="product-card__promo">₹{item.oldPrice}</span>
            </div>

            <div class="product-card__stars">
              <StarIcon />
              <StarIcon />
              <StarIcon />
              <StarIcon />
              <StarHalf />
              <span class="product-card__review-count">({item.review})</span>
            </div>
          </div>
        </div>
    </div>
  )
}

export default ProductCard
Javascript
// src/pages/Login/Login.jsx

import React from 'react'
import Navbar from "../../components/Navbar/Navbar"
import "./login.scss"

const Login = () => {
    return (
        <div className='loginPage'>
            <Navbar />
            <div class="grid">

                <h2 className='title'>Welcome Back!</h2>

                <form action="https://httpbin.org/post" method="POST"
                    class="form login">

                    <div class="form__field">
                        <label for="login__username"><svg class="icon">
                            <use href="#icon-user"></use>
                        </svg><span class="hidden">Username</span></label>
                        <input autocomplete="username" id="login__username"
                            type="text" name="username" class="form__input"
                            placeholder="Username" required />
                    </div>

                    <div class="form__field">
                        <label for="login__password"><svg class="icon">
                            <use href="#icon-lock"></use>
                        </svg><span class="hidden">Password</span></label>
                        <input id="login__password" type="password" name="password"
                            class="form__input" placeholder="Password" required />
                    </div>

                    <div class="form__field">
                        <input type="submit" value="Sign In" />
                    </div>

                </form>

                <p class="text--center">Not a member?
                    <a href="/register">Sign up now</a> <svg class="icon">
                        <use href="#icon-arrow-right"></use>
                    </svg></p>


            </div>
            <svg xmlns="http://www.w3.org/2000/svg" class="icons">
                <symbol id="icon-arrow-right" viewBox="0 0 1792 1792">
                    <path d="M1600 960q0 54-37 91l-651 651q-39 37-91 37-51 0-90-37l-75-75q-38-38-38-91t38-91l293-293H245q-52 0-84.5-37.5T128 1024V896q0-53 32.5-90.5T245 768h704L656 474q-38-36-38-90t38-90l75-75q38-38 90-38 53 0 91 38l651 651q37 35 37 90z" />
                </symbol>
                <symbol id="icon-lock" viewBox="0 0 1792 1792">
                    <path d="M640 768h512V576q0-106-75-181t-181-75-181 75-75 181v192zm832 96v576q0 40-28 68t-68 28H416q-40 0-68-28t-28-68V864q0-40 28-68t68-28h32V576q0-184 132-316t316-132 316 132 132 316v192h32q40 0 68 28t28 68z" />
                </symbol>
                <symbol id="icon-user" viewBox="0 0 1792 1792">
                    <path d="M1600 1405q0 120-73 189.5t-194 69.5H459q-121 0-194-69.5T192 1405q0-53 3.5-103.5t14-109T236 1084t43-97.5 62-81 85.5-53.5T538 832q9 0 42 21.5t74.5 48 108 48T896 971t133.5-21.5 108-48 74.5-48 42-21.5q61 0 111.5 20t85.5 53.5 62 81 43 97.5 26.5 108.5 14 109 3.5 103.5zm-320-893q0 159-112.5 271.5T896 896 624.5 783.5 512 512t112.5-271.5T896 128t271.5 112.5T1280 512z" />
                </symbol>
            </svg>
        </div>
    )
}

export default Login
Javascript
import React from 'react'
import "./about.scss"
import { Link } from 'react-router-dom'
// src/pages/About/About.jsx

const About = () => {
    return (
        <div className='about'>
            <div className="container">
                <div className="header">
                    <div className="bg-about"></div>
                    <div className="details">
                        <h1>About Us</h1>
                        <p>At Kalakari, we are on a mission to empower
                            local Indian artisans, craftsmen, small
                            shop owners, and DIY enthusiasts by providing
                            them with a thriving platform to showcase and
                            sell their exceptional creations.</p>
                    </div>
                </div>

                <div className="middle">
                    <div className="upper-row">
                        <div className="left-col">
                            <img src="https://media.geeksforgeeks.org/wp-content/uploads/20240307112320/about-artisan.png" alt="" />
                        </div>
                        <right className="right-col">
                            <h1>Our Mission</h1>
                            <p>We believe that every handmade product
                                tells a story, and by supporting local talent,
                                we contribute to preserving and celebrating India's
                                diverse cultural heritage. Our curated marketplace
                                is a testament to the talent, creativity,
                                and dedication of our artisan partners,
                                who pour their hearts into every creation.
                                Join us in this journey to discover, appreciate,
                                and support the soulful artistry of India.</p>
                        </right>
                    </div>
                    <div className="lower-row">
                        <p>In addition to celebrating the work of
                            seasoned artisans, Kalakari is a dedicated
                            platform that warmly embraces DIY enthusiasts
                            and artists. We understand the immense creativity
                            and passion that go into crafting something with your
                            own hands. Our platform provides a nurturing space
                            for DIY artists, where they can showcase their self-made
                            wonders and connect with a community that appreciates
                            the art of creating from scratch.</p>
                        <img src="https://media.geeksforgeeks.org/wp-content/uploads/20240307112911/about-diy.png" alt="" />
                    </div>
                </div>

                <div className="explore">
                    <div className="bg-explore"></div>
                    <div className="buttons">
                        <div className="focus-button">
                            <Link to="/products/new">
                                <button>New Season</button>
                            </Link>
                        </div>
                        <div className="category-button">
                            <Link to="/products/text">
                                <button>Textiles</button>
                            </Link>
                            <Link to="/products/handi">
                                <button>Handcrafts</button>
                            </Link>
                            <Link to="/products/acc">
                                <button>Accessories</button>
                            </Link>
                            <Link to="/products/diy">
                                <button>DIY</button>
                            </Link>
                        </div>
                        <div className="focus-button">
                            <Link to="/products/sale">
                                <button>Sale</button>
                            </Link>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}

export default About
Javascript
// src/pages/Home/Home.jsx

import React from 'react'
import "./home.scss"
import Slider from '../../components/Slider/Slider'
import FeaturedProducts from '../../components/FeaturedProducts/FeaturedProducts'
import Categories from '../../components/Categories/Categories'
import Contact from '../../components/Contact/Contact'


const Home = () => {
    return (
        <div className='home'>
            <FeaturedProducts type="trending" />
            <Categories />
            <FeaturedProducts type="featured" />
            <Contact />
        </div>
    )
}

export default Home
Javascript
// src/pages/Product/Product.jsx

import React from 'react'
import { useState } from 'react'
import AddShoppingCartIcon from "@mui/icons-material/AddShoppingCart";
import FavoriteBorderIcon from "@mui/icons-material/FavoriteBorder";
import BalanceIcon from "@mui/icons-material/Balance";
import "./product.scss"

const Product = () => {

    const [selectedImg, setSelectedImg] = useState(0)
    const [quantity, setQuantity] = useState(1);

    const images = [
      "https://media.geeksforgeeks.org/wp-content/uploads/20240324074650/hand-drawn-engraving-antique-vase_23-2149597241.jpg",
      "https://media.geeksforgeeks.org/wp-content/uploads/20240324074650/hand-drawn-engraving-antique-vase_23-2149597250.jpg",
      "https://media.geeksforgeeks.org/wp-content/uploads/20240324074649/hand-drawn-engraving-antique-vase_23-2149597232.jpg"
    ]

    return (
        <div className='product'>
            <div className="left">
                <div className="images">
                    <img src={images[0]} alt=""
                        onClick={e => setSelectedImg(0)} />
                    <img src={images[1]} alt=""
                        onClick={e => setSelectedImg(1)} />
                    <img src={images[2]} alt=''
                        onClick={e => setSelectedImg(2)} />
                </div>
                <div className="mainImg">
                    <img src={images[selectedImg]} alt="" />
                </div>
            </div>
            <div className="right">
                <h1>Embellished Jar</h1>
                <span className='price'>₹250</span>
                <p>Adorned with delicate embellishments
                    and hand-painted designs, this jar
                    exudes timeless elegance, making it
                    a perfect addition to your home decor
                    or a cherished gift for a loved one
                </p>
                <div className="quantity">
                    <button onClick={() => setQuantity((prev) =>
                        (prev === 1 ? 1 : prev - 1))}>-</button>
                    {quantity}
                    <button onClick={() =>
                        setQuantity(prev => prev + 1)}>+</button>
                </div>
                <button className='add'>
                    <AddShoppingCartIcon /> ADD TO CART
                </button>
                <div className="links">
                    <div className="item">
                        <FavoriteBorderIcon /> ADD TO WISH LIST
                    </div>
                    <div className="item">
                        <BalanceIcon /> ADD TO COMPARE
                    </div>
                </div>

                <div className="details">
                    <span>DESCRIPTION</span>
                    <hr />
                    <span>ADDITIONAL INFORMATION</span>
                    <hr />
                    <span>FAQ</span>
                </div>
            </div>
        </div >
    )
}

export default Product
Javascript
// src/pages/Products/Products.jsx

import React from 'react'
import { useParams } from "react-router-dom"
import List from "../../components/List/List"
import { useState } from "react";
import { categ, headers } from "./data"
import "./products.scss"

const Products = () => {

    const catId = useParams().id
    const [maxPrice, setMaxPrice] = useState(1000);
    const [sort, setSort] = useState(null);

    return (
        <div className='products'>
            <div className="left">

                <div className="filterItem">
                    <h2>Product Categories</h2>
                    {
                        categ[catId].map((item) => (
                            <div className="inputItem"
                                key={item.id}>
                                <input type="checkbox"
                                    id={item.id} value={item.id} />
                                <label htmlFor={item.id}>
                                    {item.name}
                                </label>
                            </div>
                        ))
                    }
                </div>

                <div className="filterItem">
                    <h2>Filter by Price</h2>
                    <span>0</span>
                    <input
                        type="range"
                        min={0}
                        max={1000}
                        onChange={(e) => setMaxPrice(e.target.value)}
                    />
                    <span>{maxPrice}</span>
                </div>
                <div className="filterItem">
                    <h2>Sort by</h2>
                    <div className="inputItem">
                        <input type="radio" name="price"
                            id="asc" value="asc"
                            onChange={(e) => setSort("asc")} />
                        <label htmlFor='asc'>
                            Price (Lowest first)
                        </label>
                    </div>
                    <div className="inputItem">
                        <input type="radio" name="price"
                            id="desc" value="desc"
                            onChange={(e) => setSort("desc")} />
                        <label htmlFor='desc'>
                            Price (Highest first)
                        </label>
                    </div>
                </div>
            </div>
            <div className="right">
                <div className="catImg">{headers[catId]}</div>
                <List catId={catId} maxPrice={maxPrice} sort={sort} />
            </div>
        </div>
    )
}

export default Products
Javascript
// src/pages/Wishlist/Wishlist.jsx

import React from 'react'
import "./wishlist.scss"
import ProductCard from '../../components/ProductCard/ProductCard'
import { data } from './data'

const wishlist = () => {

    return (
        <div className='wishlist'>
            <div class="container">

                {data.map((item) => (
                    <ProductCard item={item} key={item.id} />
                ))}

            </div>
        </div>
    )
}

export default wishlist
Javascript
// src/pages/Register/Register.jsx

import React from 'react'
import PhoneIcon from '@mui/icons-material/Phone';
import Navbar from "../../components/Navbar/Navbar"
import "./register.scss"

const Register = () => {
    return (
        <div className='registerPage'>
            <Navbar />
            <div class="grid">

                <h2 className='title'>Join our Community!</h2>

                <form action="https://httpbin.org/post"
                    method="POST" class="form login">

                    <div class="form__field">
                        <label for="login__username"><svg class="icon">
                            <use href="#icon-user"></use>
                        </svg><span class="hidden">Name</span></label>
                        <input autocomplete="username" id="login__username"
                            type="text" name="username" class="form__input"
                            placeholder="Name" required />
                    </div>

                    <div class="form__field">
                        <label for="login__username"><svg class="icon">
                            <use href="#icon-user"></use>
                        </svg><span class="hidden">Username</span></label>
                        <input autocomplete="username" id="login__username"
                            type="text" name="username" class="form__input"
                            placeholder="Username" required />
                    </div>

                    <div class="form__field">
                        <label for="login__username"><PhoneIcon />
                            <span class="hidden">Phone Number</span>
                        </label>
                        <input autocomplete="username" id="login__username"
                            type="text" name="username" class="form__input"
                            placeholder="Phone Number" required />
                    </div>

                    <div class="form__field">
                        <label for="login__password"><svg class="icon">
                            <use href="#icon-lock"></use>
                        </svg><span class="hidden">Password</span></label>
                        <input id="login__password" type="password"
                            name="password" class="form__input"
                            placeholder="Password" required />
                    </div>

                    <div class="form__field">
                        <input type="submit" value="Sign In" />
                    </div>

                </form>

                <p class="text--center">Already a member?
                    <a href="/login">Sign In</a> <svg class="icon">
                        <use href="#icon-arrow-right"></use>
                    </svg></p>


            </div>
            <svg xmlns="http://www.w3.org/2000/svg" class="icons">
                <symbol id="icon-arrow-right" viewBox="0 0 1792 1792">
                    <path d="M1600 960q0 54-37 91l-651 651q-39 37-91 37-51 0-90-37l-75-75q-38-38-38-91t38-91l293-293H245q-52 0-84.5-37.5T128 1024V896q0-53 32.5-90.5T245 768h704L656 474q-38-36-38-90t38-90l75-75q38-38 90-38 53 0 91 38l651 651q37 35 37 90z" />
                </symbol>
                <symbol id="icon-lock" viewBox="0 0 1792 1792">
                    <path d="M640 768h512V576q0-106-75-181t-181-75-181 75-75 181v192zm832 96v576q0 40-28 68t-68 28H416q-40 0-68-28t-28-68V864q0-40 28-68t68-28h32V576q0-184 132-316t316-132 316 132 132 316v192h32q40 0 68 28t28 68z" />
                </symbol>
                <symbol id="icon-user" viewBox="0 0 1792 1792">
                    <path d="M1600 1405q0 120-73 189.5t-194 69.5H459q-121 0-194-69.5T192 1405q0-53 3.5-103.5t14-109T236 1084t43-97.5 62-81 85.5-53.5T538 832q9 0 42 21.5t74.5 48 108 48T896 971t133.5-21.5 108-48 74.5-48 42-21.5q61 0 111.5 20t85.5 53.5 62 81 43 97.5 26.5 108.5 14 109 3.5 103.5zm-320-893q0 159-112.5 271.5T896 896 624.5 783.5 512 512t112.5-271.5T896 128t271.5 112.5T1280 512z" />
                </symbol>
            </svg>
        </div>
    )
}

export default Register
Javascript
// src/pages/Products/data.js

export const categ = {
    acc: [
        {
            id: 1,
            name: "Earrings"
        },
        {
            id: 2,
            name: "Bangles"
        },
        {
            id: 3,
            name: "Necklaces"
        },
        {
            id: 4,
            name: "Rings"
        },
        {
            id: 5,
            name: "Hair accessories"
        },
        {
            id: 6,
            name: "Kamarbands"
        }
    ],
    handi: [
        {
            id: 1,
            name: "Hand bags"
        },
        {
            id: 2,
            name: "Decor"
        },
        {
            id: 3,
            name: "Baskets"
        },
        {
            id: 4,
            name: "Statues"
        },
        {
            id: 5,
            name: "Paintings"
        }
    ],
    sale: [
        {
            id: 1,
            name: "Clothing"
        },
        {
            id: 2,
            name: "Curtains"
        },
        {
            id: 3,
            name: "Carpets"
        }
    ],
    text: [
        {
            id: 1,
            name: "Bandini",
        },
        {
            id: 2,
            name: "Kanjiwaram"
        }
    ],
    new: [
        {
            id: 1,
            name: "God Idols",
        },
        {
            id: 2,
            name: "Diwali Decor"
        },
        {
            id: 3,
            name: "Chhatt Baskets"
        }
    ],
    diy: [
        {
            id: 1,
            name: "Origami"
        },
        {
            id: 2,
            name: "Small Furnitures"
        },
        {
            id: 3,
            name: "Handknit Woollen"
        }
    ]
}

export const headers = {
    acc: "Accessories",
    text: "Textiles",
    handi: "Handicrafts",
    diy: "Do-It-Yourself",
    new: "New Season",
    sale: "Products on Sale",
}
Javascript
// src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);
Javascript
// src/App.js

import Home from './pages/Home/Home';
import Product from './pages/Product/Product';
import Products from './pages/Products/Products';
import {
    createBrowserRouter,
    RouterProvider,
    Outlet
} from "react-router-dom"
import Navbar from './components/Navbar/Navbar';
import Footer from './components/Footer/Footer';
import Login from './pages/Login/Login';
import About from './pages/About/About';
import Wishlist from './pages/Wishlist/Wishlist';
import Register from './pages/Register/Register';


const Layout = () => {
    return (
        <div className='app'>
            <Navbar />
            <Outlet />
            <Footer />
        </div>
    )
}

const router = createBrowserRouter([
    {
        path: "/",
        element: <Layout />,
        children: [
            {
                path: "/",
                element: <Home />
            },
            {
                path: "/about",
                element: <About />
            },
            {
                path: "/wishlist",
                element: <Wishlist />
            },
            {
                path: "/products/:id",
                element: <Products />
            },
            {
                path: "product/:id",
                element: <Product />
            }
        ]
    },
    {
        path: "/login",
        element: <Login />
    },
    {
        path: "/register",
        element: <Register />
    }
])

function App() {
    return (
        <div className="App">
            <RouterProvider router={router} />
        </div>
    );
}

export default App;
JavaScript
// client/src/pages/Wishlist/data.js

export const data = [
    {
      id: 1,
      img1: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180247/case_12920819.png",
      title: "Colorful Trays",
      oldPrice: 300,
      newPrice: 250,
      review: 12
    },
    {
      id: 2,
      img1: "https://media.geeksforgeeks.org/wp-content/uploads/20240323181121/jar_8517434.png",
      title: "Embellished Jar",
      oldPrice: 400,
      newPrice: 300,
      review: 16
    },
    {
      id: 3,
      img1: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180101/horse_1943770.png",
      title: "Handmade Clay Horse",
      oldPrice: 150,
      newPrice: 70,
      review: 5
    },
    {
      id: 4,
      img1: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180247/case_12920819.png",
      title: "Colorful Trays",
      oldPrice: 1000,
      newPrice: 650,
      review: 311
    },
    {
      id: 5,
      img1: "https://media.geeksforgeeks.org/wp-content/uploads/20240323180101/horse_1943770.png",
      title: "Handmade Clay Horse",
      oldPrice: 150,
      newPrice: 70,
      review: 5
    }
  ]

Start your application using the following command.

npm start

Output:

Kalakari-GoogleChrome2024-03-2407-49-04-ezgifcom-speed

Final preview of the website



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads