Skip to content

Commit

Permalink
Merge pull request #34 from abinth11/refactor-instructor-add-course
Browse files Browse the repository at this point in the history
Refactor instructor add course
  • Loading branch information
abinth11 authored Jul 24, 2023
2 parents 0a25e4a + 48c27a7 commit 1ccb543
Show file tree
Hide file tree
Showing 30 changed files with 1,437 additions and 270 deletions.
485 changes: 485 additions & 0 deletions client/package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/react-pdf": "^7.0.0",
"@types/redux-thunk": "^2.1.0",
"apexcharts": "^3.41.0",
"autoprefixer": "^10.4.14",
Expand All @@ -27,6 +28,7 @@
"react-autosuggest": "^10.1.0",
"react-dom": "^18.2.0",
"react-icons": "^4.9.0",
"react-pdf": "^7.2.0",
"react-redux": "^8.0.7",
"react-router-dom": "^6.12.1",
"react-scripts": "5.0.1",
Expand Down
2 changes: 1 addition & 1 deletion client/src/api/endpoints/course/course.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
import { getCoursesByInstructorService } from "../../services/course/courseService";
import { PaymentIntent } from "@stripe/stripe-js";

export const addCourse = (courseInfo: any) => {
export const addCourse = (courseInfo: FormData) => {
return addCourseService(END_POINTS.ADD_COURSE, courseInfo);
};

Expand Down
2 changes: 1 addition & 1 deletion client/src/api/services/course/courseService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import api from "../../middlewares/protectedInterceptor";
import { PaymentIntent } from "@stripe/stripe-js";
import axiosInstance from "../../middlewares/interceptor";

export const addCourseService = async (endpoint: string, courseInfo: any) => {
export const addCourseService = async (endpoint: string, courseInfo: FormData) => {
const response = await api.post(
`${CONSTANTS_COMMON.API_BASE_URL}/${endpoint}`,
courseInfo
Expand Down
18 changes: 9 additions & 9 deletions client/src/components/pages/Course/CourseCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,27 +12,27 @@ import {
import { formatToINR } from "../../../utils/helpers";
import { CourseInterface } from "../../../types/course";

const CourseCard = ({ course }: { course: CourseInterface }) => {
const CourseCard:React.FC<CourseInterface> = ({coursesEnrolled,rating,price,isPaid,title,thumbnailUrl,description}) => {
return (
<div className="w-[18.5rem] p-5 text-customTextColor hover:shadow-md hover:border hover:border-gray-300">
<div className="relative">
<img src={course.thumbnail} className="h-1/2" alt="ui/ux review check" />
<img src={thumbnailUrl} className="h-1/2" alt="ui/ux review check" />
<div className="absolute inset-0 h-[10rem] bg-gradient-to-tr from-transparent via-transparent to-black/60" />
</div>
<div className="pt-4">
<div className="pt-4">
<div className="mb-3">
<h5 className="text-blue-gray text-xl font-medium">{course.title}</h5>
<h5 className="text-blue-gray text-xl font-medium">{title}</h5>
</div>
<p className="text-gray text-sm line-clamp-1">{course.description}</p>
<p className="text-gray text-sm line-clamp-1">{description}</p>
<div className="mt-4 flex justify-between items-center">
<div className="group">
<p className={`text-sm font-normal ${course.isPaid ? "text-blue-gray" : "text-white p-1 text-xs rounded-tl-lg rounded-br-lg font-extrabold bg-green-400"}`}>
{course.isPaid ? formatToINR(course.price) : "Free"}
<p className={`text-sm font-normal ${isPaid ? "text-blue-gray" : "text-white p-1 text-xs rounded-tl-lg rounded-br-lg font-extrabold bg-green-400"}`}>
{isPaid ? formatToINR(price) : "Free"}
</p>
</div>
<div className="flex items-center gap-1.5">
<Rating value={course.rating} readonly />
<p className="text-blue-gray text-sm font-normal">{course.rating}</p>
<Rating value={rating} readonly />
<p className="text-blue-gray text-sm font-normal">{rating}</p>
</div>
</div>
</div>
Expand Down
8 changes: 4 additions & 4 deletions client/src/components/pages/Course/ListCourse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect, useState } from "react";
import CourseCard from "./CourseCard";
import { getAllCourses } from "../../../api/endpoints/course/course";
import { toast } from "react-toastify";
import { CourseInterface } from "../../../types/course";
import { CourseInterface } from "../../../types/course";
import { Link } from "react-router-dom";
import ShimmerCard from "../../Shimmers/ShimmerCard";
import { RiSearchLine } from "react-icons/ri";
Expand Down Expand Up @@ -110,9 +110,9 @@ const ListCourse: React.FC = () => {
<div className="w-10/12">
<div className="flex mt-3 flex-wrap justify-center">
{courses.map((course: CourseInterface, index: number) => (
<Link to={course._id} key={index} className="mt-5">
<div className="m-2">
<CourseCard course={course} />
<Link to={course._id} key={course._id} className="mt-5">
<div className="m-2">
<CourseCard {...course} />
</div>
</Link>
))}
Expand Down
22 changes: 22 additions & 0 deletions client/src/components/pages/Course/PdfViewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import { Document, Page, pdfjs } from 'react-pdf';
import 'react-pdf/dist/esm/Page/AnnotationLayer.css'; // Add this line to include annotation styles

// Register the worker to load PDFs with react-pdf
pdfjs.GlobalWorkerOptions.workerSrc = `//cdnjs.cloudflare.com/ajax/libs/pdf.js/${pdfjs.version}/pdf.worker.js`;

interface PdfViewerProps {
pdfUrl: string;
}

const PdfViewer: React.FC<PdfViewerProps> = ({ pdfUrl }) => {
return (
<div>
<Document file={pdfUrl}>
<Page pageNumber={1} />
</Document>
</div>
);
};

export default PdfViewer;
75 changes: 40 additions & 35 deletions client/src/components/pages/Course/ViewCourse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { MdDone } from "react-icons/md";
import PaymentConfirmationModal from "./PaymentConfirmationModal";
import { selectIsLoggedIn } from "../../../redux/reducers/authSlice";
import LoginConfirmation from "../../common/LoginConfirmationModal";
import PdfViewer from "./PdfViewer";
const ViewCourseStudent: React.FC = () => {
const params = useParams();
const [expandedIndex, setExpandedIndex] = useState(null);
Expand All @@ -31,6 +32,7 @@ const ViewCourseStudent: React.FC = () => {
const studentId = useSelector(selectStudentId);
const isLoggedIn = useSelector(selectIsLoggedIn);
const [loginConfirmation, setLoginConfirmation] = useState(false);
const [showPdf, setShowPdf] = useState(false);

const fetchCourse = async (courseId: string): Promise<CourseInterface> => {
try {
Expand All @@ -43,7 +45,9 @@ const ViewCourseStudent: React.FC = () => {
throw error;
}
};

const handleLiClick = (): void => {
setShowPdf(true);
};
const fetchLessons = async (courseId: string) => {
try {
const lessons = await getLessonsByCourse(courseId);
Expand Down Expand Up @@ -85,8 +89,8 @@ const ViewCourseStudent: React.FC = () => {
// });
// }
const enrolled = course?.coursesEnrolled.includes(studentId ?? "");
return (
<div className='bg-white'>
return (
<div className='bg-white w-full'>
<LoginConfirmation
confirm={loginConfirmation}
setConfirm={setLoginConfirmation}
Expand All @@ -101,7 +105,7 @@ const ViewCourseStudent: React.FC = () => {
}}
setOpen={setOpenPaymentConfirmation}
/>
<div className='flex flex-col pr-5 pl-3 pt-5 md:pl-50 lg:pl-80 '>
<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>
Expand All @@ -110,7 +114,7 @@ const ViewCourseStudent: React.FC = () => {
<div className='relative p-4 '>
<img
className='w-full h-64 object-cover'
src={course?.thumbnail}
src={course?.thumbnailUrl}
alt='Course Title'
/>
<div className='absolute top-3 right-3 shadow-md bg-blue-500 text-white px-4 py-2 text-sm rounded-tl-lg rounded-br-lg'>
Expand All @@ -121,11 +125,21 @@ const ViewCourseStudent: React.FC = () => {
<h2 className='text-3xl font-bold mb-4'>{course?.title}</h2>
<p className='text-gray-700 text-lg mb-6'>{course?.description}</p>
<div className='flex items-center mb-4'>
<div className='bg-blue-500 text-white rounded-full px-3 py-1 text-sm mr-2'>
Intermediate
<div>
<h2 className='text-md mr-2 font-semibold'>Difficulty:</h2>
</div>
<div className='bg-gray-300 text-gray-700 rounded-full px-3 py-1 text-sm'>
Technology
<div
className={`rounded-full px-2 py-1 text-sm font-semibold text-white mr-2 ${
course?.level === "easy"
? "bg-green-500"
: course?.level === "medium"
? "bg-orange-500"
: course?.level === "hard"
? "bg-red-500"
: "bg-blue-500"
}`}
>
{course?.level}
</div>
</div>
<div className='flex justify-between items-center mb-6'>
Expand Down Expand Up @@ -181,15 +195,20 @@ const ViewCourseStudent: React.FC = () => {
{expandedIndex === 0 && (
<li className=''>
<ul>
<li className='p-6 border-b flex items-center cursor-pointer hover:bg-customBlueShade'>
<li
className='p-6 border-b flex items-center cursor-pointer hover:bg-customBlueShade'
onClick={handleLiClick}
>
<IoBookSharp className='mr-2 text-blue-500' />
<span className='flex-1'>Important guidelines</span>
</li>
{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 Expand Up @@ -233,38 +252,24 @@ const ViewCourseStudent: React.FC = () => {
)}
</ul>
</div>

<div className='mb-8'>
<h4 className='text-2xl font-semibold mb-2'>About this course</h4>
<h3 className='text-gray-700 mb-2 bg-white p-6 rounded-lg shadow-lg border-2'>
This course requires basic knowledge of JavaScript, familiarity
with HTML and CSS, and access to a computer with an internet
connection.Lorem ipsum dolor sit amet, consectetur adipiscing
elit, sed do eiusmod tempor incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
<h3 className='text-gray-700 mb-2 bg-white p-6 rounded-lg shadow-lg border-2 break-all'>
{course?.about}
</h3>
</div>

<div className='mb-8'>
<h4 className='text-2xl font-semibold mb-2'>Requirements</h4>
<ul className='text-gray-700 bg-white mt-2 border-2 shadow-md rounded-lg'>
<li className='mb-2 p-3 pt-3'>
<span className='text-blue-500 mr-2 '>&#9679;</span> Basic
knowledge of JavaScript
</li>
<li className='mb-2 p-3'>
<span className='text-blue-500 mr-2'>&#9679;</span>
Familiarity with HTML and CSS
</li>
<li className='mb-4 p-3'>
<span className='text-blue-500 mr-2'>&#9679;</span> Access to
a computer with internet connection
</li>
{course?.requirements.map((item, index) => {
return (
<li className='mb-2 p-3 pt-3' key={index}>
<span className='text-blue-500 mr-2 '>&#9679;</span>
{item}
</li>
);
})}
</ul>
</div>
<div className='flex items-center justify-end'>
Expand Down
Loading

0 comments on commit 1ccb543

Please sign in to comment.