diff --git a/app/entities/course-card.tsx b/app/entities/course-card.tsx index 8d5b7cd..7d30fd3 100644 --- a/app/entities/course-card.tsx +++ b/app/entities/course-card.tsx @@ -14,7 +14,7 @@ interface Props { export function CourseCard({ id, picturePath, name, price, rating, isBought, isForEdit }: Props) { return ( - +
>() + + const navigate = useNavigate() + function changeVisibly() { setVisibly(!isVisibly) } + function setVideoPath(id_: string) { + console.log("bebra") + window.localStorage.setItem('lectureId', id_) + + if(isUpdateId) { + let requestData = new FormData() + requestData.append('courseItemId', id_) + dispatch(fetchLesson(requestData)) + + navigate(`/learn/lesson/${id_}`) + } + } + return (
{items.map((item: any, index: number) => ( -
+
setVideoPath(item.courseItemId)} key={index} className="py-3 pl-7 mt-1">

{item.elementName}

diff --git a/app/redux/slices/author.ts b/app/redux/slices/author.ts index 82dbb73..003055e 100644 --- a/app/redux/slices/author.ts +++ b/app/redux/slices/author.ts @@ -1,5 +1,4 @@ import { createSlice, createAsyncThunk } from '@reduxjs/toolkit' -import moment from 'moment' import instance from '~/axios' export const fetchAuthor = createAsyncThunk( diff --git a/app/redux/slices/lesson.ts b/app/redux/slices/lesson.ts new file mode 100644 index 0000000..ddffa75 --- /dev/null +++ b/app/redux/slices/lesson.ts @@ -0,0 +1,45 @@ +import { createSlice, createAsyncThunk } from '@reduxjs/toolkit' +import instance from '~/axios' + +export const fetchLesson = createAsyncThunk( + 'lesson/fetchLesson', + async (params: any) => { + const { data } = await instance.post('/Lesson/GetLessonFromCourseItem', params) + + return data + } +) + +const initialState = { + lesson: { + data: null, + isError: false, + status: 'loading', + }, +} + +const lessonSlice = createSlice({ + name: 'lesson', + initialState, + reducers: {}, + extraReducers: builder => { + builder.addCase(fetchLesson.pending, (state, action) => { + state.lesson.status = 'loading' + + // @ts-ignore + state.lesson.data = null + }) + builder.addCase(fetchLesson.fulfilled, (state, action) => { + state.lesson.status = 'loaded' + state.lesson.data = action.payload + }) + builder.addCase(fetchLesson.rejected, (state, action) => { + state.lesson.status = 'error' + + // @ts-ignore + state.lesson.data = null + }) + }, +}) + +export const lessonItemReducer = lessonSlice.reducer diff --git a/app/redux/store.ts b/app/redux/store.ts index a919eea..8eb0839 100644 --- a/app/redux/store.ts +++ b/app/redux/store.ts @@ -4,6 +4,7 @@ import { courseReducer } from "./slices/courses"; import { userReducer } from "./slices/user"; import { courseItemReducer } from "./slices/course"; import { authorReducer } from "./slices/author"; +import { lessonItemReducer } from "./slices/lesson"; const store = configureStore({ reducer: { @@ -12,6 +13,7 @@ const store = configureStore({ auth: authReducer, user: userReducer, author: authorReducer, + lesson: lessonItemReducer, }, }); diff --git a/app/routes/courses.$course.tsx b/app/routes/courses.$course.tsx index 32a40e4..0c3d311 100644 --- a/app/routes/courses.$course.tsx +++ b/app/routes/courses.$course.tsx @@ -9,7 +9,6 @@ import { ListElement } from '~/features' import { CourseElement } from '~/features/course-element' import { fetchAuthor } from '~/redux/slices/author' import { fetchCourse } from '~/redux/slices/courses' -import { fetchUser } from '~/redux/slices/user' import { FilledButton, Header2, Header3, Header4, Text } from '~/shared' export default function Course() { @@ -27,6 +26,8 @@ export default function Course() { formData.append('CourseID', params.course as string) formData.append('UserID', window.localStorage.getItem('userId') as string) dispatch(fetchCourse(formData)) + + window.localStorage.getItem('lectureID') }, []) useEffect(() => { diff --git a/app/routes/learn.$course.tsx b/app/routes/learn.$course.tsx new file mode 100644 index 0000000..69d67d7 --- /dev/null +++ b/app/routes/learn.$course.tsx @@ -0,0 +1,120 @@ +import type { ThunkDispatch } from '@reduxjs/toolkit' +import { useParams } from '@remix-run/react' +import { Spinner } from 'flowbite-react' +import { useEffect, useState } from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { CourseElement } from '~/features/course-element' +import { fetchAuthor } from '~/redux/slices/author' +import { fetchFullCourse } from '~/redux/slices/course' +import { Header2, Header3, Header4, Text } from '~/shared' + +export default function Course() { + const params = useParams() + + const dispatch = useDispatch>() + + // @ts-ignore + const { course } = useSelector(state => state.course) + // @ts-ignore + const { lesson } = useSelector(state => state.lesson) + + const [isPostsLoading, setIsPostLoading] = useState(true) + + useEffect(() => { + let formData = new FormData() + formData.append('ID', params.course as string) + // formData.append('ID', window.localStorage.getItem('userId') as string) + dispatch(fetchFullCourse(formData)) + + // setVideoPath(course.data.courseElementList[0].courseItems[0].videoPath) + console.log('dataview', course.data) + }, []) + + if(lesson.data != null) console.log("lesson",lesson.data.videoPath!) +// console.log("lesson",lesson.data.videoPath!) + + useEffect(() => { + if (course.status === 'loading') setIsPostLoading(true) + + if (course.status === 'loaded') setIsPostLoading(false) + + if (course.data != null) { + let authorFormData = new FormData() + authorFormData.append( + 'encriptId', + course.data.authorId.toString() as string + ) + + dispatch(fetchAuthor(authorFormData)) + } + }) + + return ( +
+ {isPostsLoading ? ( +
+ +
+ ) : ( +
+ {course.data.name} + + + +
+
+ Про курс + + Цей курс містить: + + + {course.data.description} + +
+ +
+ Програма курсу + +
+ {/* ts-ignore */} + {course.data.courseElementsList.map( + (element: any, index: number) => ( +
+ +
+ ) + )} +
+
+ +
+ Ваш викладач + +
+ +
+
+
+
+ )} +
+ ) +} diff --git a/app/routes/learn.lesson.$lesson.tsx b/app/routes/learn.lesson.$lesson.tsx new file mode 100644 index 0000000..d5c6145 --- /dev/null +++ b/app/routes/learn.lesson.$lesson.tsx @@ -0,0 +1,43 @@ +import { Spinner } from 'flowbite-react' +import { useEffect, useState } from 'react' +import { useSelector } from 'react-redux' +import { Header2} from '~/shared' + +export default function Course() { + // @ts-ignore + const { lesson } = useSelector(state => state.lesson) + + const [isPostsLoading, setIsPostLoading] = useState(true) + + useEffect(() => { + if (lesson.data != null) setIsPostLoading(false) + }) + + return ( +
+ {isPostsLoading ? ( +
+ +
+ ) : ( +
+ {lesson.data.theme} + + +
+ )} +
+ ) +} diff --git a/app/routes/my-account.courses.tsx b/app/routes/my-account.courses.tsx index 5a77e5c..86b813a 100644 --- a/app/routes/my-account.courses.tsx +++ b/app/routes/my-account.courses.tsx @@ -54,10 +54,17 @@ export default function Courses() {
) : (
- {/* @ts-ignore */} {courses.items.map((course: any) => ( - + ))}
)}