From abbdb36134fb9805955103d1433fcf15810e2288 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Sat, 18 Dec 2021 15:07:42 +0300 Subject: [PATCH] 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]),