mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: lesson progress
This commit is contained in:
parent
37c5d8c36e
commit
c0fda55e5d
22
src/hooks/queries/lesson/useFetchLessonProgress.ts
Normal file
22
src/hooks/queries/lesson/useFetchLessonProgress.ts
Normal file
@ -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<LessonProgress, Parameters<typeof fetch>>(fetch);
|
||||
|
||||
return { fetchLessonProgress: execute, ...state };
|
||||
};
|
||||
|
||||
export { useFetchLessonProgress };
|
||||
@ -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<IUser, 'id' | 'first_name' | 'fullname' | 'last_name' | 'email' | 'created_at' | 'updated_at'>;
|
||||
category: ICategory;
|
||||
lessons: Omit<ILesson, 'materials' | 'content'>[];
|
||||
lessons: Omit<ILesson, 'materials' | 'content' | 'progress'>[];
|
||||
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<ILessonMaterial>;
|
||||
progress: LessonProgress;
|
||||
content: ILessonContent;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
|
||||
@ -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<IPageProps> = () => {
|
||||
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<ILesson | null>(null);
|
||||
const [prevLesson, setPrevLesson] = useState<ILesson | null>(null);
|
||||
@ -66,7 +73,10 @@ const LessonPage: React.FC<IPageProps> = () => {
|
||||
|
||||
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<IPageProps> = () => {
|
||||
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 }}
|
||||
>
|
||||
<Icon as={MdOutlineCircle} color='gray.500' w={6} h={6} mr='2' />
|
||||
<Icon
|
||||
as={lesson.progress ? MdCheckCircle : MdOutlineCircle}
|
||||
color={lesson.progress ? 'green.500' : 'gray.500'}
|
||||
w={6}
|
||||
h={6}
|
||||
mr='2'
|
||||
/>
|
||||
<Box>
|
||||
<Text as='small' color='gray.500'>
|
||||
Lesson {i + 1}
|
||||
@ -204,7 +219,9 @@ const LessonPage: React.FC<IPageProps> = () => {
|
||||
>
|
||||
{material.client_name}
|
||||
<br />
|
||||
<Text as='small'>{helpres.transformBytes(material.size)}</Text>
|
||||
<Text as='small' color='gray.500'>
|
||||
{helpres.transformBytes(material.size)}
|
||||
</Text>
|
||||
</Text>
|
||||
</Flex>
|
||||
))}
|
||||
|
||||
@ -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<IApiRespose<LessonProgress>> {
|
||||
const result = await this.api.get(`/v1/lessons/${id}/progress`);
|
||||
return result.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete lesson by id
|
||||
*
|
||||
|
||||
6
src/types/index.d.ts
vendored
6
src/types/index.d.ts
vendored
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user