course detail styling and basic lesson module styling
This commit is contained in:
committed by
Benedikt Rötsch
parent
478633c398
commit
71c0c0e95a
@@ -1 +1,65 @@
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,38 +1,45 @@
|
||||
.table-of-contents {
|
||||
& ul {
|
||||
:root {
|
||||
--toc-gap-left: calc(var(--grid-gutter) / 2)
|
||||
}
|
||||
@block table-of-contents {
|
||||
@element list {
|
||||
list-style: none;
|
||||
margin: var(--grid-gutter) 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-left: calc(var(--grid-gutter) * 2);
|
||||
padding-left: var(--toc-gap-left);
|
||||
}
|
||||
|
||||
& li {
|
||||
margin: 0 0 var(--grid-gutter);
|
||||
padding: 0;
|
||||
}
|
||||
@element item {
|
||||
margin: 0 0 calc(var(--grid-gutter) / 4);
|
||||
padding: 0;
|
||||
font-size: 0.9em;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
& a {
|
||||
display: block;
|
||||
@element link {
|
||||
display: block;
|
||||
color: var(--color-text-grey);
|
||||
|
||||
&.active {
|
||||
position: relative;
|
||||
font-weight: bold;
|
||||
&.active {
|
||||
position: relative;
|
||||
font-family: var(--font-medium);
|
||||
color: var(--color-text-default);
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
&:before {
|
||||
content: '';
|
||||
left: calc(var(--grid-gutter) * 3 * -1);
|
||||
bottom: 0;
|
||||
width: 3px;
|
||||
background: var(--color-course-active);
|
||||
}
|
||||
&:after {
|
||||
content: '👁';
|
||||
left: calc(var(--grid-gutter) * 2 * -1);
|
||||
}
|
||||
&:before,
|
||||
&:after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
&:before {
|
||||
content: '';
|
||||
left: calc(var(--toc-gap-left) * 3 * -1);
|
||||
bottom: 0;
|
||||
width: 3px;
|
||||
background: var(--color-course-active);
|
||||
}
|
||||
&:after {
|
||||
content: '👁';
|
||||
left: calc(var(--toc-gap-left) * 2 * -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,10 @@
|
||||
}
|
||||
|
||||
@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) {
|
||||
flex: 0 1 auto;
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
.lesson-module {
|
||||
margin-top: calc(var(--grid-gutter) * 3);
|
||||
margin-top: var(--grid-gutter);
|
||||
|
||||
& img {
|
||||
width: 100%;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
7
public/images/icon-duration.svg
Normal file
7
public/images/icon-duration.svg
Normal 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 |
6
public/images/icon-skill-level.svg
Normal file
6
public/images/icon-skill-level.svg
Normal 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 |
@@ -793,7 +793,7 @@ input[type="reset"]:focus,
|
||||
}
|
||||
|
||||
.layout-sidebar__sidebar-header {
|
||||
padding: 1em 22px;
|
||||
padding: 11px 22px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
@@ -810,7 +810,16 @@ input[type="reset"]:focus,
|
||||
}
|
||||
|
||||
.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) {
|
||||
@@ -1138,44 +1147,50 @@ display: flex;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.table-of-contents ul {
|
||||
list-style: none;
|
||||
margin: 22px 0;
|
||||
padding: 0;
|
||||
padding-left: 44px;
|
||||
.table-of-contents {}
|
||||
|
||||
.table-of-contents__list {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding-left: 11px;
|
||||
}
|
||||
|
||||
.table-of-contents ul li {
|
||||
margin: 0 0 22px;
|
||||
padding: 0;
|
||||
.table-of-contents__item {
|
||||
margin: 0 0 5.5px;
|
||||
padding: 0;
|
||||
font-size: 0.9em;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.table-of-contents ul a {
|
||||
display: block;
|
||||
.table-of-contents__link {
|
||||
display: block;
|
||||
color: #8091a5;
|
||||
}
|
||||
|
||||
.table-of-contents ul a.active {
|
||||
.table-of-contents__link.active {
|
||||
position: relative;
|
||||
font-weight: bold;
|
||||
font-family: 'robotomedium', Helvetica, sans-serif;
|
||||
color: #2a3039;
|
||||
}
|
||||
|
||||
.table-of-contents ul a.active:before,
|
||||
.table-of-contents ul a.active:after {
|
||||
.table-of-contents__link.active:before,
|
||||
.table-of-contents__link.active:after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.table-of-contents ul a.active:before {
|
||||
.table-of-contents__link.active:before {
|
||||
content: '';
|
||||
left: -66px;
|
||||
left: -33px;
|
||||
bottom: 0;
|
||||
width: 3px;
|
||||
background: #536171;
|
||||
}
|
||||
|
||||
.table-of-contents ul a.active:after {
|
||||
.table-of-contents__link.active:after {
|
||||
content: '👁';
|
||||
left: -44px;
|
||||
left: -22px;
|
||||
}
|
||||
|
||||
.sidebar-menu {}
|
||||
@@ -1475,6 +1490,91 @@ github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
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__wrapper {
|
||||
@@ -1646,10 +1746,31 @@ github.com style (c) Vasily Polovnyov <vast@whiteants.net>
|
||||
}
|
||||
|
||||
.lesson-module {
|
||||
margin-top: 66px
|
||||
margin-top: 22px
|
||||
}
|
||||
|
||||
.lesson-module img {
|
||||
width: 100%;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,14 @@ router.get('/:cslug/lessons/:lslug', async function (req, res, next) {
|
||||
const lessons = course.fields.lessons
|
||||
const lessonIndex = lessons.findIndex((lesson) => lesson.fields.slug === req.params.lslug)
|
||||
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
|
||||
|
||||
@@ -7,22 +7,35 @@ block content
|
||||
section.layout-sidebar__sidebar
|
||||
.layout-sidebar__sidebar-header
|
||||
h2.layout-sidebar__sidebar-title Table of contents
|
||||
.table-of-contents
|
||||
ul
|
||||
li
|
||||
a.active(href=`/courses/${course.fields.slug}`) Course overview
|
||||
each l in course.fields.lessons
|
||||
if l.fields
|
||||
li
|
||||
a(href=`/courses/${course.fields.slug}/lessons/${l.fields.slug}${queryString}`) #{l.fields.title}
|
||||
.layout-sidebar__sidebar-content
|
||||
.table-of-contents
|
||||
.table-of-contents__list
|
||||
.table-of-contents__item
|
||||
a.table-of-contents__link.active(href=`/courses/${course.fields.slug}`) Course overview
|
||||
each l in course.fields.lessons
|
||||
if l.fields
|
||||
.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
|
||||
h1= course.fields.title
|
||||
|
||||
if lesson
|
||||
+lesson(lesson)
|
||||
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
|
||||
+lesson(lesson, course, nextLesson)
|
||||
else
|
||||
p !{helpers.markdown(course.fields.description)}
|
||||
a.cta(href=`/courses/${course.fields.slug}/lessons/${course.fields.lessons[0].fields.slug}${queryString}`) Start course
|
||||
.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)
|
||||
|
||||
@@ -2,23 +2,27 @@ include _lessonModuleCodeSnippet
|
||||
include _lessonModuleCopy
|
||||
include _lessonModuleImage
|
||||
|
||||
mixin lesson(lesson)
|
||||
mixin lesson(lesson, course, nextLesson)
|
||||
.lesson
|
||||
h2.lesson__tilte #{lesson.fields.title}
|
||||
div.lesson__short-description !{helpers.markdown(lesson.fields.description)}
|
||||
if lesson.fields.image
|
||||
img.lesson__image(src=`${lesson.fields.image.fields.file.url}` alt=`${lesson.fields.image.fields.title}`)
|
||||
each module in lesson.fields.modules
|
||||
if module.sys.contentType
|
||||
case module.sys.contentType.sys.id
|
||||
when 'lessonModuleCodeSnippets'
|
||||
+lessonModuleCodeSnippet(module)
|
||||
when 'lessonModuleCopy'
|
||||
+lessonModuleCopy(module)
|
||||
when 'lessonModuleImage'
|
||||
+lessonModuleImage(module)
|
||||
else
|
||||
h2 ️️⚠️ Invalid lesson module
|
||||
p
|
||||
span Could not determine type of
|
||||
strong #{module.sys.id}
|
||||
.lesson_content
|
||||
h1.lesson__title #{lesson.fields.title}
|
||||
div.lesson__short-description !{helpers.markdown(lesson.fields.description)}
|
||||
if lesson.fields.image
|
||||
img.lesson__image(src=`${lesson.fields.image.fields.file.url}` alt=`${lesson.fields.image.fields.title}`)
|
||||
each module in lesson.fields.modules
|
||||
if module.sys.contentType
|
||||
case module.sys.contentType.sys.id
|
||||
when 'lessonModuleCodeSnippets'
|
||||
+lessonModuleCodeSnippet(module)
|
||||
when 'lessonModuleCopy'
|
||||
+lessonModuleCopy(module)
|
||||
when 'lessonModuleImage'
|
||||
+lessonModuleImage(module)
|
||||
else
|
||||
h2 ️️⚠️ Invalid lesson module
|
||||
p
|
||||
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
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
mixin lessonModuleCodeSnippet(module)
|
||||
.lesson-module.lesson-module-code
|
||||
h1.lesson-module__title #{module.fields.title}
|
||||
if module.fields.curl
|
||||
pre.lesson-module-code__curl
|
||||
code.shell= module.fields.curl
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
mixin lessonModuleCopy(module)
|
||||
.lesson-module.lesson-module-copy
|
||||
h3.lesson-module-copy__title #{module.fields.title}
|
||||
.lesson-module-copy__copy !{helpers.markdown(module.fields.copy)}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
mixin lessonModuleImage(module)
|
||||
.lesson-module.lesson-module-image
|
||||
h2.lesson-module-image__title #{module.fields.title}
|
||||
if module.fields.file && module.fields.file.url
|
||||
img.lesson-module-image__image(src=module.fields.file.url alt=module.fields.title)
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user