Sliders

Google Reviews Slider (Відгуки напряму з локації Google Maps)

25 Nov 2022

Google Reviews Slider (Відгуки напряму з локації Google Maps)
HTML
SCSS
PostCSS
JS
                            <section class="google-reviews">
          <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=places&key=AIzaSyBjRte3tbYc09HHhebr73lecT6dTcpa6lk&language=en-GB"></script>
          <div class="cont">
            <div class="google-reviews__wrap">
              <h2 class="google-reviews__title">Google reviews</h2>

              <div class="swiper google-reviews-slider">
                <div
                  id="google-reviews"
                  class="swiper-wrapper google-reviews-slider__wrapper"
                  data-max-line-length="6"
                ></div>
                <div class="swiper-buttons btn-wrap-circle">
                  <span class="circle-btn google-reviews-slider__btn-prev">
                    <i class="icon-arrow-prev"></i>
                  </span>
                  <span class="circle-btn google-reviews-slider__btn-next">
                    <i class="icon-arrow-next"></i>
                  </span>
                </div>
              </div>
            </div>
          </div>
        </section>
                        
                            .btn-wrap-circle {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  padding-top: ac(40px, 30px);

  .circle-btn:not(:last-of-type) {
    margin-right: 10px;
  }
}

.circle-btn {
  width: ac(42px, 32px);
  height: ac(42px, 32px);
  border-radius: 50%;
  @include transition-all;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: ac(14px, 11px);
  color: #3cc5fb;
  border: solid 2px var(--white);

  button {
    opacity: 0 !important;
    width: calc(100% + 2px);
    height: calc(100% + 2px);
  }

  &.lg {
    width: ac(52px, 46px);
    height: ac(52px, 46px);
  }

  i,
  &::before,
  &::after {
    font-family: "icomoon";
    position: absolute;
  }

  &:hover {
    opacity: 1 !important;
    color: var(--primary);
    border-color: var(--primary);
  }
}

.google-reviews {
  padding-top: 100px;
  padding-bottom: 100px;

  #map-plug {
    display: none;
  }

  &__wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    width: 100%;
  }

  &__title {
    margin-bottom: ac(50px, 40px);
  }
}

.google-reviews-slider {
  width: 100%;
  max-width: 100%;
  
  &__wrapper {
    width: 100%;
    max-width: 100%;
  }

  .review-item {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    padding: ac(30px, 20px);
    border: 2px solid var(--white);
    color: var(--white);
    border-radius: 10px;
    font-size: ac(16px, 14px);
    line-height: 32px;
  }

  .review-meta {
    color: var(--secondary);
    padding-bottom: 10px;
    width: 100%;

    .review-author {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: 100%;
    }

    .review-date {
      margin-left: auto;
    }
  }

  .review-text {
    @include max-line-length(6);
    padding-bottom: 0;

    &.active {
      @include max-line-length(100);
    }
  }

  .review-stars {
    ul {
      display: flex;
      align-items: center;
      justify-content: flex-start;
      padding-bottom: 10px;
      
      li {
        width: 14px;
        height: 14px;
        background: var(--primary);
        clip-path: polygon(
                        50% 0%,
                        61% 35%,
                        98% 35%,
                        68% 57%,
                        79% 91%,
                        50% 70%,
                        21% 91%,
                        32% 57%,
                        2% 35%,
                        39% 35%
        );

        &:not(:last-child) {
          margin-right: 3px;
        }
      }
    }
  }

  .review-text-more {
    margin-top: 10px;
    position: relative;
    font-weight: 500;
    cursor: pointer;
    transition: color 0.3s ease;
    line-height: 1.4;
    font-size: ac(14px, 13px);
    padding-bottom: 0;

    &:before {
      content: "";
      position: absolute;
      bottom: 0;
      left: 0;
      height: 2px;
      width: 100%;
      transition: background-color 0.3s ease, width 0.3s ease;
      background: var(--white);
    }

    &:hover {
      color: var(--secondary);
      
      &:before {
        width: 0;
        background: var(--secondary);
      }
    }
  }

  &__btns {
    padding-top: ac(40px, 30px);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;

    .news__slide-btn {
      position: static;
      margin: 0 7px;
    }
  }
}
                        
                            .btn-wrap-circle {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  padding-top: ac(40px, 30px);

  .circle-btn:not(:last-of-type) {
    margin-right: 10px;
  }
}

.circle-btn {
  width: ac(42px, 32px);
  height: ac(42px, 32px);
  border-radius: 50%;
  @mixin transition-all;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: ac(14px, 11px);
  color: #3cc5fb;
  border: solid 2px var(--white);

  button {
    opacity: 0 !important;
    width: calc(100% + 2px);
    height: calc(100% + 2px);
  }

  &.lg {
    width: ac(52px, 46px);
    height: ac(52px, 46px);
  }

  i,
  &::before,
  &::after {
    font-family: "icomoon";
    position: absolute;
  }

  &:hover {
    opacity: 1 !important;
    color: var(--primary);
    border-color: var(--primary);
  }
}

.google-reviews {
  padding-top: 100px;
  padding-bottom: 100px;

  #map-plug {
    display: none;
  }

  &__wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    width: 100%;
  }

  &__title {
    margin-bottom: ac(50px, 40px);
  }
}

.google-reviews-slider {
  width: 100%;
  max-width: 100%;
  &__wrapper {
    width: 100%;
    max-width: 100%;
  }

  .review-item {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    padding: ac(30px, 20px);
    border: 2px solid var(--white);
    color: var(--white);
    border-radius: 10px;
    font-size: ac(16px, 14px);
    line-height: 32px;
  }

  .review-meta {
    color: var(--secondary);
    padding-bottom: 10px;
    width: 100%;

    .review-author {
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: 100%;
    }

    .review-date {
      margin-left: auto;
    }
  }

  .review-text {
    @mixin max-line-length 6;
    padding-bottom: 0;

    &.active {
      @mixin max-line-length 100;
    }
  }

  .review-stars {
    ul {
      display: flex;
      align-items: center;
      justify-content: flex-start;
      padding-bottom: 10px;
      li {
        width: 14px;
        height: 14px;
        background: var(--primary);
        clip-path: polygon(
          50% 0%,
          61% 35%,
          98% 35%,
          68% 57%,
          79% 91%,
          50% 70%,
          21% 91%,
          32% 57%,
          2% 35%,
          39% 35%
        );

        &:not(:last-child) {
          margin-right: 3px;
        }
      }
    }
  }

  .review-text-more {
    margin-top: 10px;
    position: relative;
    font-weight: 500;
    cursor: pointer;
    transition: color 0.3s ease;
    line-height: 1.4;
    font-size: ac(14px, 13px);
    padding-bottom: 0;

    &:before {
      content: "";
      position: absolute;
      bottom: 0;
      left: 0;
      height: 2px;
      width: 100%;
      transition: background-color 0.3s ease, width 0.3s ease;
      background: var(--white);
    }

    &:hover {
      color: var(--secondary);
      &:before {
        width: 0;
        background: var(--secondary);
      }
    }
  }

  &__btns {
    padding-top: ac(40px, 30px);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;

    .news__slide-btn {
      position: static;
      margin: 0 7px;
    }
  }
}
                        
                            $("#google-reviews").googlePlaces({
  placeId: "ChIJsYg77pHHh0gRAetJSJFNCS8",
  render: ["reviews"],
  min_rating: 1,
  max_rows: 20,
});

const googleReviews = document.querySelector("#google-reviews");
if (googleReviews) {
  MetaSwiper(".google-reviews-slider", {
    slidesPerView: 3,
    spaceBetween: 30,
    autoplay: {
      delay: 3000,
      pauseOnMouseEnter: true,
      disableOnInteraction: false,
    },
    navigation: {
      prevEl: ".google-reviews-slider__btn-prev",
      nextEl: ".google-reviews-slider__btn-next",
    },
    breakpoints: {
      1025: {
        spaceBetween: 30,
        slidesPerView: 3,
        769: {
          slidesPerView: 2,
          spaceBetween: 30,
        },
        300: {
          slidesPerView: 1,
          spaceBetween: 20,
        },
      },
    },
  });
  function textMore() {
    const googleReviewsSwiper = document.querySelector(
      ".google-reviews-slider"
    );
    const reviewsTextArr = googleReviewsSwiper.querySelectorAll(
      ".swiper-slide .review-text"
    );
    const reviewsMoreArr = googleReviewsSwiper.querySelectorAll(
      ".swiper-slide .review-text-more"
    );
    const maxLineLength = +googleReviews.dataset.maxLineLength;
    const lineHeight = +$(reviewsTextArr[0])
      .css("line-height")
      .replace(/[^0-9.]/g, "");
    const textHeight = lineHeight * maxLineLength;

    reviewsTextArr.forEach((text, index) => {
      if (text.offsetHeight < Math.round(textHeight)) {
        reviewsMoreArr[index].style.display = "none";
      }

      reviewsMoreArr.forEach((elem, i) => {
        elem.addEventListener("click", () => {
          if (!reviewsTextArr[i].classList.contains("active")) {
            reviewsTextArr[i].classList.add("active");
            elem.textContent = "Close";
          } else {
            reviewsTextArr[i].classList.remove("active");
            elem.textContent = "Read More";
          }
        });
      });
    });
  }
  // textMore();
  setTimeout(textMore, 1200);
}
                        

Google Reviews Slider, в якому відгуки напряму беруться з локації в Google Maps. Для цього потрібний доступ до ідентифікатора Google Places та ключ Google API. також знадобиться скрипт Google Places, який для цього слайдера трошки модифікував.

Для роботи скрипта знадобиться JQuery.

На початку секції підключений скрипт Google API, туди треба вписати свій ключ та дописати мову та регіон в кінці посилання.

Google Maps API<br>

Google Maps API

В JS-код треба вписати ідентифікатор локації.

Скрипт Google Places

Скрипт Google Places

Є можливість виводити відгуки з мінімальним рейтингом, це вказується в min_rating (від 1-5). Для обмеження кількості відгуків можна вказати це в max_rows.

Сам ідентифікатор можно взяти тут - https://developers.google.com/maps/documentation/places/web-service/place-id

В пошуку карти вводимо адресу локації:

Пошук локації<br>

Пошук локації

Потім копіюємо ідентифікатор та вставляємо його в JS-код.

Place ID<br>

Place ID

Також доданий невеликий функціонал для розкриття всього відгуку. Для id="google-reviews" додав дата-атрибут, куди необіхдно дописати скільки рядків буде видно тексту спочатку.

data-атрибут

data-атрибут

Також в стилях для тексту треба додати аналогічне значення.

max-line-length<br>

max-line-length

P.S. На цей час можливо вивести тільки 5 найкращих відгуків, щоб більше було, треба купувати підписку для сторонніх API

google-places.rar

0