lms-frontend/src/features/Lessons/LessonPageEditor/index.tsx

156 lines
3.7 KiB
TypeScript

import { useNavigate, useParams } from "react-router-dom";
import {
lessonContents,
lessonThumbnail,
setCurrentLessonId,
setEditorActive,
setLessonContents,
setLessonState,
} from "./lessonPageEditorSlice";
import { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Card, Flex } from "antd";
import { Constants } from "core/utils/utils";
import HeaderBar from "core/components/Header";
import Droppable from "./Droppable";
import LessonPreviewCard from "shared/components/MyLessonPreviewCard";
import {
useGetLessonContentsQuery,
useGetLessonSettingsQuery,
useUpdateLessonPreviewTitleMutation,
} from "core/services/lessons";
import MyErrorResult from "shared/components/MyResult";
import styles from "./styles.module.css";
import MyEmpty from "shared/components/MyEmpty";
const PreviewCard: React.FC = () => {
const dispatch = useDispatch();
const { lessonId } = useParams();
const { data, error, isLoading, refetch } = useGetLessonSettingsQuery(
lessonId as string,
{
refetchOnMountOrArgChange: true,
}
);
const [updateLessonPreviewTitle] = useUpdateLessonPreviewTitleMutation();
useEffect(() => {
if (data?.State) dispatch(setLessonState(data.State));
}, [data]);
if (error) return <MyErrorResult />;
return (
<LessonPreviewCard
mode="editable"
lessonId={lessonId as string}
loading={isLoading}
lessonSettings={{
Title: data?.Title || "",
ThumbnailUrl: data?.ThumbnailUrl || "",
}}
onEditTitle={async (newTitle) => {
try {
const res = await updateLessonPreviewTitle({
lessonId: lessonId as string,
newTitle: newTitle,
}).unwrap();
if (res) {
refetch();
}
} catch (err) {
console.error(err);
}
}}
onThumbnailChanged={refetch}
/>
);
};
const LessonContentComponents: React.FC = () => {
const { lessonId } = useParams();
const dispatch = useDispatch();
const { data, error, isLoading } = useGetLessonContentsQuery(
lessonId as string,
{
refetchOnMountOrArgChange: true,
}
);
const lnContents = useSelector(lessonContents);
useEffect(() => {
if (!data) return;
dispatch(setLessonContents(data));
}, [data]);
if (error) return <MyErrorResult />;
return (
<Card loading={isLoading}>
<Flex vertical gap={16}>
{!lnContents || lnContents.length == 0 ? (
<MyEmpty />
) : (
<Droppable items={lnContents} />
)}
</Flex>
</Card>
);
};
export default function LessonPageEditor() {
const { lessonId } = useParams();
const navigate = useNavigate();
const dispatch = useDispatch();
const lnContents = useSelector(lessonContents);
const lnThumbnail = useSelector(lessonThumbnail);
useEffect(() => {
dispatch(setEditorActive(true));
dispatch(setCurrentLessonId(lessonId as string));
return () => {
dispatch(setEditorActive(false));
};
}, []);
return (
<>
<HeaderBar
theme="light"
backTo={Constants.ROUTE_PATHS.LESSIONS.PAGE.replace(
":lessonId",
lessonId as string
)}
onView={() =>
navigate(
Constants.ROUTE_PATHS.LESSIONS.PAGE.replace(
":lessonId",
lessonId as string
)
)
}
/>
<Flex justify="center" style={{ paddingTop: 24 }}>
<Flex
justify="center"
vertical
gap={16}
className={styles.cardContainer}
>
<PreviewCard />
<LessonContentComponents />
</Flex>
</Flex>
</>
);
}