From e4eb6e84fbd16201dd0575928002a37bc1dace40 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Tue, 21 Dec 2021 00:30:33 +0300 Subject: [PATCH] feat: updated lesson page layout & fethcing lessons --- .../queries/course/useFetchCourseLessons.ts | 21 +++ src/pages/course/course.tsx | 4 + src/pages/lesson/lesson.tsx | 136 ++++++++++++++---- src/services/CourseService.ts | 13 +- 4 files changed, 146 insertions(+), 28 deletions(-) create mode 100644 src/hooks/queries/course/useFetchCourseLessons.ts diff --git a/src/hooks/queries/course/useFetchCourseLessons.ts b/src/hooks/queries/course/useFetchCourseLessons.ts new file mode 100644 index 0000000..644102f --- /dev/null +++ b/src/hooks/queries/course/useFetchCourseLessons.ts @@ -0,0 +1,21 @@ +import useAsync from '@educt/hooks/useAsync'; +import { ILesson } from '@educt/interfaces'; +import { CourseServiceInstance } from '@educt/services'; + +const useFetchCourseLessons = () => { + const fetch = async (id: string) => { + try { + const { data } = await CourseServiceInstance.fetchLessonsById(id); + return data; + } catch (error) { + console.error(error); + return Promise.reject(error); + } + }; + + const { execute, ...state } = useAsync, Parameters>(fetch); + + return { fetchCourseLessons: execute, ...state }; +}; + +export { useFetchCourseLessons }; diff --git a/src/pages/course/course.tsx b/src/pages/course/course.tsx index a35d6a1..2bab4df 100644 --- a/src/pages/course/course.tsx +++ b/src/pages/course/course.tsx @@ -24,6 +24,7 @@ import LoadingPage from '@educt/components/LoadingPage'; import { useHistory, useParams } from 'react-router-dom'; import { useFetchCourse } from '@educt/hooks/queries'; import { useRootStore } from '@educt/hooks/useRootStore'; +import { Helmet } from 'react-helmet'; const CoursePage: React.FC = () => { const { @@ -47,6 +48,9 @@ const CoursePage: React.FC = () => { return ( + + {course.title} + = () => { const { id } = useParams<{ id: string }>(); const { error, data: lesson, isLoading } = useFetchLesson(id); + const { fetchCourseLessons, data: lessons } = useFetchCourseLessons(); + const toast = useToast(); + const history = useHistory(); + const { + userStore: { me }, + } = useRootStore(); + const [nextLesson, setNextLesson] = useState(null); + const [prevLesson, setPrevLesson] = useState(null); + const [isPageAvailable, setIsPageAvailable] = useState(true); + + useEffect(() => { + /** + * Сheck if the user has access to the lesson + */ + const isHasAccess = me?.courses?.some(course => course.id === lesson?.course_id) ?? true; + + if (!isHasAccess) { + toast({ title: 'You are not able to view this lesson.', status: 'warning' }); + setIsPageAvailable(false); + } + + /** + * Define next and prev lessons + */ + if (lessons) { + const currentLessonIndex = lessons.findIndex(lesson => lesson.id === id); + + setNextLesson(lessons[currentLessonIndex + 1] || null); + setPrevLesson(lessons[currentLessonIndex - 1] || null); + } + }, [lessons]); + + useEffect(() => { + if (lesson !== null) { + fetchCourseLessons(lesson.course_id); + } + }, [lesson]); if (error?.response?.status === 404) { return ; } - if (!lesson || isLoading) return ; + if (!lesson || !lessons || isLoading) return ; + + if (!isPageAvailable) return ; + + const handleNextLesson = () => nextLesson && history.push(`/lesson/${nextLesson.id}`); + const handlePrevLesson = () => prevLesson && history.push(`/lesson/${prevLesson.id}`); return ( + + {lesson.title} + ~{moment.duration(lesson.duration, 'minutes').humanize()} - + - } size='sm' mr='2' /> - + {prevLesson && ( + } + size='sm' + mr='2' + /> + )} + {nextLesson && ( + + )} @@ -61,27 +135,35 @@ const LessonPage: React.FC = () => { - - {Array(50) - .fill(1) - .map((n, i) => ( - - - - - Lesson {i + 1} - + + {lessons.map((lesson, i) => ( + + + + + Lesson {i + 1} + + - Lorem ipsum dolor sit amet consectetur adipisicing elit. Vel, eaque. + {lesson.title} - - - ))} + + + + ))} - - - + Materials diff --git a/src/services/CourseService.ts b/src/services/CourseService.ts index 82cad95..beb7fd4 100644 --- a/src/services/CourseService.ts +++ b/src/services/CourseService.ts @@ -1,7 +1,7 @@ import { AxiosInstance } from 'axios'; import { ApiServiceInstance } from '.'; import * as helpers from '@educt/helpers'; -import { IApiRespose, ICourse, IUser } from '@educt/interfaces'; +import { IApiRespose, ICourse, ILesson, IUser } from '@educt/interfaces'; import { CourseStatusEnum } from '@educt/enums'; import { CreateCourseParamsType, FetchCoursesParams, UpdateCourseParamsType } from '@educt/types'; @@ -40,6 +40,17 @@ class CourseService { return result.data; } + /** + * Fetch lessons by course id + * + * @param id Course id + * @returns Array of lessons + */ + public async fetchLessonsById(id: string): Promise>> { + const result = await this.api.get(`/v1/courses/${id}/lessons`); + return result.data; + } + /** * Update status of course by id *