mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 02:09:08 +03:00
feat: set course like & fixed edit user modal
This commit is contained in:
parent
b82c2203bf
commit
abbdb36134
@ -1,11 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import BaseModal from '@educt/components/Modal';
|
|
||||||
|
|
||||||
import * as helpers from '@educt/helpers';
|
import * as helpers from '@educt/helpers';
|
||||||
import { FormControl, FormLabel, FormHelperText, Input, Select, Stack } from '@chakra-ui/react';
|
import { FormControl, FormLabel, FormHelperText, Input, Select, Stack } from '@chakra-ui/react';
|
||||||
import { CheckIcon } from '@chakra-ui/icons';
|
|
||||||
import { MdModeEdit } from 'react-icons/md';
|
import { MdModeEdit } from 'react-icons/md';
|
||||||
import { yupResolver } from '@hookform/resolvers/yup';
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
|
import BaseModal from '@educt/components/Modal';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Types
|
* Types
|
||||||
@ -49,6 +47,14 @@ const EditUserModal: React.FC<EditUserModalPropsType> = props => {
|
|||||||
userStore: { me },
|
userStore: { me },
|
||||||
} = useRootStore();
|
} = useRootStore();
|
||||||
const { updateUser, isLoading } = useUpdateUser();
|
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 {
|
const {
|
||||||
register,
|
register,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@ -57,7 +63,7 @@ const EditUserModal: React.FC<EditUserModalPropsType> = props => {
|
|||||||
} = useForm<UpdateUserInputType>({
|
} = useForm<UpdateUserInputType>({
|
||||||
resolver: yupResolver(EditUserSchema),
|
resolver: yupResolver(EditUserSchema),
|
||||||
defaultValues: useMemo(() => {
|
defaultValues: useMemo(() => {
|
||||||
return props.user;
|
return defaultValues;
|
||||||
}, [props]),
|
}, [props]),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -78,7 +84,7 @@ const EditUserModal: React.FC<EditUserModalPropsType> = props => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
reset(props.user);
|
reset(defaultValues);
|
||||||
}, [props.user]);
|
}, [props.user]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -107,6 +107,7 @@ export interface IMe extends IUser {
|
|||||||
* does not have the STUDENT role
|
* does not have the STUDENT role
|
||||||
*/
|
*/
|
||||||
courses?: UserCourseType[];
|
courses?: UserCourseType[];
|
||||||
|
likes: Array<Pick<ICourse, 'id'>>;
|
||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
isTeacher: boolean;
|
isTeacher: boolean;
|
||||||
isStudent: boolean;
|
isStudent: boolean;
|
||||||
|
|||||||
@ -38,6 +38,8 @@ import type { ICourse, ILesson } from '@educt/interfaces';
|
|||||||
*/
|
*/
|
||||||
import { useColorModeValue } from '@chakra-ui/react';
|
import { useColorModeValue } from '@chakra-ui/react';
|
||||||
import { useRootStore } from '@educt/hooks/useRootStore';
|
import { useRootStore } from '@educt/hooks/useRootStore';
|
||||||
|
import { CourseServiceInstance } from '@educt/services';
|
||||||
|
import { runInAction } from 'mobx';
|
||||||
|
|
||||||
export const CourseHeader: React.FC<FlexProps> = props => (
|
export const CourseHeader: React.FC<FlexProps> = props => (
|
||||||
<Flex justifyContent='space-between' flexDir={{ base: 'column', xl: 'row' }} {...props}>
|
<Flex justifyContent='space-between' flexDir={{ base: 'column', xl: 'row' }} {...props}>
|
||||||
@ -75,13 +77,36 @@ interface ICourseInfoProps extends BoxProps {
|
|||||||
likesCount: string;
|
likesCount: string;
|
||||||
}
|
}
|
||||||
export const CourseInfo: React.FC<ICourseInfoProps> = props => {
|
export const CourseInfo: React.FC<ICourseInfoProps> = props => {
|
||||||
|
const { userStore } = useRootStore();
|
||||||
|
const { me } = userStore;
|
||||||
const { id, lessonsCount, studentsCount, likesCount, ...boxProps } = props;
|
const { id, lessonsCount, studentsCount, likesCount, ...boxProps } = props;
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [likes, setLikes] = useState<number>(Number.parseInt(likesCount, 10));
|
const [likes, setLikes] = useState<number>(Number.parseInt(likesCount, 10));
|
||||||
|
|
||||||
const handleLikeCourse = (id: string) => () => {
|
const handleLikeCourse = (id: string) => async () => {
|
||||||
// TODO set like request
|
if (isLoading || me === null) {
|
||||||
setLikes(likes => likes + 1);
|
return;
|
||||||
console.log(`like course: ${id}`);
|
}
|
||||||
|
|
||||||
|
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 (
|
return (
|
||||||
|
|||||||
@ -54,6 +54,28 @@ class CourseService {
|
|||||||
return result.data;
|
return result.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set course like
|
||||||
|
*
|
||||||
|
* @param id Course id
|
||||||
|
* @returns Empty data
|
||||||
|
*/
|
||||||
|
public async setLike(id: string): Promise<IApiRespose<Record<string, never>>> {
|
||||||
|
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<IApiRespose<Record<string, never>>> {
|
||||||
|
const result = await this.api.delete(`/v1/courses/${id}/likes`);
|
||||||
|
return result.data;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param data Data for creating course
|
* @param data Data for creating course
|
||||||
|
|||||||
@ -62,7 +62,7 @@ export default class UserStore {
|
|||||||
public async loadCurrentUserData() {
|
public async loadCurrentUserData() {
|
||||||
const result = await UserServiceInstance.fetchMe();
|
const result = await UserServiceInstance.fetchMe();
|
||||||
const {
|
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;
|
} = result;
|
||||||
|
|
||||||
runInAction(() => {
|
runInAction(() => {
|
||||||
@ -73,6 +73,7 @@ export default class UserStore {
|
|||||||
email,
|
email,
|
||||||
roles,
|
roles,
|
||||||
fullname,
|
fullname,
|
||||||
|
likes,
|
||||||
contacts,
|
contacts,
|
||||||
courses,
|
courses,
|
||||||
isAdmin: helpers.userContainRoles(roles, [UserRoleEnum.ADMIN]),
|
isAdmin: helpers.userContainRoles(roles, [UserRoleEnum.ADMIN]),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user