diff --git a/backend/controllers/RatingAndReview.js b/backend/controllers/RatingAndReview.js index fbf86b8..c9e44c8 100644 --- a/backend/controllers/RatingAndReview.js +++ b/backend/controllers/RatingAndReview.js @@ -5,10 +5,11 @@ const mongoose = require("mongoose"); // create Rating and review exports.createRating = async (req, res) => { + console.log("----------------------------------------"); try { // get data const { rating, review, courseId } = req.body; - const { userId } = req.user.id; + const userId = req.user.id; // validate data if (!rating || !review || !courseId || !userId) { @@ -17,25 +18,15 @@ exports.createRating = async (req, res) => { .json({ success: false, message: "Please enter all the fields" }); } - // check if user is enrolled or not - const user = await User.findById(userId); - if (!user.courses.includes(courseId)) { - return res.status(400).json({ - success: false, - message: "You are not enrolled in this course", - }); - } - - // TODO : not forget to run this method - // const courseDetails = await Course.findOne({ - // _id: courseId, - // studentsEnrolled: { $elemMatch: { $eq: userId } }, - // }); + const courseDetails = await Course.findOne({ + _id: courseId, + studentsEnrolled: { $elemMatch: { $eq: userId } }, + }); //check if user is enrolled or not if (!courseDetails) { - return res.status(400).json({ + return res.status(404).json({ success: false, - message: "You are not enrolled in this course", + message: "Student is not enrolled in the course", }); } @@ -61,15 +52,12 @@ exports.createRating = async (req, res) => { // update course with this rating/review const updatedCourseDetails = await Course.findByIdAndUpdate( - courseId, + { _id: courseId }, { $push: { ratingAndReviews: ratingAndReview._id }, }, { new: true } - ) - .populate("updatedCourseDetails") - .exec(); - console.log(updatedCourseDetails); + ); // send response return res.status(200).json({ @@ -137,6 +125,7 @@ exports.getAllRatingAndReview = async (req, res) => { .populate({ path: "course", select: "courseName" }) .exec(); + console.log("allReviews", allReviews); if (!allReviews) { return res.status(400).json({ success: false, diff --git a/frontend/src/components/common/RatingStars.jsx b/frontend/src/components/common/RatingStars.jsx new file mode 100644 index 0000000..ae53fe6 --- /dev/null +++ b/frontend/src/components/common/RatingStars.jsx @@ -0,0 +1,38 @@ +import { useEffect, useState } from "react" +import {TiStarFullOutline, TiStarHalfOutline, TiStarOutline,} from "react-icons/ti" + + +function RatingStars({ Review_Count, Star_Size }){ + const [starCount, SetStarCount] = useState({ + full: 0, + half: 0, + empty: 0, + }) + + useEffect(() => { + const wholeStars = Math.floor(Review_Count) || 0 + SetStarCount({ + full: wholeStars, + half: Number.isInteger(Review_Count) ? 0 : 1, + empty: Number.isInteger(Review_Count) ? 5 - wholeStars : 4 - wholeStars, + }) + }, [Review_Count]) + + + return ( +
+ {[...new Array(starCount.full)].map((_, i) => { + return + })} + {[...new Array(starCount.half)].map((_, i) => { + return + })} + {[...new Array(starCount.empty)].map((_, i) => { + return + })} +
+ ) +} + + +export default RatingStars \ No newline at end of file diff --git a/frontend/src/components/common/ReviewSlider.jsx b/frontend/src/components/common/ReviewSlider.jsx new file mode 100644 index 0000000..0a40edd --- /dev/null +++ b/frontend/src/components/common/ReviewSlider.jsx @@ -0,0 +1,99 @@ +import { useEffect, useState } from "react"; +import ReactStars from "react-rating-stars-component"; + +import { Swiper, SwiperSlide } from "swiper/react"; // Import Swiper React components +import "swiper/css"; // Import Swiper styles +import "swiper/css/free-mode"; +import "swiper/css/pagination"; +import "../../App.css"; +import { FaStar } from "react-icons/fa"; // Icons + +import { apiConnector } from "../../services/apiconnector"; // Get apiFunction and the endpoint +import { ratingsEndpoints } from "../../services/apis"; + +function ReviewSlider() { + const [reviews, setReviews] = useState([]); + const truncateWords = 15; + + useEffect(() => { + (async () => { + const { data } = await apiConnector( + "GET", + ratingsEndpoints.REVIEWS_DETAILS_API + ); + if (data?.success) { + setReviews(data?.data); + } + })(); + }, []); + + return ( +
+
+ + {reviews.map((review, i) => { + return ( + +
+
+ + +
+

{`${review?.user?.firstName} ${review?.user?.lastName}`}

+

+ {" "} + {review?.course?.courseName}{" "} +

+
+
+ +

+ {review?.review.split(" ").length > truncateWords + ? `${review?.review + .split(" ") + .slice(0, truncateWords) + .join(" ")} ...` + : `${review?.review}`} +

+ +
+

+ {" "} + {review.rating.toFixed(1)}{" "} +

+ } + fullIcon={} + /> +
+
+
+ ); + })} +
+
+
+ ); +} + +export default ReviewSlider; diff --git a/frontend/src/hooks/useRouteMatch.js b/frontend/src/hooks/useRouteMatch.js new file mode 100644 index 0000000..34b5678 --- /dev/null +++ b/frontend/src/hooks/useRouteMatch.js @@ -0,0 +1,8 @@ +import { useLocation, matchPath } from "react-router-dom"; + +export default function useRouteMatch(path) { + const location = useLocation(); + return matchPath(location.pathname, { path }); +} + +// this custom hook check if current location is same as path or not; \ No newline at end of file diff --git a/frontend/src/pages/About.jsx b/frontend/src/pages/About.jsx index f897c07..49aa5df 100644 --- a/frontend/src/pages/About.jsx +++ b/frontend/src/pages/About.jsx @@ -2,13 +2,12 @@ import FoundingStory from "../assets/Images/FoundingStory.png"; import BannerImage1 from "../assets/Images/aboutus1.webp"; import BannerImage2 from "../assets/Images/aboutus2.webp"; import BannerImage3 from "../assets/Images/aboutus3.webp"; - import ContactFormSection from "../components/core/AboutPage/ContactFormSection.jsx"; import LearningGrid from "../components/core/AboutPage/LearningGrid"; import Quote from "../components/core/AboutPage/Quote"; import StatsComponenet from "../components/core/AboutPage/Stats"; import HighlightText from "../components/core/HomePage/HighlightText"; -// import ReviewSlider from "../components/common/ReviewSlider"; +import ReviewSlider from "../components/common/ReviewSlider"; import Footer from "../components/common/Footer"; const About = () => { @@ -128,7 +127,7 @@ const About = () => { {" "} Reviews from other learners{" "} - {/* */} +