<div id="root"></div>
:root {
  --padding-offset: 2rem;

  --transition-duration-300: 300ms;
  --transition-duration-100: 100ms;
  --transition-delay: 80ms;

  --body-background: rgb(225, 225, 225);

  // colors
  --white: #fff;
  --black: #000;
  --gray-light: #6d6d6d;
  --gray-dark: #494949;
  --blue-tint-light: hsl(216, 100%, 50%);
  --blue-tint-dark: hsl(216, 100%, 35%);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  width: 100%;
  min-height: 100vh;
  background: var(--body-background);
  font-family: Ubuntu, "Montserrat", sans-serif;
  overflow-x: hidden;
}

input,
button {
  border: none;
  outline: none;
}

button {
  cursor: pointer;
  &:disabled {
    cursor: not-allowed;
  }
  &:focus {
    outline: none;
  }
}

header {
  position: relative;
  width: 100%;
  height: 80px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 2rem;
  margin-bottom: 2rem;

  .btn.home {
    display: flex;
    justify-content: center;
    align-items: center;
    background: none;

    .icon {
      --size: 30px;
      width: var(--size);
      height: var(--size);
      svg {
        fill: var(--blue-tint-light);
        width: 100%;
        height: 100%;
        animation: hue-rotation 5000ms linear alternate-reverse infinite;
        animation-play-state: paused;
      }
    }
    span {
      color: var(--gray-dark);
      font-size: 1.2rem;
      font-weight: bold;
      text-transform: uppercase;
      margin-left: 0.5rem;
    }
    &:hover {
      .icon {
        svg {
          animation-play-state: running;
        }
      }
    }
  }

  form {
    display: flex;
    justify-content: center;
    align-items: center;

    input[type="text"] {
      width: 100%;
      height: 100%;
      padding: 10px 15px;
      padding-right: 35%;
      border-top-left-radius: var(--border-radius);
      border-bottom-left-radius: var(--border-radius);
      &::placeholder {
        color: rgba(0, 0, 0, 0.45);
      }
    }

    button.search {
      background: var(--blue-tint-light);
      color: var(--white);
      transition: background var(--transition-duration-100) ease,
        filter var(--transition-duration-100) ease;
      &:not(:disabled) {
        filter: grayscale(0);
        &:hover,
        &:focus {
          background: var(--blue-tint-dark);
        }
      }
      &:disabled {
        filter: grayscale(0.98);
      }
    }

    .form-group {
      --border-radius: 0.5em;
      position: relative;
      width: 300px;
      border-radius: var(--border-radius);
      overflow: hidden;

      .icon {
        --size: 12px;
        width: var(--size);
        height: var(--size);
        transition: margin var(--transition-duration-100) ease;
        svg {
          fill: var(--white);
          width: 100%;
          height: 100%;
        }
      }

      &.g-1 {
        input[type="text"] {
          &:focus {
            ~ button {
              &:not(:disabled) {
                transform: translateX(-55%);
                .icon {
                  margin-right: 4px;
                }
              }
            }
          }
        }

        .btn.search {
          position: absolute;
          top: 0;
          right: -20%;
          transform: translateX(-50%);
          width: 32%;
          height: 100%;
          display: flex;
          justify-content: center;
          align-items: center;
          border-top-right-radius: var(--border-radius);
          border-bottom-right-radius: var(--border-radius);
          transition: transform var(--transition-duration-100) ease;
          padding-right: 15px;
          padding-left: 0;
          span {
            margin-left: 5px;
          }
        }
      }

      &.g-2 {
        width: auto;
        button.search {
          width: 30px;
          height: 30px;
          display: flex;
          justify-content: center;
          align-items: center;
          background: none;

          .icon {
            --size: 20px;
            svg {
              fill: var(--gray-light);
            }
          }
        }
      }
    }

    .floating--container {
      position: absolute;
      left: 0%;
      top: 0%;
      width: 100%;
      height: 130%;
      display: flex;
      flex-direction: column;
      justify-content: space-around;
      align-items: center;
      background: var(--gray-dark);
      transition: transform var(--transition-duration-300) ease;

      .input--container {
        width: 80%;
        height: 40%;
        display: grid;
        grid-template-columns: 0.75fr 0.25fr;
        border-radius: 0.4rem;
        overflow: hidden;
        margin-top: 0.8rem;

        input[type="text"] {
          padding-right: 1rem;
          &:focus {
            ~ button {
              &:not(:disabled):hover {
                background: var(--blue-tint-dark);
              }
            }
          }
        }

        button.search {
          width: 100%;
          height: 100%;
        }
      }

      button.close {
        --size: 30px;
        width: var(--size);
        height: var(--size);
        display: flex;
        justify-content: center;
        align-items: center;
        background: none;

        .icon {
          width: calc(var(--size) / 1.6);
          height: calc(var(--size) / 1.6);
          svg {
            width: 100%;
            height: 100%;
            fill: #fb3958;
          }
        }
      }

      &.hide {
        transform: translateY(-100%);
      }
    }
  }
}

.masonry {
  width: 100%;
  height: auto;
  padding: 0 1rem 1rem 1rem;
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  grid-auto-rows: 0;

  .masonry-brick {
    .image-card {
      --card-options-height: 60px;

      position: relative;
      display: flex;
      background: var(--white);
      box-shadow: 0 6.7px 5.3px rgba(0, 0, 0, 0.016), 0 22.3px 17.9px rgba(0, 0, 0, 0.024),
        0 100px 80px rgba(0, 0, 0, 0.04);
      overflow: hidden;

      &::after {
        content: "";
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background: linear-gradient(to top, rgba(0, 0, 0, 0.75) 0%, transparent 100%);
        opacity: 0;
        transition: opacity var(--transition-duration-300) ease;
        transition-delay: var(--transition-delay);
        z-index: 1;
      }

      &:hover {
        &::after {
          opacity: 1;
        }
        img.image {
          --image-transform-offset: -30px;
        }
        .image-card--options {
          --tranform-y: 0;
        }
      }

      img.image {
        width: 100%;
        height: 100%;
        object-fit: cover;
        transition: transform var(--transition-duration-300) ease;
        transform: translateY(var(--image-transform-offset, 0%));
        transition-delay: var(--transition-delay);
      }

      &--clickable-area {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: calc(100% - var(--card-options-height));
        z-index: 20;
        cursor: pointer;
      }

      &--options {
        position: absolute;
        left: 0;
        bottom: 0;
        width: 100%;
        height: var(--card-options-height);
        display: grid;
        grid-template-columns: 1fr 0.35fr;
        align-items: center;
        background: var(--white);
        transition: transform var(--transition-duration-300) ease;
        transform: translateY(var(--tranform-y, 100%));
        transition-delay: var(--transition-delay);
        z-index: 5;
        cursor: default;

        .user-info {
          height: 100%;
          display: flex;
          align-items: center;
          padding: 0 0.5em;
          a {
            width: 35px;
            height: 35px;
            border-radius: 50%;
            overflow: hidden;
            img {
              width: 100%;
              height: 100%;
              object-fit: cover;
            }
          }
          h3 {
            margin-left: 6px;
            font-size: 0.8em;
            // white-space: nowrap;
          }
        }
        .links {
          width: 100%;
          height: 100%;
          display: flex;
          justify-content: flex-end;
          align-items: center;
          padding-right: 0.8em;
          .link {
            .icon {
              --size: 20px;
              width: var(--size);
              height: var(--size);
              margin-left: 12px;
              svg {
                fill: var(--fill, rgba(0, 0, 0, 0.6));
                width: 100%;
                height: 100%;
                transition: fill var(--transition-duration-100) ease;
              }
            }
            &:hover {
              .icon {
                &.instagram {
                  --fill: #fb3958;
                }
                &.twitter {
                  --fill: #00acee;
                }
                &.download {
                  --fill: var(--black);
                }
              }
            }
          }
        }
      }

      .image-card-fg {
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        z-index: 10;
        transform-origin: left center;
        transform: scaleX(1);
        transition: transform var(--transition-duration-300) ease;
        pointer-events: none;

        &.hide {
          transform-origin: right center;
          transform: scaleX(0);
        }
      }
    }
  }
}

.modal {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 35;
  background: rgba(0, 0, 0, 0.9);
  backdrop-filter: blur(2px);
  display: flex;
  justify-content: center;
  align-items: center;
  .image-container {
    --icon-size: 20px;

    position: relative;
    // height: attr(data-container-height-percentage);
    width: auto;
    margin-top: -2rem;

    img {
      height: 100%;
      object-fit: cover;
    }

    button.close {
      position: absolute;
      top: 0;
      right: calc(-2 * var(--icon-size));
      transform: translate(-50%, -50%);
      width: calc(var(--icon-size) * 2);
      height: calc(var(--icon-size) * 2);
      background: rgb(255, 79, 79);
      border-radius: 50%;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .icon {
      width: calc(var(--icon-size));
      height: calc(var(--icon-size));
      svg {
        fill: var(--white);
        width: 100%;
        height: 100%;
      }
    }

    .options--container {
      position: absolute;
      bottom: 0;
      left: 0;
      transform: translateY(100%);
      width: 100%;
      height: 50px;
      display: flex;
      justify-content: flex-end;
      align-items: center;
      background: var(--white);
      border-bottom-left-radius: 0.4rem;
      border-bottom-right-radius: 0.4rem;

      .icon {
        svg {
          fill: var(--gray-light);
        }
      }

      .group {
        display: flex;
        height: 32px;
        margin: 0 10px;

        a,
        button {
          --border-color: rgba(0, 0, 0, 0.25);
          color: var(--gray-light);
          font-size: 0.85rem;
          text-transform: capitalize;
          font-weight: 800;
          height: 100%;
          display: flex;
          justify-content: center;
          align-items: center;
          cursor: pointer;
          border: 1px solid var(--border-color);
          background: var(--white);
          border-radius: 4px;
          transition: border var(--transition-duration-100) ease,
            color var(--transition-duration-100) ease;

          &:hover {
            --border-color: rgba(0, 0, 0, 1);
            border: 1px solid var(--border-color);
            color: var(--black);

            .icon {
              svg {
                fill: var(--black);
              }
            }
          }
        }

        &.g-1 {
          a {
            text-decoration: none;
            padding: 0 15px;
            border-top-right-radius: 0;
            border-bottom-right-radius: 0;
          }
          .dropdown-btn--container {
            --size: 32px;
            position: relative;
            width: var(--size);
            height: var(--size);
            button {
              width: 100%;
              height: 100%;
              border-top-left-radius: 0;
              border-bottom-left-radius: 0;
              .icon {
                transform: rotate(180deg);
              }
            }

            .dropdown--menu {
              position: absolute;
              right: 5%;
              bottom: 135%;
              background: var(--black);
              width: 240px;
              border-radius: 0.45rem;
              transform-origin: 95% 115%;
              transform: scale(1);
              transition: transform var(--transition-duration-300)
                cubic-bezier(0.65, -0.65, 0.25, 1.25),
                opacity var(--transition-duration-300)
                cubic-bezier(0.65, -0.65, 0.25, 1.25);
              &::after {
                --size: 12px;
                content: "";
                position: absolute;
                right: calc(0.8 * var(--size));
                bottom: calc(-0.5 * var(--size));
                transform: rotate(45deg);
                width: var(--size);
                height: var(--size);
                background: var(--black);
              }
              &.hide {
                opacity: 0;
                transform: scale(0.5);
              }

              ul {
                padding: 5px 0;
                li {
                  list-style: none;
                  // height: 35px;
                  padding: 10px 0;
                  width: 100%;
                  cursor: pointer;
                  a {
                    display: block;
                    text-align: right;
                    border-radius: 0;
                    border: 0;
                    background: none;
                    font-weight: normal;
                    font-size: 0.95rem;
                    color: var(--white);
                    transition: color var(--transition-duration-100) ease;
                    span {
                      color: var(--gray-light);
                    }
                  }
                  &:last-child {
                    border-top: 1px solid var(----gray-light);
                  }

                  &:hover,
                  &:focus {
                    a {
                      color: var(--gray-light);
                    }
                  }
                }
              }
            }
          }
        }

        &.g-2 {
          button {
            padding: 0 8px;
            .icon {
              padding: 2px;
            }
          }
        }
      }
    }

    .image-info--container {
      position: fixed;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.65);
      display: flex;
      justify-content: center;
      align-items: center;
      backdrop-filter: blur(2px);
      padding: 0 2rem;

      .image-info--modal {
        position: relative;
        width: 550px;
        border-radius: 0.35rem;
        background-position: center;
        background-size: cover;

        .btn.close {
          background: rgb(153, 153, 153);
        }

        .row {
          padding: 18px 25px;
          &--1 {
            h1 {
              margin: 0;
              font-weight: 400;
              font-size: 1.5rem;
            }
            span {
              font-size: 0.8rem;
            }
          }
          &--2 {
            display: flex;
            .image-info {
              margin-right: 30px;
              .info {
                display: flex;
                align-items: center;
                padding: 5px 0;
                .icon {
                  --size: 16px;
                  width: var(--size);
                  height: var(--size);
                  svg {
                    fill: var(--black);
                  }
                }
                &--title {
                  font-size: 0.8rem;
                  padding: 0 5px;
                  font-weight: 500;
                }
                &--value {
                  font-weight: bold;
                  letter-spacing: 1px;
                  padding-left: 0.4rem;
                }
              }
              .monthly-stats {
                font-size: 0.75rem;
                color: var(--gray-light);
              }
              &.likes--container {
                .icon {
                  svg {
                    stroke: var(--black);
                    stroke-width: 3px;
                    fill: none;
                  }
                }
              }
            }
          }
          &--3 {
            display: grid;
            grid-template-columns: repeat(3, minmax(100px, 1fr));
            grid-template-rows: repeat(3, 1fr);
            grid-gap: 1rem;
            .camera-info {
              .info--title {
                font-size: 0.75rem;
                color: var(--gray-dark);
                margin-bottom: 6px;
                display: block;
              }
              .info--value {
                font-size: 0.85rem;
              }
            }
          }
        }
        .hr-line {
          width: 95%;
          height: 1px;
          background: var(--gray-light);
          opacity: 0.5;
          margin: auto;
        }
      }
    }
  }
}

.btn.load-more {
  border: none;
  margin: 5rem auto 20px auto;
  background: hsl(0, 0%, 55%);
  padding: 10px 20px;
  border-radius: 0.5em;
  color: var(--white);
  text-transform: capitalize;
  transition: background var(--transition-duration-300) ease;
  box-shadow: 0 6.7px 5.3px rgba(0, 0, 0, 0.016), 0 22.3px 17.9px rgba(0, 0, 0, 0.024),
    0 100px 80px rgba(0, 0, 0, 0.04);

  &:hover {
    background: hsl(0, 0%, 40%);
  }

  &.loading {
    background: hsl(0, 0%, 40%);
    cursor: not-allowed;
  }

  #wave {
    position: relative;
    width: 100%;
    height: 100%;
    .dot {
      --size: 6px;
      display: inline-block;
      width: var(--size);
      height: var(--size);
      border-radius: 50%;
      margin-right: 3px;
      background: var(--white);
      animation: wave 1.2s ease infinite;
      &:nth-child(2) {
        animation-delay: -1.1s;
      }
      &:nth-child(3) {
        animation-delay: -0.9s;
      }
    }
  }
}

.loading-text {
  width: 100%;
  text-align: center;
  color: var(--gray-dark);
  font-size: 2rem;
}

.failed-info-container {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  .failed-text,
  p {
    text-align: center;
    color: var(--gray-dark);
  }
  .failed-text {
    font-size: 4rem;
    margin-bottom: 0.4rem;
  }
  p {
    text-transform: uppercase;
    font-weight: 700;
  }
}

.no-image-found-info {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 100%;
  text-align: center;
  color: var(--gray-dark);
  h3 {
    font-size: 4rem;
    margin-bottom: 1rem;
  }
}
.text-info {
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  margin-bottom: 15px;
  &.type-something-info {
    font-size: 1.5rem;
    color: var(--gray-light);
  }
}

@media only screen and (max-width: 900px) {
  .modal {
    .image-container {
      width: 90%;
      img {
        width: 100%;
      }
    }
  }
}

@media only screen and (max-width: 550px) {
  header {
    position: sticky;
    background: var(--body-background);
    z-index: 30;
    top: 0;
    padding: 0 1rem;

    form {
      .form-group {
        &.g-1 {
          display: none;
        }
      }
    }
  }
}
@media only screen and (min-width: 550px) {
  header {
    form {
      .form-group {
        &.g-2 {
          display: none;
        }
      }

      .floating--container {
        display: none;
      }
    }
  }
}

@media only screen and (max-width: 400px) {
  .modal {
    .image-container .image-info--container .image-info--modal {
      .row--3 {
        grid-template-columns: repeat(2, 1fr);
      }
    }
  }
}

@keyframes wave {
  0%,
  60%,
  100% {
    transform: initial;
  }

  30% {
    transform: translateY(-100%);
  }
}

@keyframes hue-rotation {
  0% {
    filter: hue-rotate(360deg);
  }
  100% {
    filter: hue-rotate(0deg);
  }
}
View Compiled
// sorry the code here is real mess. As for now I am a React Beginner.
// github: https://github.com/devloop01/image-gallery
// live on github: https://devloop01.github.io/image-gallery/

console.clear()

const { useEffect, useState, Fragment, useRef } = React;


const API = 'https://api.unsplash.com';
const CLIENT_ID = '8e31e45f4a0e8959d456ba2914723451b8262337f75bcea2e04ae535491df16d';
const DEFAULT_IMAGE_COUNT = 25;
const IMAGE_INCREMENT_COUNT = 10;

function App() {
  const [images, setImages] = useState([]);
  const [query, setQuery] = useState("");
  const [prevQuery, setPrevQuery] = useState("");
  const [clickedImage, setClickedImage] = useState({});
  const [isModalActive, setModalActive] = useState(false);
  const [failedToLoad, setFailedToLoad] = useState(false);
  const [perPageCount, setPerPageCount] = useState(DEFAULT_IMAGE_COUNT);
  const [totalResults, setTotalResults] = useState(0);
  const [state, setState] = useState("loading");
  const [queryChanged, setqueryChanged] = useState(false);
  const [page, setPage] = useState("home");

  const loadButtonEl = useRef();

  const getRandomPhotos = () => {
    setState("loading");
    axios(`${API}/photos/random`, {
      params: {
        count: DEFAULT_IMAGE_COUNT,
        client_id: CLIENT_ID,
      },
    })
      .then((res) => {
      setImages(res.data);
      if (failedToLoad) setFailedToLoad(false);
    })
      .catch(() => setFailedToLoad(true));
  };

  useEffect(getRandomPhotos, [failedToLoad]);

  useEffect(waitForImages, [images]);

  const searchQuery = () => {
    if (query !== "") {
      setState("loading");
      setPage("search");
      axios(`${API}/search/photos/`, {
        params: {
          query: query,
          per_page: perPageCount,
          client_id: CLIENT_ID,
        },
      })
        .then((res) => {
        setImages(res.data.results);
        setTotalResults(res.data.total);
        if (failedToLoad) setFailedToLoad(false);
      })
        .catch(() => setFailedToLoad(true));
    }
  };

  useEffect(searchQuery, [perPageCount]);

  useEffect(() => {
    if (page === "home") {
      setQuery("");
      setPrevQuery("");
    }
  }, [page]);

  useEffect(() => {
    let loaded = 0;
    let cards = document.getElementsByClassName("image-card");
    for (let i = 0; i < cards.length; i++) {
      // eslint-disable-next-line no-loop-func
      imagesLoaded(cards[i], (instance) => {
        if (instance.isComplete) loaded++;
        if (loaded === perPageCount) setState("loaded");
      });
    }
  }, [images, perPageCount]);

  const handleSearch = () => {
    if (query !== prevQuery && query !== "") {
      setPerPageCount(DEFAULT_IMAGE_COUNT);
      setPrevQuery(query);
      searchQuery();
    }
  };

  const handleImageClick = (img) => {
    setClickedImage(img);
    setModalActive(true);
  };

  return (
    <Fragment>
      <Header
        onQueryChange={(q) => {
          setQuery(q);
          setqueryChanged(true);
        }}
        onQuerySearch={handleSearch}
        onGenarateRandomImages={() => getRandomPhotos()}
        onPageChange={(p) => setPage(p)}
        />

      {prevQuery !== "" && page !== "home" && (
        <span className="text-info">
          <span>
            search results for <strong>"{prevQuery}"</strong>
          </span>
          <span className="total-results">
            found <strong>{totalResults}</strong> matching results
          </span>
        </span>
      )}

      {query === "" && queryChanged && !failedToLoad && (
        <h3 className="text-info type-something-info">Type something!</h3>
      )}

      {prevQuery !== "" && totalResults === 0 && (
        <div className="no-image-found-info">
          <h3>No Images Found</h3>
          <span>
            Try searching <strong>dogs</strong> or <strong>cats</strong>
          </span>
        </div>
      )}

      {(!failedToLoad && (
        <main>
          <ImageCardList
            images={images}
            onImageClicked={(img) => handleImageClick(img)}
            />
          <h3
            className="text-info loading-text"
            style={{
              display: state === "loading" && !queryChanged ? "block" : "none",
            }}
            >
            Loading...
          </h3>
          <button
            className={`btn load-more ${state === "loading" ? "loading" : ""}`}
            ref={loadButtonEl}
            onClick={() => {
              setPerPageCount(perPageCount + IMAGE_INCREMENT_COUNT);
              setState("loading");
            }}
            style={{
              display:
              perPageCount >= totalResults || page === "home" ? "none" : "block",
                pointerEvents: state === "loading" ? "none" : "all",
            }}
            >
            {(state !== "loading" && "load more") || (
              <div id="wave">
                <span className="dot"></span>
                <span className="dot"></span>
                <span className="dot"></span>
              </div>
            )}
          </button>
        </main>
      )) ||
        (failedToLoad && (
        <div className="failed-info-container">
          <h1 className="failed-text">Failed To Load</h1>
          <p>check your connection</p>
        </div>
      ))}

      {isModalActive && (
        <Modal
          imageData={clickedImage}
          onModalActive={(isActive) => setModalActive(isActive)}
          />
      )}
    </Fragment>
  );
}

function resizeMasonryItem(item) {
  let grid = document.getElementsByClassName("masonry")[0],
      rowGap = parseInt(window.getComputedStyle(grid).getPropertyValue("grid-row-gap")),
      rowHeight = parseInt(window.getComputedStyle(grid).getPropertyValue("grid-auto-rows"));
  let rowSpan = Math.ceil(
    (item.querySelector(".masonry-content").getBoundingClientRect().height + rowGap) /
    (rowHeight + rowGap)
  );
  item.style.gridRowEnd = "span " + rowSpan;
}

function resizeAllMasonryItems() {
  let allItems = document.getElementsByClassName("masonry-brick");
  for (let i = 0; i < allItems.length; i++) {
    resizeMasonryItem(allItems[i]);
  }
}

function waitForImages() {
  let allItems = document.getElementsByClassName("masonry-brick");
  for (let i = 0; i < allItems.length; i++) {
    imagesLoaded(allItems[i], (instance) => {
      const item = instance.elements[0];
      const cardForegroundEl = instance.images[0].img.parentElement.parentElement.querySelector(
        ".image-card-fg"
      );
      item.style.display = "block";
      let t = setTimeout(() => {
        cardForegroundEl.classList.add("hide");
        clearTimeout(t);
      }, 200 + +cardForegroundEl.parentElement.getAttribute("data-card-index") * 120);
      resizeMasonryItem(item);
    });
  }
}

const events = ["load", "resize"];
events.forEach((event) => {
  window.addEventListener(event, resizeAllMasonryItems);
});


const Header = ({ onQueryChange, onQuerySearch, onGenarateRandomImages, onPageChange }) => {
  const [isFloatingInputActive, setFloatingInputActive] = useState(false);

  const inputEl = useRef();
  const floatingInputEl = useRef();

  const handleSubmit = (e) => {
    e.preventDefault();
    // onQuerySearch();
  };

  const handleHomePage = () => {
    onPageChange("home");
    onGenarateRandomImages();
    inputEl.current.value = "";
    floatingInputEl.current.value = "";
  };

  return (
    <header>
      <button className="btn home" onClick={handleHomePage}>
        <div className="icon gallery">
          <svg viewBox="0 0 388.309 388.309" xmlns="http://www.w3.org/2000/svg">
            <path
              d="M201.173,307.042c-11.291-0.174-22.177-4.233-30.825-11.494l-56.947-50.155c-8.961-8.373-22.664-9.036-32.392-1.567
                 L0.03,303.384v38.661c-0.582,10.371,7.355,19.25,17.726,19.832c0.534,0.03,1.07,0.037,1.605,0.021h286.824
                 c11.494,0,22.988-8.359,22.988-19.853V240.691L226.25,300.25C218.684,304.798,210.001,307.15,201.173,307.042z"
              />
            <circle cx="196.993" cy="182.699" r="22.988" />
            <path
              d="M383.508,67.238c-3.335-4.544-8.487-7.406-14.106-7.837L84.667,26.487c-5.551-0.465-11.091,1.012-15.673,4.18
                 c-4.058,3.524-6.817,8.307-7.837,13.584l-4.702,40.751h249.731c23.809,0.54,43.061,19.562,43.886,43.363v184.424
                 c0-1.045,4.702-2.09,6.792-4.18c4.326-3.397,6.834-8.606,6.792-14.106L388.21,82.389
                 C388.753,76.91,387.057,71.445,383.508,67.238z"
              />
            <path
              d="M306.185,105.899H19.361c-11.494,0-19.331,10.971-19.331,22.465v148.898l68.963-50.155
                 c17.506-12.986,41.724-11.895,57.992,2.612l57.469,50.155c8.666,7.357,21.044,8.406,30.824,2.612l113.894-66.351v-87.771
                 C328.382,116.099,318.465,106.408,306.185,105.899z M196.993,226.584c-24.237,0-43.886-19.648-43.886-43.886
                 c0-24.237,19.648-43.886,43.886-43.886c24.237,0,43.886,19.648,43.886,43.886C240.879,206.936,221.231,226.584,196.993,226.584z"
              />
          </svg>
        </div>
        <span className="title">Gallery</span>
      </button>

      <form onSubmit={handleSubmit}>
        <div className="form-group g-1">
          <input
            type="text"
            placeholder="Type here"
            onChange={() => onQueryChange(inputEl.current.value)}
            ref={inputEl}
            />
          <button
            className="btn search"
            onClick={onQuerySearch}
            disabled={
              inputEl.current !== undefined && inputEl.current.value.length === 0
                ? true
              : false
            }
            >
            <div className="icon search">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                <path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path>
              </svg>
            </div>
            <span>search</span>
          </button>
        </div>
        <div className="form-group g-2">
          <button className="btn search" onClick={() => setFloatingInputActive(true)}>
            <div className="icon search">
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                <path d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path>
              </svg>
            </div>
          </button>
        </div>

        <div className={`floating--container ${isFloatingInputActive ? "" : "hide"}`}>
          <div className="input--container">
            <input
              type="text"
              placeholder="Type here"
              onChange={() => onQueryChange(floatingInputEl.current.value)}
              ref={floatingInputEl}
              />
            <button
              className="btn search"
              onClick={onQuerySearch}
              disabled={
                floatingInputEl.current !== undefined &&
                  floatingInputEl.current.value.length === 0
                  ? true
                : false
              }
              >
              search
            </button>
          </div>

          <button className="btn close" onClick={() => setFloatingInputActive(false)}>
            <div className="icon cross">
              <svg
                viewBox="0 0 512 512"
                xmlns="http://www.w3.org/2000/svg"
                aria-hidden="false"
                >
                <path d="M443.6,387.1L312.4,255.4l131.5-130c5.4-5.4,5.4-14.2,0-19.6l-37.4-37.6c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4  L256,197.8L124.9,68.3c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4L68,105.9c-5.4,5.4-5.4,14.2,0,19.6l131.5,130L68.4,387.1  c-2.6,2.6-4.1,6.1-4.1,9.8c0,3.7,1.4,7.2,4.1,9.8l37.4,37.6c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1L256,313.1l130.7,131.1  c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1l37.4-37.6c2.6-2.6,4.1-6.1,4.1-9.8C447.7,393.2,446.2,389.7,443.6,387.1z" />
              </svg>
            </div>
          </button>
        </div>
      </form>
    </header>
  );
};



const ImageCard = ({ imageData, imageIndex, onImageClicked }) => {
  const { urls, alt_description, user, links, color } = imageData;

  return (
    <div className="masonry-brick" style={{ display: "none" }}>
      <div
        className="image-card masonry-content"
        style={{
          background: color,
        }}
        data-card-index={`${imageIndex}`}
        >
        <img className="image" src={urls.regular} alt={alt_description} />
        <div
          className="image-card--clickable-area"
          onClick={() => {
            onImageClicked(imageData);
            document.title = alt_description;
          }}
          />
        <div className="image-card--options">
          <div className="user-info">
            <a href={user.links.html} target="_blank_" tabIndex="-1">
              <img src={user.profile_image.medium} alt={user.name} />
            </a>
            <h3>{user.name}</h3>
          </div>
          <div className="links">
            <a
              className="link"
              href={`https://instagram.com/${user.instagram_username}`}
              style={{
                display: user.instagram_username ? "block" : "none",
              }}
              target="_blank_"
              tabIndex="-1"
              >
              <div className="icon instagram">
                <svg
                  viewBox="0 0 448 512"
                  xmlns="http://www.w3.org/2000/svg"
                  aria-hidden="false"
                  >
                  <path d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"></path>
                </svg>
              </div>
            </a>

            <a
              className="link"
              href={`https://twitter.com/${user.twitter_username}`}
              style={{
                display: user.twitter_username ? "block" : "none",
              }}
              target="_blank_"
              tabIndex="-1"
              >
              <div className="icon twitter">
                <svg
                  viewBox="0 0 512 512"
                  xmlns="http://www.w3.org/2000/svg"
                  aria-hidden="false"
                  >
                  <path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"></path>
                </svg>
              </div>
            </a>

            <a className="link" href={`${links.download}?force=true`} tabIndex="-1">
              <div className="icon download">
                <svg
                  viewBox="0 0 32 32"
                  xmlns="http://www.w3.org/2000/svg"
                  aria-hidden="false"
                  >
                  <path d="M25.8 15.5l-7.8 7.2v-20.7h-4v20.7l-7.8-7.2-2.7 3 12.5 11.4 12.5-11.4z"></path>
                </svg>
              </div>
            </a>
          </div>
        </div>
        <div
          className="image-card-fg"
          style={{
            background: color,
          }}
          />
      </div>
    </div>
  );
};


const ImageCardList = ({ images, onImageClicked }) => {
  return (
    <div className="masonry">
      {images.map((image, index) => (
        <ImageCard
          imageData={image}
          key={image.id}
          imageIndex={index}
          onImageClicked={(img) => onImageClicked(img)}
          />
      ))}
    </div>
  );
};



const months = [
  "January",
  "February",
  "March",
  "April",
  "May",
  "June",
  "July",
  "August",
  "September",
  "October",
  "November",
  "December",
];

const Modal = ({ imageData, onModalActive }) => {
  const { urls, alt_description, color, links, height, width, created_at, exif } = imageData;

  const date = new Date(created_at);

  const [dropdownActive, setDropdownActive] = useState(false);
  const [infoActive, setInfoActive] = useState(false);
  const [views, setViews] = useState(0);
  const [downloads, setDownloads] = useState(0);
  const [likes, setLikes] = useState(0);
  const [viewsLastMonth, setViewsLastMonth] = useState(0);
  const [downloadsLastMonth, setDownloadsLastMonth] = useState(0);
  const [likesLastMonth, setLikesLastMonth] = useState(0);

  const modalEl = useRef();
  const imageEl = useRef();

  const handleClose = () => {
    modalEl.current.style.display = "none";
    onModalActive(false);
    document.title = "Image Gallery | UNSPLASH";
  };

  const handleDropdown = () => {
    setDropdownActive(!dropdownActive);
  };

  const fetchStats = () => {
    axios(`${API}/photos/${imageData.id}/statistics`, {
      params: {
        client_id: CLIENT_ID,
      },
    }).then((res) => {
      // get all the values in an array
      const lastMonthViewValues = res.data.views.historical.values.map((e) => e.value);
      const lastMonthDownloadValues = res.data.downloads.historical.values.map(
        (e) => e.value
      );
      const lastMonthLikeValues = res.data.likes.historical.values.map((e) => e.value);

      // add up the array
      const lastMonthTotalViews = numberFormatter(returnTotal(lastMonthViewValues), 1);
      const lastMonthTotalDownloads = numberFormatter(
        returnTotal(lastMonthDownloadValues),
        1
      );
      const lastMonthTotalLikes = numberFormatter(returnTotal(lastMonthLikeValues), 1);

      // set all the values
      setViews(res.data.views.total);
      setDownloads(res.data.downloads.total);
      setLikes(res.data.likes.total);
      setViewsLastMonth(lastMonthTotalViews);
      setDownloadsLastMonth(lastMonthTotalDownloads);
      setLikesLastMonth(lastMonthTotalLikes);
    });
  };

  useEffect(fetchStats, []);

  return (
    <div className="modal" ref={modalEl}>
      <div
        className="image-container"
        style={{
          background: color,
            height: width / height > 2 ? "50%" : "80%",
        }}
        >
        <img src={urls.full} alt={alt_description} ref={imageEl} />
        <button className="btn close" onClick={handleClose}>
          <div className="icon">
            <svg
              viewBox="0 0 512 512"
              xmlns="http://www.w3.org/2000/svg"
              aria-hidden="false"
              >
              <path d="M443.6,387.1L312.4,255.4l131.5-130c5.4-5.4,5.4-14.2,0-19.6l-37.4-37.6c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4  L256,197.8L124.9,68.3c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4L68,105.9c-5.4,5.4-5.4,14.2,0,19.6l131.5,130L68.4,387.1  c-2.6,2.6-4.1,6.1-4.1,9.8c0,3.7,1.4,7.2,4.1,9.8l37.4,37.6c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1L256,313.1l130.7,131.1  c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1l37.4-37.6c2.6-2.6,4.1-6.1,4.1-9.8C447.7,393.2,446.2,389.7,443.6,387.1z" />
            </svg>
          </div>
        </button>

        <div className="options--container">
          <div className="group g-1">
            <a href={`${links.download}?force=true`} className="download">
              download
            </a>
            <div className="dropdown-btn--container">
              <button className="btn dropdown" onClick={handleDropdown}>
                <div className="icon">
                  <svg viewBox="0 0 32 32" aria-hidden="false">
                    <path d="M9.9 11.5l6.1 6.1 6.1-6.1 1.9 1.9-8 8-8-8 1.9-1.9z"></path>
                  </svg>
                </div>
              </button>
              
              <div className={`dropdown--menu ${dropdownActive ? "" : "hide"}`} tabIndex="-1">
                <ul>
                  <li>
                    <a href={`${links.download}?force=true&w=640`}>
                      Small <span>(640x960)</span>
                    </a>
                  </li>
                  <li>
                    <a href={`${links.download}?force=true&w=1920`}>
                      Medium <span>(1920x2880)</span>
                    </a>
                  </li>
                  <li>
                    <a href={`${links.download}?force=true&w=2400`}>
                      Large <span>(2400x3600)</span>
                    </a>
                  </li>
                  <li>
                    <a href={`${links.download}?force=true`}>
                      Original Size{" "}
                      <span>
                        ({height}x{width})
                      </span>
                    </a>
                  </li>
                </ul>
              </div>
            </div>
          </div>

          <div className="group g-2">
            <button className="btn info" onClick={() => setInfoActive(true)}>
              <div className="icon">
                <svg
                  viewBox="0 0 512 512"
                  xmlns="http://www.w3.org/2000/svg"
                  aria-hidden="true"
                  >
                  <path d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"></path>
                </svg>
              </div>
            </button>
          </div>
        </div>

        <div
          className="image-info--container"
          style={{
            display: infoActive ? "flex" : "none",
          }}
          >
          <div
            className="image-info--modal"
            style={{
              backgroundImage: `linear-gradient(rgba(255, 255, 255, 0.8), white 150px), url("${urls.thumb}&auto=format&fit=crop&w=200&q=60&blur=20")`,
            }}
            >
            <button className="btn close" onClick={() => setInfoActive(false)}>
              <div className="icon">
                <svg
                  viewBox="0 0 512 512"
                  xmlns="http://www.w3.org/2000/svg"
                  aria-hidden="false"
                  >
                  <path d="M443.6,387.1L312.4,255.4l131.5-130c5.4-5.4,5.4-14.2,0-19.6l-37.4-37.6c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4  L256,197.8L124.9,68.3c-2.6-2.6-6.1-4-9.8-4c-3.7,0-7.2,1.5-9.8,4L68,105.9c-5.4,5.4-5.4,14.2,0,19.6l131.5,130L68.4,387.1  c-2.6,2.6-4.1,6.1-4.1,9.8c0,3.7,1.4,7.2,4.1,9.8l37.4,37.6c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1L256,313.1l130.7,131.1  c2.7,2.7,6.2,4.1,9.8,4.1c3.5,0,7.1-1.3,9.8-4.1l37.4-37.6c2.6-2.6,4.1-6.1,4.1-9.8C447.7,393.2,446.2,389.7,443.6,387.1z" />
                </svg>
              </div>
            </button>

            <div className="row row--1">
              <h1>Info</h1>
              <span>
                Published on {months[date.getMonth()]} {date.getDate()},{" "}
                {date.getFullYear()}
              </span>
            </div>
            <div className="row row--2">
              <div className="image-info views--container">
                <div className="info">
                  <div className="icon">
                    <svg
                      version="1.1"
                      viewBox="0 0 32 32"
                      width="32"
                      height="32"
                      aria-hidden="false"
                      >
                      <path d="M31.8 15.1l-.2-.4c-3.5-6.9-9.7-11.5-15.6-11.5-6.3 0-12.3 4.5-15.7 11.7l-.2.4c-.2.5-.2 1.1 0 1.6l.2.4c3.6 7 9.7 11.5 15.6 11.5 6.3 0 12.3-4.5 15.6-11.6l.2-.4c.4-.5.4-1.2.1-1.7zm-2 1.2c-3 6.5-8.3 10.5-13.8 10.5-5.2 0-10.6-4.1-13.8-10.4l-.2-.4.1-.3c3.1-6.5 8.4-10.5 13.9-10.5 5.2 0 10.6 4.1 13.8 10.4l.2.4-.2.3zm-13.8-6.6c-3.5 0-6.3 2.8-6.3 6.3s2.8 6.3 6.3 6.3 6.3-2.8 6.3-6.3-2.8-6.3-6.3-6.3zm0 10.6c-2.4 0-4.3-1.9-4.3-4.3s1.9-4.3 4.3-4.3 4.3 1.9 4.3 4.3-1.9 4.3-4.3 4.3z"></path>
                    </svg>
                  </div>
                  <span className="info--title">Views</span>
                </div>
                <div className="info info--value">
                  <span className="total-views">{beautifyNumber(views)}</span>
                </div>
                <div className="monthly-stats">
                  <span className="views-stat">+{viewsLastMonth}</span> since last
                  month
                </div>
              </div>
              <div className="image-info downloads--container">
                <div className="info">
                  <div className="icon">
                    <svg
                      version="1.1"
                      viewBox="0 0 32 32"
                      width="32"
                      height="32"
                      aria-hidden="false"
                      >
                      <path d="M27.5 18.08a1 1 0 0 0-1.42 0l-9.08 8.59v-23.67a1 1 0 0 0-2 0v23.67l-9.08-8.62a1 1 0 1 0-1.38 1.45l10.77 10.23a1.19 1.19 0 0 0 .15.09.54.54 0 0 0 .16.1.94.94 0 0 0 .76 0 .54.54 0 0 0 .16-.1l.15-.09 10.77-10.23a1 1 0 0 0 .04-1.42z"></path>
                    </svg>
                  </div>
                  <span className="info info--title">Downloads</span>
                </div>
                <div className="info info--value">
                  <span className="total-views">{beautifyNumber(downloads)}</span>
                </div>
                <div className="monthly-stats">
                  <span className="downloads-stat">+{downloadsLastMonth}</span>{" "}
                  since last month
                </div>
              </div>
              <div className="image-info likes--container">
                <div className="info">
                  <div className="icon">
                    <svg
                      version="1.1"
                      viewBox="0 -4 32 40"
                      width="32"
                      height="32"
                      aria-hidden="false"
                      >
                      <path d="M17.4 29c-.8.8-2 .8-2.8 0l-12.3-12.8c-3.1-3.1-3.1-8.2 0-11.4 3.1-3.1 8.2-3.1 11.3 0l2.4 2.8 2.3-2.8c3.1-3.1 8.2-3.1 11.3 0 3.1 3.1 3.1 8.2 0 11.4l-12.2 12.8z"></path>
                    </svg>
                  </div>
                  <span className="info info--title">Likes</span>
                </div>
                <div className="info info--value">
                  <span className="total-views">{beautifyNumber(likes)}</span>
                </div>
                <div className="monthly-stats">
                  <span className="likes-stat">+{likesLastMonth}</span> since last
                  month
                </div>
              </div>
            </div>
            <div className="hr-line"></div>
            <div className="row row--3">
              <div className="camera-info">
                <span className="info--title">Camera Make</span>
                <span className="info--value">
                  {exif !== undefined ? exif.make : "--"}
                </span>
              </div>
              <div className="camera-info">
                <span className="info--title">Camera Model</span>
                <span className="info--value">
                  {exif !== undefined ? exif.model : "--"}
                </span>
              </div>
              <div className="camera-info">
                <span className="info--title">Focal Length</span>
                <span className="info--value">
                  {exif !== undefined ? `${exif.focal_length}mm` : "--"}
                </span>
              </div>
              <div className="camera-info">
                <span className="info--title">Aperture</span>
                <span className="info--value">
                  {exif !== undefined ? `ƒ/${exif.aperture}` : "--"}
                </span>
              </div>
              <div className="camera-info">
                <span className="info--title">Shutter Speed</span>
                <span className="info--value">
                  {exif !== undefined ? `${exif.exposure_time}s` : "--"}
                </span>
              </div>
              <div className="camera-info">
                <span className="info--title">ISO</span>
                <span className="info--value">
                  {exif !== undefined ? exif.iso : "--"}
                </span>
              </div>
              <div className="camera-info">
                <span className="info--title">Dimensions</span>
                <span className="info--value">
                  {`${width} × ${height}` || "--"}
                </span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

function numberFormatter(num, digits) {
  let si = [
    { value: 1, symbol: "" },
    { value: 1e3, symbol: "k" },
    { value: 1e6, symbol: "M" },
    { value: 1e9, symbol: "G" },
    { value: 1e12, symbol: "T" },
    { value: 1e15, symbol: "P" },
    { value: 1e18, symbol: "E" },
  ];
  let rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
  let i;
  for (i = si.length - 1; i > 0; i--) {
    if (num >= si[i].value) {
      break;
    }
  }
  return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol;
}

function beautifyNumber(num) {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

function returnTotal(arrOfValues) {
  return arrOfValues.reduce((a, c) => (a += c));
}


ReactDOM.render(
  <App />,
  document.getElementById('root')
);
View Compiled

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css

External JavaScript

  1. https://unpkg.com/react@16.7.0-alpha.0/umd/react.production.min.js
  2. https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.production.min.js
  3. https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js
  4. https://unpkg.com/imagesloaded@4/imagesloaded.pkgd.min.js