Skip to content

Instantly share code, notes, and snippets.

@jimmybyrum
Last active September 7, 2017 17:21
Show Gist options
  • Save jimmybyrum/1887f022f8b70f43b14b7bfd1ede54a1 to your computer and use it in GitHub Desktop.
Save jimmybyrum/1887f022f8b70f43b14b7bfd1ede54a1 to your computer and use it in GitHub Desktop.
<div
class="course-container"
cl-course-provider
cl-gallery-provider
ng-init="clGalleryReInit=false;"
cl-course-slug="{{ courseSlug }}"
cl-course-opts='{
"keys": ["short_description"],
"bff": true
}'
cl-course-key="course"
>
<div
ng-if="course"
cl-course-id="{{ ::course._id }}"
cl-product-id="{{ ::(course.product._id || course.product) }}"
cl-price-provider
cl-material-list-provider
cl-material-list-provider-key="materialsData"
cl-lesson-list-provider
cl-current-lesson-slug="lessonSlug"
cl-player-id="coursePlayer"
cl-base-url="/class/{{ ::course.slug }}/lesson/"
cl-course-navigation-provider
cl-course-navigation-provider-key="clCourseNavigation"
cl-course-stats-provider
cl-course-stats-provider-key="stats"
cl-course-onair-provider
cl-course-what-you-get-provider
cl-course-what-you-get-provider-key="wyg"
cl-reviews-provider
cl-reviews-provider-key="clReviews"
cl-reviews-provider-page-size="3"
cl-reviews-provider-limit="9999"
>
<div class="course-page-header pad-top-m pad-bottom-l" cl-affix cl-affix-id="course-header">
<div class="container">
<div class="row">
<div class="col-sm-12">
<div class="gray3 text-uppercase margin-bottom-m">{{ ::clCourseNavigation.channel.title }} Class</div>
<h2
scroll-to-anchor
cl-set-location="false"
href=""
class="margin-none"
style="line-height: 1"
cl-document-title="{{ ::(course.title || course.short_title) + ' | CreativeLive' }}"
>{{ ::course.short_title }}</h2>
<span
scroll-to-anchor
cl-set-location="false"
cl-scroll-spy="true"
cl-scroll-spy-target="#instructors"
href="#instructors"
cl-offset-element=".course-page-header"
cl-offset="70"
ng-repeat="instructor in ::course.instructors"
class="gray1 clickable inline-block"
style="margin-top: -4px;"
>
{{ ::instructor.profile.name }}<span ng-show="!$last">,&nbsp;</span>
</span>
<ul
cl-scroll-spy-target="#description,#lessons,#materials,#student-work,#reviews"
cl-scroll-spy-target-current="clScrollSpyCurrent"
cl-scroll-spy-unwatch-after-seconds="5"
class="jump-links list-unstyled list-inline current-{{ clScrollSpyCurrent }}"
>
<li><a
id="nav-lessons"
scroll-to-anchor
cl-set-location="false"
cl-offset-element=".course-page-header"
cl-offset="70"
href="#lessons"
>Lessons</a></li>
<li><a
id="nav-materials"
scroll-to-anchor
cl-set-location="false"
cl-offset-element=".course-page-header"
cl-offset="70"
href="#materials"
>Class Materials</a></li>
<li><a
id="nav-description"
scroll-to-anchor
cl-set-location="false"
cl-offset-element=".course-page-header"
cl-offset="70"
href="#description"
>Class Description</a></li>
<li><a
ng-show="clGalleryProvider.gallery.count"
id="nav-student-work"
scroll-to-anchor
cl-set-location="false"
cl-offset-element=".course-page-header"
cl-offset="70"
href="#student-work">Student Work</a></li>
<li><a
ng-show="clReviews.reviews.length"
id="nav-reviews"
scroll-to-anchor
cl-set-location="false"
cl-offset-element=".course-page-header"
cl-offset="70"
href="#reviews"
>Reviews</a></li>
</ul>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-sm-8 main-column">
<div
cl-affix
cl-affix-id="course-video-player"
cl-affix-mobile-enabled="true"
class="cl-video-player cl-affix-waypoint"
cl-video-player
cl-fullscreen-player="coursePlayer"
cl-player-id="coursePlayer"
cl-course-id="{{ ::course._id }}"
cl-lesson-slug="{{ ::lessonSlug }}"
autoplay="{{ ::$root.routeParams.autoplay }}"
ng-controller="clCoursePlayerController"
>
<overlay>
<!-- lesson overlay -->
<div
ng-controller="clLessonController"
cl-base-url="/class/{{ ::course.slug }}/lesson/"
class="lesson-overlay"
ng-class="{
'bg-black-transparent': videoPlayer.currentVideoItem.type !== 'promo'
}"
ng-if="videoPlayer.getState() ==='ready' && !videoPlayer.isBroadcasting"
>
<div class="overlay-content">
<p ng-visible="videoPlayer.currentVideoItem.type !== 'promo' && videoPlayer.currentVideoItem.token" class="caption">playing next</p>
<h3 ng-bind="videoPlayer.currentVideoItem.title"></h3>
<div class="row">
<div class="col-xs-4 text-right">
<i
class="fa fa-step-backward"
ng-show="videoPlayer.hasPrevious"
ng-click="videoPlayer.previous();setBrowserLocation(videoPlayer.currentVideoItem);"
></i>
</div>
<div
ng-show="!videoPlayer.currentVideoItem.token"
class="col-xs-4 text-center"><i class="fa fa-lock"></i></div>
<div
ng-show="videoPlayer.currentVideoItem.token"
class="col-xs-4 text-center"
>
<icon-play-transparent
class="play-btn"
ng-click="videoPlayer.play()"
width="60px"
></icon-play-transparent>
<p ng-visible="videoPlayer.currentVideoItem.type === 'promo' && videoPlayer.currentVideoItem.token" class="caption">Watch Preview</p>
</div>
<div class="col-xs-4 text-left">
<i
class="fa fa-step-forward"
ng-show="videoPlayer.hasNext"
ng-click="videoPlayer.next();setBrowserLocation(videoPlayer.currentVideoItem);"
></i>
</div>
</div>
<div ng-show="priceData.current_price > 0 && !videoPlayer.currentVideoItem.token" class="lesson-cta font-size-s pad-left-l pad-right-l">
<div ng-show="::course.lessonCount < 1">
<p>Lessons coming soon!</p>
</div>
<div ng-show="::course.lessonCount > 1">
<p>This lesson is only available to students who have purchased the class.</p>
<p class="hidden-xs">Buy this class to watch, or watch it free with our <a href="/apps" target="_blank">iOS app</a>.</p>
</div>
</div>
<div
ng-show="priceData.current_price === 0 && !videoPlayer.currentVideoItem.token"
class="lesson-cta font-size-s pad-left-l pad-right-l"
>
<p>Get this class for free to watch.</p>
<cta-buy
class="btn btn-primary btn-sm margin-top-l"
onboarding="false"
cl-template-url="/class/cta-buy-free.html"
product-id="{{ ::course.product._id }}"
source-type="course"
></cta-buy>
</div>
<p
ng-if="autoplay === 'true'"
cl-timer
timer-duration="10"
on-done="videoPlayer.play"
start-timer="videoPlayer.state==='stopped'"
reset-timer="event==='next' || event==='previous'"
clear-timer="videoPlayer.state!=='stopped'"
refresh="data"
>Start playing in {{ $parent.timer }} seconds</p>
</div>
</div>
<!-- /lesson overlay -->
<div cl-overlay cl-template="pause-lesson"></div>
<div cl-overlay cl-template="next-lesson"></div>
<div cl-overlay cl-template="perfect-timing"></div>
<div class="hidden-phone" cl-overlay cl-template="vod-hover" cl-skip-seconds=15></div>
</overlay>
<panel>
<div
class="white"
cl-lesson-list-provider
cl-current-lesson-slug="lessonSlug"
cl-player-id="coursePlayer"
cl-base-url="/class/{{ ::course.slug }}/lesson/"
ng-include="'/templates/lesson-list/playlist.html'"
></div>
</panel>
</div>
<div class="row margin-top-m">
<div class="col-sm-6">
<cta-star
login-required
product="::course.product"
product-type="course"
template-url="/class/cta-star.html"
></cta-star>
</div>
<div class="col-sm-6 text-right">
<div
cl-course-share-provider
cl-course-share-provider-key="share"
cl-course-id="{{ ::course._id }}"
cl-segment-slug="{{ lessonSlug }}"
>
<div class="cl-course-share text-right font-weight-bold" ng-if="::clCourseShareReady">
<a class="black text-uppercase font-size-s margin-right-m" target="_blank" popup no-cl-via ng-href="{{ ::share.facebookUrl }}"><i class="fa fa-facebook"></i> Share</a>
<a class="black text-uppercase font-size-s" target="_blank" popup no-cl-via ng-href="{{ ::share.twitterUrl }}"><i class="fa fa-twitter"></i> Tweet</a>
</div>
</div>
</div>
</div>
<section ng-if="clReviews.reviews.length" class="top-reviews">
<div
ng-if="clReviews.reviews.length"
class="top-reviews margin-top-xl"
cl-reviews-provider
cl-reviews-provider-key="clTopReviews"
cl-reviews-provider-sort="sentiment.score"
cl-reviews-provider-limit="2"
cl-course-id="{{ ::course._id }}"
ng-show="clTopReviews.reviews.length"
>
<div
ng-repeat="review in clTopReviews.reviews | orderBy:'sentiment.score':true | limitTo:1"
ng-include="'/templates/reviews/featured-review.html'"
></div>
</div>
</section>
<section id="description" class="margin-top-xl">
<h3 ng-if="course.tagline">{{ ::course.tagline }}</h3>
<h3 class="text-uppercase">Class Description</h3>
<div ng-bind-html="::course.description"></div>
<div id="materials" class="margin-top-xl">
<div class="gray3 text-uppercase">Class Materials</div>
<div ng-repeat="material in materialsData.materials">
<h6 class="gray3 text-uppercase font-weight-light margin-top-l">{{ ::material.title }}</h6>
<ul
class="list-unstyled flexbox text-center"
style="flex-wrap: wrap; align-content: flex-start"
>
<li ng-repeat="media in material.media"
class="pad-m"
style="width: 25%;"
ng-click="download($event, media, material)"
ng-class="{
'clickable link': media.token,
'text-muted': !media.token
}"
>
<i class="font-size-xl fa {{ ::fileIcon(media) }}"></i>
<div class="font-size-xs margin-top-s" style="line-height:1.2">{{ ::media.title }}</div>
</li>
</ul>
</div>
</div>
</section>
<section id="lessons">
<div ng-show="clLessonList.freeLessons.length" class="margin-bottom-xl">
<h5 class="font-weight-bold">FREE LESSON</h5>
<div
ng-repeat="videoItem in clLessonList.freeLessons"
>
<span class="gray3 inline-block text-center" style="width:1.8em;">{{ ::(videoItem.index + 1) }}</span>
<span ng-show="clLessonList.videoPlayer.currentVideoItem.slug === videoItem.slug">
<i
ng-show="clLessonList.videoPlayer.state === 'ready'"
class="clickable fa fa-play-circle"
ng-click="clLessonList.videoPlayer.play()"
></i>
<i
ng-show="clLessonList.videoPlayer.state === 'paused'"
class="clickable fa fa-play-circle"
ng-click="clLessonList.videoPlayer.play()"
></i>
<i
ng-show="clLessonList.videoPlayer.state === 'playing'"
class="clickable fa fa-pause-circle"
ng-click="clLessonList.videoPlayer.pause()"
></i>
</span>
<span ng-show="clLessonList.videoPlayer.currentVideoItem.slug !== videoItem.slug">
<i
class="clickable fa fa-play-circle"
ng-click="clLessonList.videoPlayer.playVideoItem(videoItem)"
></i>
</span>
<strong>{{ ::videoItem.title }}</strong>
</div>
</div>
<h3 class="inline-block text-uppercase">Lessons</h3>
<em class="inline-block gray3" ng-if="clLessonList.totalSeconds">
({{ clLessonList.lessonList.length }} {{ 'Video' | pluralize:clLessonList.lessonList.length }},
{{ ::(clLessonList.totalSeconds * 1000) | duration:'d days, h hours, m minutes' }})
</em>
<div ng-include="'/templates/lesson-list/lesson-list.html'"></div>
</section>
<section ng-show="clReviews.reviews.length" id="reviews" class="clearfix">
<h3 class="text-uppercase inline-block">Reviews</h3>
<em class="inline-block gray3">({{ ::clReviews.reviews.length }})</em>
<div class="row margin-top-l">
<div class="col-sm-7">
<div
cl-review-stats
cl-review-stats-data="clReviews.reviews"
cl-review-stats-description="Students Recommended<br>This Class"
cl-review-stats-template="/templates/reviews/stats.html"
></div>
</div>
<div class="col-sm-5 text-center xs-margin-bottom-l xs-margin-top-m" ng-show="clReviews.getUserReview()">
<button ng-show="!clReviews.userReview"
review-modal-toggle
review-modal-toggle-source="course"
class="btn btn-dark-alpha btn-sm"
>Write a Review</button>
</div>
</div>
<div
class="margin-top-l"
ng-repeat="review in clReviews.reviews | limitTo:clReviews.pageSize:((clReviews.page - 1) * clReviews.pageSize)"
reviews-review="review"
cl-template="/templates/reviews/cl-review.html"
></div>
<div class="reviews-pagination text-right">
<pagination
ng-if="::clReviews.reviews.length"
ng-show="::(clReviews.reviews.length > clReviews.pageSize)"
total-items="::clReviews.reviews.length"
items-per-page="::clReviews.pageSize"
ng-model="clReviews.page"
max-size="7"
boundary-links="false"
next-text=">"
previous-text="<"
rotate="false"
></pagination>
</div>
</section>
<section
ng-show="clGalleryProvider.gallery.count"
id="student-work"
class="pad-bottom-xl"
>
<div class="row margin-top-l">
<div class="col-sm-7">
<h3 class="text-uppercase inline-block margin-bottom-m">Student Work</h3>
<em class="inline-block gray3" ng-if="::clGalleryProvider.gallery.count">
({{ ::clGalleryProvider.gallery.count }} photos)
</em>
<div class="gallery-sorting text-uppercase">
<small class="text-uppercase">sort by:</small>
<ul class="list-unstyled list-inline">
<li
class="clickable"
ng-class="{
'font-weight-heavy': clGalleryProvider.sort === 'created'
}"
ng-click="clGalleryProvider.setSort('created');clGalleryProvider.getPage(1)"
>Newest</li>
<li
class="clickable"
ng-class="{
'font-weight-heavy': clGalleryProvider.sort === 'like_count'
}"
ng-click="clGalleryProvider.setSort('like_count');clGalleryProvider.getPage(1)"
>Most Popular</li>
</ul>
</div>
</div>
<div class="col-sm-5 text-right">
<gallery-upload-modal
class="bar"
gallery="clGalleryProvider.gallery"
gallery-upload-modal-template-url="/class/upload.html"
course="course"
data-cta="upload"
login-required
first-item
></gallery-upload-modal>
</div>
</div>
<ul class="gallery-list margin-bottom-none list-unstyled row">
<li
class="col-xs-6 col-sm-4 col-md-3"
ng-repeat="image in clGalleryProvider.gallery.images | orderBy:'-' + clGallerySort"
cl-lazy-load
lazy-load-init-delay="clGalleryProvider.gallery !== undefined"
lazy-load-re-init="clGalleryReInit"
>
<gallery-image
ng-init="clGalleryReInit=!clGalleryReInit"
base-path="/courses/{{ ::course.slug }}"
type="course"
width="600"
height="600"
method="chop"
image="image"
gallery="clGalleryProvider.gallery"
owner="image.owner"
></gallery-image>
</li>
</ul>
<div class="student-work-pagination text-right">
<pagination
total-items="clGalleryProvider.gallery.count"
items-per-page="clGalleryProvider.perPage"
ng-model="clGalleryProvider.page"
max-size="7"
boundary-links="false"
next-text=">"
previous-text="<"
rotate="false"
ng-change="clGalleryProvider.getPage()"
></pagination>
</div>
</section>
</div>
<div class="col-sm-4 secondary-column">
<section ng-show="!(course.accessRight.owned || course.accessRight.subscribed)">
<div class="text-center">
<div class="price">
<div
class="text-muted margin-bottom-l strikethrough inline-block"
ng-if="priceData.on_sale"
ng-bind="::priceData.full_price | centsToDollars:'$':2:true"
></div>
<strong
class="h4 font-size-l block-level"
ng-if="priceData.current_price"
ng-bind="::priceData.current_price | centsToDollars:'$':2:true"
></strong>
<p class="gray4 text-uppercase font-size-xs margin-bottom-l">For On-Demand Access</p>
</div>
</div>
<cta-buy
class="btn btn-primary btn-block margin-top-l"
onboarding="false"
product-id="{{ ::course.product._id }}"
source-type="course"
></cta-buy>
<div class="text-center margin-top-l"
countdown-timer
ng-if="priceData.on_sale"
wording="Sale Ends in"
deal-start="priceData.applied_discounts[0].conditions[1].start"
deal-end="priceData.applied_discounts[0].conditions[1].end">
</div>
<cta-gift
product="course.product"
cl-cta-gift-template="/cta-gift-header.html"
></cta-gift>
</section>
<section class="what-you-get" ng-if="::(!wyg.hasAccess && wyg.hasForSaleFlag)">
<ul>
<li ng-if="::wyg.segmentsLength > 0">{{ ::wyg.segmentsLength }} Video {{ ::'lesson' | pluralize:ctrl.segments.length }} in HD</li>
<li ng-if="::wyg.hasBonusMaterial">Exclusive bonus content</li>
<li>Lifetime access, anywhere, anytime</li>
<li>Streaming and downloadable files</li>
<li>Available on desktop, mobile and tablet</li>
<li>Watch offline with iPhone &amp; iPad</li>
<li ng-if="::wyg.current_price">100% satisfaction guarantee</li>
</ul>
</section>
<section class="class-stats flexbox">
<div class="flex-grow-1 flex-basis-0 text-center" ng-if="stats.counts.students">
<strong>{{ ::stats.counts.students | friendlyNumber:1 }}</strong>
<span class="class-stats-sub">{{ ::'Student' | pluralize:stats.counts.students }}</span>
</div>
<div class="flex-grow-1 flex-basis-0 text-center" ng-if="stats.counts.recommendPercentage >= 60">
<span itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
<strong itemprop="ratingValue">{{ ::stats.counts.recommendPercentage }}%</strong>
<span class="class-stats-sub">Students&nbsp;Recommend this&nbsp;Class</span>
<meta itemprop="bestRating" content="100"/>
<meta itemprop="worstRating" content="0"/>
<span class="hide" itemprop="ratingCount">{{ ::stats.counts.reviews | friendlyNumber }}</span>
</span>
</div>
<div class="flex-grow-1 flex-basis-0 text-center" ng-if="stats.gallery.count">
<strong>{{ ::stats.gallery.count | friendlyNumber }}</strong>
<span class="class-stats-sub">{{ ::'Student Project' | pluralize:stats.gallery.count }}</span>
</div>
</section>
<section
ng-if="::(!clCourseOnair.broadcast.playingNow && (clCourseOnair.broadcast || clCourseOnair.schedule))"
ng-include="'/templates/course-onair/onair-card.html'"
></section>
<section
ng-if="::course.accepting_studio_audience && clCourseOnair.broadcast"
cl-call-to-audience
ng-include="'/templates/call-to-audience/index.html'"
></section>
<section id="instructors">
<div class="row" ng-repeat="instructor in ::course.instructors">
<div class="col-sm-12 text-center margin-bottom-xl">
<a class="color-inherit" ng-href="/instructor/{{ ::instructor.slug }}">
<img
ng-src="{{ ::instructor.profile.image | magick:{width: 800} }}"
class="img-circle"
style="width: 80px; height: 80px; object-fit: cover;"
>
<h3 class="pad-top-l text-uppercase">{{ ::instructor.profile.name }}</h3>
</a>
<div class="margin-top-l" ng-bind-html="::instructor.profile.bio.short"></div>
<a class="block-level margin-top-l text-uppercase" ng-href="/instructor/{{ ::instructor.slug }}">read full bio</a>
</div>
</div>
</section>
<section
ng-show="::(clCourseNavigation && clCourseNavigation.channel)"
class="text-center"
>
<h3 class="text-uppercase">In This Class</h3>
<a
class="btn btn-tag btn-light font-weight-heavy"
no-cl-via
ng-href="{{ ::clCourseNavigation.channel.slug | addQueryParams:{
via: 'navpath_' + clCourseNavigation.courseData.nid
} }}"
>{{ ::clCourseNavigation.channel.title }}</a>
<a
class="btn btn-tag btn-light"
no-cl-via
ng-repeat="topic in ::clCourseNavigation.topics"
ng-href="catalog/{{ ::topic.path | addQueryParams:{
via: 'navpath_' + clCourseNavigation.courseData.nid
} }}"
>{{ ::topic.name }}</a>
</div>
</section>
</div>
</div>
</div>
</div>
<style>
.main-column > section {
margin: 100px 0;
}
.secondary-column > section {
padding-bottom: 30px;
margin-bottom: 30px;
border-bottom: 1px solid #E6E6E6;
}
.course-container {
min-height: 200vh;
padding-bottom: 35vh;
}
.current-id-description #nav-description,
.current-id-lessons #nav-lessons,
.current-id-materials #nav-materials,
.current-id-student-work #nav-student-work,
.current-id-reviews #nav-reviews {
font-weight: bold;
}
.course-page-header.cl-affix h2 {
cursor: pointer;
}
.class-stats strong {
font-size: 30px;
}
.class-stats .class-stats-sub {
display: block;
margin-top: 5px;
text-transform: uppercase;
color: #a4a4a4;
font-size: 12px;
line-height: 1.4;
}
.gallery-list li {
padding-top: 0;
padding-bottom: 0;
margin-bottom: 30px;
}
.cl-video-player.cl-affix {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
z-index: 100;
}
@media (min-width: 768px) {
.course-page-header.cl-affix {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index:99;
background: white;
}
.jump-links {
display: none;
opacity: 0;
z-index: -1;
-webkit-transition: opacity .3s ease;
-moz-transition: opacity .3s ease;
transition: opacity .3s ease;
}
.course-page-header.cl-affix .jump-links {
display: block;
opacity: 1;
z-index: inherit;
}
.cl-video-player.cl-affix {
position: fixed;
top: auto;
left: auto;
right: 0;
bottom: 0;
width: 40vw;
max-width: 600px;
min-width: 400px;
z-index: 100;
}
}
</style>
<div class="hide">
<script type="text/ng-template" id="/cta-gift-header.html">
<a href class="block-level margin-top-l font-size-s text-nowrap text-center" ng-click="$event.preventDefault();startGifting()">
<i class="fa fa-gift"></i>
Give as a gift
</a>
</script>
<script type="text/ng-template" id="/class/upload.html">
<button
login-required
onboarding="false"
ng-click="onClick()"
class="btn btn-dark-alpha btn-sm"
>Upload to Gallery</button>
</script>
<script type="text/ng-template" id="/class/cta-buy-free.html">
<a ng-show="purchasable" ng-cloak ng-click="addToCart($event)">
<i class="fa fa-refresh fa-spin fa-fw margin-bottom" ng-show="showSpinner"></i>
Add this class to my library
</a>
</script>
<script type="text/ng-template" id="/class/cta-star.html">
<a class="black text-uppercase font-size-s font-weight-bold" ng-click="toggleStar($event)" class="clickable" ng-cloak>
<i class="fa" ng-class="{
'fa-star': starred,
'fa-star-o': !starred
}"></i>
<span ng-show="starred">Saved Class</span>
<span ng-show="!starred">Save Class</span>
</a>
</script>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment