diff --git a/src/hooks/queries/lesson/useFetchLessonProgress.ts b/src/hooks/queries/lesson/useFetchLessonProgress.ts new file mode 100644 index 0000000..da9facf --- /dev/null +++ b/src/hooks/queries/lesson/useFetchLessonProgress.ts @@ -0,0 +1,22 @@ +import { LessonServiceInstance } from '@educt/services'; +import type { LessonProgress } from '@educt/types'; +import useAsync from '../../useAsync'; + +const useFetchLessonProgress = () => { + const fetch = async (id: string) => { + try { + const result = await LessonServiceInstance.fetchProgress(id); + return result.data; + } catch (error) { + console.error(error); + + return Promise.reject(error); + } + }; + + const { execute, ...state } = useAsync>(fetch); + + return { fetchLessonProgress: execute, ...state }; +}; + +export { useFetchLessonProgress }; diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts index 53e43fa..f4a1633 100644 --- a/src/interfaces/index.ts +++ b/src/interfaces/index.ts @@ -1,5 +1,5 @@ import type { RouteComponentProps } from 'react-router-dom'; -import { AttachmentFileType, ColorType, LinkType } from '@educt/types'; +import { AttachmentFileType, ColorType, LessonProgress, LinkType } from '@educt/types'; import { CourseStatusEnum, UserRoleEnum } from '../enums'; export interface IAppConfig { @@ -27,7 +27,7 @@ export interface ICourse { status: CourseStatusEnum; teacher: Pick; category: ICategory; - lessons: Omit[]; + lessons: Omit[]; students: IUser[]; color: ColorType | null; students_count: string; @@ -46,6 +46,7 @@ export interface ILesson { color?: ColorType | undefined | null; materials_count?: string | undefined; materials: Array; + progress: LessonProgress; content: ILessonContent; created_at: string; updated_at: string; diff --git a/src/pages/lesson/lesson.tsx b/src/pages/lesson/lesson.tsx index 9c3349c..f24dcc2 100644 --- a/src/pages/lesson/lesson.tsx +++ b/src/pages/lesson/lesson.tsx @@ -1,7 +1,8 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React from 'react'; import moment from 'moment'; import * as helpres from '@educt/helpers'; -import { Link as ReactRouterLink, useHistory } from 'react-router-dom'; +import { Link as ReactRouterLink, Redirect } from 'react-router-dom'; +import { Helmet } from 'react-helmet'; import { Flex, Box, @@ -18,6 +19,9 @@ import { IconButton, useColorModeValue, } from '@chakra-ui/react'; +import { MdOutlineCircle, MdCheckCircle, MdOutlineFilePresent, MdSkipNext, MdSkipPrevious } from 'react-icons/md'; +import LoadingPage from '@educt/components/LoadingPage'; +import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements'; /** * Types @@ -27,13 +31,15 @@ import { ILesson, ILessonMaterial, IPageProps } from '@educt/interfaces'; /** * Hooks */ -import { Redirect, useParams } from 'react-router-dom'; -import { PageContent, PageHeading, PageWrapper } from '@educt/components/PageElements'; +import { useEffect, useRef, useState } from 'react'; +import { useHistory, useParams } from 'react-router-dom'; import { useFetchLesson } from '@educt/hooks/queries/lesson/useFetchLesson'; -import LoadingPage from '@educt/components/LoadingPage'; -import { MdOutlineCircle, MdOutlineFilePresent, MdSkipNext, MdSkipPrevious } from 'react-icons/md'; -import { Helmet } from 'react-helmet'; import { useFetchCourseLessons } from '@educt/hooks/queries/course/useFetchCourseLessons'; +import { useFetchLessonProgress } from '@educt/hooks/queries/lesson/useFetchLessonProgress'; + +/** + * Services + */ import { LessonServiceInstance } from '@educt/services'; /** @@ -43,6 +49,7 @@ const LessonPage: React.FC = () => { const { id } = useParams<{ id: string }>(); const { error, data: lesson, isLoading } = useFetchLesson(id); const { fetchCourseLessons, data: lessons } = useFetchCourseLessons(); + const { fetchLessonProgress } = useFetchLessonProgress(); const history = useHistory(); const [nextLesson, setNextLesson] = useState(null); const [prevLesson, setPrevLesson] = useState(null); @@ -66,7 +73,10 @@ const LessonPage: React.FC = () => { useEffect(() => { if (lesson !== null) { - fetchCourseLessons(lesson.course_id); + (async () => { + await fetchCourseLessons(lesson.course_id); + await fetchLessonProgress(lesson.id); + })(); } }, [lesson]); @@ -154,15 +164,20 @@ const LessonPage: React.FC = () => { ref={lesson.id === id ? currentLessonRef : undefined} as='div' display={'flex'} + minH='100' key={lesson.id} bg={lesson.id === id ? bg : ''} p='4' alignItems={'center'} - _hover={{ - bg, - }} + _hover={{ bg }} > - + Lesson {i + 1} @@ -204,7 +219,9 @@ const LessonPage: React.FC = () => { > {material.client_name}
- {helpres.transformBytes(material.size)} + + {helpres.transformBytes(material.size)} +
))} diff --git a/src/services/LessonService.ts b/src/services/LessonService.ts index 7073638..22cb726 100644 --- a/src/services/LessonService.ts +++ b/src/services/LessonService.ts @@ -1,6 +1,7 @@ import { AxiosInstance } from 'axios'; import { IApiRespose, ILesson } from '@educt/interfaces'; import { ApiServiceInstance } from './ApiService'; +import type { LessonProgress } from '@educt/types'; class LessonService { public api: AxiosInstance; @@ -31,6 +32,17 @@ class LessonService { return result.data; } + /** + * Get progress about lesson + * + * @param id Lesson id + * @returns Progress info + */ + public async fetchProgress(id: string): Promise> { + const result = await this.api.get(`/v1/lessons/${id}/progress`); + return result.data; + } + /** * Delete lesson by id * diff --git a/src/types/index.d.ts b/src/types/index.d.ts index 9ebd833..e626fcb 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -34,6 +34,12 @@ export type ColorType = { hex: string; }; +export type LessonProgress = { + progress: { + is_watched: boolean; + } | null; +}; + export type ConfirmEmailContainerDataType = { newEmail: string; expired_seconds: number;