<section class="course-overview" data-behavior="course-overview">
    <header>
        <h2>Course Overview</h2>
    </header>
    <article data-brand="mens" class="course-overview__inner">
        <a class="course-overview_show-hide"></a>
        <div class="info-title-sticky">Introduction to Coaching Football</div>
        <div class="course-overview__info">
            <div>
                <p>Course type:</p>
                <h3>Online</h3>
            </div>
            <div class="sticky-price">
                <h3>£160</h3>
            </div>
        </div>
        <div class="course-overview__info">
            <p>Duration:</p>
            <h3>12 Months</h3>
            <p>
                The taught element of this course is 12 days in total: <br>6 x 2 day modules<br>3 day in-situ support visits (minimum)<br>
            </p>
        </div>
        <div class="course-overview__info">
            <p>Leading To:</p>
            <h3>FA Level 5 (UEFA Pro)</h3>
            <p>in Coaching Football</p>
        </div>
        <div class="course-overview__info">
            <div>
                <p>Price:</p>
                <h3 class="course-overview__price">£160</h3>
            </div>
            <a class="cta cta--efl  " id="efl-offline-signin" tabindex="0">Sign in to find course</a>

        </div>

    </article>
</section>

No notes defined.

{
  "venue": "Online",
  "isOnline": false,
  "duration": "12 Months",
  "price": 160,
  "leadingTo": {
    "name": "FA Level 5 (UEFA Pro)",
    "category": "in Coaching Football"
  },
  "content": [
    "The taught element of this course is 12 days in total: ",
    "6 x 2 day modules",
    "3 day in-situ support visits (minimum)"
  ],
  "course-overview-cta": {
    "copy": "Sign in to find course",
    "modifier": "efl",
    "id": "efl-offline-signin",
    "href": "",
    "additionalClass": ""
  }
}
  • Content:
    import { gsap } from 'gsap';
    import { ScrollToPlugin } from 'gsap/ScrollToPlugin';
    
    export default parentElement => {
      const bookCourse = parentElement.querySelector('#efl-online-book-course');
      const findCOurse = parentElement.querySelector('#efl-offline-find-course');
      const courseAvail = document.querySelector(
        '[data-behavior=course-availability]'
      );
      const courseAvail2 = document.querySelector('.membership-signpost');
      const boxWidth = parentElement.clientWidth;
      const boxHeight = parentElement.clientHeight;
      const MOBILE_BREAKPOINT = 820;
      const mobTouch = parentElement.querySelector('.course-overview_show-hide');
      const mobSwipe = parentElement.querySelector('.course-overview__inner');
      const defaultWidth = window.innerWidth;
    
      gsap.registerPlugin(ScrollToPlugin);
    
      const courseJourneyTwo = () => {
        if (!courseAvail) {
          return false;
        }
    
        gsap.to(window, {
          duration: 5,
          scrollTo: { y: courseAvail.offsetTop },
          ease: 'power2',
        });
        // window.scroll(0, courseAvail.offsetTop);
        return true;
      };
    
      const courseJourneyFour = () => {
        if (!courseAvail2) {
          return false;
        }
        gsap.to(window, {
          duration: 5,
          scrollTo: { y: courseAvail2.offsetTop },
          ease: 'power2',
        });
        // window.scroll(0, courseAvail2.offsetTop);
        return true;
      };
    
      const setContainerSize = () => {
        // eslint-disable-next-line no-param-reassign
        parentElement.style.width = `${boxWidth}px`;
        // eslint-disable-next-line no-param-reassign
        parentElement.style.height = `${boxHeight}px`;
      };
    
      const findPos = obj => {
        // eslint-disable-next-line no-unused-vars
        let curleft = 0;
        let curtop = 0;
    
        if (obj.offsetParent) {
          curleft = obj.offsetLeft;
          curtop = obj.offsetTop;
    
          // eslint-disable-next-line no-param-reassign, no-cond-assign
          while ((obj = obj.offsetParent)) {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
          }
        }
        return curtop;
      };
    
      if (bookCourse) {
        if (courseAvail) {
          const titleTxt = courseAvail.querySelector('h2').innerText;
    
          bookCourse.setAttribute(
            'aria-label',
            `${bookCourse.innerText} jump to ${titleTxt} section`
          );
        } else {
          bookCourse.setAttribute(
            'aria-label',
            `Course overview - ${bookCourse.innerText}`
          );
        }
        bookCourse.addEventListener('click', () => courseJourneyTwo());
    
        bookCourse.addEventListener('keyup', event => {
          if (event.keyCode === 13) {
            // Cancel the default action, if needed
            event.preventDefault();
            bookCourse.click();
          }
        });
      }
    
      if (findCOurse) {
        if (courseAvail2) {
          const titleTxt2 = courseAvail2.querySelector('h3').innerText;
    
          findCOurse.setAttribute(
            'aria-label',
            `${findCOurse.innerText} jump to ${titleTxt2} section`
          );
        } else {
          findCOurse.setAttribute(
            'aria-label',
            `Course overview - ${findCOurse.innerText}`
          );
        }
        findCOurse.addEventListener('click', () => courseJourneyFour());
    
        findCOurse.addEventListener('keyup', event => {
          if (event.keyCode === 13) {
            // Cancel the default action, if needed
            event.preventDefault();
            findCOurse.click();
          }
        });
      }
    
      setContainerSize();
      // eslint-disable-next-line complexity
      window.addEventListener('scroll', () => {
        const courseOverviewInner = parentElement.querySelector(
          '.course-overview__inner'
        );
    
        if (window.innerWidth > MOBILE_BREAKPOINT) {
          if (
            parentElement.querySelector('article').getAttribute('aria-expanded') ===
            'true'
          ) {
            mobTouch.innerHTML = 'Hide Course Overview';
          } else {
            mobTouch.innerHTML = 'Show Course Overview';
          }
        } else {
          mobTouch.innerHTML = null;
        }
    
        if (findPos(parentElement) + parentElement.clientHeight < window.scrollY) {
          if (
            !parentElement.classList.contains('sticky') &&
            findPos(parentElement) + parentElement.clientHeight + 200 >
              window.scrollY
          ) {
            parentElement.classList.add('sliding');
          }
          parentElement.classList.add('sticky');
          if (
            !parentElement.querySelector('article').getAttribute('aria-expanded')
          ) {
            // eslint-disable-next-line no-param-reassign
            parentElement
              .querySelector('article')
              .setAttribute('aria-expanded', 'false');
          }
    
          setTimeout(() => {
            parentElement.classList.remove('sliding');
          }, 305);
        } else {
          parentElement.classList.remove('sliding');
          parentElement.classList.remove('sticky');
          // eslint-disable-next-line no-param-reassign
          parentElement.querySelector('article').removeAttribute('aria-expanded');
        }
    
        // Removing Course Overview
        // landing page, default variant
        if (courseAvail) {
          if (
            window.innerWidth > MOBILE_BREAKPOINT &&
            window.scrollY + window.innerHeight > findPos(courseAvail)
          ) {
            parentElement.classList.remove('sticky');
          } else if (
            window.innerWidth < MOBILE_BREAKPOINT &&
            window.scrollY + window.innerHeight > findPos(courseAvail)
          ) {
            parentElement.classList.remove('sticky');
          }
        }
    
        // landing page, find-course variant
        if (courseAvail2) {
          if (
            window.innerWidth > MOBILE_BREAKPOINT &&
            window.scrollY >
              findPos(courseAvail2) - courseOverviewInner.clientHeight - 100
          ) {
            parentElement.classList.remove('sticky');
          } else if (
            window.innerWidth < MOBILE_BREAKPOINT &&
            window.scrollY + window.innerHeight > findPos(courseAvail2)
          ) {
            parentElement.classList.remove('sticky');
          }
        }
      });
    
      window.addEventListener('load', () => {
        let startX;
        let startY;
        let dist;
        const threshold = 150; // required min distance traveled to be considered swipe
        const allowedTime = 500; // maximum time allowed to travel that distance
        let elapsedTime;
        let startTime;
    
        function handleswipe(isupswipe) {
          if (isupswipe) {
            if (
              parentElement
                .querySelector('article')
                .getAttribute('aria-expanded') === 'true'
            ) {
              // eslint-disable-next-line no-param-reassign
              parentElement
                .querySelector('article')
                .setAttribute('aria-expanded', 'false');
            } else {
              // eslint-disable-next-line no-param-reassign
              parentElement
                .querySelector('article')
                .setAttribute('aria-expanded', 'true');
            }
          }
        }
        mobTouch.addEventListener('click', () => {
          if (
            parentElement.querySelector('article').getAttribute('aria-expanded') ===
            'true'
          ) {
            // eslint-disable-next-line no-param-reassign
            parentElement
              .querySelector('article')
              .setAttribute('aria-expanded', 'false');
            if (window.innerWidth > MOBILE_BREAKPOINT) {
              mobTouch.innerHTML = 'Show Course Overview';
            }
          } else {
            // eslint-disable-next-line no-param-reassign
            parentElement
              .querySelector('article')
              .setAttribute('aria-expanded', 'true');
            if (window.innerWidth > MOBILE_BREAKPOINT) {
              mobTouch.innerHTML = 'Hide Course Overview';
            }
          }
        });
    
        mobSwipe.addEventListener('touchstart', e => {
          const touchobj = e.changedTouches[0];
    
          dist = 0;
          startX = touchobj.pageX;
          startY = touchobj.pageY;
          startTime = new Date().getTime(); // record time when finger first makes contact with surface
          // e.preventDefault();
        });
    
        mobSwipe.addEventListener('touchmove', () => {
          // e.preventDefault(); // prevent scrolling when inside DIV
        });
    
        mobSwipe.addEventListener('touchend', e => {
          const touchobj = e.changedTouches[0];
          let swipedownBol = null;
          let swipeupBol = null;
          // check that elapsed time is within horizontal & vertical dist traveled >= threshold
    
          dist = touchobj.pageY - startY; // get total dist traveled by finger while in contact
          elapsedTime = new Date().getTime() - startTime; // get time elapsed
          swipeupBol =
            elapsedTime <= allowedTime &&
            -dist >= threshold &&
            Math.abs(touchobj.pageX - startX) <= 100;
    
          swipedownBol =
            elapsedTime <= allowedTime &&
            dist >= threshold &&
            Math.abs(touchobj.pageX - startX) <= 100;
          // depending whether the tab is expanded or not, checking for up or down swipe
          if (
            parentElement.querySelector('article').getAttribute('aria-expanded') ===
            'true'
          ) {
            handleswipe(swipedownBol);
          } else {
            handleswipe(swipeupBol);
          }
    
          // e.preventDefault();
        });
      });
    
      // touch to expand, specifically for the nudge only
      mobTouch.addEventListener('touchstart', () => {
        if (
          parentElement.querySelector('article').getAttribute('aria-expanded') ===
            'true' &&
          window.innerWidth < MOBILE_BREAKPOINT
        ) {
          // eslint-disable-next-line no-param-reassign
          parentElement
            .querySelector('article')
            .setAttribute('aria-expanded', 'false');
        } else if (window.innerWidth < MOBILE_BREAKPOINT) {
          // eslint-disable-next-line no-param-reassign
          parentElement
            .querySelector('article')
            .setAttribute('aria-expanded', 'true');
        }
      });
    
      window.addEventListener('resize', () => {
        if (defaultWidth !== window.innerWidth) {
          parentElement.removeAttribute('style');
          parentElement.classList.remove('sliding');
        }
      });
    };
    
  • URL: /components/raw/course-overview/course-overview.js
  • Filesystem Path: src/library/components/course-overview/course-overview.js
  • Size: 9.8 KB
  • Content:
    .course-overview {
      max-width: 119.6rem;
      box-shadow: 0 0.4rem 0.6rem 0 rgba(57, 48, 48, 0.15);
      background-color: $white;
      border-radius: 1em;
    
      &_show-hide {
        display: none;
    
        @extend .efl-p-large;
      }
      .info-title-sticky {
        display: none;
      }
      :last-child {
        border-bottom: none;
      }
    
      header {
        h2 {
          font-family: $text-font-ef;
          text-transform: uppercase;
          font-size: 1.6rem;
          line-height: 1.6rem;
          letter-spacing: 0.14em;
          max-width: 95.2rem;
          text-align: left;
          margin: 0;
        }
    
        background-color: $color-primary;
        color: $white;
        border-radius: 1rem 1rem 0 0;
        padding: 1.6rem 3.2rem;
      }
    
      article {
        padding: 1.6rem 3.2rem;
        color: #5b6885;
        display: flex;
        flex-direction: column;
        margin: 0 auto;
        top: 0;
        transition: top 0.3s ease-out, bottom 0.3s ease-out;
      }
    
      &__info {
        border-bottom: 0.1rem solid $grey-light;
        padding-top: 0.8rem;
        padding-bottom: 1rem;
        display: flex;
        flex-direction: column;
        align-items: stretch;
    
        a:last-child {
          margin-top: 0.8rem;
        }
        &:nth-child(3) {
          padding-top: 0;
          border-left: none;
        }
        .cta--efl {
          color: $white;
          max-width: none;
          font-family: $text-font-ef;
          font-size: 1.4rem;
          line-height: 2.8rem;
          letter-spacing: 0.01em;
          min-height: 4.3rem;
          &:hover {
            color: $white;
          }
        }
        .sticky-price {
          display: none;
        }
    
        // P Small
    
        > :first-child {
          font-size: 1.6rem;
          line-height: 2.4rem;
        }
      }
    
      h3 {
        font-family: $text-font-ef;
        font-style: normal;
        font-weight: 700;
        font-size: 2rem;
        line-height: 2.4rem;
        color: $color-primary;
      }
    
      &__price {
        font-size: 4.4rem !important;
        line-height: 4.4rem !important;
      }
    
      p {
        text-align: left;
    
        @extend .efl-p-medium;
        &:first-child {
          @extend .efl-p-small;
        }
      }
    
      @media screen and (max-width: $mq-medium) {
        &.sticky {
          article {
            position: fixed;
            bottom: 0;
            background-color: $white;
            left: 0;
            right: 0;
            filter: drop-shadow(0 0 6px rgba(91, 104, 133, 0.5));
            border-radius: 1rem 1rem 0 0;
            z-index: 99;
            width: 100%;
            top: initial;
            transition: bottom 0.3s ease-out;
            .course-overview__info {
              transition: all 0.3s ease-out;
              max-height: 0;
              overflow: hidden;
              padding: 0;
              border-bottom: none;
              &:last-child {
                display: flex;
                flex-direction: row;
                gap: 2.4rem;
                a {
                  flex-grow: 1;
                  margin-top: 0;
                }
    
                padding: 0;
                max-height: initial;
                .course-overview__price {
                  font-size: 2.4rem !important;
                  line-height: 2.6rem !important;
                }
              }
            }
            &[aria-expanded='true'] {
              .course-overview__info {
                max-height: initial;
                overflow: visible;
                border-bottom: 0.1rem solid $grey-light;
                padding-top: 0.8rem;
                padding-bottom: 1rem;
                transition: all 0.3s ease-out;
                &:last-child {
                  border-bottom: none;
                  padding-top: 3.1rem;
                }
              }
            }
          }
          .course-overview_show-hide {
            display: block;
            text-align: center;
            padding: 0.8rem;
            margin-top: -1rem;
            &::before {
              content: '';
              border-bottom: 0.3rem solid #5b6885;
              border-radius: 10rem;
              width: 4rem;
              display: inline-block;
            }
          }
          &.sliding {
            article {
              bottom: -7.5rem;
            }
          }
        }
      }
    }
    
    @media screen and (min-width: $mq-medium) {
      .course-overview {
        header {
          padding-top: 0.9rem;
          padding-bottom: 0.8rem;
          h2 {
            font-size: 1.7rem;
            line-height: 2.7rem;
            margin-left: 7.2rem;
          }
        }
    
        article {
          flex-direction: row;
          justify-content: space-between;
          padding: 3.4rem 3.2rem;
          padding-left: 10.4rem;
          padding-right: 10.4rem;
        }
    
        &__info {
          border-bottom: none;
          padding-left: 2.4rem;
          padding-right: 2.4rem;
          border-left: 0.1rem solid $grey-light;
          padding-top: 0;
    
          h3 {
            font-size: 2.2rem;
            line-height: 3rem;
          }
          &:nth-child(3) {
            padding-left: 0;
          }
          &:last-child {
            padding-right: 0;
          }
    
          .cta--efl {
            min-width: 25.1rem;
          }
        }
    
        &__sign-in {
          margin: 1.5rem 0;
        }
    
        &.course-overview--cpd {
          h3 {
            letter-spacing: -0.01rem;
          }
          .course-overview__info {
            .cta--efl {
              max-width: 25.1rem;
              min-width: none;
              width: 100%;
            }
          }
    
          article {
            justify-content: start;
            padding-left: 10.4rem;
            h3 {
              white-space: nowrap;
            }
          }
        }
    
        a:last-child {
          border-bottom: none;
          border-left: none;
        }
        &__price {
          font-size: 4.2rem !important;
          line-height: 4rem !important;
        }
        &.sticky {
          article {
            position: fixed;
            display: grid;
            grid-template-areas:
              'infoA infoA infoB infoB infoC infoC'
              'infoCta infoCta 1fr 1fr infoExpand infoExpand';
            grid-template-columns: repeat(6, minmax(100px, 500px));
            align-items: center;
            padding: 2.35rem calc(50vw - 54.8rem);
            bottom: 0;
            background-color: $white;
            left: 0;
            right: 0;
            filter: drop-shadow(0 0 6px rgba(91, 104, 133, 0.5));
            z-index: 99;
            width: 100%;
            top: initial;
            transition: bottom 0.3s ease-out;
            .course-overview_show-hide {
              display: block;
              white-space: nowrap;
              padding-left: 0;
              &::before {
                content: '';
                background-image: url('./assets/images/red-arrow.svg');
                background-repeat: no-repeat;
                background-position: center;
                width: 1.7rem;
                height: 1.05rem;
                margin-right: 1.6rem;
                display: inline-block;
                transform: rotate(180deg);
              }
            }
    
            .course-overview__info {
              max-height: 0;
              overflow: hidden;
              border-bottom: none;
              &:last-child {
                display: flex;
                flex-direction: row;
                gap: 2.4rem;
                a {
                  flex-grow: 1;
                  margin-top: 0;
                }
    
                padding: 0 0 0 3.2rem;
                max-height: initial;
                .course-overview__price {
                  font-size: 2.4rem !important;
                  line-height: 2.6rem !important;
                }
              }
            }
    
            &[aria-expanded='false'] {
              .course-overview__info {
                padding: 0;
                &:last-child {
                  padding: 0 0 0 3.2rem;
                  overflow: visible;
                }
              }
            }
    
            &[aria-expanded='true'] {
              row-gap: 5.2rem;
              /* stylelint-disable no-descending-specificity */
              .course-overview__info {
                margin-bottom: auto;
                max-height: initial;
                min-height: -webkit-fill-available;
                overflow: visible;
                border-bottom: none;
                padding-top: 0.8rem;
                padding-bottom: 1rem;
                transition: max-height 0.3s ease-out;
                &:last-child {
                  border-bottom: none;
                  padding: 0 0 0 3.2rem;
                  overflow: visible;
                }
              }
              .course-overview_show-hide::before {
                transform: rotate(0deg);
              }
            }
    
            & > * {
              grid-area: info;
              grid-column: span 2;
              grid-row: 1;
              padding-left: 4rem;
            }
            & > :last-child {
              grid-area: infoCta;
              grid-column: span 2;
              border-left: none;
            }
    
            & > :first-child {
              grid-area: infoExpand;
              grid-column: 5 / span 2;
              cursor: pointer;
            }
          }
          &.sliding {
            article {
              bottom: -7.5rem;
            }
          }
        }
      }
    }
    
    @media screen and (min-width: 1016px) and (max-width: 1266px) {
      .course-overview {
        margin: 0 3rem;
      }
    }
    
    @media screen and (min-width: $mq-medium) and (max-width: 1196px) {
      .course-overview {
        .header {
          padding: 0;
        }
    
        &--cpd.course-overview {
          article {
            padding-left: 2rem;
            h3 {
              white-space: normal;
            }
          }
        }
        p {
          white-space: normal;
        }
      }
    }
    
  • URL: /components/raw/course-overview/course-overview.scss
  • Filesystem Path: src/library/components/course-overview/course-overview.scss
  • Size: 8.8 KB
<section class="course-overview" data-behavior="course-overview">
    <header>
        <h2>Course Overview</h2>
    </header>
    <article data-brand="mens" class="course-overview__inner">
        <a class="course-overview_show-hide"></a>
        <div class="info-title-sticky">Introduction to Coaching Football</div>
        <div class="course-overview__info">
            <div>
                <p>Course type:</p>
                {{#unless isOnline}}
                <h3>{{venue}}</h3>
                {{else}}
                <h3>Online Only</h3>
                {{/unless}}
            </div>
            <div class="sticky-price">
                <h3>£{{price}}</h3>
            </div>
        </div>
        <div class="course-overview__info">
            <p>Duration:</p>
            <h3>{{duration}}</h3>
            <p>
            {{#each content}}{{this}}<br>{{/each}}
            </p>
        </div>
        <div class="course-overview__info">
            <p>Leading To:</p>
            <h3>{{leadingTo.name}}</h3>
            <p>{{leadingTo.category}}</p>
        </div>
        <div class="course-overview__info">
            <div>
                <p>Price:</p>
                <h3 class="course-overview__price">£{{price}}</h3>
            </div>
            {{render '@cta' course-overview-cta merge="true" }}
        </div>
        
    </article>
</section>