Skip to content

Commit

Permalink
Merge pull request #74 from abinth11/bug-fixes-and-updates
Browse files Browse the repository at this point in the history
Bug fixes and updates
  • Loading branch information
abinth11 committed Aug 30, 2023
2 parents 6579e80 + 527152f commit c9d485f
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 71 deletions.
1 change: 1 addition & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"react-spinners": "^0.13.8",
"react-toastify": "^9.1.3",
"redux": "^4.2.1",
"redux-persist": "^6.0.0",
"redux-thunk": "^2.4.2",
"socket.io-client": "^4.7.1",
"tailwind-scrollbar": "^3.0.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,12 +136,12 @@ const PaymentConfirmationModal: React.FC<PaymentModalProps> = ({
)}
</Typography>
<Typography variant='body' color='gray'>
<span className='font-semibold'>Course Overview:</span>{" "}
<span className='font-semibold'>Course Overview:</span><br />
{courseDetails?.overview}
</Typography>
</DialogBody>
<DialogFooter>
<Button
<Button
variant='gradient'
color='green'
onClick={handleCourseEnroll}
Expand Down
8 changes: 1 addition & 7 deletions client/src/components/pages/course-pages/video-player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,12 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({
type: "video/mp4", // Update the MIME type to video/mp4
});
} else {
showPurchaseOverlay();
// Show something in the player or outside when the course is not purchased
// For example, you can show a message or a custom component
// player.poster("path/to/poster-image.jpg"); // Set a poster image to show as a thumbnail
// You can also add a custom overlay or message within the player
// player.addChild("CustomOverlayComponent", {});
showPurchaseOverlay()
}
}
};

const showPurchaseOverlay = () => {
// JSX for the purchase poster overlay content
const purchaseOverlay = (
<div className='purchase-overlay pt-16 flex items-center justify-center'>
<div className='text-center '>
Expand Down
24 changes: 14 additions & 10 deletions client/src/components/pages/course-pages/view-course.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { IoBookSharp } from "react-icons/io5";
import useApiData from "../../../hooks/useApiCall";
import { getLessonsByCourse } from "../../../api/endpoints/course/lesson";
import { useDispatch } from "react-redux";
import { setCourseId } from "../../../redux/reducers/courseSlice";
import { setCourse } from "../../../redux/reducers/courseSlice";
import { useSelector } from "react-redux";
import { selectStudentId } from "../../../redux/reducers/studentSlice";
import { MdDone } from "react-icons/md";
Expand All @@ -33,6 +33,7 @@ const ViewCourseStudent: React.FC = () => {
const isLoggedIn = useSelector(selectIsLoggedIn);
const [loginConfirmation, setLoginConfirmation] = useState(false);
const [showPdf, setShowPdf] = useState(false);
const [successToastShown, setSuccessToastShown] = useState(false);

const fetchCourse = async (courseId: string): Promise<CourseInterface> => {
try {
Expand Down Expand Up @@ -67,7 +68,7 @@ const ViewCourseStudent: React.FC = () => {
);

const course: CourseInterface | null = data;
courseId && dispatch(setCourseId({ courseId }));
course && dispatch(setCourse({ course }));

const handleToggle = (index: any) => {
setExpandedIndex(index === expandedIndex ? null : index);
Expand All @@ -83,11 +84,13 @@ const ViewCourseStudent: React.FC = () => {
if (isLoading || isLessonsLoading) {
return <ViewCourseShimmer />;
}
// if (location.hash === "#success") {
// toast.success("Successfully enrolled into the course", {
// position: toast.POSITION.BOTTOM_RIGHT,
// });
// }

if (location.hash === "#success" && !successToastShown) {
toast.success("Successfully enrolled into the course", {
position: toast.POSITION.BOTTOM_RIGHT,
});
setSuccessToastShown(true);
}
const enrolled = course?.coursesEnrolled.includes(studentId ?? "");
return (
<div className='bg-white w-full'>
Expand All @@ -106,7 +109,6 @@ const ViewCourseStudent: React.FC = () => {
setOpen={setOpenPaymentConfirmation}
/>
<div className='flex flex-col pr-5 pl-3 pt-5 md:pl-50 lg:pl-80 '>
<h2>{location.hash}</h2>
<CustomBreadCrumbs paths={location.pathname} />
</div>
<div className='flex flex-col items-center '>
Expand Down Expand Up @@ -202,13 +204,15 @@ const ViewCourseStudent: React.FC = () => {
<IoBookSharp className='mr-2 text-blue-500' />
<span className='flex-1'>Important guidelines</span>
</li>
{showPdf && <PdfViewer pdfUrl={course?.guidelinesUrl??""} />}
{showPdf && (
<PdfViewer pdfUrl={course?.guidelinesUrl ?? ""} />
)}

<Link to={"watch-lessons/1"}>
<li className='p-6 border-b flex items-center cursor-pointer hover:bg-customBlueShade'>
<BiVideo className='mr-2 text-blue-500' />
<span className='flex-1'>Introduction video</span>
</li>
</li>
</Link>
</ul>
</li>
Expand Down
35 changes: 21 additions & 14 deletions client/src/components/pages/course-pages/watch-lesson.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,11 @@ import { ApiResponseLesson } from "../../../api/types/apiResponses/ap-response-l
import { Media } from "../../../api/types/apiResponses/ap-response-lesson";
import { BiVideo } from "react-icons/bi";
import { useSelector } from "react-redux";
import { selectIsLoggedIn } from "../../../redux/reducers/authSlice";
import { selectStudentId } from "../../../redux/reducers/studentSlice";
import { selectUserType } from "../../../redux/reducers/authSlice";
import { selectCourse } from "redux/reducers/courseSlice";
import ShimmerEffectWatchLessons from "../../shimmer/watch-lessons-shimmer";
import ShimmerVideoPlayer from "../../shimmer/shimmer-video-player";



const WatchLessons: React.FC = () => {
const [selectedItemIndex, setSelectedItemIndex] = useState(0);
const [isLoadingAllLessons, setIsLoadingAllLessons] = useState(false);
Expand All @@ -27,13 +24,18 @@ const WatchLessons: React.FC = () => {
const [allLessons, setAllLessons] = useState<Array<ApiResponseLesson>>([]);
const [videoKey, setVideoKey] = useState<string | null>(null);
const { lessonId } = useParams();
const isLoggedIn = useSelector(selectIsLoggedIn);
const [currentLessonId, setCurrentLessonId] = useState<string | undefined>(
lessonId
);
const studentId = useSelector(selectStudentId)
const studentId = useSelector(selectStudentId);
const currentCourse = useSelector(selectCourse);
const { courseId } = useParams();
const user = useSelector(selectUserType)
let isCoursePurchased = false;

if (currentCourse) {
isCoursePurchased = currentCourse.coursesEnrolled.includes(studentId)
}


const handleItemClick = (index: number) => {
setSelectedItemIndex(index);
Expand Down Expand Up @@ -109,7 +111,10 @@ const WatchLessons: React.FC = () => {
) : (
<div className='md:w-3/4 w-full overflow-y-scroll scrollbar-track-blue-gray-50 scrollbar-thumb-gray-400 scrollbar-thin scrollbar-h-md'>
<div className='h-3/4'>
<VideoPlayer videoKey={videoKey} isCoursePurchased={isLoggedIn&&user==="student"} />
<VideoPlayer
videoKey={videoKey}
isCoursePurchased={isCoursePurchased}
/>
</div>
<div className=''>
<ul className='flex p-3'>
Expand Down Expand Up @@ -161,9 +166,9 @@ const WatchLessons: React.FC = () => {
<div className='w-1/4 hidden md:block flex-grow mt-3 mb-2 overflow-y-scroll scrollbar-thumb-gray-400 scrollbar-rounded scrollbar-track-gray-200 scrollbar-thin'>
<h1 className='font-semibold text-blue-gray-800 text-2xl border-b border-gray-300 p-2'>
Lessons
</h1>
</h1>
<ul>
{allLessons.map((lesson,index) => (
{allLessons.map((lesson, index) => (
<li
key={lesson._id}
onClick={() => {
Expand All @@ -176,12 +181,14 @@ const WatchLessons: React.FC = () => {
: "hover:bg-gray-100"
}
`}
>
<BiVideo className='mr-2 text-blue-500' />
<span className='flex-1 text-sm font-light text-gray-700'>Episode 0{index+1} - {lesson.title}</span>
>
<BiVideo className='mr-2 text-blue-500' />
<span className='flex-1 text-sm font-light text-gray-700'>
Episode 0{index + 1} - {lesson.title}
</span>
</li>
))}
</ul>
</ul>
</div>
</div>
);
Expand Down
24 changes: 12 additions & 12 deletions client/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,29 @@ import AppRouter from "./routes";
import { RouterProvider } from "react-router-dom";
import { GoogleOAuthProvider } from "@react-oauth/google";
import { Provider } from "react-redux";
import { store } from "./redux/store";
import { ThemeProvider } from "@material-tailwind/react";
import { store,persistor } from "./redux/store";
import { ThemeProvider } from "@material-tailwind/react";
import { ToastContainer } from "react-toastify";
import Modal from 'react-modal';
import Modal from "react-modal";
import CONFIG_KEYS from "./config";
import { PersistGate } from "redux-persist/integration/react";


const root = ReactDOM.createRoot(
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
Modal.setAppElement('#root');
Modal.setAppElement("#root");

root.render(
<React.StrictMode>
<GoogleOAuthProvider clientId={CONFIG_KEYS.GOOGLE_AUTH_CLIENT_ID}>
<Provider store={store}>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<ThemeProvider>
<RouterProvider router={AppRouter} />
<ToastContainer />
<RouterProvider router={AppRouter} />
<ToastContainer />
</ThemeProvider>
</Provider>
</PersistGate>
</Provider>
</GoogleOAuthProvider>
</React.StrictMode>
);


28 changes: 13 additions & 15 deletions client/src/redux/reducers/courseSlice.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,30 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
import { RootState } from "../store";
import { CourseInterface } from "../../types/course"; // Corrected import path

const initialState = {
data: {
courseId: "",
},
interface InitialState {
course: CourseInterface | null;
}

const initialState: InitialState = {
course: null,
};

const courseSlice = createSlice({
name: "course",
initialState,
reducers: {
setCourseId(state, action: PayloadAction<{ courseId: string }>) {
state.data = {
courseId: action.payload.courseId,
};
setCourse(state, action: PayloadAction<{ course: CourseInterface }>) {
state.course = action.payload.course;
},
clearCourseId(state) {
state.data = {
courseId: "",
};
clearCourse(state) {
state.course = null;
},
},
});

export const { setCourseId, clearCourseId } = courseSlice.actions;

export const selectCourseId = (state: RootState) => state.course.data.courseId;
export const { setCourse, clearCourse } = courseSlice.actions;

export const selectCourse = (state: RootState) => state.course.course

export const courseReducer = courseSlice.reducer;
2 changes: 1 addition & 1 deletion client/src/redux/reducers/studentSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const { setDetails, clearDetails } = studentSlice.actions;

export const selectStudent = (state: RootState) => state.student;

export const selectStudentId = (state: RootState) => state.student.studentId;
export const selectStudentId = (state: RootState) => state.student.studentDetails?._id;

export const selectIsFetchingStudent = (state: RootState) => state.student.isFetching;

Expand Down
33 changes: 24 additions & 9 deletions client/src/redux/store.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
import { configureStore } from "@reduxjs/toolkit";
import { configureStore,combineReducers } from "@reduxjs/toolkit";
import { authReducer } from "./reducers/authSlice";
import { courseReducer } from "./reducers/courseSlice";
import { studentReducer } from "./reducers/studentSlice";
import { helperReducer } from "./reducers/helperSlice";
import { instructorReducer } from "./reducers/instructorSlice";
import * as reduxThunk from "redux-thunk/extend-redux";
export const store = configureStore({
reducer: {
auth: authReducer,
course: courseReducer,
student: studentReducer,
instructor: instructorReducer,
helper: helperReducer,
},
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';

const persistConfig = {
key: 'root', // Key to use for storing data in storage
storage, // Storage mechanism (local storage or session storage)
whitelist: ['course', 'student', 'instructor'], // Reducers to persist
};

const persistedReducer = persistReducer(persistConfig, combineReducers({
auth: authReducer,
course: courseReducer,
student: studentReducer,
instructor: instructorReducer,
helper: helperReducer,
}));

const store = configureStore({
reducer: persistedReducer, // Use the persisted reducer
});

const persistor = persistStore(store);

export type State = typeof store;

export type RootState = ReturnType<typeof store.getState>;

export type AppDispatch = typeof store.dispatch;

export {store,persistor}
5 changes: 5 additions & 0 deletions client/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8860,6 +8860,11 @@ redent@^3.0.0:
indent-string "^4.0.0"
strip-indent "^3.0.0"

redux-persist@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8"
integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==

redux-thunk@*, redux-thunk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b"
Expand Down
2 changes: 1 addition & 1 deletion server/src/frameworks/webserver/express.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import rateLimit from 'express-rate-limit';

const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // maximum requests per windowMs
max: 200, // maximum requests per windowMs
message: 'Too many requests from this IP, please try again later.',
keyGenerator: (req) => {
const xRealIp = req.headers['x-real-ip'];
Expand Down

0 comments on commit c9d485f

Please sign in to comment.