From 904dc95d5cefa60d895c523d2111fceb45d1ce4f Mon Sep 17 00:00:00 2001 From: bezkagoit <142536080+bezkagoit@users.noreply.github.com> Date: Sun, 11 Feb 2024 19:15:11 +0000 Subject: [PATCH 1/5] Updated file search and body-parts --- src/css/exercises.css | 417 ++++++++++++++++++++++++++---------- src/js/body-parts.js | 95 ++++++++ src/js/search.js | 92 ++++++++ src/partials/exercises.html | 36 +++- 4 files changed, 523 insertions(+), 117 deletions(-) diff --git a/src/css/exercises.css b/src/css/exercises.css index e5103e4..6aa219d 100644 --- a/src/css/exercises.css +++ b/src/css/exercises.css @@ -1,174 +1,365 @@ .container-exercises { - padding: 40px 20px 92px; - border-radius: 30px; - background-color: var(--light-gray-background); - + padding: 40px 20px 92px; + border-radius: 30px; + background-color: var(--light-gray-background); } .text-thirdlevel { - - font-weight: 400; - font-size: 32px; - line-height: 1.1; - letter-spacing: 0.02em; - color: var(--text-dark); - margin-bottom: 20px; + font-weight: 400; + font-size: 32px; + line-height: 1.1; + letter-spacing: 0.02em; + color: var(--text-dark); + margin-bottom: 20px; } .button-list { - - display: flex; - gap: 6px; - margin-bottom: 40px; - + display: flex; + gap: 6px; + margin-bottom: 40px; } .button-exercises { - - font-weight: 400; - font-size: 14px; - line-height: 1.29; - letter-spacing: -0.02em; - text-align: center; - color: var( --text-dark); - border-style: none; - border-radius: 30px; - padding: 7px 14px; - + font-weight: 400; + font-size: 14px; + line-height: 1.29; + letter-spacing: -0.02em; + text-align: center; + color: var(--text-dark); + border-style: none; + border-radius: 30px; + padding: 7px 14px; } - .active { - color: var(--text-light); - background-color: var( --accent); - + color: var(--text-light); + background-color: var(--accent); } .gallery { - - display: flex; - flex-wrap: wrap; - gap: 20px; - + display: flex; + flex-wrap: wrap; + gap: 20px; } .lists { - - position: relative; - + position: relative; } .pic { - - filter: brightness(0.4); - border-radius: 12px; - width: 295px; - height: 232px; - + filter: brightness(0.4); + border-radius: 12px; + width: 295px; + height: 232px; } .position-text { - - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - text-align: center; - - + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + text-align: center; } .muscles-title { - - font-weight: 400; - font-size: 20px; - line-height: 1.1; - color: var(--text-light); - text-transform: capitalize; - + font-weight: 400; + font-size: 20px; + line-height: 1.1; + color: var(--text-light); + text-transform: capitalize; } .filter-title { - - font-weight: 400; - font-size: 12px; - line-height: 1.5; - color: var(--text-color-alfa); - + font-weight: 400; + font-size: 12px; + line-height: 1.5; + color: var(--text-color-alfa); } -@media screen and (min-width: 768px){ - - .container-exercises { +@media screen and (min-width: 768px) { + .container-exercises { + padding: 64px 48px 128px; + } - padding: 64px 48px 128px; + .text-thirdlevel { + font-size: 44px; + line-height: 1.1; + letter-spacing: -0.02em; + } - } + .button-list { + margin-bottom: 32px; + gap: 8px; + } - .text-thirdlevel { + .button-exercises { + padding: 10px 20px; + font-size: 16px; + line-height: 1.5; + } - font-size: 44px; - line-height: 1.1; - letter-spacing: -0.02em; - - } + .muscles-title { + font-size: 24px; + } - .button-list { + .gallery { + gap: 14px; + } - margin-bottom: 32px; - gap: 8px; - } + .list { + flex-basis: calc((100% - 14px) / 2); + } - .button-exercises { + .pic { + width: 313px; + height: 250px; + } +} - padding: 10px 20px; - font-size: 16px; - line-height: 1.5; - } +@media screen and (min-width: 1440px) { + .gallery { + gap: 20px; + } - .muscles-title { + .text-thirdlevel { + margin-bottom: 32px; + } - font-size: 24px; - } + .gallery { + gap: 40px 20px; + } - .gallery { - - gap: 14px; - } + .list { + flex-basis: calc((100% - 60px) / 4); + } +} - .list { +/* styles for excercises after the click */ - flex-basis: calc((100% - 14px) / 2); - } +.ex-search { + display: none; +} - .pic { +.head-small { + font-size: 20px; + line-height: 1; + letter-spacing: -0.02em; + color: rgba(27, 27, 27, 0.5); +} - width: 313px; - height: 250px; +.ex-list-no-result { + padding-top: 164px; + padding-bottom: 320px; + font-size: 14px; + line-height: 1.29; + letter-spacing: -0.01em; + text-align: center; +} +.exercise-item { + width: 295px; + height: 165px; + border-radius: 15px; + padding: 16px; + background-color: var(--white-color); + overflow: hidden; +} +.ex-item-head { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 25px; +} +.ex-item-head-group { + display: flex; + gap: 16px; +} +.ex-item-workout { + border-radius: 15px; + background-color: var(--dark-grey-background); + padding: 5px 8px; + color: var(--text-light); + font-size: 12px; + font-weight: 500; + line-height: 1.5; +} +.ex-rating-group { + display: flex; + gap: 2px; + align-items: center; +} +.ex-item-rating { + font-size: 12px; + line-height: 1.5; + color: var(--black-background); + align-self: center; +} +.ex-star-icon { + width: 18px; + height: 18px; + fill: var(--star); + align-self: center; +} +.ex-item-start { + display: flex; + gap: 8px; + font-size: 14px; + line-height: 1.29; + color: var(--black-background); + align-self: center; +} +.ex-arrow-icon { + width: 14px; + height: 14px; + fill: var(--black-background); + align-self: center; +} - } +.ex-title { + display: flex; + gap: 16px; + align-items: center; + margin-bottom: 16px; + text-wrap: nowrap; +} +.ex-run-men { + width: 24px; + height: 24px; + background-color: var(--dark-grey-background); + border-radius: 100%; + flex-shrink: 0; + padding: 4px 5px; +} +.ex-icon-run { + width: 14px; + height: 16px; + fill: var(--text-light); } -@media screen and (min-width: 1440px) { +.ex-item-name { + font-size: 20px; + line-height: 1.2; - .gallery { + overflow: hidden; + text-overflow: ellipsis; +} +.ex-item-info { + font-size: 12px; + line-height: 1.5; - gap: 20px; - } + overflow: hidden; + text-overflow: ellipsis; +} +.ex-info-group:not(:first-child) { + padding-left: 16px; +} +.ex-item-desc { + color: var(--border-color); +} - .text-thirdlevel { - margin-bottom: 32px; - } +/* Search form */ +.search-form { + position: relative; +} +.search-input { + display: block; + padding: 12px 50px 12px 14px; + width: 295px; + background-color: var(--text-light); + border-radius: 30px; + border: none; + outline: none; +} +.search-input::placeholder { + color: var(--black-background); + font-size: 16px; + line-height: 1.5; +} - .gallery { - gap: 40px 20px; - } +.search-btn, +.search-clear-btn { + position: absolute; + top: 0; + right: 0; + border: none; + padding: 10px; + border-radius: 30px; + background-color: var(--text-light); +} +.search-clear-btn { + right: 30px; + visibility: hidden; +} +.search-icon { + width: 18px; + height: 18px; + stroke: var(--black-background); + fill: var(--white-color); +} - .list { - flex-basis: calc((100% - 60px) / 4); - } +/* Media queries for search and excercises after the click*/ +@media screen and (min-width: 768px) { + .head-small { + font-size: 24px; + line-height: 1.33; + letter-spacing: -0.02em; + color: rgba(27, 27, 27, 0.5); + } + .ex-list-no-result { + padding-top: 222px; + padding-bottom: 585px; + padding-left: 50px; + padding-right: 50px; + } + .exercises-card { + row-gap: 20px; + } + + .exercise-item { + width: 313px; + height: 165px; + } + .search-input { + width: 246px; + } + .ex-item-start { + font-size: 16px; + line-height: 1.5; + } + .ex-arrow-icon { + width: 16px; + height: 16px; + } + .ex-title { + margin-bottom: 12px; + } + .ex-item-name { + font-size: 24px; + line-height: 1.33; + } +} +@media screen and (min-width: 1440px) { + .exercises-card { + row-gap: 28px; + } + .ex-list-no-result { + padding-top: 217px; + padding-bottom: 350px; + padding-left: 340px; + padding-right: 340px; + } + .ex-item-info { + gap: 10px; + text-wrap: nowrap; + } + .exercise-item { + width: 424px; + height: 141px; + } +} +.accent-text { + color: var(--dark-grey-background); } diff --git a/src/js/body-parts.js b/src/js/body-parts.js index e69de29..4bd4d8e 100644 --- a/src/js/body-parts.js +++ b/src/js/body-parts.js @@ -0,0 +1,95 @@ +// відображення вправ після натискання на картку, перенести потім у файл боді-партс +import axios from 'axios'; +import icons from '../img/icons/sprite.svg'; +import { galleryElement, searchInputField, exerciseParams } from './search.js'; +export { updateExercisesList, renderExercises }; +async function updateExercisesList(filter) { + try { + const data = await getExercisesData(filter); + const results = data.results; + + if (results.length === 0) { + // No results found + galleryElement.innerHTML = `

Unfortunately, no results were found. You may want to consider other search options to find the exercise you are looking for. Our range is wide and you have the opportunity to find more options that suit your needs.

`; + } else { + // Results found, render exercises + renderExercises(results); + } + } catch (error) { + // Error handling + handleError(error.message); + } +} + +async function getExercisesData(filter) { + const keyword = searchInputField.value.trim().toLowerCase(); + const params = { + [filter]: exerciseParams.filterGroup, + keyword: keyword, + page: exerciseParams.page, + limit: exerciseParams.limit, + }; + + const response = await axios.get('/exercises', { params }); + return response.data; +} + +function renderExercises(data) { + let markup = data + .map(i => { + return ` +
  • +

    + + WORKOUT + + ${Number(i.rating).toFixed(1)} + + + + + Start + + +

    + + +

    ${capitalizeFirstLetter(i.name)}

    +
    +

    + + Burned calories: + ${i.burnedCalories} / ${ + i.time + } min + + + Body part: + ${capitalizeFirstLetter( + i.bodyPart + )} + + + Target: + ${capitalizeFirstLetter( + i.target + )} + +

    +
  • `; + }) + .join(''); + + galleryElement.innerHTML = markup; +} + +function capitalizeFirstLetter(string) { + return string.charAt(0).toUpperCase() + string.slice(1); +} + +async function handleError(message) { + iziToast.error({ + position: 'topRight', + message: message, + }); +} diff --git a/src/js/search.js b/src/js/search.js index e69de29..cde0729 100644 --- a/src/js/search.js +++ b/src/js/search.js @@ -0,0 +1,92 @@ +import { updateExercisesList, renderExercises } from './body-parts.js'; +export { galleryElement, searchInputField, exerciseParams }; +// import axios from 'axios'; +// import icons from '../img/icons/sprite.svg'; + +const exerciseParams = { + page: 1, + totalPages: 1, + totalItems: 0, + keyword: '', + filter: '', + filterGroup: '', + limit: 12, +}; + +const galleryElement = document.querySelector('.js-gallery'); + +if (galleryElement) { + galleryElement.addEventListener('click', handleClickOnCard); + galleryElement.classList.add('exercises-card'); +} + +const searchButton = document.querySelector('.search-btn'); +const clearSearchButton = document.querySelector('.search-clear-btn'); +const searchInputField = document.querySelector('.search-input'); +const filterButtonsContainer = document.querySelector('.button-list'); +const searchFormContainer = document.querySelector('.ex-search'); +const sectionHeaderElement = document.querySelector('.text-thirdlevel'); + +function handleClickOnCard(event) { + event.preventDefault(); + + if (event.target.closest('ul').dataset.exercises) { + searchButton.addEventListener('click', handleSearchButtonClick); + clearSearchButton.addEventListener('click', handleClearSearchInput); + searchInputField.addEventListener('input', handleSearchInput); + filterButtonsContainer.addEventListener('click', handleClickOnFilterButton); + searchFormContainer.style.display = 'block'; + + const filterButton = document.querySelector('.button-exercises.active'); + exerciseParams.filter = filterButton.textContent.trim(); + exerciseParams.filterGroup = 'Exercises'; + const headerContent = `Exercises / ${exerciseParams.filter}`; + sectionHeaderElement.innerHTML = headerContent; + updateExercisesList(exerciseParams.filter); + } + return; +} + +function handleSearchButtonClick(event) { + event.preventDefault(); + if (searchInputField.value.length > 0) { + exerciseParams.page = 1; + exerciseParams.keyword = searchInputField.value.trim().toLowerCase(); + updateExercisesList(exerciseParams.filter); + } + return; +} + +function handleSearchInput() { + if (searchInputField.value.length > 0) { + clearSearchButton.style.visibility = 'visible'; + } else { + clearSearchButton.style.visibility = 'hidden'; + } +} + +function handleClearSearchInput() { + searchInputField.value = ''; + clearSearchButton.style.visibility = 'hidden'; + exerciseParams.page = 1; + updateExercisesList(exerciseParams.filter); +} + +function handleClickOnFilterButton(event) { + if (event.target.tagName === 'BUTTON') { + searchInputField.value = ''; + searchFormContainer.style.display = 'none'; + galleryElement.innerHTML = ''; + galleryElement.classList.remove('exercises-card'); + searchButton.removeEventListener('click', handleSearchButtonClick); + clearSearchButton.removeEventListener('click', handleClearSearchInput); + searchInputField.removeEventListener('input', handleSearchInput); + filterButtonsContainer.removeEventListener( + 'click', + handleClickOnFilterButton + ); + + exerciseParams.page = 1; + sectionHeaderElement.innerHTML = 'Exercises'; + } +} diff --git a/src/partials/exercises.html b/src/partials/exercises.html index d6cafaf..ac8e9f6 100644 --- a/src/partials/exercises.html +++ b/src/partials/exercises.html @@ -4,16 +4,44 @@

    Exercises

    - + + + + From e1ad67d8be2db7c5217c690c506b6441ca810665 Mon Sep 17 00:00:00 2001 From: bezkagoit <142536080+bezkagoit@users.noreply.github.com> Date: Sun, 11 Feb 2024 19:29:07 +0000 Subject: [PATCH 2/5] Updated files based on the first file exercises --- src/js/body-parts.js | 158 ++++++++++++++++++++++--------------------- src/js/search.js | 29 +++++--- 2 files changed, 99 insertions(+), 88 deletions(-) diff --git a/src/js/body-parts.js b/src/js/body-parts.js index 4bd4d8e..2c825b0 100644 --- a/src/js/body-parts.js +++ b/src/js/body-parts.js @@ -1,95 +1,99 @@ -// відображення вправ після натискання на картку, перенести потім у файл боді-партс +// відображення вправ після натискання на картку import axios from 'axios'; import icons from '../img/icons/sprite.svg'; import { galleryElement, searchInputField, exerciseParams } from './search.js'; -export { updateExercisesList, renderExercises }; -async function updateExercisesList(filter) { - try { - const data = await getExercisesData(filter); - const results = data.results; +export { updateExercisesList, loadExercises, renderExercises, getLoader }; - if (results.length === 0) { - // No results found - galleryElement.innerHTML = `

    Unfortunately, no results were found. You may want to consider other search options to find the exercise you are looking for. Our range is wide and you have the opportunity to find more options that suit your needs.

    `; - } else { - // Results found, render exercises - renderExercises(results); - } - } catch (error) { - // Error handling - handleError(error.message); - } +function updateExercisesList(filter) { + galleryElement.innerHTML = ''; + loadExercises(filter) + .then(data => { + if (data.results.length === 0) { + galleryElement.innerHTML = + '

    Unfortunately, no results were found. You may want to consider other search options to find the exercise you are looking for. Our range is wide and you have the opportunity to find more options that suit your needs.

    '; + } else { + renderExercises(data.results); + } + getLoader('hide'); + }) + .catch(error => { + getLoader('hide'); + handleError(error.message); + }); } -async function getExercisesData(filter) { - const keyword = searchInputField.value.trim().toLowerCase(); - const params = { - [filter]: exerciseParams.filterGroup, - keyword: keyword, - page: exerciseParams.page, - limit: exerciseParams.limit, - }; - - const response = await axios.get('/exercises', { params }); - return response.data; +async function loadExercises(filter) { + getLoader(); + if (searchInputField.value.length > 0) { + exerciseParams.keyword = searchInputField.value.trim().toLowerCase(); + } else { + exerciseParams.keyword = ''; + } + const data = await axios.get('/exercises', { + params: { + [filter]: exerciseParams.filterGroup, + keyword: exerciseParams.keyword, + page: exerciseParams.page, + limit: exerciseParams.limit, + }, + }); + return data.data; } function renderExercises(data) { let markup = data - .map(i => { - return ` -
  • -

    - - WORKOUT - - ${Number(i.rating).toFixed(1)} - - + .map( + i => + `

  • +

    + + WORKOUT + + ${Number(i.rating).toFixed(1)} + - - Start - - -

    - - -

    ${capitalizeFirstLetter(i.name)}

    -

    - - Burned calories: - ${i.burnedCalories} / ${ - i.time - } min - - - Body part: - ${capitalizeFirstLetter( - i.bodyPart - )} - - - Target: - ${capitalizeFirstLetter( - i.target - )} - -

    -
  • `; - }) + + Start + + +

    + + +

    ${ + i.name.charAt(0).toUpperCase() + i.name.slice(1) + }

    +
    +

    + + Burned calories: + ${i.burnedCalories} / ${i.time} min + + + Body part: + ${ + i.bodyPart.charAt(0).toUpperCase() + i.bodyPart.slice(1) + } + + + Target: + ${ + i.target.charAt(0).toUpperCase() + i.target.slice(1) + } + +

    + ` + ) .join(''); galleryElement.innerHTML = markup; } -function capitalizeFirstLetter(string) { - return string.charAt(0).toUpperCase() + string.slice(1); -} - -async function handleError(message) { - iziToast.error({ - position: 'topRight', - message: message, - }); +function getLoader(act = 'show') { + const loader = document.querySelector('.loader'); + if (act === 'show') { + loader.style.display = 'inline-block'; + } else { + loader.style.display = 'none'; + } } diff --git a/src/js/search.js b/src/js/search.js index cde0729..2f3ec91 100644 --- a/src/js/search.js +++ b/src/js/search.js @@ -1,4 +1,9 @@ -import { updateExercisesList, renderExercises } from './body-parts.js'; +import { + updateExercisesList, + loadExercises, + renderExercises, + getLoader, +} from './body-parts.js'; export { galleryElement, searchInputField, exerciseParams }; // import axios from 'axios'; // import icons from '../img/icons/sprite.svg'; @@ -13,7 +18,7 @@ const exerciseParams = { limit: 12, }; -const galleryElement = document.querySelector('.js-gallery'); +const galleryElement = document.querySelector('.gallery'); if (galleryElement) { galleryElement.addEventListener('click', handleClickOnCard); @@ -23,13 +28,12 @@ if (galleryElement) { const searchButton = document.querySelector('.search-btn'); const clearSearchButton = document.querySelector('.search-clear-btn'); const searchInputField = document.querySelector('.search-input'); -const filterButtonsContainer = document.querySelector('.button-list'); +const filterButtonsContainer = document.querySelector('.exercises-btns-div'); const searchFormContainer = document.querySelector('.ex-search'); -const sectionHeaderElement = document.querySelector('.text-thirdlevel'); +const sectionHeaderElement = document.querySelector('.exercises-header'); function handleClickOnCard(event) { event.preventDefault(); - if (event.target.closest('ul').dataset.exercises) { searchButton.addEventListener('click', handleSearchButtonClick); clearSearchButton.addEventListener('click', handleClearSearchInput); @@ -37,10 +41,13 @@ function handleClickOnCard(event) { filterButtonsContainer.addEventListener('click', handleClickOnFilterButton); searchFormContainer.style.display = 'block'; - const filterButton = document.querySelector('.button-exercises.active'); - exerciseParams.filter = filterButton.textContent.trim(); - exerciseParams.filterGroup = 'Exercises'; - const headerContent = `Exercises / ${exerciseParams.filter}`; + const filterButton = document.querySelector('.exercises-button.active'); + exerciseParams.filter = filterButton.dataset.filter; + exerciseParams.filterGroup = event.target.closest('ul').dataset.exercises; + const headerContent = `Exercises / ${ + exerciseParams.filterGroup.charAt(0).toUpperCase() + + exerciseParams.filterGroup.slice(1) + }`; sectionHeaderElement.innerHTML = headerContent; updateExercisesList(exerciseParams.filter); } @@ -52,7 +59,7 @@ function handleSearchButtonClick(event) { if (searchInputField.value.length > 0) { exerciseParams.page = 1; exerciseParams.keyword = searchInputField.value.trim().toLowerCase(); - updateExercisesList(exerciseParams.filter); + updateExercisesList(exerciseParams.filter, true); } return; } @@ -69,7 +76,7 @@ function handleClearSearchInput() { searchInputField.value = ''; clearSearchButton.style.visibility = 'hidden'; exerciseParams.page = 1; - updateExercisesList(exerciseParams.filter); + updateExercisesList(exerciseParams.filter, exerciseParams.filterGroup); } function handleClickOnFilterButton(event) { From f9f376beba3bc68e3c2e9bd1010b3f6e17620203 Mon Sep 17 00:00:00 2001 From: bezkagoit <142536080+bezkagoit@users.noreply.github.com> Date: Sun, 11 Feb 2024 20:56:28 +0000 Subject: [PATCH 3/5] Search and body-parts files --- src/css/exercises.css | 214 +++++++++++++++++++----------------- src/js/body-parts.js | 8 +- src/js/muscles.js | 174 +++++++++++++++++++---------- src/js/search.js | 11 ++ src/partials/exercises.html | 61 +++++----- 5 files changed, 277 insertions(+), 191 deletions(-) diff --git a/src/css/exercises.css b/src/css/exercises.css index 6aa219d..711dbd9 100644 --- a/src/css/exercises.css +++ b/src/css/exercises.css @@ -1,136 +1,154 @@ -.container-exercises { - padding: 40px 20px 92px; - border-radius: 30px; - background-color: var(--light-gray-background); -} - -.text-thirdlevel { - font-weight: 400; - font-size: 32px; - line-height: 1.1; - letter-spacing: 0.02em; - color: var(--text-dark); - margin-bottom: 20px; -} - -.button-list { +.exercises-filter { display: flex; - gap: 6px; - margin-bottom: 40px; + flex-wrap: wrap; + justify-content: space-between; + margin-bottom: 32px; + margin-top: 32px; } - -.button-exercises { - font-weight: 400; - font-size: 14px; - line-height: 1.29; - letter-spacing: -0.02em; - text-align: center; - color: var(--text-dark); - border-style: none; +.exercises-button { + padding: 10px 20px; border-radius: 30px; - padding: 7px 14px; + border: none; + font-size: 16px; + font-weight: 400; + line-height: 1.5; + background-color: var(--text-light); + color: var(--black-background); } - .active { + background-color: var(--dark-grey-background); color: var(--text-light); - background-color: var(--accent); } - .gallery { display: flex; flex-wrap: wrap; gap: 20px; + row-gap: 40px; + margin-bottom: 32px; } - -.lists { +.gallery-item { + border-radius: 12px; + border: 1px solid rgba(246, 246, 246, 0.3); + width: 313px; + height: 250px; + overflow: hidden; position: relative; } - -.pic { - filter: brightness(0.4); - border-radius: 12px; - width: 295px; - height: 232px; +.gallery-image { + max-width: 100%; } - -.position-text { +.gallery-item-description { position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - text-align: center; -} - -.muscles-title { - font-weight: 400; - font-size: 20px; - line-height: 1.1; - color: var(--text-light); - text-transform: capitalize; -} - -.filter-title { - font-weight: 400; - font-size: 12px; - line-height: 1.5; - color: var(--text-color-alfa); -} - -@media screen and (min-width: 768px) { - .container-exercises { - padding: 64px 48px 128px; + inset: 0; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + width: 100%; + padding: 45px, 105px, 45px, 105px; + background: linear-gradient( + 0deg, + rgba(16, 16, 16, 0.7), + rgba(16, 16, 16, 0.7) + ), + linear-gradient(0deg, rgba(246, 246, 246, 0.3), rgba(246, 246, 246, 0.3)); + .name { + font-size: 24px; + font-weight: 400; + line-height: 24px; + letter-spacing: 0px; + text-align: center; + color: var(--text-light); } - - .text-thirdlevel { - font-size: 44px; - line-height: 1.1; - letter-spacing: -0.02em; + .filter { + font-size: 12px; + font-weight: 400; + line-height: 18px; + letter-spacing: 0px; + text-align: left; + color: var(--text-light); } +} - .button-list { - margin-bottom: 32px; +@media screen and (max-width: 1440px) { + .exercises-btns-div { gap: 8px; } - - .button-exercises { - padding: 10px 20px; - font-size: 16px; - line-height: 1.5; + .gallery { + column-gap: 14px; + row-gap: 14px; } +} - .muscles-title { - font-size: 24px; +@media screen and (max-width: 768px) { + .exercises-header { + margin-bottom: 20px; + font-size: 32px; + letter-spacing: -0.02em; + line-height: 1; + } + .exercises-btns-div { + display: flex; + row-gap: 20px; + align-items: center; + justify-content: center; + flex-direction: row; + justify-content: space-between; + flex-wrap: nowrap; + } + .exercises-button { + padding: 7px 14px; + font-size: 14px; } - .gallery { - gap: 14px; + column-gap: 20px; + row-gap: 20px; } - - .list { - flex-basis: calc((100% - 14px) / 2); + .gallery-item { + width: 295px; + height: 232px; } - - .pic { - width: 313px; - height: 250px; + .ex-search { + margin-top: 40px; } } -@media screen and (min-width: 1440px) { - .gallery { - gap: 20px; - } +.container { + min-width: 320px; + max-width: 335px; + padding: 40px 20px; + border-radius: 30px; + overflow: hidden; + background-color: var(--light-gray-background); + margin: 0 auto; +} - .text-thirdlevel { - margin-bottom: 32px; +@media screen and (min-width: 768px) { + .container { + max-width: 736px; + border-radius: 50px; + padding: 64px 48px; } +} - .gallery { - gap: 40px 20px; +@media screen and (min-width: 1440px) { + .container { + max-width: 1408px; } +} + +.container-exercises { + background-color: var(--light-gray-background); + border-radius: 30px; + min-height: 760px; +} - .list { - flex-basis: calc((100% - 60px) / 4); +@media screen and (min-width: 768px) { + .exersizes-container { + padding: 64px 48px; + border-radius: 50px; + min-height: 1091px; + width: 100%; } } diff --git a/src/js/body-parts.js b/src/js/body-parts.js index 2c825b0..c5bec7f 100644 --- a/src/js/body-parts.js +++ b/src/js/body-parts.js @@ -1,9 +1,12 @@ -// відображення вправ після натискання на картку +// відображення вправ після натискання на картку, перенести потім у файл боді-партс + import axios from 'axios'; import icons from '../img/icons/sprite.svg'; import { galleryElement, searchInputField, exerciseParams } from './search.js'; export { updateExercisesList, loadExercises, renderExercises, getLoader }; +// Ця функція оновлює список вправ на основі наданого фільтра.Він очищає вміст galleryElement. + function updateExercisesList(filter) { galleryElement.innerHTML = ''; loadExercises(filter) @@ -22,6 +25,8 @@ function updateExercisesList(filter) { }); } +// Ця функція завантажує дані вправ із сервера на основі наданого фільтра. + async function loadExercises(filter) { getLoader(); if (searchInputField.value.length > 0) { @@ -39,6 +44,7 @@ async function loadExercises(filter) { }); return data.data; } +// Ця функція відтворює дані вправ у DOM. Він приймає отримані дані як вхідні дані. Він генерує HTML-розмітку для кожного елемента вправи за допомогою шаблонних літералів і наданих піктограм. function renderExercises(data) { let markup = data diff --git a/src/js/muscles.js b/src/js/muscles.js index 3272147..a93a7bd 100644 --- a/src/js/muscles.js +++ b/src/js/muscles.js @@ -1,68 +1,128 @@ -import { getAccess } from './helper/get-access.js'; -import { createMarkupFilter } from './helper/helpers.js'; -import { iziToastFunctions } from './helper/helpers.js'; - -const list = document.querySelector('.js-gallery'); -const buttonMuscles = document.querySelector('.js-buttonMuscles'); -const buttonBodyparts = document.querySelector('.js-buttonBodyparts'); -const buttonEquipment = document.querySelector('.js-buttonEquipment'); - -buttonMuscles.addEventListener('click', handlerMuscles); -buttonBodyparts.addEventListener('click', handlerBodyparts); -buttonEquipment.addEventListener('click', handlerEquipment); - -reflectMarkupMuscles(); -async function reflectMarkupMuscles() { - buttonBodyparts.classList.remove('active'); - buttonEquipment.classList.remove('active'); - buttonMuscles.classList.add('active'); - const datas = await getAccess({ - filter: 'Muscles', - typeFilter: 'filters', - }) - .then(({ data }) => data) - .catch(err => - iziToastFunctions.getErrorInfo( - 'Unfortunately, no results were found. You may want to consider other search options to find the exercise you are looking for. Our range is wide and you have the opportunity to find more options that suit your needs.' - ) - ); - - const objMuscles = datas.results; - - list.innerHTML = createMarkupFilter(objMuscles, list); +import axios from 'axios'; +import iziToast from 'izitoast'; + +const refs = { + gallery: document.querySelector('.gallery'), + buttons: document.querySelector('.exercises-btns-div'), + musclesBtn: document.querySelector('[data-filter="muscles"]'), + bodypartsBtn: document.querySelector('[data-filter="bodypart"]'), + equipBtn: document.querySelector('[data-filter="equipment"]'), +}; + +axios.defaults.baseURL = 'https://energyflow.b.goit.study/api'; +function getLoader(act = 'show') { + const loader = document.querySelector('.loader'); + if (act === 'show') { + loader.style.display = 'inline-block'; + } else { + loader.style.display = 'none'; + } } -function handlerMuscles() { - reflectMarkupMuscles(); +const params = { + perPage: 12, + page: 1, + filter: 'Muscles', + totalPages: 1, + totalItems: 0, +}; + +async function getData() { + getLoader(); + const data = await axios.get('/filters', { + params: { + filter: params.filter, + page: params.page, + limit: params.perPage, + }, + }); + return data.data; } -async function handlerBodyparts() { - buttonBodyparts.classList.add('active'); - buttonMuscles.classList.remove('active'); - buttonEquipment.classList.remove('active'); - const datas = await getAccess({ - filter: 'Body parts', - typeFilter: 'filters', +function handleError(message) { + iziToast.error({ + position: 'topRight', + message: message, }); +} + +function createMarkup(results) { + refs.gallery.innerHTML = ''; + const markup = results + .map( + ({ name, filter, imgUrl }) => `` + ) + .join(''); - const objBodyparts = datas.data.results; - list.innerHTML = createMarkupFilter(objBodyparts, list); + refs.gallery.innerHTML = markup; } -async function handlerEquipment() { - buttonEquipment.classList.add('active'); - if ( - buttonMuscles.classList.contains('active') || - buttonBodyparts.classList.contains('active') - ) { - buttonMuscles.classList.remove('active'); - buttonBodyparts.classList.remove('active'); +function handleSearch() { + params.page = 1; + getData() + .then(data => { + const { results } = data; + createMarkup(results); + }) + .catch(error => { + handleError(error.message); + }); +} +handleSearch(); +refs.musclesBtn.classList.add('active'); +refs.musclesBtn.disabled = true; + +refs.buttons.addEventListener('click', event => { + selected(event); + const targetMenu = event.target; + + if (targetMenu === event.currentTarget) { + return; + } else if (targetMenu === refs.musclesBtn) { + refs.musclesBtn.disabled = true; + refs.bodypartsBtn.disabled = false; + refs.equipBtn.disabled = false; + params.filter = 'Muscles'; + } else if (targetMenu === refs.bodypartsBtn) { + refs.musclesBtn.disabled = false; + refs.bodypartsBtn.disabled = true; + refs.equipBtn.disabled = false; + params.filter = 'Body parts'; + } else if (targetMenu === refs.equipBtn) { + refs.musclesBtn.disabled = false; + refs.bodypartsBtn.disabled = false; + refs.equipBtn.disabled = true; + params.filter = 'Equipment'; + } + handleSearch(); +}); + +let prevButton = null; + +function selected(e) { + const isButton = e.target.nodeName === 'BUTTON'; + refs.musclesBtn.classList.remove('active'); + + if (!isButton) { + return; } - const datas = await getAccess({ - filter: 'Equipment', - typeFilter: 'filters', - }); - const objEquipment = datas.data.results; - list.innerHTML = createMarkupFilter(objEquipment, list); + e.target.classList.add('active'); + + if (prevButton !== null) { + prevButton.classList.remove('active'); + } + prevButton = e.target; + + if (prevButton === prevButton) { + prevButton.classList.add('active'); + } } diff --git a/src/js/search.js b/src/js/search.js index 2f3ec91..0af8672 100644 --- a/src/js/search.js +++ b/src/js/search.js @@ -32,6 +32,8 @@ const filterButtonsContainer = document.querySelector('.exercises-btns-div'); const searchFormContainer = document.querySelector('.ex-search'); const sectionHeaderElement = document.querySelector('.exercises-header'); +// * обробляємо клік по карточці для групи вправ + function handleClickOnCard(event) { event.preventDefault(); if (event.target.closest('ul').dataset.exercises) { @@ -53,6 +55,7 @@ function handleClickOnCard(event) { } return; } +// * обробляємо клік по кнопці пошуку function handleSearchButtonClick(event) { event.preventDefault(); @@ -64,6 +67,10 @@ function handleSearchButtonClick(event) { return; } +/** + * Обробка пошукового тексту в полі пошуку + */ + function handleSearchInput() { if (searchInputField.value.length > 0) { clearSearchButton.style.visibility = 'visible'; @@ -72,6 +79,8 @@ function handleSearchInput() { } } +// * Очищаємо поле пошуку при натисканні на кнопку + function handleClearSearchInput() { searchInputField.value = ''; clearSearchButton.style.visibility = 'hidden'; @@ -79,6 +88,8 @@ function handleClearSearchInput() { updateExercisesList(exerciseParams.filter, exerciseParams.filterGroup); } +// * Обробляємо клік по одній з трьох кнопок. Видаляємо слухачі подій. Очищаємо поле пошуку. + function handleClickOnFilterButton(event) { if (event.target.tagName === 'BUTTON') { searchInputField.value = ''; diff --git a/src/partials/exercises.html b/src/partials/exercises.html index ac8e9f6..15a2e2d 100644 --- a/src/partials/exercises.html +++ b/src/partials/exercises.html @@ -1,45 +1,36 @@ -
    +
    -
    -

    Exercises

    -
      -
    • - -
    • -
    • - -
    • -
    • - -
    • -
    - - +
    - -
    From c04a11a295cef06ef216fc5f206f9a92e06a37dc Mon Sep 17 00:00:00 2001 From: bezkagoit <142536080+bezkagoit@users.noreply.github.com> Date: Mon, 12 Feb 2024 08:42:51 +0000 Subject: [PATCH 4/5] Changed css name container --- src/css/exercises.css | 6 +++--- src/partials/exercises.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/css/exercises.css b/src/css/exercises.css index 711dbd9..4cf85d2 100644 --- a/src/css/exercises.css +++ b/src/css/exercises.css @@ -113,7 +113,7 @@ } } -.container { +.container-block { min-width: 320px; max-width: 335px; padding: 40px 20px; @@ -124,7 +124,7 @@ } @media screen and (min-width: 768px) { - .container { + .container-block { max-width: 736px; border-radius: 50px; padding: 64px 48px; @@ -132,7 +132,7 @@ } @media screen and (min-width: 1440px) { - .container { + .container-block { max-width: 1408px; } } diff --git a/src/partials/exercises.html b/src/partials/exercises.html index 15a2e2d..b98c749 100644 --- a/src/partials/exercises.html +++ b/src/partials/exercises.html @@ -1,5 +1,5 @@
    -
    +

    Exercises

    From b0ccf53902169aaae95ff6f1ab60a5c7cd6d2561 Mon Sep 17 00:00:00 2001 From: bezkagoit <142536080+bezkagoit@users.noreply.github.com> Date: Mon, 12 Feb 2024 10:17:22 +0000 Subject: [PATCH 5/5] Updated css --- src/css/exercises.css | 23 +++++++++++------------ src/index.html | 2 +- src/js/body-parts.js | 10 +++++----- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/css/exercises.css b/src/css/exercises.css index 4cf85d2..6c455db 100644 --- a/src/css/exercises.css +++ b/src/css/exercises.css @@ -4,6 +4,7 @@ justify-content: space-between; margin-bottom: 32px; margin-top: 32px; + gap: 20px; } .exercises-button { padding: 10px 20px; @@ -109,7 +110,7 @@ height: 232px; } .ex-search { - margin-top: 40px; + margin-top: 0px; } } @@ -174,8 +175,6 @@ text-align: center; } .exercise-item { - width: 295px; - height: 165px; border-radius: 15px; padding: 16px; background-color: var(--white-color); @@ -209,13 +208,11 @@ font-size: 12px; line-height: 1.5; color: var(--black-background); - align-self: center; } .ex-star-icon { width: 18px; height: 18px; fill: var(--star); - align-self: center; } .ex-item-start { display: flex; @@ -257,7 +254,7 @@ .ex-item-name { font-size: 20px; line-height: 1.2; - + font-weight: 400; overflow: hidden; text-overflow: ellipsis; } @@ -331,12 +328,13 @@ padding-right: 50px; } .exercises-card { - row-gap: 20px; + gap: 20px 14px; } .exercise-item { - width: 313px; - height: 165px; + /* width: 313px; + height: 165px; */ + flex-basis: calc((100%-14px) / 2); } .search-input { width: 246px; @@ -360,7 +358,7 @@ @media screen and (min-width: 1440px) { .exercises-card { - row-gap: 28px; + gap: 28px 20px; } .ex-list-no-result { padding-top: 217px; @@ -373,8 +371,9 @@ text-wrap: nowrap; } .exercise-item { - width: 424px; - height: 141px; + /* width: 424px; + height: 141px; */ + flex-basis: calc((100%-40px) / 3); } } diff --git a/src/index.html b/src/index.html index 1889beb..720d04c 100644 --- a/src/index.html +++ b/src/index.html @@ -34,7 +34,7 @@ - + diff --git a/src/js/body-parts.js b/src/js/body-parts.js index c5bec7f..1187a50 100644 --- a/src/js/body-parts.js +++ b/src/js/body-parts.js @@ -51,7 +51,7 @@ function renderExercises(data) { .map( i => `
  • -

    +

    WORKOUT @@ -61,16 +61,16 @@ function renderExercises(data) { Start - + -

    +

    ${ i.name.charAt(0).toUpperCase() + i.name.slice(1) }

    -

    +

    Burned calories: ${i.burnedCalories} / ${i.time} min @@ -87,7 +87,7 @@ function renderExercises(data) { i.target.charAt(0).toUpperCase() + i.target.slice(1) } -

    +
  • ` ) .join('');