mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 18:29:15 +03:00
feat: rendering courses
This commit is contained in:
parent
5ad94b7b25
commit
2c6534648a
33
src/hooks/queries/course/useFetchCourses.ts
Normal file
33
src/hooks/queries/course/useFetchCourses.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { ICourse } from '@educt/interfaces';
|
||||||
|
import { CourseServiceInstance } from '@educt/services';
|
||||||
|
import { FetchCoursesParams } from '@educt/types';
|
||||||
|
import useAsync from '@educt/hooks/useAsync';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useErrorHandler } from 'react-error-boundary';
|
||||||
|
|
||||||
|
const useFetchCourses = (params?: FetchCoursesParams | undefined) => {
|
||||||
|
const handleError = useErrorHandler();
|
||||||
|
|
||||||
|
const fetchCourses = async (params?: FetchCoursesParams | undefined) => {
|
||||||
|
try {
|
||||||
|
const result = await CourseServiceInstance.fetchAll(params);
|
||||||
|
return result.data;
|
||||||
|
} catch (error) {
|
||||||
|
handleError(error);
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const { execute: fetch, ...state } = useAsync<
|
||||||
|
Omit<ICourse, 'teacher' | 'students' | 'lessons'>[],
|
||||||
|
Parameters<typeof fetchCourses>
|
||||||
|
>(fetchCourses);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch(params);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { ...state };
|
||||||
|
};
|
||||||
|
|
||||||
|
export { useFetchCourses };
|
||||||
@ -14,6 +14,7 @@ import { useUpdateLesson } from './lesson/useUpdateLesson';
|
|||||||
/**
|
/**
|
||||||
* Course
|
* Course
|
||||||
*/
|
*/
|
||||||
|
import { useFetchCourses } from './course/useFetchCourses';
|
||||||
import { useCreateCourse } from './course/useCreateCourse';
|
import { useCreateCourse } from './course/useCreateCourse';
|
||||||
import { useUpdateCourse } from './course/useUpdateCourse';
|
import { useUpdateCourse } from './course/useUpdateCourse';
|
||||||
import { useFetchCourse } from './course/useFetchCourse';
|
import { useFetchCourse } from './course/useFetchCourse';
|
||||||
@ -40,6 +41,7 @@ import { useUpdateCategory } from './category/useUpdateCategory';
|
|||||||
export {
|
export {
|
||||||
useLogin,
|
useLogin,
|
||||||
useLogout,
|
useLogout,
|
||||||
|
useFetchCourses,
|
||||||
useCreateCourse,
|
useCreateCourse,
|
||||||
useUpdateCourse,
|
useUpdateCourse,
|
||||||
useFetchCourse,
|
useFetchCourse,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import moment from 'moment';
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
BoxProps,
|
BoxProps,
|
||||||
@ -48,7 +49,7 @@ export const CourseCardCreated: React.FC<{ created: string }> = props => (
|
|||||||
Created
|
Created
|
||||||
</Text>
|
</Text>
|
||||||
<Box as='time' verticalAlign='middle' dateTime={props.created}>
|
<Box as='time' verticalAlign='middle' dateTime={props.created}>
|
||||||
{props.created}
|
{moment(props.created).format('ll')}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
@ -86,7 +87,7 @@ export const CourseCardWatch: React.FC<{ id: string }> = props => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Button onClick={() => history.push(`/courses/${props.id}`)} leftIcon={<MdOutlinePlayCircle />} size='sm'>
|
<Button onClick={() => history.push(`/course/${props.id}`)} leftIcon={<MdOutlinePlayCircle />} size='sm'>
|
||||||
Watch
|
Watch
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -20,6 +20,8 @@ import {
|
|||||||
CourseCardStat,
|
CourseCardStat,
|
||||||
CourseCardList,
|
CourseCardList,
|
||||||
} from './components';
|
} from './components';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
import { useFetchCourses } from '@educt/hooks/queries';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main page
|
* Main page
|
||||||
@ -28,8 +30,9 @@ const MainPage: React.FC<IPageProps> = () => {
|
|||||||
const {
|
const {
|
||||||
userStore: { me },
|
userStore: { me },
|
||||||
} = useRootStore();
|
} = useRootStore();
|
||||||
|
const { data: courses } = useFetchCourses({ limit: 3 });
|
||||||
|
|
||||||
if (me === null) return <LoadingPage />;
|
if (me === null || courses === null) return <LoadingPage />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageWrapper>
|
<PageWrapper>
|
||||||
@ -39,7 +42,11 @@ const MainPage: React.FC<IPageProps> = () => {
|
|||||||
<Stat>
|
<Stat>
|
||||||
<StatLabel>Unread messages</StatLabel>
|
<StatLabel>Unread messages</StatLabel>
|
||||||
<StatContent>
|
<StatContent>
|
||||||
<StatNumber>3</StatNumber>
|
<StatNumber>
|
||||||
|
<Link as={ReactRouterLink} to='/messages'>
|
||||||
|
3
|
||||||
|
</Link>
|
||||||
|
</StatNumber>
|
||||||
<StatIcon icon={MdOutlineMessage} />
|
<StatIcon icon={MdOutlineMessage} />
|
||||||
</StatContent>
|
</StatContent>
|
||||||
</Stat>
|
</Stat>
|
||||||
@ -76,22 +83,24 @@ const MainPage: React.FC<IPageProps> = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
</Flex>
|
</Flex>
|
||||||
<CourseCardList>
|
<CourseCardList>
|
||||||
<CourseCard>
|
{courses.map(course => (
|
||||||
<CourseCardHeading>
|
<CourseCard key={course.id}>
|
||||||
<CourseCardTitle>Javascript in a nutshell</CourseCardTitle>
|
<CourseCardHeading borderColor={course.color?.hex}>
|
||||||
<CourseCardCategory>Web Developing</CourseCardCategory>
|
<CourseCardTitle>{course.title}</CourseCardTitle>
|
||||||
</CourseCardHeading>
|
<CourseCardCategory>{course.category.title}</CourseCardCategory>
|
||||||
|
</CourseCardHeading>
|
||||||
|
|
||||||
<CourseCardContent>
|
<CourseCardContent>
|
||||||
<CourseCardCreated created='29 Nov 2022' />
|
<CourseCardCreated created={course.created_at} />
|
||||||
<CourseCardLessons count={26} />
|
<CourseCardLessons count={course.lessons_count} />
|
||||||
</CourseCardContent>
|
</CourseCardContent>
|
||||||
|
|
||||||
<CourseCardFooter>
|
<CourseCardFooter>
|
||||||
<CourseCardStat students={24} likes={14} />
|
<CourseCardStat students={course.students_count} likes={course.likes_count} />
|
||||||
<CourseCardWatch id='123' />
|
<CourseCardWatch id={course.id} />
|
||||||
</CourseCardFooter>
|
</CourseCardFooter>
|
||||||
</CourseCard>
|
</CourseCard>
|
||||||
|
))}
|
||||||
</CourseCardList>
|
</CourseCardList>
|
||||||
</Box>
|
</Box>
|
||||||
<Divider />
|
<Divider />
|
||||||
@ -100,4 +109,4 @@ const MainPage: React.FC<IPageProps> = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MainPage;
|
export default observer(MainPage);
|
||||||
|
|||||||
@ -24,6 +24,7 @@ class CourseService {
|
|||||||
params: {
|
params: {
|
||||||
status: params?.status,
|
status: params?.status,
|
||||||
category_id: params?.category_id,
|
category_id: params?.category_id,
|
||||||
|
limit: params?.limit,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return result.data;
|
return result.data;
|
||||||
|
|||||||
8
src/types/index.d.ts
vendored
8
src/types/index.d.ts
vendored
@ -109,15 +109,9 @@ export type CoursesPageContextType = {
|
|||||||
setCourseStatus: React.Dispatch<React.SetStateAction<CourseStatusEnum | undefined>>;
|
setCourseStatus: React.Dispatch<React.SetStateAction<CourseStatusEnum | undefined>>;
|
||||||
};
|
};
|
||||||
export type FetchCoursesParams = {
|
export type FetchCoursesParams = {
|
||||||
/**
|
|
||||||
* Get courses by status
|
|
||||||
*/
|
|
||||||
status?: CourseStatusEnum;
|
status?: CourseStatusEnum;
|
||||||
|
|
||||||
/**
|
|
||||||
* Get courses with category by id
|
|
||||||
*/
|
|
||||||
category_id?: string;
|
category_id?: string;
|
||||||
|
limit?: number;
|
||||||
};
|
};
|
||||||
export type FetchUsersParamsType = {
|
export type FetchUsersParamsType = {
|
||||||
page?: number;
|
page?: number;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user