feat: delete course from edit page

This commit is contained in:
Sergey Yarkov 2021-12-03 00:19:04 +03:00
parent 321149a1f2
commit 3db6174b8b
7 changed files with 53 additions and 26 deletions

View File

@ -1,4 +1,4 @@
import React, { useContext } from 'react';
import React from 'react';
/**
* Types
@ -10,15 +10,12 @@ import { ICourse } from '@educt/interfaces';
*/
import ConfirmDialog from '@educt/components/ConfirmDialog/ConfirmDialog';
/**
* Contexts
*/
import { CoursesPageContext } from '@educt/contexts';
/**
* Hooks
*/
import { useDeleteCourse } from '@educt/hooks/queries/course/useDeleteCourse';
import { useHistory, useLocation } from 'react-router';
import useIsMountedRef from '@educt/hooks/useIsMountedRef';
type DeleteCourseDialogPropsType = {
course: Pick<ICourse, 'id' | 'title'>;
@ -27,24 +24,29 @@ type DeleteCourseDialogPropsType = {
};
const DeleteCourseDialog: React.FC<DeleteCourseDialogPropsType> = ({ onClose, isOpen, course }) => {
const { setDeletingCourse } = useContext(CoursesPageContext);
const { deleteCourse, isLoading } = useDeleteCourse();
const isMountedRef = useIsMountedRef();
const history = useHistory();
const location = useLocation();
const handleDelete = async (isConfirmed: boolean, id: string) => {
if (isConfirmed) {
try {
await deleteCourse(id);
if (isMountedRef.current && location.pathname !== '/courses') {
history.push('/courses');
}
} catch (error: any) {
console.error(error);
} finally {
setDeletingCourse(undefined);
}
}
if (isMountedRef.current) {
/**
* Close dialog
*/
onClose();
}
};
return (

View File

@ -21,6 +21,7 @@ type DeleteLessonDialogPropsType = {
onClose: () => void;
};
//TODO pass lesson by prop
const DeleteLessonDialog: React.FC<DeleteLessonDialogPropsType> = ({ isOpen, onClose }) => {
const {
pageStore: {
@ -31,7 +32,11 @@ const DeleteLessonDialog: React.FC<DeleteLessonDialogPropsType> = ({ isOpen, onC
const handleDelete = async (isConfirmed: boolean) => {
if (isConfirmed && deletingLesson) {
try {
await deleteLesson(deletingLesson.id);
} catch (error: any) {
console.error(error);
}
}
/**

View File

@ -29,6 +29,8 @@ export const CoursesPageContext = createContext<CoursesPageContextType>({
setSelectedCategory: () => {},
courseStatus: undefined,
setCourseStatus: () => {},
//TODO: remove
deletingCourse: undefined,
setDeletingCourse: () => {},
});

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import { observer } from 'mobx-react';
import { Box, Grid, Text } from '@chakra-ui/react';
@ -11,7 +11,7 @@ import { CourseItemPropsType } from './CourseItem';
/**
* Components
*/
import DeleteCourseDialog from '../DeleteCourseDialog';
import DeleteCourseDialog from '@educt/components/Dialogs/DeleteCourseDialog';
import LoadingList from '@educt/components/LoadingList';
/**
@ -26,6 +26,7 @@ import { useDisclosure } from '@chakra-ui/hooks';
* Contexts
*/
import { CoursesPageContext } from '@educt/contexts';
import { ICourse } from '@educt/interfaces';
type CourseListPropsType = {
render: React.FC<CourseItemPropsType>;
@ -36,11 +37,17 @@ const CourseList: React.FC<CourseListPropsType> = ({ render: Item }) => {
userStore: { me },
courseStore,
} = useRootStore();
const { selectedCategory, courseStatus, deletingCourse, setDeletingCourse } = useContext(CoursesPageContext);
const [deleting, setDeleting] = useState<Pick<ICourse, 'id' | 'title'> | null>(null);
const { selectedCategory, courseStatus } = useContext(CoursesPageContext);
const { onOpen: onOpenDeleteDialog, onClose: onCloseDeleteDialog, isOpen: isOpenDeleteDialog } = useDisclosure();
const { setCourseStatus } = useSetCourseStatus();
const { courses, isLoading } = courseStore;
const deleteHandler = (course: Pick<ICourse, 'id' | 'title'>) => {
setDeleting(course);
onOpenDeleteDialog();
};
/**
* Fetch courses handler
*/
@ -57,19 +64,14 @@ const CourseList: React.FC<CourseListPropsType> = ({ render: Item }) => {
return (
<Box>
{deletingCourse && (
<DeleteCourseDialog course={deletingCourse} onClose={onCloseDeleteDialog} isOpen={isOpenDeleteDialog} />
)}
{deleting && <DeleteCourseDialog course={deleting} onClose={onCloseDeleteDialog} isOpen={isOpenDeleteDialog} />}
{courses.length !== 0 ? (
<Grid templateColumns={{ sm: 'repeat(auto-fill, minmax(400px, 1fr))' }} gap='4'>
{courses.map(course => (
<Item
key={course.id}
course={course}
onDelete={() => {
setDeletingCourse(course);
onOpenDeleteDialog();
}}
onDelete={() => deleteHandler({ id: course.id, title: course.title })}
onSetStatus={setCourseStatus}
/>
))}

View File

@ -1,7 +1,8 @@
import React from 'react';
import Helmet from 'react-helmet';
import { Redirect } from 'react-router-dom';
import { Box, Heading, Text, Tab, TabList, Flex, Tabs, TabPanels, TabPanel } from '@chakra-ui/react';
import { Box, Heading, Text, Tab, TabList, Flex, Tabs, TabPanels, TabPanel, Button } from '@chakra-ui/react';
import { DeleteIcon } from '@chakra-ui/icons';
/**
* Types
@ -16,6 +17,7 @@ import { EditCourseForm } from '@educt/components/Forms/CourseForm';
import SetCourseStatusButton from '@educt/components/SetCourseStatusButton';
import LessonList from './components/LessonList';
import { StudentList, StudentItem } from './components/StudentList';
import DeleteCourseDialog from '@educt/components/Dialogs/DeleteCourseDialog';
/**
* Hooks
@ -23,6 +25,7 @@ import { StudentList, StudentItem } from './components/StudentList';
import { useParams } from 'react-router-dom';
import { useRootStore } from '@educt/hooks/useRootStore';
import { useFetchCourse } from '@educt/hooks/queries';
import { useDisclosure } from '@chakra-ui/hooks';
/**
* Course editor
@ -35,6 +38,7 @@ const EditCoursePage: React.FC<IPageProps> = () => {
},
} = useRootStore();
const { error, isLoading } = useFetchCourse(params.id);
const { onOpen: onOpenDeleteDialog, onClose: onCloseDeleteDialog, isOpen: isOpenDeleteDialog } = useDisclosure();
/**
* Not Found
@ -53,6 +57,7 @@ const EditCoursePage: React.FC<IPageProps> = () => {
<Helmet>
<title>Editing {course.title}</title>
</Helmet>
<DeleteCourseDialog course={course} onClose={onCloseDeleteDialog} isOpen={isOpenDeleteDialog} />
<Flex justifyContent='space-between' alignItems='center' flexWrap='wrap'>
<Box mr='3'>
<Heading as='h1'>Course editor</Heading>
@ -60,6 +65,9 @@ const EditCoursePage: React.FC<IPageProps> = () => {
</Box>
<Box ml='auto' alignSelf='flex-end' justifySelf='flex-end' mt={{ base: '7', md: '0' }}>
<SetCourseStatusButton courseId={course.id} currentStatus={course.status} />
<Button onClick={onOpenDeleteDialog} ml='2' variant='outline' leftIcon={<DeleteIcon />} colorScheme='red'>
Delete
</Button>
</Box>
</Flex>
<Box>

View File

@ -10,6 +10,10 @@ export default class EditCourseStore {
public course: Omit<ICourse, 'students_count' | 'likes_count' | 'lessons_count'> | null = null;
public isDeleting: boolean = false;
public deletingCourse: Pick<ICourse, 'id' | 'title'> | undefined;
public deletingLesson: ILesson | undefined;
constructor(pageStore: PageStore) {
@ -72,7 +76,11 @@ export default class EditCourseStore {
}
}
setDeletingLesson(lesson: ILesson) {
public setDeletingLesson(lesson: ILesson) {
this.deletingLesson = lesson;
}
public setDeletingCourse(course: Pick<ICourse, 'id' | 'title'> | undefined) {
this.deletingCourse = course;
}
}