diff --git a/src/css/layout/05-modal-exercise.css b/src/css/layout/05-modal-exercise.css index d280080..4ef123c 100644 --- a/src/css/layout/05-modal-exercise.css +++ b/src/css/layout/05-modal-exercise.css @@ -82,7 +82,7 @@ display: flex; align-items: center; justify-content: center; - padding: 0; + padding: 0px; stroke: var(--color-white); background-color: rgba(0, 0, 0, 0); border: none; diff --git a/src/css/layout/06-modal-rating.css b/src/css/layout/06-modal-rating.css index 71eeb77..e619344 100644 --- a/src/css/layout/06-modal-rating.css +++ b/src/css/layout/06-modal-rating.css @@ -17,89 +17,45 @@ } } -.rating-fieldset { - margin: 0; - padding: 0; - border: none; - display: flex; - gap: 2px; -} - .rating-close-btn { position: absolute; top: 14px; right: 14px; - padding: 0; + display: flex; + align-items: center; + justify-content: center; + padding: 7px; margin: 0; border: none; + background-color: transparent; + cursor: pointer; } .rating-icon-close { - width: 24px; - height: 24px; + width: 20px; + height: 20px; + stroke-width: 1.5px; stroke: #f4f4f4; + transition: all var(--transition-dur-and-func); } -@media screen and (min-width: 768px) { - .rating-icon-close { - width: 28px; - height: 28px; - } +.rating-icon-close:hover { + transform: rotate(270deg); } .rating-icon-close:hover, .rating-icon-close:focus { - cursor: pointer; - border-radius: 50%; - background-color: #000000; -} - -.rating-input { - display: none; + transform: rotate(270deg); } -.rating-star { - fill: rgba(244, 244, 244, 0.2); -} - -.rating-star.rated { - fill: #eea10c; -} - -.rating-label { - display: flex; - cursor: pointer; - margin: 2px; - width: 24px; - height: 24px; -} - -.rating-title { - color: #f4f4f4; - opacity: 0.4; - font-feature-settings: 'clig' off, 'liga' off; - font-size: 12px; - font-style: normal; - font-weight: 400; - line-height: 18px; +.form__label { margin-bottom: 8px; -} - -.rating-value { - color: #f4f4f4; + font-family: 'DM Sans'; font-size: 12px; font-style: normal; font-weight: 400; line-height: 18px; - height: 19px; - margin: 5px; -} - -.rating-form { - display: flex; - justify-content: center; - align-items: center; - flex-direction: column; + color: rgba(244, 244, 244, 0.4); } .rating-email { @@ -152,7 +108,7 @@ } } -.rating-submit-btn { +.form__btn { font-size: 14px; font-style: normal; font-weight: 400; @@ -168,9 +124,132 @@ } @media screen and (min-width: 768px) { - .rating-submit-btn { + .form__btn { font-size: 16px; line-height: 24px; margin-top: 32px; } } + +.form__btn[disabled] { + background-color: #f0f0f0; + color: #a0a0a0; + cursor: not-allowed; +} + +.rating { + display: flex; + align-items: flex-start; + gap: 4px; + margin-bottom: 8px; +} + +.rating__value { + color: #f4f4f4; + font-feature-settings: 'liga' off, 'clig' off; + font-family: 'DM Sans'; + font-size: 12px; + font-style: normal; + font-weight: 400; + line-height: 18px; + padding-top: 1px; + margin-top: 1px; +} + +.rating__body { + position: relative; +} + +.rating__body::before { + content: '★★★★★'; + display: block; + color: rgba(244, 244, 244, 0.2); + font-size: 20px; + letter-spacing: 6px; +} + +.rating__active { + position: absolute; + width: 0; + height: 100%; + top: 0; + left: 0; + overflow: hidden; + font-size: 20px; + letter-spacing: 6px; +} + +.rating__active::before { + content: '★★★★★'; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + color: #eea10c; +} + +.rating__items { + display: flex; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; +} + +.rating__item { + flex: 0 0 20%; + height: 100%; + opacity: 0; +} + +.rating-email { + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 18px; + display: inline-flex; + align-items: center; + width: 100%; + margin-top: 20px; + padding: 12px 14px; + border-radius: 30px; + border: 1px solid #f4f4f4; + color: #f4f4f4; + background-color: transparent; +} + +@media screen and (min-width: 768px) { + .rating-email { + font-size: 16px; + line-height: 24px; + margin-top: 32px; + } +} + +.rating-comment { + font-size: 14px; + font-style: normal; + font-weight: 400; + line-height: 18px; + display: inline-flex; + align-items: center; + height: 94px; + width: 100%; + margin-top: 10px; + padding: 12px 14px; + gap: 10px; + border: 1px solid #f4f4f4; + border-radius: 15px; + color: #f4f4f4; + background-color: transparent; +} + +@media screen and (min-width: 768px) { + .rating-comment { + font-size: 16px; + line-height: 24px; + margin-top: 16px; + } +} diff --git a/src/img/sprite.svg b/src/img/sprite.svg index 2356cfc..1d34bfa 100644 --- a/src/img/sprite.svg +++ b/src/img/sprite.svg @@ -44,7 +44,7 @@ - + diff --git a/src/js/06-modal-rating.js b/src/js/06-modal-rating.js index 6585196..413278c 100644 --- a/src/js/06-modal-rating.js +++ b/src/js/06-modal-rating.js @@ -1,12 +1,17 @@ const modalExercises = document.querySelector('.modal-exercises'); const modalIsOpen = document.querySelector('.modal-rating'); const btnIsClosed = document.querySelector('.rating-close-btn'); +const sendButton = document.querySelector('.form__btn'); +const ratingValueElement = document.querySelector('.rating__value'); +const emailInput = document.querySelector('.rating-email'); +const commentTextarea = document.querySelector('.rating-comment'); modalExercises.addEventListener('click', onExercisesCardClick); btnIsClosed.addEventListener('click', closeModal); modalIsOpen.addEventListener('click', closeOverlay); document.addEventListener('keydown', onEscClick); +// Обробник натискання на кнопку "Оцінка" function onExercisesCardClick(event) { if (!event.target.closest('.modal-exercises__btn-rating')) { return; @@ -16,19 +21,158 @@ function onExercisesCardClick(event) { modalExercises.classList.add('hidden'); } +// Закриття модального вікна function closeModal() { modalIsOpen.classList.add('is-hidden'); modalExercises.classList.remove('hidden'); } +// Закриття модального вікна при натисканні на оверлей function closeOverlay(event) { - if (event.target == modalIsOpen) { + if (event.target === modalIsOpen) { closeModal(); } } +// Закриття модального вікна при натисканні клавіші Escape function onEscClick(event) { if (event.key === 'Escape') { closeModal(); } } + +// ========== Рейтинг ========== + +const ratings = document.querySelectorAll('.rating'); + +if (ratings.length > 0) { + initRatings(); +} + +// Функція для встановлення ширини активних зірок +function setRatingActiveWidth(ratingActive, ratingValue, index) { + const ratingActiveWidth = parseFloat(index) * 20; // перетворюємо в число з плаваючою комою + ratingActive.style.width = `${ratingActiveWidth}%`; + // Відображення значення з одним десятковим знаком + ratingValue.innerHTML = parseFloat(index).toFixed(1); +} + +// Головна функція +function initRatings() { + let ratingActive, ratingValue, currentRating; + + // Прохід по всіх рейтингах + for (let index = 0; index < ratings.length; index++) { + const rating = ratings[index]; + initRating(rating); + } + + // Ініціалізація конкретного рейтингу + function initRating(rating) { + initRatingVars(rating); + setRatingActiveWidth(ratingActive, ratingValue, currentRating); + + if (rating.classList.contains('rating_set')) { + setRating(rating); + } + } + + // Ініціалізація змінних + function initRatingVars(rating) { + ratingActive = rating.querySelector('.rating__active'); + ratingValue = rating.querySelector('.rating__value'); + currentRating = parseFloat(ratingValue.innerHTML); // зберігаємо поточне значення рейтингу + } + + // Можливість вказати оцінку + function setRating(rating) { + const ratingItems = rating.querySelectorAll('.rating__item'); + for (let index = 0; index < ratingItems.length; index++) { + const ratingItem = ratingItems[index]; + + ratingItem.addEventListener('mouseenter', function () { + initRatingVars(rating); + setRatingActiveWidth(ratingActive, ratingValue, (index + 1).toFixed(1)); + }); + + ratingItem.addEventListener('mouseleave', function () { + setRatingActiveWidth(ratingActive, ratingValue, currentRating); + }); + + ratingItem.addEventListener('click', function () { + initRatingVars(rating); + const newRating = (index + 1).toFixed(1); // оновлюємо поточне значення рейтингу + if (newRating !== '0.0') { + // Забороняємо вибір нульового рейтингу + currentRating = newRating; + if (rating.dataset.ajax) { + setRatingValue(currentRating, rating); + } else { + ratingValue.innerHTML = currentRating; + setRatingActiveWidth(ratingActive, ratingValue, currentRating); + } + updateSendButtonState(); // Оновлюємо стан кнопки при виборі рейтингу + } + }); + } + } +} + +// Перевірка, чи заповнені всі обов'язкові поля +function isFormValid() { + const emailValue = emailInput.value.trim(); + const commentValue = commentTextarea.value.trim(); + const ratingValue = ratingValueElement.innerHTML.trim(); + + return emailValue !== '' && commentValue !== '' && ratingValue !== '0.0'; +} + +// Оновлення стану кнопки "Send" +function updateSendButtonState() { + sendButton.disabled = !isFormValid(); // Активувати кнопку тільки якщо форма валідна +} + +// Додаємо обробники подій для полів форми +emailInput.addEventListener('input', updateSendButtonState); +commentTextarea.addEventListener('input', updateSendButtonState); + +// Обробник для елемента рейтингу з використанням MutationObserver +const observer = new MutationObserver(updateSendButtonState); + +observer.observe(ratingValueElement, { childList: true, subtree: true }); + +// Очищення форми після відправки +function clearForm() { + emailInput.value = ''; + commentTextarea.value = ''; + ratingValueElement.innerHTML = '0.0'; + setTimeout(() => { + const ratingActive = document.querySelector('.rating__active'); + setRatingActiveWidth(ratingActive, ratingValueElement, '0.0'); // Для очищення ширини активних зірок + updateSendButtonState(); // Перевіряємо стан кнопки після очищення форми + }, 0); +} + +// Виведення значень рейтингу, пошти і коментаря в консоль при натисканні кнопки "Send" +sendButton.addEventListener('click', event => { + event.preventDefault(); + + if (!isFormValid()) { + console.warn( + 'Форма не валідна. Будь ласка, заповніть всі поля та оберіть оцінку.' + ); + return; + } + + const ratingValue = ratingValueElement.innerHTML; + const emailValue = emailInput.value; + const commentValue = commentTextarea.value; + + console.log('Поточне значення рейтингу:', ratingValue); + console.log('Введений email:', emailValue); + console.log('Введений коментар:', commentValue); + + // Закриття модального вікна та очищення форми + closeModal(); + clearForm(); +}); diff --git a/src/partials/06-modal-rating.html b/src/partials/06-modal-rating.html index 7380f0e..7d32f10 100644 --- a/src/partials/06-modal-rating.html +++ b/src/partials/06-modal-rating.html @@ -1,131 +1,70 @@