skip to Main Content

For example!
I need to create 3 radio buttons, if i click on 1-4, i will need to see the workouts that has 1 to 4 Weeks, if i click on 5-9 i need to see the workouts that has 5 to 9 weeks!

How can i fix the code and create that?

This is my code!

import React, { useState, useEffect, useContext } from "react";
import { Link } from "react-router-dom";
import "../../styles/workoutLibStyle.css";
import { Context } from "../store/appContext";

import {
  CDBSidebar,
  CDBSidebarContent,
  CDBSidebarHeader,
  CDBSidebarMenu,
  CDBSidebarMenuItem,
  CDBSidebarFooter,
} from "cdbreact";

export const Workouts = () => {{}
  const { store, actions } = useContext(Context);
  const [searchName, setSearchName] = useState("");
  const [selectedDifficulty, setSelectedDifficulty] = useState("");
  const [selectedWeeks, setSelectedWeeks] = useState("");

function filterByWeeks(elements) {
  const oneToFour = elements.filter(element => element.weeks >= 1 && element.weeks <= 4 ? true : false);
  const fiveToNine = elements.filter(element => element.weeks >= 5 && element.weeks <= 9 ? true : false);
  const moreThanTen = elements.filter(element => element.weeks > 10 ? true : false);
  
  return [oneToFour, fiveToNine, moreThanTen];
}

  useEffect(() => {
    async function fetchData() {
      actions.getList("workouts");
    }
    fetchData();
  }, []);

  const inputSearch = (event) => {
    setSearchName(event.target.value);
  };

  const inputDifficulty = (event) => {
    setSelectedDifficulty(event.target.value);
  };

   const inputWeeks = (event) => {
    setSelectedWeeks(event.target.value);
  };


  return (
    <>
      <div className="workout-main-container">
        <div>
          {/* Start Sidebar */}
          <CDBSidebar
            toggled="false"
            textColor="#333"
            backgroundColor="#f0f0f0"
            className="workout-sidebar-title sidebar-height "
          >
            <CDBSidebarHeader prefix={<i className="fa fa-bars " />}>
              Find the Workout or Coach
            </CDBSidebarHeader>
            <CDBSidebarContent>
              <CDBSidebarMenu>
                <CDBSidebarMenuItem icon="search">
                  <input
                    className="form-control mr-sm-2"
                    type="text"
                    placeholder="Type to search..."
                    value={searchName}
                    onChange={inputSearch}
                  />
                </CDBSidebarMenuItem>
                <CDBSidebarMenuItem icon="sticky-note">
                  Filter by Difficulty
                </CDBSidebarMenuItem>
                <CDBSidebarMenuItem className="mx-5 my-2">
                  <div>
                    <div className="form-check">
                      <input
                        className="form-check-input"
                        type="radio"
                        name="difficulty"
                        id="easy"
                        value="Easy"
                        checked={selectedDifficulty === "Easy"}
                        onChange={inputDifficulty}
                      />
                      <label
                        className="form-check-label"
                        htmlFor="exampleRadios1"
                      >
                        Easy
                      </label>
                    </div>
                    <div className="form-check">
                      <input
                        className="form-check-input"
                        type="radio"
                        name="difficulty"
                        id="medium"
                        value="Medium"
                        checked={selectedDifficulty === "Medium"}
                        onChange={inputDifficulty}
                      />
                      <label
                        className="form-check-label"
                        htmlFor="exampleRadios2"
                      >
                        Medium
                      </label>
                    </div>
                    <div className="form-check disabled">
                      <input
                        className="form-check-input"
                        type="radio"
                        name="difficulty"
                        id="hard"
                        value="Hard"
                        checked={selectedDifficulty === "Hard"}
                        onChange={inputDifficulty}
                      />
                      <label
                        className="form-check-label"
                        htmlFor="exampleRadios3"
                      >
                        Hard
                      </label>
                    </div>
                  </div>
                </CDBSidebarMenuItem>
                <CDBSidebarMenuItem icon="calendar">
                  Filter by Weeks
                </CDBSidebarMenuItem>
                  
                <CDBSidebarMenuItem className="mx-5 my-2">
                  <div>
                    <div className="form-check">
                      <input
                        className="form-check-input"
                        type="radio"
                        name="weeks"
                        id="1-4"
                        value="1-4"
                        checked={selectedWeeks === "1-4"}
                        onChange={inputWeeks}
                      />
                      <label
                        className="form-check-label"
                        htmlFor="exampleRadios1"
                      >
                        1-4
                      </label>
                    </div>
                    <div className="form-check">
                      <input
                        className="form-check-input"
                        type="radio"
                        name="weeks"
                        id="5-9"
                        value="5-9"
                        checked={selectedWeeks}
                        onChange={inputWeeks}
                      />
                      <label
                        className="form-check-label"
                        htmlFor="exampleRadios2"
                      >
                        5-9
                      </label>
                    </div>
                    <div className="form-check disabled">
                      <input
                        className="form-check-input"
                        type="radio"
                        name="weeks"
                        id="10+"
                        value="10+"
                        checked={selectedWeeks}
                        onChange={inputWeeks}
                      />
                      <label
                        className="form-check-label"
                        htmlFor="exampleRadios3"
                      >
                        10+
                      </label>
                    </div>
                  </div>
                </CDBSidebarMenuItem>

              </CDBSidebarMenu>

            </CDBSidebarContent>

            <CDBSidebarFooter
              style={{ textAlign: "center" }}
            ></CDBSidebarFooter>
          </CDBSidebar>
          {/* Aca Finaliza el Sidebar */}
        </div>
        <div className="d-flex-column w-100 justify-content-center">
          <h1 className="page-title text-center my-4 page-title-workoutLib w-100">
            Workout Library
          </h1>

          <div className="container">
            <div className="row ">
              {store.workouts?.filter((element) => element.name.toLowerCase().includes(searchName.toLowerCase()) ||
                element.coach_name.toLowerCase().includes(searchName.toLowerCase())
              ).filter((element) => selectedDifficulty ? element.difficulty === selectedDifficulty : true).filter((element) => selectedWeeks ? element.weeks >= 1 && element.weeks <= 4 : true).map((element, index) => (
                <div
                  className="col-sm-12 col-md-6 col-lg-4 col-xl-3 my-3"
                  key={element.id || index}
                >
                  <div className="card">
                    <h5 className="card-title-section text-center title-container">
                      {element.name}
                    </h5>
                    <ul className="list-group list-group-flush list-group-workouts">
                      <li>
                        <img
                          className="workout-library-img"
                          src={element.wk_image}
                          alt="Workout Image"
                        />
                      </li>
                      <li className="list-group-item workout-item workout-description bg-light ">
                        {element.description}
                      </li>
                      <li className="list-group-item workout-item">
                        <i className="fa-solid fa-calendar-day mx-2"></i>
                        <span>Days per week: </span>
                        {element.days_per_week}
                      </li>
                      <li className="list-group-item workout-item bg-light ">
                        <i className="fa-solid fa-calendar-days mx-2"></i>
                        <span>Weeks: </span>
                        {element.weeks}
                      </li>
                      <li className="list-group-item workout-item ">
                        <i className="fa-solid fa-square-poll-vertical mx-2"></i>
                        <span>Difficulty: </span>
                        {element.difficulty}
                      </li>
                      <li className="list-group-item workout-item bg-light ">
                        <i className="fa-solid fa-user mx-2"></i>
                        <span>Coach: </span>
                        {element.coach_name}
                      </li>
                    </ul>
                  </div>
                  <div className="btn-container-workouts my-3">
                    <Link
                      to="#"
                      className="btn btn-warning btn-workout-library"
                    >
                      Buy
                    </Link>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

i dont know how to start, so thanks if you can help me with that

2

Answers


  1. You have to create a variable like workousFilterByWeeks, you probably would like to use a useMemo to avoid unnecesary rerenders, since you have a lot of state in your component

    const workoutsFilteredByWeeks = useMemo(() => {
      const { upperLimit, lowerLimit } = getLimits(filterOption);
      return workouts.filter(
        (element) =>
          element.weeks >= lowerLimit &&
          (!upperLimit || element.weeks <= upperLimit ? true : false)
      )
    }, [workouts, filterOption]);
    

    Also, you can create a function to get the limits depending on the option, to make things more clear. Here’s a sandbox you can check for all the code.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search