How I built a Gym webApp using HTML, CSS, and Vanilla JS

Building a Gym webApp

Introduction

The greatest approach to improving your web development skills is to use them to create projects. In this article, we are going to build a web page of a gym using HTML, CSS and JavaScript. In this article, I will be going through how I built a gym web page using HTML, CSS and vanilla JS. The need to be more project inclined can't be over-emphasized.

Technologies Used ⚡⚡

Some technologies used in building this project are:

  • HTML

image.png

  • CSS

image.png

  • JavaScript

image.png

  • Vercel - for hosting

image.png

  • JavaScript library - ScrollReveal

image.png

  • favicon, remixicon - for icons

image.png

  • fonts: google fonts

image.png

Features 🤩

  • Hero Section
  • logos Section
  • Skills Section
  • Program Section
  • Choose Section
  • Pricing Section
  • Calculate Section
  • Footer Section

Demo

This is the demo Gym Website and I hosted it on Vercel, which I built for both Mobile and desktop.

image.png

File structure

image.png

In the Gym website repository, I have the index file, and the assets folder containing the CSS, JS, and Image folders that contain the styling, javascript, and image files respectively.

Project initial

image.png

Initially, I had some CSS variables that saved colors, background colors, headings, font size, z-index, and font weight in the root styling.

Header

image.png

The header section contained the links around the page including the Home, Program, Choose Us, and Pricing, register now. I added some javascript for the mobile to make the hamburger icon close and open to display the links.

image.png

Hero section 1️⃣

image.png

The hero section is the home page otherwise the landing page. It contains the title and image of the page.

Logos section 2️⃣

image.png The logos section is the section that contains mock logos for the section representing partner brands.

Program Section 3️⃣

image.png This section contains all our various programs and what they offer.

Choose section 4️⃣

image.png It contains who we are and what we have to offer and why you should choose Us.

Pricing section 5️⃣

image.png This section contains the various packages we have and what they offer.

Calculate section 6️⃣

image.png The calculate section is the section where you can calculate your BMI with your weight and height.

image.png

The footer section is the section where you can subscribe to our newsletter and emails.

Media queries 8️⃣

image.png

I added media queries at various breaking points to fit different screens.

JavaScript functionality

/*=============== SHOW MENU ===============*/
const navMenu = document.getElementById("nav-menu"),
  navToggle = document.getElementById("nav-toggle"),
  navClose = document.getElementById("nav-close");

/*===== MENU SHOW =====*/
/* Validate if constant exists */
if (navToggle) {
  navToggle.addEventListener("click", () => {
    navMenu.classList.add("show-menu");
  });
}

/*===== MENU HIDDEN =====*/
/* Validate if constant exists */
if (navClose) {
  navClose.addEventListener("click", () => {
    navMenu.classList.remove("show-menu");
  });
}

/*=============== REMOVE MENU MOBILE ===============*/
const navLink = document.querySelectorAll(".nav__link");

const linkAction = () => {
  const navMenu = document.getElementById("nav-menu");
  // When we click on each nav__link, we remove the show-menu class
  navMenu.classList.remove("show-menu");
};
navLink.forEach((n) => n.addEventListener("click", linkAction));

/*=============== CHANGE BACKGROUND HEADER ===============*/

const scrollHeader = () => {
  const header = document.getElementById("header");
  // When the scroll is greater than 50 viewport height, add the scroll-header class to the header tag
  this.scrollY >= 50
    ? header.classList.add("bg-header")
    : header.classList.remove("bg-header");
};
window.addEventListener("scroll", scrollHeader);
/*=============== SCROLL SECTIONS ACTIVE LINK ===============*/
const sections = document.querySelectorAll("section[id]");

const scrollActive = () => {
  const scrollY = window.pageYOffset;

  sections.forEach((current) => {
    const sectionHeight = current.offsetHeight,
      sectionTop = current.offsetTop - 58,
      sectionId = current.getAttribute("id"),
      sectionsClass = document.querySelector(
        ".nav__menu a[href*=" + sectionId + "]"
      );

    if (scrollY > sectionTop && scrollY <= sectionTop + sectionHeight) {
      sectionsClass.classList.add("active-link");
    } else {
      sectionsClass.classList.remove("active-link");
    }
  });
};
window.addEventListener("scroll", scrollActive);
/*=============== SHOW SCROLL UP ===============*/
const scrollUp = () => {
  const scrollUp = document.getElementById("scroll-up");
  // When the scroll is higher than 350 viewport height, add the show-scroll class to the a tag with the scrollup class
  this.scrollY >= 350
    ? scrollUp.classList.add("show-scroll")
    : scrollUp.classList.remove("show-scroll");
};
window.addEventListener("scroll", scrollUp);

/*=============== SCROLL REVEAL ANIMATION ===============*/
const sr = ScrollReveal({
  origin: "top",
  distance: "60px",
  duration: 2500,
  delay: 400,
});
sr.reveal(`.home__data, .footer__container, .footer__group`);
sr.reveal(`.home__img`, { delay: 700, origin: "bottom" });
sr.reveal(`.logos__img, .program__card, .pricing__card`, { interval: 100 });
sr.reveal(`.choose__img, .calculate__content`, { origin: "left" });
sr.reveal(`.choose__content, .calculate__img`, { origin: "right" });
/*=============== CALCULATE JS ===============*/
const calculateForm = document.getElementById("calculate-form"),
  calculateCm = document.getElementById("calculate-cm"),
  calculateKg = document.getElementById("calculate-kg"),
  calculateMessage = document.getElementById("calculate-message");

const calculateBmi = (e) => {
  e.preventDefault();

  if (calculateCm.value === "" || calculateKg.value === "") {
    calculateMessage.classList.remove("color-green");
    calculateMessage.classList.add("color-red");

    calculateMessage.textContent = "Fill in the Height and Weight";
    setTimeout(() => {
      calculateMessage.textContent = "";
    }, 3000);
  } else {
    const cm = calculateCm.value / 100,
      kg = calculateKg.value,
      bmi = Math.round(kg / (cm * cm));

    if (bmi < 18.5) {
      calculateMessage.classList.add("color-green");
      calculateMessage.textContent = `Your BMI is ${bmi} and you are skinny`;
    } else if (bmi < 25) {
      calculateMessage.classList.add("color-green");
      calculateMessage.textContent = `Your BMI is ${bmi} and you are healthy`;
    } else {
      calculateMessage.classList.add("color-green");
      calculateMessage.textContent = `Your BMI is ${bmi} and you are obese`;
    }
    calculateCm.value = "";
    calculateCm.value = "";

    setTimeout(() => {
      calculateMessage.textContent = "";
    }, 4000);
  }
};
calculateForm.addEventListener("submit", calculateBmi);

/*=============== EMAIL JS ===============*/
const contactForm = document.getElementById("contact-form"),
  contactMessage = document.getElementById("contact-message"),
  contactUser = document.getElementById("contact-user");

const sendEmail = (e) => {
  e.preventDefault();
  if (contactUser.value === "") {
    contactMessage.classList.remove("color-green");
    contactMessage.classList.add("color-red");
    contactMessage.textContent = "You must enter your email";
    setTimeout(() => {
      contactMessage.textContent = "";
    }, 3000);
  } else {
    //serviceID - templateID - #form -publicKey

    emailjs.sendForm("service_8ii265v", "", "", "").then(
      () => {
        contactMessage.classList.add("color-green");
        contactMessage.textContent = "You registered successfully ";

        setTimeout(() => {
          contactMessage.textContent = "";
        }, 3000);
      },
      (error) => {
        // Mail sending error
        alert("OOPS! SOMETHING HAS FAILED...", error);
      }
    );
    // To clear input field
    contactUser.value = "";
  }
};
contactForm.addEventListener("submit", sendEmail);

🚀🚀🚀

Conclusion

Trying this project was superb as it taught me a whole lot and I put so many things to good use.

What I learned from this project and Challenges 🤗

You never know how much you know until you put in the work and much practice.

Thanks for reading! ❤️ This article is part of the #4articles4weeks @4articles4weeks challenge. NB: This article was published as the #week3 article for the Hashnode #4articles4weeks writeathon.

If you liked this article please follow me on Hashnode for my latest articles. I'm tweeting my journey on Twitter daily, this way to my LinkedIn . Hasnode

I share my knowledge on,

  • 🌐 Web Development
  • ✍️ Content Creation
  • 💼 Career Development
  • 🦾Personal Growth
  • BlockChain
  • And more!

Happy reading!