diff --git a/judgels-client/src/routes/courses/courses/single/CourseChaptersSidebar/CourseChaptersSidebar.jsx b/judgels-client/src/routes/courses/courses/single/CourseChaptersSidebar/CourseChaptersSidebar.jsx
index 8c15653a3..4ceee4492 100644
--- a/judgels-client/src/routes/courses/courses/single/CourseChaptersSidebar/CourseChaptersSidebar.jsx
+++ b/judgels-client/src/routes/courses/courses/single/CourseChaptersSidebar/CourseChaptersSidebar.jsx
@@ -1,3 +1,5 @@
+import { Popover, Position } from '@blueprintjs/core';
+import { ChevronDown, ChevronRight, Menu } from '@blueprintjs/icons';
import classNames from 'classnames';
import { Component } from 'react';
import { connect } from 'react-redux';
@@ -15,6 +17,7 @@ import './CourseChaptersSidebar.scss';
class CourseChaptersSidebar extends Component {
state = {
response: undefined,
+ isResponsivePopoverOpen: false,
};
async componentDidMount() {
@@ -22,19 +25,43 @@ class CourseChaptersSidebar extends Component {
this.setState({ response });
}
+ componentDidUpdate() {}
+
render() {
return (
-
- {this.renderChapters()}
-
+ <>
+
+ {this.renderChapters({ showName: !this.isInProblemPath() })}
+
+
+
+
+
+
+ Chapters Menu
+
+
+
+ >
);
}
- renderChapters = () => {
+ renderChapters = ({ showName }) => {
const { course, match, onPutCourseChapter } = this.props;
const { response } = this.state;
if (!course || !response) {
@@ -49,18 +76,22 @@ class CourseChaptersSidebar extends Component {
'course-chapters-sidebar__item--selected': this.isInChapterPath(courseChapter.alias),
})}
to={`${match.url}/chapters/${courseChapter.alias}`}
- onClick={() =>
+ onClick={() => {
onPutCourseChapter({
jid: courseChapter.chapterJid,
name: chaptersMap[courseChapter.chapterJid].name,
alias: courseChapter.alias,
courseSlug: course.slug,
- })
- }
+ });
+
+ if (this.state.isResponsivePopoverOpen) {
+ this.onResponsiveItemClick();
+ }
+ }}
>
- {courseChapter.alias} {!this.isInProblemPath() && <>. {chaptersMap[courseChapter.chapterJid].name}>}
-
+ {courseChapter.alias} {showName && <>. {chaptersMap[courseChapter.chapterJid].name}>}
+
{this.renderProgress(chapterProgressesMap[courseChapter.chapterJid])}
{!this.isInProblemPath() && this.renderProgressBar(chapterProgressesMap[courseChapter.chapterJid])}
@@ -68,6 +99,10 @@ class CourseChaptersSidebar extends Component {
));
};
+ isInChaptersPath = () => {
+ return this.props.location.pathname.includes('/chapters/');
+ };
+
isInChapterPath = chapterAlias => {
return (this.props.location.pathname + '/')
.replace('//', '/')
@@ -97,6 +132,16 @@ class CourseChaptersSidebar extends Component {
}
return ;
};
+
+ onResponsivePopoverInteraction = state => {
+ this.setState({ isResponsivePopoverOpen: state });
+ };
+
+ onResponsiveItemClick = () => {
+ setTimeout(() => {
+ this.setState({ isResponsivePopoverOpen: false });
+ }, 200);
+ };
}
const mapStateToProps = state => ({
diff --git a/judgels-client/src/routes/courses/courses/single/CourseChaptersSidebar/CourseChaptersSidebar.scss b/judgels-client/src/routes/courses/courses/single/CourseChaptersSidebar/CourseChaptersSidebar.scss
index e494c0281..68d9e1b2f 100644
--- a/judgels-client/src/routes/courses/courses/single/CourseChaptersSidebar/CourseChaptersSidebar.scss
+++ b/judgels-client/src/routes/courses/courses/single/CourseChaptersSidebar/CourseChaptersSidebar.scss
@@ -8,8 +8,7 @@
font-family: $accent-font;
background-color: inherit !important;
box-shadow: none !important;
-
- transition: all 0.2s ease-in-out;
+ transition: flex-grow 0.2s ease-in-out;
hr {
margin: 0 !important;
@@ -19,6 +18,10 @@
flex-grow: unset;
margin-right: 10px;
}
+
+ &__responsive {
+ display: none;
+ }
}
a.course-chapters-sidebar__item {
@@ -73,7 +76,32 @@ a.course-chapters-sidebar__item {
@media only screen and (max-width: 750px) {
.course-chapters-sidebar {
- flex-grow: unset;
- margin-right: 10px;
+ &__full {
+ display: none;
+ }
+
+ &__responsive {
+ display: block;
+ flex: none;
+ width: 100%;
+ max-width: unset;
+ margin-top: 0;
+ margin-bottom: 10px;
+ }
+ }
+}
+
+@media only screen and (max-width: 1024px) {
+ .course-chapters-sidebar--wide.course-chapters-sidebar__full {
+ display: block;
+ flex: none;
+ order: 2;
+ width: 100%;
+ max-width: unset;
+ margin-top: 20px;
+ }
+
+ .course-chapters-sidebar--wide.course-chapters-sidebar__responsive {
+ display: none;
}
}
diff --git a/judgels-client/src/routes/courses/courses/single/SingleCourseRoutes.scss b/judgels-client/src/routes/courses/courses/single/SingleCourseRoutes.scss
index f2835bbd4..b791714f8 100644
--- a/judgels-client/src/routes/courses/courses/single/SingleCourseRoutes.scss
+++ b/judgels-client/src/routes/courses/courses/single/SingleCourseRoutes.scss
@@ -1,4 +1,5 @@
.single-course-routes {
display: flex;
+ flex-wrap: wrap;
width: 100%;
}
diff --git a/judgels-client/src/routes/courses/courses/single/chapters/single/problems/single/ChapterProblemPage/ChapterProblemPage.jsx b/judgels-client/src/routes/courses/courses/single/chapters/single/problems/single/ChapterProblemPage/ChapterProblemPage.jsx
index 00499944a..4f286029c 100644
--- a/judgels-client/src/routes/courses/courses/single/chapters/single/problems/single/ChapterProblemPage/ChapterProblemPage.jsx
+++ b/judgels-client/src/routes/courses/courses/single/chapters/single/problems/single/ChapterProblemPage/ChapterProblemPage.jsx
@@ -100,6 +100,9 @@ export class ChapterProblemPage extends Component {
}
const { progress } = response;
+ if (!progress) {
+ return null;
+ }
return ;
};
diff --git a/judgels-client/src/routes/courses/courses/single/chapters/single/resources/ChapterProblemCard/ChapterProblemCard.scss b/judgels-client/src/routes/courses/courses/single/chapters/single/resources/ChapterProblemCard/ChapterProblemCard.scss
index b884e3fa5..f999bf1c1 100644
--- a/judgels-client/src/routes/courses/courses/single/chapters/single/resources/ChapterProblemCard/ChapterProblemCard.scss
+++ b/judgels-client/src/routes/courses/courses/single/chapters/single/resources/ChapterProblemCard/ChapterProblemCard.scss
@@ -9,15 +9,19 @@
.chapter-problem-card__heading {
display: flex;
+ gap: 10px;
}
h4 {
- flex-grow: 1;
- margin-left: 10px;
+ flex: 1 1;
margin-bottom: 0;
}
.bp4-icon {
padding-top: 1px;
}
+
+ .bp4-tag {
+ height: 21px;
+ }
}