mirror of
https://github.com/sergeyyarkov/educt-client.git
synced 2026-10-11 10:19:22 +03:00
feat: delete course from edit page
This commit is contained in:
parent
321149a1f2
commit
3db6174b8b
@ -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 (
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -29,6 +29,8 @@ export const CoursesPageContext = createContext<CoursesPageContextType>({
|
||||
setSelectedCategory: () => {},
|
||||
courseStatus: undefined,
|
||||
setCourseStatus: () => {},
|
||||
|
||||
//TODO: remove
|
||||
deletingCourse: undefined,
|
||||
setDeletingCourse: () => {},
|
||||
});
|
||||
|
||||
@ -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}
|
||||
/>
|
||||
))}
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user