Skip to content

Commit 0ae2b8c

Browse files
committed
merge pull from staging
2 parents f2ea3a2 + 3e2c925 commit 0ae2b8c

File tree

10 files changed

+133
-69
lines changed

10 files changed

+133
-69
lines changed

package-lock.json

Lines changed: 55 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"@fortawesome/react-fontawesome": "^0.1.4",
99
"@glidejs/glide": "^3.3.0",
1010
"axios": "^0.19.0",
11+
"dotenv": "^8.1.0",
1112
"isotope-layout": "^3.0.6",
1213
"node-sass": "^4.12.0",
1314
"prop-types": "^15.7.2",
@@ -16,7 +17,8 @@
1617
"react-dom": "^16.8.6",
1718
"react-router-dom": "^5.0.1",
1819
"react-scripts": "3.0.1",
19-
"react-vertical-timeline-component": "^2.4.0"
20+
"react-vertical-timeline-component": "^2.4.0",
21+
"react-youtube": "^7.9.0"
2022
},
2123
"scripts": {
2224
"start": "react-scripts start",

src/App.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,15 @@ function App() {
5353
const courseObj = courses.find(
5454
course => course.slug === props.match.params.course,
5555
);
56-
if (!courseObj) return <ErrorPage />;
56+
const order = parseInt(props.match.params.order, 10);
57+
if (!courseObj || order >= courseObj.lessons.length) return <ErrorPage />;
5758
return (
5859
<LessonPage
5960
{...props}
61+
course_title={courseObj.title}
6062
lessons={courseObj.lessons}
61-
curr_lesson_num={parseInt(props.match.params.order, 10)}
62-
base_path={props.match.params.course}
63+
curr_lesson_num={order}
64+
base_path={courseObj.slug}
6365
/>
6466
);
6567
}}

src/DUMMY_DATA.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
// channel page: https://www.youtube.com/channel/UCqJ-Xo29CKyLTjn6z2XwYAw
2+
// api call: https://www.googleapis.com/youtube/v3/videos?part=[PART TYPE]&id=[VIDEO ID]key=[API KEY]
3+
// part type = snippet gets: publishedAt, channelId, title, description, thumbnails, channelTitle, tags, categoryId
4+
// part type = contentDetails gets: duration, dimension, definition, caption, licensedContent, projection
5+
16
const example_session = {
27
order: 0,
38
src: 'https://www.youtube.com/embed/MFCzwiqlnCE',
@@ -65,7 +70,7 @@ const adventure_begins = {
6570
const make_rules = {
6671
order: 0,
6772
src: 'https://www.youtube.com/embed/g5lrIDoEPOw',
68-
length: 3603,
73+
length: 'PT3H9M7S',
6974
title: 'You Make the Rules!',
7075
description: `The published D&D sourcebooks have their fair share of suggested rules... but as the DM, you have the special privilege to bend those to your will! Learn in this video how to set house rules for your campaign and your world, and begin collecting these guidelines in a Player's Guide for your party.`,
7176
yt_chan_name: 'Nerdarchy',

src/components/lesson/Lesson.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3+
// import YouTube from 'react-youtube';
4+
// https://www.npmjs.com/package/react-youtube
35
import { LessonVideo, LessonInfo } from '..';
46
import '../../css/lesson/Lesson.scss';
57

src/components/lesson/LessonLink.js

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
import React from 'react';
2-
import { Link } from 'react-router-dom'
2+
import { Link } from 'react-router-dom';
33
import PropTypes from 'prop-types';
44
import '../../css/lesson/LessonLink.scss';
55

6-
const formatTime = seconds => {
7-
const h = Math.floor(seconds / 3600);
8-
const m = Math.floor((seconds % 3600) / 60);
9-
const s = Math.floor((seconds % 3600) % 60);
6+
const formatTime = time => {
7+
let h;
8+
let m;
9+
let s;
10+
11+
if (typeof time === 'number') {
12+
h = Math.floor(time / 3600);
13+
m = Math.floor((time % 3600) / 60);
14+
s = Math.floor((time % 3600) % 60);
15+
} else {
16+
// this is the date format the YouTube API uses: "PT3H9M7S"
17+
const timeStr = time.slice(2, time.length - 1);
18+
let msStr;
19+
// TODO: this breaks if there are no hours
20+
[h, msStr] = timeStr.split('H');
21+
[m, s] = msStr.split('M');
22+
}
1023

1124
const hStr = h > 0 ? `${h}:` : '';
1225
const mStr = `${m < 10 ? '0' : ''}${m}:`;
@@ -15,22 +28,15 @@ const formatTime = seconds => {
1528
return `${hStr}${mStr}${sStr}`;
1629
};
1730

18-
const LessonLink = ({ title, length, order, active, base_path }) => (
19-
<div className="lesson-link">
20-
{/* TODO: this can probably be consolidated */}
21-
{active ? (
22-
<div className="active-video">
23-
<p>{title}
24-
<span className="video-length">{formatTime(length)}</span>
25-
</p>
26-
</div>
27-
) : (
28-
<div className="link">
29-
<Link to={`/courses/${base_path}/${order}`}>{title}<span className="video-length">{formatTime(length)}</span></Link>
30-
</div>
31-
)}
32-
</div>
33-
);
31+
const LessonLink = ({ title, length, order, active, base_path }) => {
32+
const TagType = active ? 'p' : Link;
33+
return (
34+
<TagType to={`/courses/${base_path}/${order}`} className="lesson-link">
35+
{title}
36+
<span className="video-length">{formatTime(length)}</span>
37+
</TagType>
38+
);
39+
};
3440

3541
LessonLink.propTypes = {
3642
title: PropTypes.string.isRequired,

src/components/lesson/LessonsPane.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ import PropTypes from 'prop-types';
33
import { LessonLink } from '..';
44
import '../../css/lesson/LessonsPane.scss';
55

6-
const LessonsPane = ({ lessons, curr_lesson_num, base_path }) => (
6+
// TODO: add next and previous course buttons
7+
const LessonsPane = ({ course_title, lessons, curr_lesson_num, base_path }) => (
78
<div className="lessons-pane">
8-
<h2>Lessons</h2>
9-
{lessons.map(({ order, title, src, length }) => (
9+
<h2>{course_title}</h2>
10+
{lessons.map(({ order, title, length }) => (
1011
<LessonLink
12+
key={order}
1113
order={order}
1214
title={title}
13-
src={src}
1415
length={length}
15-
key={order}
1616
base_path={base_path}
1717
active={order === curr_lesson_num}
1818
/>
@@ -21,12 +21,12 @@ const LessonsPane = ({ lessons, curr_lesson_num, base_path }) => (
2121
);
2222

2323
LessonsPane.propTypes = {
24+
course_title: PropTypes.string.isRequired,
2425
curr_lesson_num: PropTypes.number.isRequired,
2526
lessons: PropTypes.arrayOf(
2627
PropTypes.shape({
2728
order: PropTypes.number.isRequired,
2829
title: PropTypes.string.isRequired,
29-
src: PropTypes.string.isRequired,
3030
length: PropTypes.number.isRequired,
3131
}),
3232
).isRequired,

src/components/pages/LessonPage.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Lesson, LessonsPane } from '..';
44
import '../../css/pages/LessonPage.scss';
55

66
function LessonPage(props) {
7-
const { curr_lesson_num, lessons, base_path } = props;
7+
const { curr_lesson_num, lessons, base_path, course_title } = props;
88
// const { title, src, description, id } = lessons.find(elem => elem.id === activeId);
99
// const { title, src, description, order } = lessons[curr_lesson_num];
1010
const lesson = lessons[curr_lesson_num];
@@ -13,12 +13,18 @@ function LessonPage(props) {
1313
return (
1414
<div className="lesson-page">
1515
<Lesson lesson={lesson} course_size={total} base_path={base_path}/>
16-
<LessonsPane lessons={lessons} curr_lesson_num={curr_lesson_num} base_path={base_path} />
16+
<LessonsPane
17+
course_title={course_title}
18+
lessons={lessons}
19+
curr_lesson_num={curr_lesson_num}
20+
base_path={base_path}
21+
/>
1722
</div>
1823
);
1924
}
2025

2126
LessonPage.propTypes = {
27+
course_title: PropTypes.string.isRequired,
2228
curr_lesson_num: PropTypes.number.isRequired,
2329
lessons: PropTypes.arrayOf(
2430
PropTypes.shape({

src/css/lesson/LessonLink.scss

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,36 @@
1-
21
@import '../VARIABLES.scss';
32

43
.lesson-link {
54
border: dotted var(--blue) 0.5px;
6-
}
7-
8-
.lesson-link .link {
9-
display: flex;
10-
justify-content: space-between;
11-
// padding: 1rem;
12-
cursor: pointer;
135
font-family: var(--fontfamily-alt);
6+
color: var(--black);
147

15-
p {
16-
color: var(--black);
8+
.video-length {
9+
float: right;
1710
}
18-
1911
}
2012

21-
.lesson-link .link a {
22-
color: var(--black);
23-
text-decoration: none;
13+
a.lesson-link,
14+
p.lesson-link {
15+
display: flex;
16+
justify-content: space-between;
2417
padding: 1rem;
2518
width: 100%;
2619
}
2720

28-
.lesson-link .link:hover a{
29-
background-color: var(--greyblue);
30-
color: var(--white);
31-
border: none;
32-
}
33-
34-
.lesson-link .video-length {
35-
float: right;
21+
a.lesson-link {
22+
cursor: pointer;
23+
color: var(--black);
24+
text-decoration: none;
3625
}
3726

38-
.lesson-link .active-video {
39-
display: flex;
40-
justify-content: space-between;
41-
padding: 1rem;
27+
p.lesson-link {
28+
color: var(--white);
4229
background-color: var(--brown);
43-
font-family: var(--fontfamily-alt);
4430
}
4531

46-
47-
.lesson-link .active-video p{
48-
width: 100%;
49-
}
32+
a.lesson-link:hover {
33+
background-color: var(--greyblue);
34+
color: var(--white);
35+
border: none;
36+
}

src/css/lesson/LessonsPane.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
background-color: var(--white);
55
min-width: 30%;
66
border: solid var(--blue) 2px;
7+
flex: 1 0 30%;
78
}
89

910
.lessons-pane h2 {
1011
background-color: var(--navy);
1112
padding: 1rem;
1213
font-weight: bold;
1314
color: var(--white);
14-
}
15+
font-size: calc(16px + 1vw);
16+
}

0 commit comments

Comments
 (0)