MINTO - ReactJS NFT Marketplace UI kit (template) - Documentation

Minto - NFT Marketplace, is a ReactJs based Template ( UI Kit). You can use this template with your custom backend or connect with some common opensource NFT Marketplace like Opensea etc.

The Template is well documented, neat, and clean, properly structured so that it can be easily customized with the user’s requirement. It supports Dark and Light Theme functionality, Responsive designs for all screens, Multilingual functionality etc. Minto NFT Marketplace is a dedicated ReactJS template for NFT Shops, NFT assets stores, Crypto Art Markets, and Digital asserts bidding and selling websites. It has 30+ Unique Screens and several widgets.


  • Version: 1.2
  • Author: Thriftysoft
  • Created: 17 January, 2022
  • Update: 27 June, 2022

Thank you for purchasing our theme. If you have any questions that are beyond the scope of this help file, please feel free to email us at admin@thriftysoft.tech. You can also contact us via Skype Thanks so much!


Features

This project is Build with React, a JavaScript frameworks for building user interfaces. Besides, Material UI was used as a UI component library. These are the main tools that are used in this project and the other tools and libraries are listed below.


Tools

Here is the list of all dependancies
  
"dependencies": {
  "@emotion/react": "^11.7.1",
    "@emotion/styled": "^11.6.0",
    "@mui/icons-material": "^5.6.1",
    "@mui/lab": "^5.0.0-alpha.62",
    "@mui/material": "^5.2.4",
    "@mui/styled-engine-sc": "^5.1.0",
    "@testing-library/jest-dom": "^5.14.1",
    "@testing-library/react": "^12.0.0",
    "@testing-library/user-event": "^13.2.1",
    "animejs": "^3.2.1",
    "axios": "^0.24.0",
    "date-fns": "^2.27.0",
    "formik": "^2.2.9",
    "i18next": "^21.6.5",
    "i18next-browser-languagedetector": "^6.1.2",
    "i18next-http-backend": "^1.3.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-helmet": "^6.1.0",
    "react-i18next": "^11.15.3",
    "react-icons": "^4.3.1",
    "react-lazy-load-image-component": "^1.5.1",
    "react-router-dom": "6",
    "react-scripts": "5.0.0",
    "react-slick": "^0.28.1",
    "react-spring": "^9.4.2",
    "react-use-gesture": "^9.1.3",
    "slick-carousel": "^1.8.1",
    "styled-components": "^5.3.3",
    "web-vitals": "^2.1.0",
    "yup": "^0.32.11"
},
            
          

Core Features

  • Fully Responsive, Compatible with All Screen Size
  • Major Browser Compatiblity
  • Clean,neat and well documneted source code
  • Reusable Code Components
  • SEO Freindly
  • Material UI & CSS Lib
  • Google Font Used
  • Icon library - React Icons
  • Animations - Anime.js and React Spring
  • Easy Customization
  • Light & Dark Theme
  • Multilingual
  • Support skeleton Screens
  • Clean and well-commented code built in HTML5 and CSS3

Getting Started

It is a complete React Project, so we assume that you have the latest version of Node.js pre-installed. The Node Package Manager or NPM came with the Node.js bundle so you don't need to install it separately.

Our recommendation is to use the YARN package manager.

                
npm install --global yarn
                
              

Then check the version with:

                
yarn --version
                
              

Installation

To complete the installation please follow the steps below:

  • First, change directory to the project folder by running:

    
    cd minto-nft-marketplace-ui
                  

  • Then you have to install all the dependacies that came with the project. We recommend to use YARN, as there exist a .lock file.

    TL;DR - it will make your life easier 😎

    
    yarn # or npm install
                  
  • After installing all required dependancies, now we are good to start our project by running:

    
    yarn start # or npm start
                  
  • That's it. Now you can view the entire project on your local server.


How to use

So, the basic usage of the application is really simple. We divided this section with:

The initial index.html and other publicly seen assets can be found in /public directory


Main App.js File

The App.js file is the root of all the Pages and Components that will described below. Here we used the Custom Theme Provider, the states of theme switching and the Animated Loader

Here is the minimal view

Components


import ArtCardDetails from "./components/ArtCardDetails/ArtCardDetails";
import AuctionCardDetails from "./components/AuctionCardDetails/AuctionCardDetails";
import Layout from "./components/Layout/Layout";
import Footer from "./components/Footer/Footer";
import ProfileInterface from "./components/ProfileInterface/ProfileInterface";
import KYCInterface from "./components/KYCInterface/KYCInterface";
import LanguageInterface from "./components/LanguageInterface/LanguageInterface";
import ThemeInterface from "./components/ThemeInterface/ThemeInterface";
import EditProfile from "./components/ProfileInterface/EditProfile";
import KYCPending from "./components/KYCInterface/KYCPending";
import KYCApproved from "./components/KYCInterface/KYCApproved";
import ChangePasswordInterface from './components/ChangePasswordInterface/ChangePasswordInterface';
import ChangeEmailInterface from './components/ChangeEmailInterface/ChangeEmailInterface';
              

Pages


import Collections from './Pages/Collections/Collections';
import SignUpPage from './Pages/Authentication/SignUpPage/SignUpPage';
import AuthInterface from './Pages/Authentication/AuthInterface';
import SignInPage from './Pages/Authentication/SignInPage/SignInPage';
import VerifyEmailPage from './Pages/Authentication/VerifyEmailPage/VerifyEmailPage';
import SetPasswordPage from './Pages/Authentication/SetPasswordPage/SetPasswordPage';
import IndividualNft from './Pages/Collections/Individualnft';
import MyBidsContainer from './Pages/MyBids/MyBidsContainer';
import Auction from "./Pages/Auction/Auction";
import Explore from "./Pages/Explore/Explore";
import Favourites from "./Pages/Favourites/Favourites";
import TrendingSellers from "./Pages/TrendingSellers/TrendingSellers";
import Home from "./Pages/Home/Home";
import SellersDetails from "./Pages/SellerDetails/SellersDetails";
import Footer from "./components/Footer/Footer";
import UserProfile from "./Pages/UserProfile/UserProfile";
import TrendingCreators from "./Pages/TrendingCreators/TrendingCreators";
import TermsAndCondition from "./Pages/Terms&Condition/TermsAndCondition";
import FAQ from "./Pages/FAQ/FAQ";
import PrivacyPolicy from "./Pages/PrivacyPolicy/PrivacyPolicy";
import ContactUs from "./Pages/ContactUs/ContactUs";
import CreateAssets from "./Pages/CreateAssets/CreateAssets";
import DummyUserProfile from "./Pages/DummyUser/DummyUserProfile";
import CreatorsDetails from "./Pages/CreatorsDetails/CreatorsDetails";
              

Utilities


import AnimatedLoader from "./Utils/AnimatedLoader/AnimatedLoader";
              

Hooks


import useCustomTheme from "./hooks/useCustomTheme";
              

Global Styles


import "./App.css";
              

Render Items


function App() {
  //...states

  //...hooks

  //...handlerFuncitons

  return (
    <ThemeProvider theme={customTheme}>
      <div
      >
        {showApp ? (
          <Box>
            <BrowserRouter>
              <Layout darkMode={darkMode}>
                <Routes>
                  <Route path="" element={}/>
                </Routes>
              </Layout>
            </BrowserRouter>
          </Box>
        ) : (
          <Box
          >
            <AnimatedLoader />
          </Box>
        )}
      </div>
    </ThemeProvider>
  );
}

              

Folder Structure

The project has approximately 26 reusable components, 8 sub-components and 15 Pages. Besides, all the main hooks that were used in this project can be found on /src/hooks folder and the Utilities are situated in the /src/Utils folder.

Here is the full src folders and files tree view


|   App.css
|   App.js
|   index.css
|   index.js
|   reportWebVitals.js
|
+---assets
|   |   accepteeImg.png
|   |   backdropMobile.svg
|   |   BackgroundWrinkles1.svg
|   |   BackgroundWrinkles2.svg
|   |   backgroundWrinklesLight.svg
|   |   bidderImg.png
|   |   contact-us-writing.svg
|   |   darkUIPrev.svg
|   |   exploreBackDropCircle.svg
|   |   feamaleUser.png
|   |   femaleUser.svg
|   |   heroVectorLineDark.svg
|   |   heroVectorLineLight.svg
|   |   heroVectorMainDark.svg
|   |   heroVectorSecondaryOneDark.svg
|   |   heroVectorSecondaryTwoDark.svg
|   |   kycApprovedImg.svg
|   |   kycPendingImg.svg
|   |   lightUIPrev.svg
|   |   mainLogo.svg
|   |   mainLogoLight.svg
|   |   polygonInner.svg
|   |   polygonInnerMobile.svg
|   |   polygonOuter.svg
|   |   polygonOuterMobile.svg
|   |   sideFooterLogoDark.svg
|   |   sideFooterLogoLight.svg
|   |   sideNavigationShadow.svg
|   |   sideNavRef.png
|   |   StatHexaInner.svg
|   |   StatHexaOuter.svg
|   |   userProfileAvatar.png
|   |
|   +---collectionImages
|       | collection1.png
|       | collection2.png
|       | collection3.png
|       | collection4.png
|       | collection5.png
|       | collection6.png
|   |
|   +---Icons
|       +---darkUIIcons
|       |       metaMaskIcon.svg
|       |       minuteDotIcon.svg
|       |       binanceWalletIcon.svg
|       |       documentEditIconDark.svg
|       |       ipfs.svg
|       |       keyIconDark.svg
|       |       polygon.svg
|       |       searchIconExplore.svg
|       |
|       +---lightUIIcons
|       |       metaMaskIcon.svg
|       |       change-email-icon.svg
|       |       change-pass-icon.svg
|       |
|       | altIcon.svg
|       | lockIcon.svg
|       | personFillIcon.svg
|       | personOutlineIcon.svg
|
+---components
|   +---ArtCard
|   |       ArtCard.js
|   |       ArtCard.module.css
|   |
|   +---ArtCardContainer
|   |       AllArtCards.js
|   |       ArtArtCards.js
|   |       ArtCardContainer.js
|   |       MemesArtCards.js
|   |       MusicArtCards.js
|   |       PosterArtCards.js
|   |       SignatureArtCards.js
|   |
|   +---ArtCardDetails
|   |       ArtCardDetails.js
|   |       ArtCardDetails.module.css
|   |       biddingData.js
|   |       SingleArtWork.js
|   |       SingleArtWork.module.css
|   |       TabPanel.js
|   |
|   +---AssetPropertiesModal
|   |       AssetProperModal.js
|   |       AssetProperModal.module.css
|   |
|   +---AuctionCard
|   |       AuctionCard.js
|   |       AuctionCard.module.css
|   |       AuctionCardPrev.js
|   |       AuctionCardPrev.module.css
|   |
|   +---AuctionCardDetails
|   |       AuctionCardDetails.js
|   |       AuctionCardDetails.module.css
|   |       biddingData.js
|   |       SingleAuctionCard.js
|   |       SingleAuctionCard.module.css
|   |       TabPanel.js
|   |
|   +---BackDrop
|   |       BackDrop.js
|   |       Backdrop.module.css
|   |
|   +---ChangeEmailInterface
|   |       ChangeEmailInterface.js
|   |
|   +---ChangePasswordInterface
|   |       ChangePasswordInterface.js
|   |
|   +---ConnectWalletPopUp
|   |       ConnectWalletPopUp.js
|   |       PopUp.module.css
|   |
|   +---CountDownBoard
|   |       CountDownBoard.js
|   |
|   +---CreateCollection
|   |       CreateCollection.js
|   |       CreateCollection.module.css
|   |
|   +---CreatorCard
|   |       CreatorCard.js
|   |
|   +---FavouriteCard
|   |       FavoriteCardPrev.js
|   |       FavouriteCard.css
|   |       FavouriteCard.js
|   |
|   +---FilterTab
|   |       FilterTab.js
|   |
|   +---Footer
|   |       Footer.js
|   |
|   +---KYCInterface
|   |       KYCApproved.js
|   |       KYCInterface.js
|   |       KYCPending.js
|   |
|   +---LanguageInterface
|   |       LanguageInterface.js
|   |
|   +---Layout
|   |       Layout.js
|   |
|   +---LiveAuctions
|   |       LiveAuctions.js
|   |
|   +---Loader
|   |       Loader.js
|   |
|   +---Navigation
|   |       MobileNavigation.js
|   |       Navigation.js
|   |
|   +---PastAuctions
|   |       PastAuctions.js
|   |
|   +---ProfileInterface
|   |       EditProfile.css
|   |       EditProfile.js
|   |       ProfileInterface.js
|   |
|   +---ProfileSideBar
|   |       ProfileSideBar.js
|   |
|   +---SellerDetailsCard
|   |       SellerDetailsCard.js
|   |
|   +---SellerDetailsOwnedModals
|   |       AddtoCollectionModal.js
|   |       DeleteFromCollectionModal.js
|   |       RemoveFromCollectionModal.js
|   |
|   +---SellersCard
|   |       SellersCard.js
|   |       SellersCardPrev.js
|   |
|   +---SideBar
|   |       SideBar.js
|   |       SideDrawer.js
|   |
|   +---Skeletons
|   |       ArtCardFB.js
|   |       ArtCardHome.js
|   |       AuctionCardFB.js
|   |       AuctionCardHome.js
|   |       TrendingSellersFB.js
|   |       TrendingSellersHome.js
|   |
|   +---StyledMenu
|   |       StyledMenu.js
|   |
|   +---ThemeInterface
|           ThemeInterface.css
|           ThemeInterface.js
|
+---hooks
|       useAuth.js
|       useCountDown.js
|       useCustomTheme.js
|       useQuery.js
|
+---Pages
|   +---Auction
|   |       Auction.js
|   |
|   +---Authentication
|   |       SetPasswordPage
|   |          SetPasswordPage.js
|   |       SigninPage
|   |          SignInPage.js
|   |       SignUpPage
|   |          SignUpPage.js
|   |       VerifyEmailPage
|   |          VerifyEmailPage.js
|   |       AuthInterface.js
|   |       AuthStatic.js
|   |       AuthStyles.module.css
|   |
|   +---Collections
|   |       CollectionCard
|   |          CollectionCard.js
|   |       CollectioContainer
|   |          CollectioContainer.js
|   |       CollectionData.js
|   |       Collections.js
|   |       IndividualNft.js
|   |
|   +---ContactUs
|   |       ContactUs.js
|   |
|   +---CreateAssets
|   |       CreateAssets.js
|   |
|   +---CreatorsDetails
|   |       CreatorsDetails.js
|   |
|   +---DummyUser
|   |       DummyUserProfile.js
|   |
|   +---Explore
|   |       Explore.js
|   |
|   +---FAQ
|   |       FAQ.js
|   |
|   +---Favourites
|   |       AuctionBookmark.js
|   |       Favourites.js
|   |       NftBookmarks.js
|   |
|   +---Home
|   |       CardDeck.js
|   |       cardStyle.module.css
|   |       HeroBanner.js
|   |       heroBannerStyles.module.css
|   |       Home.js
|   |       LiveAuctionContainer.js
|   |       MobileCardDeck.js
|   |       TrendingNFTContainer.js
|   |       TrendingSellersContainer.js
|   |
|   +---MyBids
|   |       BidCard.js
|   |       Bidcard.module.css
|   |       MyBidsContainer.js
|   |
|   +---PrivacyPolicy
|   |       PrivacyPolicy.js
|   |
|   +---SellerDetails
|   |       SellersDetails.js
|   |
|   +---Terms&Condition
|   |       TermsAndCondition.js
|   |
|   +---TrendingCreators
|   |       TrendingCreators.js
|   |
|   +---TrendingSellers
|   |       TrendingSellers.js
|   |
|   +---UserProfile
|           UserProfile.js
|
+---Utils
    +---AnimatedLoader
    |       AnimatedLoader.js
    |
    +---GradientButtons
    |       GradientButtons.js
    |
    +---StatsComponent
            StatsComponent.js
            statsComponent.module.css
              

Components

As mentioned before the project has 26 components. Here is a briefing of all the components.


ArtCard Component

First one is the ArtCard.module.css component folder. It has it own separate CSS modules and all the styles excep the dynamic ones can be found on that ArtCard.module.css file.


ArtCardContainer Component

This components holds all the ArtCard components. There are 7 different container for them.


ArtCardDetails Component

Every ArtCard from the explore section has a descriptive details about it and this component mainly holds the SingleArtWork component. Have a look at the functionality:


const ArtCardDetails = ({ darkMode }) => {
    const { id } = useParams(); // Read from the url

    const [artWorks, setArtWorks] = useState([]);

    useEffect(() => {
      axios.get("/artWorkData.json").then((res) => {
        setArtWorks(res.data);
      });
    }, [id]);

    //TODO: After adding API endpoints, we do not need to filter

    // Filtering artwork by IDs
    const filteredArtWork = artWorks.filter((artWork) => artWork.id === id);

    return (
      ... // Container
    );
  };
              


AssetPropertiesModal Component

This modal component will pop-up when you need to create your own assets in /src/Pages/CreateAssets Page. All the styles of the component except the dynamic styles can be found on its module.css folder.


AuctionCard Component

Similar to ArtCard Component component, this cards are used in /src/Pages/Auction Page for showing auction items. Along with this component there is also a sub-component named AuctionCardPrev Component which is used in /src/Pages/Home page for showing the Live Auctions.


AuctionCardDetails Component

This component is also very similar to the ArtCardDetails Component component, but it only holds the details for the auction items. It mainly holds the SingleAuctionCard sub-component.


Backdrop Component

It only holds the backdrop effect found in web view.


ChangeEmailInterface Component

It holds the Interface for the Changing the Email.


ChangePasswordInterface Component

This component is also very similar to the ChangeEmailInterface Component component, but it is For the changing the password.


ConnectWalletPopUp Component

This modal will show if any user try to connect the crypto wallets.


CountDownBoard Component

This component is used to show the Auction countdown on the **Trending NFTs** and the AuctionCard Component. It heavily depends on the useCountDown hooks for performing its functionality. We will talk more about it later on the hooks section.


CreateCollection Component

This component is the model for the creating the Collection .


CreatorCard Component

This component is basically the cards that were used to show the Trending Creators on the /src/Pages/TrendingCreators page.


FavouriteCard Component

This is the component card that were used to show the cards on /src/Pages/Favourites page. The styling are separated on its own CSS file. Besides, it has another sub-component named FavouriteCardPrev Component for showing the Trending NFTs on the /src/Pages/Home page.


FilterTab Component

This component was used to show the top tabs in /src/Pages/Explore page. This component has also a separate Menu item for filtering and sorting the items present in the Explore page.

KYCInterface Component

This component was used in the settings of /src/Pages/UserProfile page for registering as a seller on the marketplace. It has 2 other sub-component named KYCApproved and KYCPending which were used to show the the pending and approved status of that seller.


LanguageInterface Component

This component was used to switch between the Languages that we primarily support. This mainly manipulates and triggers the i18Next library to change the language of the entire application. Also, it gets the language changes data that stored in the browser's Cookie storage and set it as the default value of the radio buttons, so it doesn't break the change. Follow the below code snippet:

This function is used to get the cookie value.


const changeLang = () => {
    const localeLang = document.cookie;
    return localeLang.slice(8);
  };
            

After that it sets as the default value of the radio, like this:


<RadioGroup
    aria-label="language"
    defaultValue="{changeLang}"
    name="language-button-group"
></RadioGroup>
            

Basically, the changeLanguage(lang) method from i18next triggered the changes. We will talk more about it in the Customization section. For now you can see something like this:


<Radio
    onClick={() => i18next.changeLanguage("en")}> 
/>
            

Layout Component

This component basically holds the main structure of the of the page. It holds the Navigation and Sidebar, and it takes children props to show all other components that were used underneath. The whole Layout component is used in /src/App.js file.


LiveAuction Component

It was mainly used as a container for holding the AuctionCard component which has the live status.


Loader Component

It is basically the Loading Element for our any Page untill we fetch the complete data.


PastAuction Component

Similar to LiveAuction Component, used to show the which has the past status.


Navigation Component

This component can be divided into two sub-component which are Navigation for the web view and MobileNavigation for smaller devices. Although, the MobileNavigation component is rely on the Navigation component which is also the parent or container components that holds the MobileNavigation. Besides, this component has some smaller components like Menu item for showing a drop-down menu on the Connect Wallet button. The wallet connection happens here. Also, it holds the ConnectWalletPopUp Component.


ProfileInterface Component

This component is used to show the user profile information altogether. It has another sub-component which is called EditProfile for editing the user profile information.


ProfileSideBar Component

This mainly act like a navigation panel situated on /src/Pages/UserProfile Setting page.


SellerDetailsCard Component

This reusable component is used mainly showing the tab panel content. It used in CreatorsDetails, SellersDetails, and DummyUserProfile


SellerDetailsOwnedModal Component

It contains the popup for the various actions are AddtoCollectionModal, RemoveFromCollectionModal, DeleteFromCollectionModal.


SellerCard Component

This component is similar to the CreatorCard. However, it was used to show the Trending Sellers on the /src/Pages/TrendingSellers page. It also has a sub-component named SellerCardPrev which showed on the /src/Pages/Home page.


SideBar Component

This component has two sub-component. The main SideBar is used to show the sidebar all over the place of the application, and the SideDrawer is used to show a drawer like navigation for the smaller devices.


Skeletons Component

This folders contains all the skeletons screen for ArtCard (both for `Home` and `Explore` page), AuctionCard(both for `Home` and `Auction` page), SellerCard, CreatorCard.


StyledMenu Component

This is the Menu Item with styling according to the theme.


ThemeInterface Component

This component in used to switch between the light and dark theme. This also works like the Radio button in LanguageInterface by invoking a function like this:


const whatTheme = () => {
    const theme = localStorage.getItem("theme");
    if (theme === "dark") {
      return "darkUI";
    } else if (theme === "light") {
      return "lightUI";
    }
  };
            

Pages

As we mentioned there are 15 pages in this project. Find the brief description below


Main Pages

Home Page

This the main landing page of this marketplace application. It has 6 sub-components which are

Auction Page

The Auction Page is a separate route and a container for holding all the component.


Explore Page

The Explore Page is a separate route and a container for holding all the component.


Authentication Page

The Authentication Page is containig multiples Auth pages such as SignInPage, SignUpPage, VerifyEmailPage, SetPasswordPage.


Collections Page

The Collections Page is holding the CollectionCard and also the CollectionContainer for those cards.


MyBids Page

The MyBids Page is a separate route and a container for holding all the Bid component.


UserProfile Page

This is the user settings page with a separate route named /profile. It mainly holds the ProfileSideBar components and the outlets.


SellerDetails Page

Mainly a separate page that holds the all the information about a seller. This is a dynamic page with route and holds the SellerDetails component.


CreatorDetails Page

Similar to SellerDetails page and show the CreatorCard component.


DummyUserProfile Page

A separate route only for the user, where a user can view his/her NFTs.


Favourite Page

All the favourite cards of a user showed in this page. It mainly holds the FavouriteCard component.


TrendingSeller Page

It is a container for showing all the SellerCard components.


TrendingCreator Page

Similar to TrendingSeller page. It is the container for showing all the CreatorCard components.


Other Pages


Hooks

This project has `3` custom hooks. They are:


useCountDown Hook

This hook has one purpose only, that is show the desired countdown on the AuctionCard component. It takes an argument with the parameter of futureDate which can be passed during the use of this hook. The code is below:


export const useCountDown = (futureDate) => {
  const [now, setNow] = useState(new Date());

  useEffect(() => {
    const interval = setInterval(() => {
      setNow(new Date());
    }, 1000);

    return () => {
      clearInterval(interval);
    };
  }, [futureDate]);

  const isTimeUp = isBefore(futureDate, now);

  if (isTimeUp) {
    return { days: 0, hours: 0, minutes: 0, seconds: 0, isTimeUp };
  }

  let { days, hours, minutes, seconds } = intervalToDuration({
    start: now,
    end: futureDate,
  });

  return { days, hours, minutes, seconds, isTimeUp };
};
              

It is using the date-fns library for handling the date-time.


useCustomTheme Hook

This is the main theme hook for the entire project. We were used a custom theme color palette with custom FontFamily other than Roboto that comes with the Material UI by default. It was used in the main App.js file with a ThemeProvider context from the @emotion-react library.


const useCustomTheme = (darkMode) => {
  const customTheme = createTheme(
    darkMode
      ? {
          palette: {
            primary: {
              main: "#121212",
            },
            secondary: {
              main: "#ffffff",
            },
            accent: {
              main: "#171C26",
            },
            pink: {
              main: "#E552FF",
            },
            blue: {
              main: "#01D4FA",
            },
            black: {
              main: "#040404",
            },
          },
          typography: {
            fontFamily: "'Poppins', sans-serif",
            fontWeightRegular: 400,
            fontWeightMedium: 500,
            fontWeightBold: 700,
          },
        }
      : {
          palette: {
            background: {
              default: "#ffffff",
            },
            primary: {
              main: "#ffffff",
            },
            secondary: {
              main: "#121212",
            },
            accent: {
              main: "#ffffff",
            },
            pink: {
              main: "#E552FF",
            },
            blue: {
              main: "#01D4FA",
            },
            black: {
              main: "#FFFFFF",
            },
          },
          typography: {
            fontFamily: "'Poppins', sans-serif",
            fontWeightRegular: 400,
            fontWeightMedium: 500,
            fontWeightBold: 700,
          },
        }
  );

  return { customTheme };
};
              

useQuery Hook

This hook is relatively a utility hook for reading and manipulating the query parameters from the URL using the useMemo hook from React and the useLocation hook from React Router.


const useQuery = () => {
  const { search } = useLocation();
  return useMemo(() => new URLSearchParams(search), [search]);
};
              

Utilities

There are three different utility components which are:


AnimatedLoader Utilities

This component was used to show the animated loader for the entire application. It will show on the first entry on this app and if the user refreshes it. Mainly, this component is built by using the Anime.js library. This JavaScript library is a handy way to build simple animations with the SVGs.

Follow the code below:


const AnimatedLoader = () => {
  useEffect(() => {
    var pathEls = document.querySelectorAll("path");
    for (var i = 0; i < pathEls.length; i++) {
      var pathEl = pathEls[i];
      var offset = anime.setDashoffset(pathEl);
      pathEl.setAttribute("stroke-dashoffset", offset);
      anime({
        targets: pathEl,
        strokeDashoffset: [offset, 0],
        duration: anime.random(1000, 1500),
        delay: function (el, i) {
          return i * 250;
        },
        loop: true,
        direction: "alternate",
        easing: "easeInOutSine",
        autoplay: true,
      });
    }
  }, []);

  return (
    <svg>
      <path/>
      // All paths...
    </svg>
  )
              

Here it mainly targets all the svg path that with correspondent with the pathEl variable and loops through it. The main functionality in done within the anime() function. It takes an object of instructions like targets duration loop direction easing delay. The duration and the delay can also be used as function. Here we use the delay dynamically by invoking a function.


function (el, i) {
  return i * 250;
}
              

GradientButtons Utilities

This is basically a styled component function that contains two different gradient buttons. Mainly we used the styled components with the power of Material UI by invoking the styled from it.


StatsComponent Utilities

This utility component was used to build the statistics shown on the Home page. Anime.js library is also used here. Mainly this component takes totalNFT totalSeller totalSold as props. However, if there is no data passed through these props it will invoke its default values which are 80 30 50 to show the numbers in the stats. There used two different function wrapped up with the useEffect hook from React. These two different function takes inner path and outer path as the path variable and loops through it.

Take a look:


// Outer paths
useEffect(() => {
  const outerPathEls = document.querySelectorAll(".outerPath");
  // var pathEls = document.getElementsByClassName("path");
  for (var i = 0; i < outerPathEls.length; i++) {
    let pathEl = outerPathEls[i];
    let offset = anime.setDashoffset(pathEl);
    pathEl.setAttribute("stroke-dashoffset", offset);
    anime({
      targets: pathEl,
      strokeDashoffset: [offset, 0],
      duration: anime.random(1000, 1000),
      delay: function (el, i) {
        return i * 250;
      },
      loop: false,
      direction: "alternate",
      easing: "easeInOutSine",
      autoplay: true,
    });
  }
}, []);
              


// Inner Paths
useEffect(() => {
  const innerPathEls = document.querySelectorAll(".innerPath");
  for (var i = 0; i < innerPathEls.length; i++) {
    let pathEl = innerPathEls[i];
    let offset = anime.setDashoffset(pathEl);
    let x = 0.5;
    let y = -0.5;
    pathEl.setAttribute("stroke-dashoffset", offset);
    anime({
      targets: pathEl,
      strokeDashoffset: [offset, 0],
      duration: anime.random(1000, 3000),
      delay: function (el, i) {
        return i * 150;
      },
      loop: false,
      direction: "alternate",
      translateX: function () {
        return x * 3;
      },
      translateY: function () {
        return y * 3;
      },
      easing: "easeInOutSine",
      autoplay: true,
    });
  }
}, []);
              

Assets

The Asset folder contains all the static image assets and icons that were used in this application.

The asset directory contains the svg icons which can be found in /assets/Icons and they are also separated in two directory named darkUIIcons and LightUIIcons.

However, all the general images can be found in the asset directory


Customization

The customization will cover the following topics


Theme Customization

if you want to customize the look and feel of the application, go to the /src/hooks/useCustomTheme.js folder. There are two different palette for dark and light UI.

Have a look:


palette: {
  primary: {
    main: "#121212",
  },
  secondary: {
    main: "#ffffff",
  },
  accent: {
    main: "#171C26",
  },
  pink: {
    main: "#E552FF",
  },
  blue: {
    main: "#01D4FA",
  },
  black: {
   main: "#040404",
  },
},
              

This palette is for the Dark UI.

Let's break this!

  • The primary color here is #121212 which mainly used for the background and the cards.
  • The secondary color here is #ffffff which mainly used for the texts.
  • The accent color was used for the Papers and Card background color.
  • The pink and blue were used in buttons and highlighter.
  • The black was used as another shade of the primary color.

Similarly, for the light UI, take a look at this palette.


palette: {
  background: {
    default: "#ffffff",
  },
  primary: {
    main: "#ffffff",
  },
  secondary: {
    main: "#121212",
  },
  accent: {
    main: "#ffffff",
  },
  pink: {
    main: "#E552FF",
  },
  blue: {
    main: "#01D4FA",
  },
  black: {
    main: "#FFFFFF",
  },
},
              

All the above code is same as for the dark UI, here we just alter the color combination.


Language Customization

This application used the i18next library for managing all the language related work that took place within the app. The language customization folder can be found in /public/locales directory.

Let's add a new language!

Go to /public/locales directory and create new folder with its correspondent ISO 639-1 Code. Let's say we are adding the Bengali language. For this:

  • Create a folder in this /public/locales directory named bn and create a json file named as translation.json.
  • Then go to /public/locales/en/translation.json and copy all the data into our newly created translation.json file located in /public/locales/bn
  • Then re-add the correspondent keywords like this
  • 
    {
        "NAV_HOME": "হোম",
        "NAV_EXPLORE": "খুঁজুন",
        "NAV_AUCTION": "নিলাম",
        "NAV_CREATE_ASSET": "অ্যাসেট তৈরি করুন",
        "NAV_CONNECT_WALLET": "ওয়ালেট কানেক্ট করুন",
        "SETTINGS_USER_PROFILE": "ইউজার প্রোফাইল",
        "SETTINGS_EDIT_PROFILE": "এডিট প্রোফাইল",
        "SETTINGS_KYC": "কেওয়াইসি",
        "SETTINGS_KYC_APPROVED": "কেওয়াইসি অনুমোদিত",
        "SETTINGS_KYC_PENDING": "কেওয়াইসি চলছে",
        "SETTINGS_LANGUAGE": "ভাষা",
        "SETTINGS_THEME": "থিম",
        "LIVE_AUCTIONS": "চলতি নিলামসমূহ",
        "PAST_AUCTIONS": "বিগত নিলামসমূহ",
        "FAVOURITES": "প্রিয়গুলো",
        "SETTINGS": "সেটিংস",
        "TOTAL_NFT": "সর্বমোট এনএফটি"
      }
                    
  • Then go to the /src/index.js file and add the language's ISO 639-1 Code in that array like this:
  • 
    supportedLngs: ["en", "bn", "hi", "ta"],
                    

    Here we also add the the ISO 639-1 Code for Hindi and Tamil.

  • It mainly takes this below by using the i18Next Http Backend plugin.
  • 
    backend: {
          loadPath: "/locales/{{lng}}/translation.json",
    },
                    

That's it. now you can switch and view this in Bengali language.

Note: Here we just demonstrated the existing language translation. If you really want to add another language make sure you add the switcher in LanguageInterface component


Deployment

So, by far we're done with the Usage and the Customization, now this application is good to deploy.

To deploy the local build in your machine, run:


yarn build #or npm run build
              

You can also view the live website by deploying it to Netlify. For this you can simply drag your build folder on Netlify.

But, if you like command line and want to done everything automatically, you may want to use vercel cli tool.

For deploying the project with vercel without connecting to git, first you have to install the vercel cli, run:


yarn global add vercel

#or

npm i -g vercel
              

Then open your shell cd to the project folder and run


vercel #all right, that's it!!
              

It will automatically minified and build the project and give you a live url where you can `preview` the project.

If you want to go to production build, simply run:


vercel --prod
              

If you are using the vercel cli for the first time, we recommend you to go through the Vercel CLI docs at once. It just makes your life easier.


Changelog

See what's new added, changed, fixed, improved or updated in the latest versions.

Version 1.3 (27th June, 2022)

Major Updates

  • Major UI Fixes
  • NFT Detail Page Updated
  • User Profile Page Improved
  • Collection Option in User Profile Page
  • Multiple Translation Working

Version 1.2 (17th May, 2022)

Major Updates

  • Login, Signup, reset password Screens Included
  • Browse Collection Screen Included
  • Collection Tab in User detail page & My Profile Page Included
  • Option like Burn NFT, Move to Collection, Remove Sale Included
  • Change Password & Change email screens Included
  • User Cover image in Edit Profile & View Profile
  • UI Issues
  • Bug Fixes
  • Performance Optimized

Version 1.1 (02 Feb, 2022)

Major UI Fixes

  • Mobile Responsive Fix
  • Tab Responsive Fix
  • Allignment issue Fixed
  • Performance Optimized

Version 1.0 (22 Jan, 2022)

Initial Release


For any query & customization, reach out us at admin@thriftysoft.tech