I am working on fitness app using react js where there is a list of bodyparts. I wanted to have a seperate image for each body part but getting same image for all
BodyPart.js
import React,{useState} from 'react'
import { Stack, Typography } from '@mui/material';
const BodyPart = ({ item, setBodyPart, bodyPart}) => {
const image = require(`../assets/images/bodypart/${bodyPart}.jpg`);
return (
<Stack type="button"
alignItems="center"
justifyContent="center"
className="bodyPart-card"
sx={{
borderTop: bodyPart === item ? '4px solid #ff2625' : '',
backgroundColor: "#fff",
borderBottomLeftRadius: '20px',
width: '270px',
height: '280px ',
cursor: 'pointer',
gap: '47px'
}}
onClick={()=>{
setBodyPart(item);
window.scrollTo({top:1800, left:100, behavior:'smooth'})
}}
>
<img
src= {image}
alt='dumbell'
style={{ width: '70px', height: '70px' }}
/>
<Typography fontSize="24px" fontWeight="bold" color="#3A1212">
{item}
</Typography>
</Stack>
)
}
export default BodyPart
HorizontalScroll.js
import React, { useContext } from 'react'
import { Box, Typography } from '@mui/material';
import BodyPart from './BodyPart';
import { ScrollMenu, VisibilityContext } from 'react-horizontal-scrolling-menu';
import RightArrowIcon from '../assets/icons/right-arrow.png';
import LeftArrowIcon from '../assets/icons/left-arrow.png';
import ExerciseCard from './ExerciseCard';
const LeftArrow = () => {
const { scrollPrev } = useContext(VisibilityContext);
return (
<Typography onClick={() => scrollPrev()} className="right-arrow">
<img src={LeftArrowIcon} alt="right-arrow" />
</Typography>
);
};
const RightArrow = () => {
const { scrollNext } = useContext(VisibilityContext);
return (
<Typography onClick={() => scrollNext()} className="left-arrow">
<img src={RightArrowIcon} alt="right-arrow" />
</Typography>
);
};
const HorizontalScrollbar = ({ data, bodyParts, setBodyPart, bodyPart}) => {
return (<ScrollMenu LeftArrow={LeftArrow} RightArrow={RightArrow}>
{data.map((item) => (
<Box
key={item.id || item}
itemId={item.id || item}
title={item.id || item}
m="0 40px"
>
{bodyParts ? <BodyPart item={item}
setBodyPart={setBodyPart} bodyPart={bodyPart}/>: <ExerciseCard exercise={item}/> }
</Box>
))}
</ScrollMenu>
)
}
export default HorizontalScrollbar
SearchExercises.js
import React,{useEffect, useState} from 'react'
import {Box, Button, Stack,TextField, Typography} from '@mui/material';
import {fetchData, exercisesOptions} from '../utils/fetchData';
import HorizontalScrollbar from './HorizontalScrollbar';
import images from './images'
const SearchExercises = ({setExercises,bodyPart,setBodyPart}) => {
const [search, setSearch] = useState('');
const [bodyParts, setBodyParts] = useState([])
useEffect(()=>{
const fetchExercisesData = async () => {
const bodyPartData = await fetchData('https://exercisedb.p.rapidapi.com/exercises/bodyPartList',
exercisesOptions);
setBodyParts(['all',...bodyPartData]);
}
fetchExercisesData();
}, [])
const handleSearch = async () => {
if(search) {
const exercisesData = await fetchData(
'https://exercisedb.p.rapidapi.com/exercises',
exercisesOptions
);
const searchedExercises = exercisesData.filter(
(item) => item.name.toLowerCase().includes(search)
|| item.target.toLowerCase().includes(search)
|| item.equipment.toLowerCase().includes(search)
|| item.bodyPart.toLowerCase().includes(search),
);
setSearch('');
setExercises(searchedExercises);
}
}
return (
<Stack alignItems="center" mt="37px"
justifyContent="center" p="20px">
<Typography fontWeight={700}
sx={{fontSize:{lg: '44px', xs:'30px'}}}
mb="50px" textAlign="center">
Awesome Exercises You <br/>
Should know
</Typography>
<Box position="relative" mb="72px">
<TextField
sx={{
input: {fontWeight: '700',
border :'none',
borderRadius:'4px'
},
width :{lg:'800px', xs:'350px'},
backgroundColor : "#fff",
borderRadius:'40px'
}}
height="76px"
value={search}
onChange={(e)=>{setSearch(e.target.value.toLowerCase())}}
placeholder="Search Exercises"
type="text" />
<Button className="search-btn"
sx={{
bgcolor:'#FF2625',
color:"#fff",
textTransform :'none',
width:{lg:'175px', xs:'80px'},
fontSize :{lg:'20px', xs:'14px'},
height:'56px',
position : 'absolute',
right:0
}} onClick={handleSearch}>
Search
</Button>
</Box>
<Box sx={{position:'relative', width:'100%', p:'20px'}}>
<HorizontalScrollbar data={bodyParts} bodyParts
setBodyPart={setBodyPart} bodyPart={bodyPart} isBodyParts/>
</Box>
</Stack>
)
}
export default SearchExercises
I wanted to have separate image for each body part. I tried to create array of all bodyParts data with images and name but that also didn't work in this scenarios.
This "https://exercisedb.p.rapidapi.com/exercises/bodyPartList" API returns below data
I have already render the required data as individual box here. I just wanted to apply image for each bodyPart separately currently it is applying same image