course detail styling and basic lesson module styling

This commit is contained in:
Benedikt Rötsch
2017-10-02 17:33:40 +02:00
committed by Benedikt Rötsch
parent 478633c398
commit 71c0c0e95a
13 changed files with 335 additions and 92 deletions

View File

@@ -1 +1,65 @@
@import './card'; @import './card';
@block course {
display: flex;
flex-direction: column;
justify-content: space-between;
@element title {
margin-bottom: calc(var(--grid-gutter));
}
@element overview {
font-family: var(--font-medium);
@media (--breakpoint-desktop) {
float: right;
border-radius: var(--border-radius);
box-shadow: var(--card-box-shadow);
width: 228px;
margin: 0 0 var(--grid-gutter) var(--grid-gutter);
}
}
@element overview-title {
border-bottom: 1px solid var(--color-sidebar-seperator);
padding: calc(var(--grid-gutter) / 2) 0;
margin: 0;
line-height: 1.31;
font-weight: normal;
text-transform: uppercase;
text-align: center;
}
@element overview-item {
display: flex;
align-items: center;
padding: calc(var(--grid-gutter) / 2);
border-bottom: 1px solid var(--color-sidebar-seperator);
line-height: 1.54;
font-size: 0.8em;
}
@element overview-icon {
flex: 0 0 auto;
width: 24px;
height: 24px;
padding-right: calc(var(--grid-gutter) / 2);
}
@element overview-value {
flex: 1 0 auto;
}
@element overview-cta-wrapper {
padding: calc(var(--grid-gutter) / 2) 0;
text-align: center;
}
@element overview-cta {
margin: 0;
}
@element cta {
margin-bottom: 0;
}
}

View File

@@ -1,38 +1,45 @@
.table-of-contents { :root {
& ul { --toc-gap-left: calc(var(--grid-gutter) / 2)
}
@block table-of-contents {
@element list {
list-style: none; list-style: none;
margin: var(--grid-gutter) 0; margin: 0;
padding: 0; padding: 0;
padding-left: calc(var(--grid-gutter) * 2); padding-left: var(--toc-gap-left);
}
& li { @element item {
margin: 0 0 var(--grid-gutter); margin: 0 0 calc(var(--grid-gutter) / 4);
padding: 0; padding: 0;
} font-size: 0.9em;
line-height: 1.8;
}
& a { @element link {
display: block; display: block;
color: var(--color-text-grey);
&.active { &.active {
position: relative; position: relative;
font-weight: bold; font-family: var(--font-medium);
color: var(--color-text-default);
&:before, &:before,
&:after { &:after {
position: absolute; position: absolute;
top: 0; top: 0;
} }
&:before { &:before {
content: ''; content: '';
left: calc(var(--grid-gutter) * 3 * -1); left: calc(var(--toc-gap-left) * 3 * -1);
bottom: 0; bottom: 0;
width: 3px; width: 3px;
background: var(--color-course-active); background: var(--color-course-active);
} }
&:after { &:after {
content: '👁'; content: '👁';
left: calc(var(--grid-gutter) * 2 * -1); left: calc(var(--toc-gap-left) * 2 * -1);
}
} }
} }
} }

View File

@@ -18,7 +18,7 @@
} }
@element sidebar-header { @element sidebar-header {
padding: 1em var(--grid-gutter); padding: calc(var(--grid-gutter) / 2) var(--grid-gutter);
border-bottom: 1px solid var(--color-sidebar-seperator); border-bottom: 1px solid var(--color-sidebar-seperator);
} }
@@ -35,7 +35,10 @@
} }
@element content { @element content {
padding: var(--grid-gutter) 0; display: flex;
flex-direction: column;
align-self: stretch;
padding-top: calc(var(--grid-gutter) / 2);
@media (--breakpoint-desktop) { @media (--breakpoint-desktop) {
flex: 0 1 auto; flex: 0 1 auto;

View File

@@ -1,8 +1,22 @@
.lesson-module { .lesson-module {
margin-top: calc(var(--grid-gutter) * 3); margin-top: var(--grid-gutter);
& img { & img {
width: 100%; width: 100%;
height: auto; height: auto;
} }
} }
@block lesson {
display: flex;
flex-direction: column;
justify-content: space-between;
@element title {
margin-bottom: calc(var(--grid-gutter));
}
@element cta {
margin-bottom: 0;
}
}

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path fill="#A9B9C0" fill-rule="nonzero" d="M12 2C6.46 2 2 6.48 2 12s4.47 10 10 10c5.52 0 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/>
<path d="M0 0h24v24H0z"/>
<path fill="#A9B9C0" fill-rule="nonzero" d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 418 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<g fill="none" fill-rule="evenodd">
<path fill="#A9B9C0" fill-rule="nonzero" d="M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z"/>
<path d="M0 0h24v24H0z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 316 B

View File

@@ -793,7 +793,7 @@ input[type="reset"]:focus,
} }
.layout-sidebar__sidebar-header { .layout-sidebar__sidebar-header {
padding: 1em 22px; padding: 11px 22px;
border-bottom: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee;
} }
@@ -810,7 +810,16 @@ input[type="reset"]:focus,
} }
.layout-sidebar__content { .layout-sidebar__content {
padding: 22px 0; display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-ms-flex-item-align: stretch;
align-self: stretch;
padding-top: 11px;
} }
@media (min-width: 700px) { @media (min-width: 700px) {
@@ -1138,44 +1147,50 @@ display: flex;
height: auto; height: auto;
} }
.table-of-contents ul { .table-of-contents {}
list-style: none;
margin: 22px 0; .table-of-contents__list {
padding: 0; list-style: none;
padding-left: 44px; margin: 0;
padding: 0;
padding-left: 11px;
} }
.table-of-contents ul li { .table-of-contents__item {
margin: 0 0 22px; margin: 0 0 5.5px;
padding: 0; padding: 0;
font-size: 0.9em;
line-height: 1.8;
} }
.table-of-contents ul a { .table-of-contents__link {
display: block; display: block;
color: #8091a5;
} }
.table-of-contents ul a.active { .table-of-contents__link.active {
position: relative; position: relative;
font-weight: bold; font-family: 'robotomedium', Helvetica, sans-serif;
color: #2a3039;
} }
.table-of-contents ul a.active:before, .table-of-contents__link.active:before,
.table-of-contents ul a.active:after { .table-of-contents__link.active:after {
position: absolute; position: absolute;
top: 0; top: 0;
} }
.table-of-contents ul a.active:before { .table-of-contents__link.active:before {
content: ''; content: '';
left: -66px; left: -33px;
bottom: 0; bottom: 0;
width: 3px; width: 3px;
background: #536171; background: #536171;
} }
.table-of-contents ul a.active:after { .table-of-contents__link.active:after {
content: '👁'; content: '👁';
left: -44px; left: -22px;
} }
.sidebar-menu {} .sidebar-menu {}
@@ -1475,6 +1490,91 @@ github.com style (c) Vasily Polovnyov <vast@whiteants.net>
letter-spacing: 2px; letter-spacing: 2px;
} }
.course {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
}
.course__title {
margin-bottom: 22px;
}
.course__overview {
font-family: 'robotomedium', Helvetica, sans-serif;
}
@media (min-width: 700px) {
.course__overview {
float: right;
border-radius: 4px;
-webkit-box-shadow: 0 1px 3px 1px rgba(0, 0, 0, .1);
box-shadow: 0 1px 3px 1px rgba(0, 0, 0, .1);
width: 228px;
margin: 0 0 22px 22px;
}
}
.course__overview-title {
border-bottom: 1px solid #eeeeee;
padding: 11px 0;
margin: 0;
line-height: 1.31;
font-weight: normal;
text-transform: uppercase;
text-align: center;
}
.course__overview-item {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
padding: 11px;
border-bottom: 1px solid #eeeeee;
line-height: 1.54;
font-size: 0.8em;
}
.course__overview-icon {
-webkit-box-flex: 0;
-ms-flex: 0 0 auto;
flex: 0 0 auto;
width: 24px;
height: 24px;
padding-right: 11px;
}
.course__overview-value {
-webkit-box-flex: 1;
-ms-flex: 1 0 auto;
flex: 1 0 auto;
}
.course__overview-cta-wrapper {
padding: 11px 0;
text-align: center;
}
.course__overview-cta {
margin: 0;
}
.course__cta {
margin-bottom: 0;
}
.module-hero-image {} .module-hero-image {}
.module-hero-image__wrapper { .module-hero-image__wrapper {
@@ -1646,10 +1746,31 @@ github.com style (c) Vasily Polovnyov <vast@whiteants.net>
} }
.lesson-module { .lesson-module {
margin-top: 66px margin-top: 22px
} }
.lesson-module img { .lesson-module img {
width: 100%; width: 100%;
height: auto; height: auto;
} }
.lesson {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-ms-flex-direction: column;
flex-direction: column;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
}
.lesson__title {
margin-bottom: 22px;
}
.lesson__cta {
margin-bottom: 0;
}

View File

@@ -48,7 +48,14 @@ router.get('/:cslug/lessons/:lslug', async function (req, res, next) {
const lessons = course.fields.lessons const lessons = course.fields.lessons
const lessonIndex = lessons.findIndex((lesson) => lesson.fields.slug === req.params.lslug) const lessonIndex = lessons.findIndex((lesson) => lesson.fields.slug === req.params.lslug)
const lesson = lessons[lessonIndex] const lesson = lessons[lessonIndex]
res.render('course', {title: `${course.fields.title} | ${lesson.fields.title}`, course, lesson, lessons, lessonIndex}) const nextLesson = lessons[lessonIndex + 1] || null
res.render('course', {
title: `${course.fields.title} | ${lesson.fields.title}`,
course,
lesson,
lessons,
nextLesson
})
}) })
module.exports = router module.exports = router

View File

@@ -7,22 +7,35 @@ block content
section.layout-sidebar__sidebar section.layout-sidebar__sidebar
.layout-sidebar__sidebar-header .layout-sidebar__sidebar-header
h2.layout-sidebar__sidebar-title Table of contents h2.layout-sidebar__sidebar-title Table of contents
.table-of-contents .layout-sidebar__sidebar-content
ul .table-of-contents
li .table-of-contents__list
a.active(href=`/courses/${course.fields.slug}`) Course overview .table-of-contents__item
each l in course.fields.lessons a.table-of-contents__link.active(href=`/courses/${course.fields.slug}`) Course overview
if l.fields each l in course.fields.lessons
li if l.fields
a(href=`/courses/${course.fields.slug}/lessons/${l.fields.slug}${queryString}`) #{l.fields.title} .table-of-contents__item
a.table-of-contents__link(href=`/courses/${course.fields.slug}/lessons/${l.fields.slug}${queryString}`) #{l.fields.title}
section.layout-sidebar__content section.layout-sidebar__content
h1= course.fields.title
if lesson if lesson
+lesson(lesson) +lesson(lesson, course, nextLesson)
if lessonIndex + 1< lessons.length
if lessons[lessonIndex + 1].fields
a.cta(href=`/courses/${course.fields.slug}/lessons/${lessons[lessonIndex + 1].fields.slug}${queryString}`) View next lesson
else else
p !{helpers.markdown(course.fields.description)} .course
a.cta(href=`/courses/${course.fields.slug}/lessons/${course.fields.lessons[0].fields.slug}${queryString}`) Start course .course__content
h1.course__title= course.fields.title
.course__overview
h3.course__overview-title Overview
if course.fields.duration
.course__overview-item
img.course__overview-icon(src='/images/icon-duration.svg')
.course__overview-value Duration: #{course.fields.duration}min
if course.fields.skillLevel
.course__overview-item
img.course__overview-icon(src='/images/icon-skill-level.svg')
.course__overview-value Skill level: #{course.fields.skillLevel}
.course__overview-cta-wrapper
a.course__overview-cta.cta(href=`/courses/${course.fields.slug}/lessons/${course.fields.lessons[0].fields.slug}${queryString}`) Start course
.course__description !{helpers.markdown(course.fields.description)}
.course__footer
a.course__cta.cta(href=`/courses/${course.fields.slug}/lessons/${course.fields.lessons[0].fields.slug}${queryString}`) Start course
//pre= helpers.dump(course)

View File

@@ -2,23 +2,27 @@ include _lessonModuleCodeSnippet
include _lessonModuleCopy include _lessonModuleCopy
include _lessonModuleImage include _lessonModuleImage
mixin lesson(lesson) mixin lesson(lesson, course, nextLesson)
.lesson .lesson
h2.lesson__tilte #{lesson.fields.title} .lesson_content
div.lesson__short-description !{helpers.markdown(lesson.fields.description)} h1.lesson__title #{lesson.fields.title}
if lesson.fields.image div.lesson__short-description !{helpers.markdown(lesson.fields.description)}
img.lesson__image(src=`${lesson.fields.image.fields.file.url}` alt=`${lesson.fields.image.fields.title}`) if lesson.fields.image
each module in lesson.fields.modules img.lesson__image(src=`${lesson.fields.image.fields.file.url}` alt=`${lesson.fields.image.fields.title}`)
if module.sys.contentType each module in lesson.fields.modules
case module.sys.contentType.sys.id if module.sys.contentType
when 'lessonModuleCodeSnippets' case module.sys.contentType.sys.id
+lessonModuleCodeSnippet(module) when 'lessonModuleCodeSnippets'
when 'lessonModuleCopy' +lessonModuleCodeSnippet(module)
+lessonModuleCopy(module) when 'lessonModuleCopy'
when 'lessonModuleImage' +lessonModuleCopy(module)
+lessonModuleImage(module) when 'lessonModuleImage'
else +lessonModuleImage(module)
h2 ️️⚠️ Invalid lesson module else
p h2 ️️⚠️ Invalid lesson module
span Could not determine type of p
strong #{module.sys.id} span Could not determine type of
strong #{module.sys.id}
.lesson_footer
if nextLesson
a.lesson__cta.cta(href=`/courses/${course.fields.slug}/lessons/${nextLesson.fields.slug}${queryString}`) View next lesson

View File

@@ -1,6 +1,5 @@
mixin lessonModuleCodeSnippet(module) mixin lessonModuleCodeSnippet(module)
.lesson-module.lesson-module-code .lesson-module.lesson-module-code
h1.lesson-module__title #{module.fields.title}
if module.fields.curl if module.fields.curl
pre.lesson-module-code__curl pre.lesson-module-code__curl
code.shell= module.fields.curl code.shell= module.fields.curl

View File

@@ -1,4 +1,3 @@
mixin lessonModuleCopy(module) mixin lessonModuleCopy(module)
.lesson-module.lesson-module-copy .lesson-module.lesson-module-copy
h3.lesson-module-copy__title #{module.fields.title}
.lesson-module-copy__copy !{helpers.markdown(module.fields.copy)} .lesson-module-copy__copy !{helpers.markdown(module.fields.copy)}

View File

@@ -1,6 +1,5 @@
mixin lessonModuleImage(module) mixin lessonModuleImage(module)
.lesson-module.lesson-module-image .lesson-module.lesson-module-image
h2.lesson-module-image__title #{module.fields.title}
if module.fields.file && module.fields.file.url if module.fields.file && module.fields.file.url
img.lesson-module-image__image(src=module.fields.file.url alt=module.fields.title) img.lesson-module-image__image(src=module.fields.file.url alt=module.fields.title)
else else