From 63082e50c22cb76e9619f5a63c221417b4b7816c Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Fri, 17 Dec 2021 21:55:28 +0300 Subject: [PATCH 1/6] feat: added layout --- src/hooks/queries/course/useFetchCourse.ts | 4 +- src/index.tsx | 3 +- src/pages/404/404.tsx | 2 +- src/pages/auth/auth.tsx | 7 +- .../auth/components/AuthForm/AuthForm.tsx | 2 +- src/pages/course/course.tsx | 221 ++++++++++++++++++ src/routes.config.ts | 8 + src/services/CourseService.ts | 4 +- src/theme.ts | 24 ++ 9 files changed, 261 insertions(+), 14 deletions(-) create mode 100644 src/pages/course/course.tsx create mode 100644 src/theme.ts diff --git a/src/hooks/queries/course/useFetchCourse.ts b/src/hooks/queries/course/useFetchCourse.ts index 7f00f53..636ad5a 100644 --- a/src/hooks/queries/course/useFetchCourse.ts +++ b/src/hooks/queries/course/useFetchCourse.ts @@ -10,15 +10,13 @@ import { CourseServiceInstance } from '@educt/services'; import { useEffect } from 'react'; import useAsync from '../../useAsync'; -type CourseResultDataType = Omit; - const useFetchCourse = (id: string) => { const fetch = async (id: string) => { const { data } = await CourseServiceInstance.fetchById(id); return data; }; - const { execute: fetchCourseById, ...state } = useAsync>(fetch); + const { execute: fetchCourseById, ...state } = useAsync>(fetch); useEffect(() => { fetchCourseById(id); diff --git a/src/index.tsx b/src/index.tsx index c2f00a8..085d093 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,7 +1,8 @@ -import { ChakraProvider, ColorModeScript, theme } from '@chakra-ui/react'; import * as React from 'react'; import ReactDOM from 'react-dom'; +import { ChakraProvider, ColorModeScript } from '@chakra-ui/react'; import App from './App'; +import { theme } from './theme'; import { RootStoreProvider } from './providers'; ReactDOM.render( diff --git a/src/pages/404/404.tsx b/src/pages/404/404.tsx index 53d58a9..4dc3dc3 100644 --- a/src/pages/404/404.tsx +++ b/src/pages/404/404.tsx @@ -21,7 +21,7 @@ const NotFoundPage: React.FC = ({ title }) => { useEffect(() => { toast({ title: `Page not found`, duration: 10000, isClosable: true, status: 'warning' }); - }); + }, []); return ( <> diff --git a/src/pages/auth/auth.tsx b/src/pages/auth/auth.tsx index e7f4288..44b7759 100644 --- a/src/pages/auth/auth.tsx +++ b/src/pages/auth/auth.tsx @@ -41,11 +41,8 @@ const AuthPage: React.FC = ({ title }) => { {title} - - - - Login to your account - + + diff --git a/src/pages/auth/components/AuthForm/AuthForm.tsx b/src/pages/auth/components/AuthForm/AuthForm.tsx index 74186b2..60dd7e2 100644 --- a/src/pages/auth/components/AuthForm/AuthForm.tsx +++ b/src/pages/auth/components/AuthForm/AuthForm.tsx @@ -84,7 +84,7 @@ const AuthForm: React.FC = () => { + + + + + + + + + Last update: {new Date(course.updated_at).toLocaleDateString()} + + + + + + + + About + + + + + + + About this course + + {course.description} + + {course.students.length !== 0 ? ( + + + Students: + + + {course.students.map(student => ( + + ))} + + + ) : ( + + + 0 students + + + )} + + + + + + + + + + + What you'll learn. + + + Lorem, ipsum dolor sit amet consectetur adipisicing elit. Iste temporibus harum eos praesentium hic, + sunt corporis deserunt impedit natus consequuntur? + + + + + + + Content + + + {course.lessons_count} lessons + + + {course.lessons.length !== 0 ? ( + + {course.lessons.map(lesson => { + return ( + + + + + {lesson.title} + + + {moment.duration(lesson.duration).asMinutes()}min + + ); + })} + + ) : ( + + + There are no lessons here yet + + + )} + + + + + + + ); +}; + +export default CoursePage; diff --git a/src/routes.config.ts b/src/routes.config.ts index dc7357d..75b90ba 100644 --- a/src/routes.config.ts +++ b/src/routes.config.ts @@ -8,6 +8,7 @@ import AuthPage from '@educt/pages/auth/auth'; import NotFoundPage from '@educt/pages/404/404'; import CreateCoursePage from '@educt/pages/courses/create/create'; import CreateLessonPage from '@educt/pages/courses/create-lesson/create-lesson'; +import CoursePage from '@educt/pages/course/course'; import EditCoursePage from '@educt/pages/courses/edit/edit'; import ChangePasswordPage from '@educt/pages/profile/change-password/change-password'; import ChangeEmailPage from '@educt/pages/profile/change-email/change-email'; @@ -32,6 +33,13 @@ export const routes: IRouteOption[] = [ exact: true, isPrivate: true, }, + { + path: '/course/:id', + title: 'Course', + component: CoursePage, + isPrivate: true, + exact: true, + }, { path: '/courses', title: 'Courses', diff --git a/src/services/CourseService.ts b/src/services/CourseService.ts index 2078ad6..881a8f2 100644 --- a/src/services/CourseService.ts +++ b/src/services/CourseService.ts @@ -35,9 +35,7 @@ class CourseService { * @param id Course id * @returns Course */ - public async fetchById( - id: string - ): Promise>> { + public async fetchById(id: string): Promise> { const result = await this.api.get(`/v1/courses/${id}`); return result.data; } diff --git a/src/theme.ts b/src/theme.ts new file mode 100644 index 0000000..2af47ec --- /dev/null +++ b/src/theme.ts @@ -0,0 +1,24 @@ +import { extendTheme } from '@chakra-ui/react'; + +export const theme = extendTheme({ + styles: { + global: { + body: { + scrollbarWidth: 'thin', + scrollbarColor: '#000', + }, + '::-webkit-scrollbar': { + width: '5px', + height: '5px', + }, + '::-webkit-scrollbar-track': { + backgroundColor: 'gray.100', + borderRadius: '100px', + }, + '::-webkit-scrollbar-thumb': { + background: 'blue.600', + borderRadius: '100px', + }, + }, + }, +}); From 9d67c14fee5b76492234b21324c41771b94463fb Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Sat, 18 Dec 2021 00:17:56 +0300 Subject: [PATCH 2/6] feat: rendering course page --- src/helpers/index.ts | 7 +- src/pages/404/404.tsx | 2 +- src/pages/auth/auth.tsx | 2 +- src/pages/course/course.tsx | 150 ++++++++------------------- src/pages/course/index.tsx | 195 ++++++++++++++++++++++++++++++++++++ 5 files changed, 246 insertions(+), 110 deletions(-) create mode 100644 src/pages/course/index.tsx diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 8b65582..9cf8a9e 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1,5 +1,5 @@ import { UserRoleEnum } from '@educt/enums'; -import { IUserRole } from '@educt/interfaces'; +import { ICourse, IUserRole, UserCourseType } from '@educt/interfaces'; export function userHasRoles(userRoles: IUserRole[], roles: UserRoleEnum[]): boolean { for (let i = 0; i < roles.length; i += 1) { @@ -97,3 +97,8 @@ export function arrayMove(array: T[], from: number, to: number) { export function getDirtyFields(dirtyFields: { [key: string]: boolean | undefined }, data: T) { return Object.fromEntries(Object.keys(dirtyFields).map(k => [k, data[k as keyof T]])); } + +export function userHasCourse(findingCourse: ICourse, userCourses?: Array | undefined) { + if (!userCourses) return true; + return userCourses.some(course => course.id === findingCourse.id); +} diff --git a/src/pages/404/404.tsx b/src/pages/404/404.tsx index 4dc3dc3..2d67e41 100644 --- a/src/pages/404/404.tsx +++ b/src/pages/404/404.tsx @@ -1,7 +1,7 @@ import React from 'react'; import Helmet from 'react-helmet'; import { Link as ReactRouterLink } from 'react-router-dom'; -import { Flex, Heading, Text, Link, Icon } from '@chakra-ui/react'; +import { Heading, Text, Link, Icon } from '@chakra-ui/react'; import { MdError } from 'react-icons/md'; /** diff --git a/src/pages/auth/auth.tsx b/src/pages/auth/auth.tsx index 44b7759..1a28914 100644 --- a/src/pages/auth/auth.tsx +++ b/src/pages/auth/auth.tsx @@ -2,7 +2,7 @@ import React from 'react'; import Helmet from 'react-helmet'; import { Redirect } from 'react-router-dom'; import { observer } from 'mobx-react'; -import { Box, Heading } from '@chakra-ui/react'; +import { Box } from '@chakra-ui/react'; /** * Types diff --git a/src/pages/course/course.tsx b/src/pages/course/course.tsx index bf4d9c5..c99b48c 100644 --- a/src/pages/course/course.tsx +++ b/src/pages/course/course.tsx @@ -1,26 +1,9 @@ import React from 'react'; -import { Redirect, useHistory } from 'react-router-dom'; -import { - Flex, - Box, - Text, - Tag, - Heading, - Icon, - Button, - Grid, - GridItem, - Image, - Divider, - AvatarGroup, - LinkBox, - LinkOverlay, - Avatar, - useColorModeValue, -} from '@chakra-ui/react'; -import { MdThumbUpOffAlt, MdPlayCircleOutline, MdOutlineGroup, MdOutlineVideoLibrary } from 'react-icons/md'; -import { Tabs, TabList, TabPanels, Tab, TabPanel, Stack } from '@chakra-ui/react'; -import { Link as ReactRouterLink } from 'react-router-dom'; +import * as helpres from '@educt/helpers'; +import { Redirect } from 'react-router-dom'; +import { Flex, Box, Text, Heading, Button, Grid, GridItem, Divider, AvatarGroup, Avatar } from '@chakra-ui/react'; +import { MdPlayCircleOutline } from 'react-icons/md'; +import { Tabs, TabList, TabPanels, Tab, TabPanel } from '@chakra-ui/react'; /** * Types @@ -30,78 +13,67 @@ import { IPageProps } from '@educt/interfaces'; /** * Components */ +import { CourseBackgroundImage, CourseHeader, CourseHeading, CourseInfo, LessonItem, LessonList } from '.'; import { PageWrapper, PageContent } from '@educt/components/PageElements'; +import LoadingPage from '@educt/components/LoadingPage'; /** * Hooks */ -import { useParams } from 'react-router-dom'; +import { useHistory, useParams } from 'react-router-dom'; import { useFetchCourse } from '@educt/hooks/queries'; -import LoadingPage from '@educt/components/LoadingPage'; -import moment from 'moment'; +import { useRootStore } from '@educt/hooks/useRootStore'; +import { observer } from 'mobx-react'; const CoursePage: React.FC = () => { + const { + userStore: { me }, + } = useRootStore(); const params = useParams<{ id: string }>(); const { error, data: course, isLoading } = useFetchCourse(params.id); const history = useHistory(); - const color = useColorModeValue('gray.50', 'gray.700'); if (error?.response?.status === 404) { return ; } - if (!course || isLoading) return ; + if (!me || !course || isLoading) return ; - const onWatchCourse = () => history.push(`/lesson/${course.lessons[0].id}`); + const isCourseAvailable = helpres.userHasCourse(course, me.courses); + const isEmptyLessons = course.lessons.length === 0; + const isEmptyStudents = course.students.length === 0; + + const handleWatchCourse = () => history.push(`/lesson/${course.lessons[0].id}`); return ( - - - - {course.title} - - - {course.teacher.fullname} •  - - {course.category.title} - - - - - - - - {course.lessons_count} - - - - {course.students_count} - - - - - + + + + + Last update: {new Date(course.updated_at).toLocaleDateString()} - - + @@ -117,7 +89,7 @@ const CoursePage: React.FC = () => { {course.description} - {course.students.length !== 0 ? ( + {!isEmptyStudents ? ( Students: @@ -152,7 +124,9 @@ const CoursePage: React.FC = () => { sunt corporis deserunt impedit natus consequuntur? + + @@ -162,46 +136,8 @@ const CoursePage: React.FC = () => { {course.lessons_count} lessons - {course.lessons.length !== 0 ? ( - - {course.lessons.map(lesson => { - return ( - - - - - {lesson.title} - - - {moment.duration(lesson.duration).asMinutes()}min - - ); - })} - + {!isEmptyLessons ? ( + ) : ( @@ -218,4 +154,4 @@ const CoursePage: React.FC = () => { ); }; -export default CoursePage; +export default observer(CoursePage); diff --git a/src/pages/course/index.tsx b/src/pages/course/index.tsx new file mode 100644 index 0000000..4ee2913 --- /dev/null +++ b/src/pages/course/index.tsx @@ -0,0 +1,195 @@ +import React from 'react'; +import moment from 'moment'; +import * as helpers from '@educt/helpers'; +import { Link as ReactRouterLink } from 'react-router-dom'; +import { + Box, + BoxProps, + Flex, + FlexProps, + Button, + Icon, + Image, + Text, + Heading, + Tag, + Stack, + ImageProps, + LinkBox, + LinkOverlay, + LinkBoxProps, + StackProps, +} from '@chakra-ui/react'; +import { + MdThumbUpOffAlt, + MdPlayCircleOutline, + MdOutlineGroup, + MdOutlineVideoLibrary, + MdOutlineLock, +} from 'react-icons/md'; + +/** + * Types + */ +import type { ICourse, ILesson } from '@educt/interfaces'; + +/** + * Hooks + */ +import { useColorModeValue } from '@chakra-ui/react'; +import { useRootStore } from '@educt/hooks/useRootStore'; + +export const CourseHeader: React.FC = props => ( + + {props.children} + +); + +interface ICourseHeadingProps extends BoxProps { + title: string; + teacher: ICourse['teacher']; + category: ICourse['category']; +} +export const CourseHeading: React.FC = props => { + const { title, teacher, category, ...boxProps } = props; + + return ( + + + {title} + + + {teacher.fullname} •  + + {category.title} + + + + ); +}; + +interface ICourseInfoProps extends BoxProps { + id: string; + lessonsCount: string; + studentsCount: string; + likesCount: string; +} +export const CourseInfo: React.FC = props => { + const { id, lessonsCount, studentsCount, likesCount, ...boxProps } = props; + + const handleLikeCourse = (id: string) => () => { + // TODO set like request + console.log(`like course: ${id}`); + }; + + return ( + + + + + {lessonsCount} + + + + + {studentsCount} + + + + + + ); +}; + +export const CourseBackgroundImage: React.FC = props => { + return ( + + ); +}; + +interface ILessonListProps extends StackProps { + course: ICourse; + render: React.FC; +} +export const LessonList: React.FC = props => { + const { course, render: Item, ...stackProps } = props; + const { + userStore: { me }, + } = useRootStore(); + const bg = useColorModeValue('gray.50', 'gray.700'); + + if (!me) return null; + + const isCourseAvailable = helpers.userHasCourse(course, me.courses); + + return ( + + {course.lessons.map(lesson => ( + + ))} + + ); +}; + +interface ILessonItemProps extends LinkBoxProps { + id: string; + title: string; + duration: string; + isDisabled?: boolean | undefined; +} +export const LessonItem: React.FC = props => { + const { id, title, duration, isDisabled, ...linkBoxProps } = props; + return ( + + + + {!isDisabled ? ( + + {title} + + ) : ( + + {title} + + )} + + {moment.duration(duration).asMinutes()}min + + ); +}; From b82c2203bf265bea082c9b42f50749e919a7b198 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Sat, 18 Dec 2021 00:28:38 +0300 Subject: [PATCH 3/6] feat: likes state --- src/pages/course/index.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/course/index.tsx b/src/pages/course/index.tsx index 4ee2913..1e68b2d 100644 --- a/src/pages/course/index.tsx +++ b/src/pages/course/index.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useRef, useState } from 'react'; import moment from 'moment'; import * as helpers from '@educt/helpers'; import { Link as ReactRouterLink } from 'react-router-dom'; @@ -76,9 +76,11 @@ interface ICourseInfoProps extends BoxProps { } export const CourseInfo: React.FC = props => { const { id, lessonsCount, studentsCount, likesCount, ...boxProps } = props; + const [likes, setLikes] = useState(Number.parseInt(likesCount, 10)); const handleLikeCourse = (id: string) => () => { // TODO set like request + setLikes(likes => likes + 1); console.log(`like course: ${id}`); }; @@ -96,7 +98,7 @@ export const CourseInfo: React.FC = props => { From abbdb36134fb9805955103d1433fcf15810e2288 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Sat, 18 Dec 2021 15:07:42 +0300 Subject: [PATCH 4/6] feat: set course like & fixed edit user modal --- .../Modals/EditUserModal/EditUserModal.tsx | 16 ++++++--- src/interfaces/index.ts | 1 + src/pages/course/index.tsx | 33 ++++++++++++++++--- src/services/CourseService.ts | 22 +++++++++++++ src/stores/UserStore.ts | 3 +- 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/src/components/Modals/EditUserModal/EditUserModal.tsx b/src/components/Modals/EditUserModal/EditUserModal.tsx index ceb6611..64d371f 100644 --- a/src/components/Modals/EditUserModal/EditUserModal.tsx +++ b/src/components/Modals/EditUserModal/EditUserModal.tsx @@ -1,11 +1,9 @@ import React from 'react'; -import BaseModal from '@educt/components/Modal'; - import * as helpers from '@educt/helpers'; import { FormControl, FormLabel, FormHelperText, Input, Select, Stack } from '@chakra-ui/react'; -import { CheckIcon } from '@chakra-ui/icons'; import { MdModeEdit } from 'react-icons/md'; import { yupResolver } from '@hookform/resolvers/yup'; +import BaseModal from '@educt/components/Modal'; /** * Types @@ -49,6 +47,14 @@ const EditUserModal: React.FC = props => { userStore: { me }, } = useRootStore(); const { updateUser, isLoading } = useUpdateUser(); + const defaultValues = { + login: null, + first_name: user.first_name, + last_name: user.last_name, + email: user.email, + role: user.roles[0].slug, + password: null, + }; const { register, handleSubmit, @@ -57,7 +63,7 @@ const EditUserModal: React.FC = props => { } = useForm({ resolver: yupResolver(EditUserSchema), defaultValues: useMemo(() => { - return props.user; + return defaultValues; }, [props]), }); @@ -78,7 +84,7 @@ const EditUserModal: React.FC = props => { }; useEffect(() => { - reset(props.user); + reset(defaultValues); }, [props.user]); return ( diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts index 3d36eaf..636fde6 100644 --- a/src/interfaces/index.ts +++ b/src/interfaces/index.ts @@ -107,6 +107,7 @@ export interface IMe extends IUser { * does not have the STUDENT role */ courses?: UserCourseType[]; + likes: Array>; isAdmin: boolean; isTeacher: boolean; isStudent: boolean; diff --git a/src/pages/course/index.tsx b/src/pages/course/index.tsx index 1e68b2d..e511c1d 100644 --- a/src/pages/course/index.tsx +++ b/src/pages/course/index.tsx @@ -38,6 +38,8 @@ import type { ICourse, ILesson } from '@educt/interfaces'; */ import { useColorModeValue } from '@chakra-ui/react'; import { useRootStore } from '@educt/hooks/useRootStore'; +import { CourseServiceInstance } from '@educt/services'; +import { runInAction } from 'mobx'; export const CourseHeader: React.FC = props => ( @@ -75,13 +77,36 @@ interface ICourseInfoProps extends BoxProps { likesCount: string; } export const CourseInfo: React.FC = props => { + const { userStore } = useRootStore(); + const { me } = userStore; const { id, lessonsCount, studentsCount, likesCount, ...boxProps } = props; + const [isLoading, setIsLoading] = useState(false); const [likes, setLikes] = useState(Number.parseInt(likesCount, 10)); - const handleLikeCourse = (id: string) => () => { - // TODO set like request - setLikes(likes => likes + 1); - console.log(`like course: ${id}`); + const handleLikeCourse = (id: string) => async () => { + if (isLoading || me === null) { + return; + } + + try { + const isCourseLiked = me.likes.some(course => course.id === id); + const setCourseLike = () => me.likes.push({ id }); + const unsetCourseLike = () => (me.likes = me.likes.filter(course => course.id !== id)); + + if (!isCourseLiked) { + setIsLoading(true); + setLikes(likes => likes + 1); + await CourseServiceInstance.setLike(id); + runInAction(setCourseLike); + } else { + setIsLoading(true); + setLikes(likes => likes - 1); + await CourseServiceInstance.unsetLike(id); + runInAction(unsetCourseLike); + } + } finally { + setIsLoading(false); + } }; return ( diff --git a/src/services/CourseService.ts b/src/services/CourseService.ts index 881a8f2..82cad95 100644 --- a/src/services/CourseService.ts +++ b/src/services/CourseService.ts @@ -54,6 +54,28 @@ class CourseService { return result.data; } + /** + * Set course like + * + * @param id Course id + * @returns Empty data + */ + public async setLike(id: string): Promise>> { + const result = await this.api.put(`/v1/courses/${id}/likes`); + return result.data; + } + + /** + * Unset course like + * + * @param id Course id + * @returns Empty data + */ + public async unsetLike(id: string): Promise>> { + const result = await this.api.delete(`/v1/courses/${id}/likes`); + return result.data; + } + /** * * @param data Data for creating course diff --git a/src/stores/UserStore.ts b/src/stores/UserStore.ts index 423e175..aef29e3 100644 --- a/src/stores/UserStore.ts +++ b/src/stores/UserStore.ts @@ -62,7 +62,7 @@ export default class UserStore { public async loadCurrentUserData() { const result = await UserServiceInstance.fetchMe(); const { - data: { id, first_name, last_name, fullname, email, roles, contacts, courses, created_at, updated_at }, + data: { id, first_name, last_name, fullname, email, roles, likes, contacts, courses, created_at, updated_at }, } = result; runInAction(() => { @@ -73,6 +73,7 @@ export default class UserStore { email, roles, fullname, + likes, contacts, courses, isAdmin: helpers.userContainRoles(roles, [UserRoleEnum.ADMIN]), From 3b766504a8d0a4d0e28efc1bc46d8e07c2204196 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Sat, 18 Dec 2021 15:16:04 +0300 Subject: [PATCH 5/6] feat: added notranslate attribute to html --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index cd4d8a1..39f5472 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@ - + From 329a21a47d0dabeaf8e06ee9401646e73ee3b7bf Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Sat, 18 Dec 2021 15:23:30 +0300 Subject: [PATCH 6/6] refactor: imports naming --- src/pages/course/course.tsx | 4 ++-- src/pages/course/index.tsx | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/pages/course/course.tsx b/src/pages/course/course.tsx index c99b48c..d5ed0ec 100644 --- a/src/pages/course/course.tsx +++ b/src/pages/course/course.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { observer } from 'mobx-react'; import * as helpres from '@educt/helpers'; import { Redirect } from 'react-router-dom'; import { Flex, Box, Text, Heading, Button, Grid, GridItem, Divider, AvatarGroup, Avatar } from '@chakra-ui/react'; @@ -8,7 +9,7 @@ import { Tabs, TabList, TabPanels, Tab, TabPanel } from '@chakra-ui/react'; /** * Types */ -import { IPageProps } from '@educt/interfaces'; +import type { IPageProps } from '@educt/interfaces'; /** * Components @@ -23,7 +24,6 @@ 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 { observer } from 'mobx-react'; const CoursePage: React.FC = () => { const { diff --git a/src/pages/course/index.tsx b/src/pages/course/index.tsx index e511c1d..79d0d75 100644 --- a/src/pages/course/index.tsx +++ b/src/pages/course/index.tsx @@ -1,4 +1,5 @@ -import React, { useRef, useState } from 'react'; +import React from 'react'; +import { runInAction } from 'mobx'; import moment from 'moment'; import * as helpers from '@educt/helpers'; import { Link as ReactRouterLink } from 'react-router-dom'; @@ -31,15 +32,15 @@ import { /** * Types */ -import type { ICourse, ILesson } from '@educt/interfaces'; +import type { ICourse } from '@educt/interfaces'; /** * Hooks */ +import { useState } from 'react'; import { useColorModeValue } from '@chakra-ui/react'; import { useRootStore } from '@educt/hooks/useRootStore'; import { CourseServiceInstance } from '@educt/services'; -import { runInAction } from 'mobx'; export const CourseHeader: React.FC = props => (