From 1a271613da66e2bb77d0f70a7d4b6e26303daeb1 Mon Sep 17 00:00:00 2001 From: Amit Amrutiya Date: Tue, 13 Feb 2024 00:35:39 +0530 Subject: [PATCH] convert single quotes into double quotes --- .eslintignore | 4 - .eslintrc.js | 15 +- backend/config/cloudinary.js | 6 +- backend/config/database.js | 14 +- backend/config/razorpay.js | 6 +- backend/controllers/auth.controller.js | 128 ++--- backend/controllers/cart.controller.js | 56 +-- backend/controllers/category.controller.js | 52 +- backend/controllers/contactUs.controller.js | 14 +- backend/controllers/course.controller.js | 174 +++---- .../controllers/courseProgress.controller.js | 28 +- backend/controllers/payments.controller.js | 108 ++--- backend/controllers/profile.controller.js | 114 ++--- .../controllers/ratingAndReview.controller.js | 56 +-- .../controllers/resetPassword.controller.js | 54 +-- backend/controllers/section.controller.js | 80 +-- backend/controllers/subSection.controller.js | 94 ++-- backend/controllers/user.controller.js | 46 +- backend/index.js | 60 +-- backend/mail/templates/contactFormRes.js | 2 +- .../mail/templates/courseEnrollmentEmail.js | 2 +- .../templates/emailVerficationTemplate.js | 2 +- backend/mail/templates/passwordUpdate.js | 2 +- backend/mail/templates/paymentSuccessEmail.js | 2 +- .../mail/templates/resetPasswordTemplate.js | 2 +- backend/middlewares/auth.middelware.js | 50 +- backend/models/category.model.js | 6 +- backend/models/course.model.js | 6 +- backend/models/courseProgress.model.js | 6 +- backend/models/otp.model.js | 24 +- backend/models/profile.model.js | 6 +- backend/models/ratingAndReview.model.js | 6 +- backend/models/section.model.js | 6 +- backend/models/subSection.model.js | 6 +- backend/models/tags.model.js | 6 +- backend/models/user.model.js | 6 +- backend/routes/contactUs.route.js | 10 +- backend/routes/course.route.js | 68 +-- backend/routes/payment.route.js | 16 +- backend/routes/profile.route.js | 18 +- backend/routes/user.route.js | 30 +- backend/test/models/category.model.test.js | 32 +- backend/utils/fileUploader.js | 16 +- backend/utils/mailSender.js | 12 +- backend/utils/secToDuration.js | 12 +- frontend/postcss.config.js | 2 +- frontend/src/data/dashboard-links.js | 4 +- frontend/src/data/footer-links.js | 2 +- frontend/src/data/homepage-explore.js | 2 +- frontend/src/data/navbar-links.js | 2 +- frontend/src/hooks/useOnClickOutside.js | 20 +- frontend/src/hooks/useRouteMatch.js | 6 +- frontend/src/reducer/index.js | 16 +- frontend/src/services/apiconnector.js | 8 +- frontend/src/services/apis.js | 22 +- frontend/src/services/formatDate.js | 18 +- .../src/services/operations/SettingsAPI.js | 98 ++-- frontend/src/services/operations/authAPI.js | 154 +++--- .../services/operations/courseDetailsAPI.js | 458 +++++++++--------- .../operations/pageAndComponentData.js | 28 +- .../src/services/operations/profileAPI.js | 76 +-- .../services/operations/studentFeaturesAPI.js | 90 ++-- frontend/src/slices/authSlice.js | 16 +- frontend/src/slices/cartSlice.js | 60 +-- frontend/src/slices/courseSlice.js | 24 +- frontend/src/slices/profileSlice.js | 14 +- frontend/src/slices/viewCourseSlice.js | 20 +- frontend/src/utils/avgRating.js | 14 +- frontend/src/utils/constants.js | 4 +- frontend/src/utils/dateFormatter.js | 4 +- frontend/src/utils/totalDuration.js | 24 +- frontend/tailwind.config.js | 2 +- frontend/vite.config.js | 10 +- package.json | 4 +- 74 files changed, 1331 insertions(+), 1334 deletions(-) delete mode 100644 .eslintignore diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index fa7842d..0000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -dist/*.js -test.js -frontend/dist/*.js -frontend/dist diff --git a/.eslintrc.js b/.eslintrc.js index 176c65f..3aec6ab 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,40 +6,39 @@ module.exports = { extends: [ "standard", "plugin:react/recommended", + "eslint:recommended", + "plugin:react/recommended", ], overrides: [ { env: { node: true, }, - files: [ - ".eslintrc.{js,cjs}", - ], + files: [".eslintrc.{js,cjs,jsx,mjs,ts,tsx}"], parserOptions: { sourceType: "script", }, }, ], + parser: "@babel/eslint-parser", parserOptions: { ecmaVersion: "latest", sourceType: "module", ecmaFeatures: { jsx: true, // This is the key line - it tells ESLint to expect JSX syntax }, + requireConfigFile: false, }, - plugins: [ - "react", - ], + plugins: ["react"], rules: { "comma-dangle": ["error", "always-multiline"], // Enforces trailing commas for multiline statements "react/jsx-filename-extension": ["warn", { extensions: [".js", ".jsx"] }], // Enforces .jsx extension for JSX files "react/react-in-jsx-scope": "off", // Prevents React to be incorrectly marked as unused quotes: ["error", "double"], - semi: ["error", "always"], }, settings: { react: { version: "detect", // Automatically picks the version you have installed. }, }, -}; +} diff --git a/backend/config/cloudinary.js b/backend/config/cloudinary.js index 1a34811..2d71712 100644 --- a/backend/config/cloudinary.js +++ b/backend/config/cloudinary.js @@ -1,4 +1,4 @@ -import { v2 as cloudinary } from "cloudinary"; +import { v2 as cloudinary } from "cloudinary" export function cloudinaryConnect () { try { @@ -6,8 +6,8 @@ export function cloudinaryConnect () { cloud_name: process.env.CLOUDINARY_CLOUD_NAME, api_key: process.env.CLOUDINARY_API_KEY, api_secret: process.env.CLOUDINARY_API_SECRET, - }); + }) } catch (error) { - console.log("Error in connecting to cloudinary: " + error); + console.log("Error in connecting to cloudinary: " + error) } } diff --git a/backend/config/database.js b/backend/config/database.js index fc470e0..4fc6eec 100644 --- a/backend/config/database.js +++ b/backend/config/database.js @@ -1,13 +1,13 @@ -import mongoose from "mongoose"; +import mongoose from "mongoose" const connectDB = async () => { try { - await mongoose.connect(process.env.MONGODB_URL); - console.log("\n MongoDB connected"); + await mongoose.connect(process.env.MONGODB_URL) + console.log("\n MongoDB connected") } catch (error) { - console.log("MongoDB connection FAILED", error); - process.exit(1); + console.log("MongoDB connection FAILED", error) + process.exit(1) } -}; +} -export default connectDB; +export default connectDB diff --git a/backend/config/razorpay.js b/backend/config/razorpay.js index 10a93cd..ef69d43 100644 --- a/backend/config/razorpay.js +++ b/backend/config/razorpay.js @@ -1,8 +1,8 @@ -import Razorpay from "razorpay"; +import Razorpay from "razorpay" const instance = new Razorpay({ key_id: process.env.RAZORPAY_KEY_ID, key_secret: process.env.RAZORPAY_KEY_SECRET, -}); +}) -export default instance; +export default instance diff --git a/backend/controllers/auth.controller.js b/backend/controllers/auth.controller.js index 9cc5465..4e7c389 100644 --- a/backend/controllers/auth.controller.js +++ b/backend/controllers/auth.controller.js @@ -1,33 +1,33 @@ -import User from "../models/user.model.js"; -import OTP from "../models/otp.model.js"; -import Profile from "../models/profile.model.js"; -import otpGenerator from "otp-generator"; -import bcrypt from "bcrypt"; -import jwt from "jsonwebtoken"; -import mailSender from "../utils/mailSender.js"; -import passwordUpdated from "../mail/templates/passwordUpdate.js"; +import User from "../models/user.model.js" +import OTP from "../models/otp.model.js" +import Profile from "../models/profile.model.js" +import otpGenerator from "otp-generator" +import bcrypt from "bcrypt" +import jwt from "jsonwebtoken" +import mailSender from "../utils/mailSender.js" +import passwordUpdated from "../mail/templates/passwordUpdate.js" // Send Otp export async function sendOTP (req, res) { try { // fetch email from request body - const { email } = req.body; + const { email } = req.body // validate data if (!email) { return res .status(403) - .json({ success: false, message: "Please fill all the fields" }); + .json({ success: false, message: "Please fill all the fields" }) } // check if user already exist - const checkUserPresent = await User.findOne({ email }); + const checkUserPresent = await User.findOne({ email }) // if user laready exist then return a response if (checkUserPresent) { return res .status(401) - .json({ success: true, message: "User already exist" }); + .json({ success: true, message: "User already exist" }) } // generate otp @@ -35,37 +35,37 @@ export async function sendOTP (req, res) { specialChars: false, lowerCaseAlphabets: false, upperCaseAlphabets: false, - }); - console.log("OTP generated: " + otp); + }) + console.log("OTP generated: " + otp) // check if otp already exist // TODO 1: this is not a good way to check if otp already exist make it more efficient by bruteforce - let result = await OTP.findOne({ otp }); + let result = await OTP.findOne({ otp }) while (result) { otp = otpGenerator.generate(6, { upperCase: false, specialChars: false, alphabets: false, - }); - result = await OTP.findOne({ otp }); + }) + result = await OTP.findOne({ otp }) } // save otp to database - const otpBody = await OTP.create({ email, otp }); + const otpBody = await OTP.create({ email, otp }) // return response successful res.status(200).json({ success: true, message: "OTP sent successfully", data: otpBody, - }); + }) } catch (error) { - console.log("Error in sending OTP: " + error); + console.log("Error in sending OTP: " + error) return res.status(500).json({ success: false, message: error.message, - }); + }) } } @@ -82,7 +82,7 @@ export async function signUp (req, res) { accountType, contactNumber, otp, - } = req.body; + } = req.body // validate data if ( @@ -95,42 +95,42 @@ export async function signUp (req, res) { ) { return res .status(403) - .json({ success: false, message: "Please fill all the fields" }); + .json({ success: false, message: "Please fill all the fields" }) } // match 2 password if (password !== confirmPassword) { return res .status(400) - .json({ success: false, message: "Password does not match" }); + .json({ success: false, message: "Password does not match" }) } // check if user already exist - const existingUser = await User.findOne({ email }); + const existingUser = await User.findOne({ email }) if (existingUser) { return res .status(400) - .json({ success: false, message: "User already exist" }); + .json({ success: false, message: "User already exist" }) } // find most recent OTP stored for the user const recentOtp = await OTP.find({ email }) .sort({ createdAt: -1 }) - .limit(1); + .limit(1) - console.log("recentOtp " + recentOtp); + console.log("recentOtp " + recentOtp) // check if OTP is valid if (recentOtp.length === 0) { - return res.status(400).json({ success: false, message: "OTP not found" }); + return res.status(400).json({ success: false, message: "OTP not found" }) } else if (recentOtp[0].otp !== otp) { - return res.status(400).json({ success: false, message: "Invalid OTP" }); + return res.status(400).json({ success: false, message: "Invalid OTP" }) } // Hash Password - const hashedPawword = await bcrypt.hash(password, 10); + const hashedPawword = await bcrypt.hash(password, 10) // Create the user - let approved = ""; - approved === "Instructor" ? (approved = false) : (approved = true); + let approved = "" + approved === "Instructor" ? (approved = false) : (approved = true) // save user to database const profileDetails = await Profile.create({ @@ -138,7 +138,7 @@ export async function signUp (req, res) { dateOfBirth: null, about: null, contactNumber: contactNumber ?? null, - }); + }) const user = await User.create({ firstName, @@ -150,42 +150,42 @@ export async function signUp (req, res) { approved, additionalDetails: profileDetails._id, image: `https://api.dicebear.com/5.x/initials/svg?seed=${firstName}+${lastName}`, - }); + }) // return response res.status(200).json({ success: true, message: "User created successfully", data: user, - }); + }) } catch (error) { - console.log("Error in creating user: " + error); + console.log("Error in creating user: " + error) return res.status(500).json({ success: false, message: error.message, - }); + }) } } // Login export async function login (req, res) { try { - const { email, password } = req.body; // get data from req body + const { email, password } = req.body // get data from req body if (!email || !password) { // validate krlo means all inbox are filled or not; return res.status(403).json({ success: false, message: "Please Fill up All the Required Fields", - }); + }) } - const user = await User.findOne({ email }).populate("additionalDetails"); // user check exist or not + const user = await User.findOne({ email }).populate("additionalDetails") // user check exist or not if (!user) { return res.status(401).json({ success: false, message: "User is not registrered, please signup first", - }); + }) } if (await bcrypt.compare(password, user.password)) { @@ -195,13 +195,13 @@ export async function login (req, res) { email: user.email, id: user._id, accountType: user.accountType, - }; + } const token = jwt.sign(payload, process.env.JWT_SECRET, { // generate token (combination of header , payload , signature) expiresIn: "20h", // set expiry time; - }); - user.token = token; - user.password = undefined; + }) + user.token = token + user.password = undefined const options = { // create cookie and send response @@ -209,25 +209,25 @@ export async function login (req, res) { Date.now() + process.env.JWT_COOKIE_EXPIRE * 24 * 60 * 60 * 1000, ), httpOnly: true, - }; + } res.cookie("token", token, options).status(200).json({ success: true, token, user, message: "Logged in successfully", - }); + }) } else { return res.status(401).json({ success: false, message: "Password is incorrect", - }); + }) } } catch (error) { - console.log(error); + console.log(error) return res.status(500).json({ success: false, message: "Login Failure, please try again", - }); + }) } } @@ -235,31 +235,31 @@ export async function login (req, res) { export async function changePassword (req, res) { try { // Fetch data from request body - const { oldPassword, newPassword } = req.body; - const userDetails = await User.findById(req.user.id); + const { oldPassword, newPassword } = req.body + const userDetails = await User.findById(req.user.id) // Validate data if (!userDetails || !oldPassword || !newPassword) { return res .status(403) - .json({ success: false, message: "Please fill all the fields" }); + .json({ success: false, message: "Please fill all the fields" }) } // Check if password is correct const isPasswordCorrect = await bcrypt.compare( oldPassword, userDetails.password, - ); + ) if (isPasswordCorrect) { // Hash Password - const hashedPawword = await bcrypt.hash(newPassword, 10); + const hashedPawword = await bcrypt.hash(newPassword, 10) // update password const updatedUserDetails = await User.findByIdAndUpdate( req.user.id, { password: hashedPawword }, { new: true }, - ); + ) // Send mail to user try { @@ -270,28 +270,28 @@ export async function changePassword (req, res) { updatedUserDetails.email, `Password updated successfully for ${updatedUserDetails.firstName} ${updatedUserDetails.lastName}`, ), - ); - console.log("Email sent successfully:", emailResponse.response); + ) + console.log("Email sent successfully:", emailResponse.response) } catch (error) { return res.status(500).json({ success: false, message: "Error occurred while sending email", error: error.message, - }); + }) } // return response res.status(200).json({ success: true, message: "Password changed successfully", - }); + }) } else { return res .status(401) - .json({ success: false, message: "Password not correct" }); + .json({ success: false, message: "Password not correct" }) } } catch (error) { - console.log("Error in changing password: " + error); - return res.status(500).json({ success: false, message: error.message }); + console.log("Error in changing password: " + error) + return res.status(500).json({ success: false, message: error.message }) } } diff --git a/backend/controllers/cart.controller.js b/backend/controllers/cart.controller.js index a1438e8..39eb0b4 100644 --- a/backend/controllers/cart.controller.js +++ b/backend/controllers/cart.controller.js @@ -1,100 +1,100 @@ -import User from "../models/user.model.js"; +import User from "../models/user.model.js" export async function addCourseIntoCart (req, res) { try { - const { courseId, userId } = req.body; - const user = await User.findById(userId); + const { courseId, userId } = req.body + const user = await User.findById(userId) if (courseId === undefined || userId === undefined) { return res.status(400).json({ success: false, message: "courseId or userId is undefined", - }); + }) } if (!user) { return res.status(404).json({ success: false, message: "User not found", - }); + }) } - user.cartAddedCourses.push(courseId); - await user.save(); + user.cartAddedCourses.push(courseId) + await user.save() return res.status(200).json({ success: true, message: "Course added to cart", - }); + }) } catch (error) { - console.log("Error in addCourseIntoCart: " + error); + console.log("Error in addCourseIntoCart: " + error) return res.status(500).json({ success: false, message: "Error on addCourseIntoCart controller: " + error, - }); + }) } } export async function removeCourseFromCart (req, res) { - const { courseId, userId } = req.body; + const { courseId, userId } = req.body if (courseId === undefined || userId === undefined) { return res.status(400).json({ success: false, message: "courseId or userId is undefined", - }); + }) } try { - const user = await User.findById(userId); + const user = await User.findById(userId) if (!user) { return res.status(404).json({ success: false, message: "User not found", - }); + }) } - user.cartAddedCourses.pull(courseId); - await user.save(); + user.cartAddedCourses.pull(courseId) + await user.save() return res.status(200).json({ success: true, message: "Course removed from cart", - }); + }) } catch (error) { - console.log("Error in removeFromCart: " + error); + console.log("Error in removeFromCart: " + error) return res.status(500).json({ success: false, message: "Error on removeFromCart controller: " + error, - }); + }) } } export async function clearCart (req, res) { - const { userId } = req.body; + const { userId } = req.body if (userId === undefined) { return res.status(400).json({ success: false, message: "userId is undefined", - }); + }) } try { - const user = await User.findById(userId); + const user = await User.findById(userId) if (!user) { return res.status(404).json({ success: false, message: "User not found", - }); + }) } - user.cartAddedCourses = []; - await user.save(); + user.cartAddedCourses = [] + await user.save() return res.status(200).json({ success: true, message: "Cart cleared", - }); + }) } catch (error) { - console.log("Error in clearCart: " + error); + console.log("Error in clearCart: " + error) return res.status(500).json({ success: false, message: "Error on clearCart controller: " + error, - }); + }) } } diff --git a/backend/controllers/category.controller.js b/backend/controllers/category.controller.js index e8c427c..b22b839 100644 --- a/backend/controllers/category.controller.js +++ b/backend/controllers/category.controller.js @@ -1,21 +1,21 @@ -import Category from "../models/category.model.js"; +import Category from "../models/category.model.js" function getRandomInt (max) { - return Math.floor(Math.random() * max); + return Math.floor(Math.random() * max) } // create category handler function export async function createCategory (req, res) { try { // fetch name and description from request body - const { name, description } = req.body; + const { name, description } = req.body // validate data if (!name || !description) { return res.status(403).json({ success: false, message: "Please fill all the fields", - }); + }) } // check if user is admin then only create category @@ -23,33 +23,33 @@ export async function createCategory (req, res) { return res.status(403).json({ success: false, message: "You are not authorized to create category", - }); + }) } // check if category already exist - const isExistingCategory = await Category.findOne({ name }); + const isExistingCategory = await Category.findOne({ name }) if (isExistingCategory) { return res.status(400).json({ success: false, message: "Category already exist", - }); + }) } // create category - const categoryDetails = await Category.create({ name, description }); + const categoryDetails = await Category.create({ name, description }) // return response res.status(200).json({ success: true, message: "Category created successfully", categoryDetails, - }); + }) } catch (error) { - console.log("Error in creating category: " + error); + console.log("Error in creating category: " + error) return res.status(500).json({ success: false, message: error.message, - }); + }) } } @@ -57,17 +57,17 @@ export async function createCategory (req, res) { export async function showAllCategories (req, res) { try { // fetch all categories - const allCategories = await Category.find(); + const allCategories = await Category.find() res.status(200).json({ success: true, message: "All categories return successfully", allCategories, - }); + }) } catch (error) { return res.status(500).json({ success: false, message: error.message, - }); + }) } } @@ -75,14 +75,14 @@ export async function showAllCategories (req, res) { export async function categoryPageDetails (req, res) { try { // get categoryId - const { categoryId } = req.body; + const { categoryId } = req.body // validate data if (!categoryId) { return res.status(400).json({ success: false, message: "Please provide category id", - }); + }) } // get category details @@ -92,14 +92,14 @@ export async function categoryPageDetails (req, res) { match: { status: "Published" }, populate: ["ratingAndReviews", "instructor"], }) - .exec(); + .exec() // validation if (selectedCategory.courses.length === 0) { return res.status(404).json({ success: false, message: "No courses found for the selected category.", - }); + }) } // get courses of different category @@ -107,7 +107,7 @@ export async function categoryPageDetails (req, res) { _id: { $ne: categoryId }, }) .populate("courses") - .exec(); + .exec() const differentCategory = await Category.findOne( categoriesExceptSelected[getRandomInt(categoriesExceptSelected.length)] @@ -118,7 +118,7 @@ export async function categoryPageDetails (req, res) { match: { status: "Published" }, populate: ["ratingAndReviews", "instructor"], }) - .exec(); + .exec() // Get top-selling courses across all categories const allCategories = await Category.find() @@ -129,12 +129,12 @@ export async function categoryPageDetails (req, res) { path: "instructor", }, }) - .exec(); + .exec() - const allCourses = allCategories.flatMap((category) => category.courses); + const allCourses = allCategories.flatMap((category) => category.courses) const mostSellingCourses = allCourses .sort((a, b) => b.sold - a.sold) - .slice(0, 10); + .slice(0, 10) // send response return res.status(200).json({ @@ -145,9 +145,9 @@ export async function categoryPageDetails (req, res) { differentCategory, mostSellingCourses, }, - }); + }) } catch (error) { - console.log("Error in categoryPageDetails"); - return res.status(500).json({ success: false, message: error.message }); + console.log("Error in categoryPageDetails") + return res.status(500).json({ success: false, message: error.message }) } } diff --git a/backend/controllers/contactUs.controller.js b/backend/controllers/contactUs.controller.js index a02533e..f1e3799 100644 --- a/backend/controllers/contactUs.controller.js +++ b/backend/controllers/contactUs.controller.js @@ -1,26 +1,26 @@ -import contactUsEmail from "../mail/templates/contactFormRes.js"; -import mailSender from "../utils/mailSender.js"; +import contactUsEmail from "../mail/templates/contactFormRes.js" +import mailSender from "../utils/mailSender.js" export async function contactUsController (req, res) { // fetch data const { email, firstname, lastname, message, phoneNo, countrycode } = - req.body; + req.body try { await mailSender( process.env.CONTACT_MAIL_ID, "Someone Send this data to you", contactUsEmail(email, firstname, lastname, message, phoneNo, countrycode), - ); + ) return res.status(200).json({ success: true, message: "Your data send successfully", - }); + }) } catch (error) { - console.log(error); + console.log(error) return res.status(500).json({ success: false, message: "Something went wrong in contact us...", - }); + }) } } diff --git a/backend/controllers/course.controller.js b/backend/controllers/course.controller.js index c61928d..4484a46 100644 --- a/backend/controllers/course.controller.js +++ b/backend/controllers/course.controller.js @@ -1,11 +1,11 @@ -import Course from "../models/course.model.js"; -import Category from "../models/category.model.js"; -import User from "../models/user.model.js"; -import SubSection from "../models/subSection.model.js"; -import Section from "../models/section.model.js"; -import CourseProgress from "../models/courseProgress.model.js"; -import uploadFileToCloudinary from "../utils/fileUploader.js"; -import convertSecondsToDuration from "../utils/secToDuration.js"; +import Course from "../models/course.model.js" +import Category from "../models/category.model.js" +import User from "../models/user.model.js" +import SubSection from "../models/subSection.model.js" +import Section from "../models/section.model.js" +import CourseProgress from "../models/courseProgress.model.js" +import uploadFileToCloudinary from "../utils/fileUploader.js" +import convertSecondsToDuration from "../utils/secToDuration.js" // createCourse handler function export async function createCourse (req, res) { @@ -22,12 +22,12 @@ export async function createCourse (req, res) { language, status, instructions, - } = req.body; + } = req.body // get thumbnail - const thumbnail = req.files.thumbnailImage; - const tagList = tags ? JSON.parse(tags) : []; - const instructionList = instructions ? JSON.parse(instructions) : []; + const thumbnail = req.files.thumbnailImage + const tagList = tags ? JSON.parse(tags) : [] + const instructionList = instructions ? JSON.parse(instructions) : [] // validate data if ( @@ -43,36 +43,36 @@ export async function createCourse (req, res) { ) { return res .status(400) - .json({ success: false, message: "Please enter all the fields" }); + .json({ success: false, message: "Please enter all the fields" }) } if (!status || status === undefined) { - status = "Draft"; + status = "Draft" } // Check for instructor const instructorDetails = await User.findById(req.user.id, { accountType: "Instructor", - }); + }) if (!instructorDetails) { return res.status(400).json({ success: false, message: "You are not authorized to create course", - }); + }) } // check for category - const categoryDetails = await Category.findById(category); + const categoryDetails = await Category.findById(category) if (!categoryDetails) { return res.status(400).json({ success: false, message: "Please select a valid category", - }); + }) } // upload thumbnail to cloudinary const thumbnailImage = await uploadFileToCloudinary( thumbnail, process.env.CLOUDINARY_COURSE_THUMBNAIL_FOLDER, - ); + ) // create an entry for new course const newCourse = await Course.create({ @@ -88,34 +88,34 @@ export async function createCourse (req, res) { // totalDuration, status, instructions: instructionList, - }); + }) // push course id to instructor's course array await User.findByIdAndUpdate( instructorDetails._id, { $push: { courses: newCourse._id } }, { new: true }, - ); + ) // update category schema await Category.findByIdAndUpdate( category, { $push: { courses: newCourse._id } }, { new: true }, - ); + ) // send response return res.status(200).json({ success: true, message: "Course created successfully", data: newCourse, - }); + }) } catch (error) { - console.log("Error in creating course: " + error); + console.log("Error in creating course: " + error) return res.status(500).json({ success: false, message: "Error on createCourse controller: " + error, - }); + }) } } @@ -135,19 +135,19 @@ export async function getAllCourses (req, res) { }, ) .populate("instructor") - .exec(); + .exec() return res.status(200).json({ success: true, message: "All courses fetched successfully", data: allCourses, - }); + }) } catch (error) { - console.log("Error in showAllCourses controller: "); + console.log("Error in showAllCourses controller: ") return res.status(500).json({ success: false, message: error.message, - }); + }) } } @@ -155,14 +155,14 @@ export async function getAllCourses (req, res) { export async function getCourseDetails (req, res) { try { // get id - const { courseId } = req.body; + const { courseId } = req.body // validate data if (!courseId) { return res.status(400).json({ success: false, message: "Please give course Id", - }); + }) } // find course details @@ -177,25 +177,25 @@ export async function getCourseDetails (req, res) { path: "courseContent", populate: { path: "subSections" }, }) - .exec(); + .exec() if (!courseDetails) { return res.status(400).json({ success: false, message: `Could not find course details with ${courseId}`, - }); + }) } - let totalDuration; + let totalDuration if (courseDetails.courseContent.length) { - let totalDurationInSeconds = 0; + let totalDurationInSeconds = 0 courseDetails.courseContent.forEach((content) => { content.subSections.forEach((subSection) => { - const timeDurationInSeconds = parseInt(subSection.timeDuration); - totalDurationInSeconds += timeDurationInSeconds; - }); - }); + const timeDurationInSeconds = parseInt(subSection.timeDuration) + totalDurationInSeconds += timeDurationInSeconds + }) + }) - totalDuration = convertSecondsToDuration(totalDurationInSeconds); + totalDuration = convertSecondsToDuration(totalDurationInSeconds) } // send response @@ -203,20 +203,20 @@ export async function getCourseDetails (req, res) { success: true, message: "Course details fetched successfully", data: { courseDetails, totalDuration }, - }); + }) } catch (error) { - console.log("Error in getCourseDetails controller: "); + console.log("Error in getCourseDetails controller: ") return res.status(500).json({ success: false, message: error.message, - }); + }) } } export async function getFullCourseDetails (req, res) { try { - const { courseId } = req.body; - const userId = req.user.id; + const { courseId } = req.body + const userId = req.user.id const courseDetails = await Course.findOne({ _id: courseId }) .populate({ path: "instructor", @@ -232,27 +232,27 @@ export async function getFullCourseDetails (req, res) { path: "subSections", }, }) - .exec(); + .exec() const courseProgressCount = await CourseProgress.findOne({ courseId, userId, - }); + }) if (!courseDetails) { return res.status(400).json({ success: false, message: `Could not find course with id: ${courseId}`, - }); + }) } - let totalDurationInSeconds = 0; + let totalDurationInSeconds = 0 courseDetails.courseContent.forEach((content) => { content.subSections.forEach((subSection) => { - const timeDurationInSeconds = parseInt(subSection.timeDuration); - totalDurationInSeconds += timeDurationInSeconds; - }); - }); + const timeDurationInSeconds = parseInt(subSection.timeDuration) + totalDurationInSeconds += timeDurationInSeconds + }) + }) - const totalDuration = convertSecondsToDuration(totalDurationInSeconds); + const totalDuration = convertSecondsToDuration(totalDurationInSeconds) return res.status(200).json({ success: true, @@ -263,19 +263,19 @@ export async function getFullCourseDetails (req, res) { ? courseProgressCount?.completedVideos : [], }, - }); + }) } catch (error) { return res.status(500).json({ success: false, message: error.message, - }); + }) } } // Get a list of Course for a given Instructor export async function getInstructorCourses (req, res) { try { - const instructorId = req.user.id; // Get the instructor ID from the authenticated user or request body + const instructorId = req.user.id // Get the instructor ID from the authenticated user or request body // Find all courses belonging to the instructor const instructorCourses = await Course.find({ @@ -287,97 +287,97 @@ export async function getInstructorCourses (req, res) { path: "subSections", }, }) - .sort({ createdAt: -1 }); + .sort({ createdAt: -1 }) res.status(200).json({ // Return the instructor's courses success: true, data: instructorCourses, - }); + }) } catch (error) { res.status(500).json({ success: false, message: "Failed to retrieve instructor courses", error: error.message, - }); + }) } } export async function deleteCourse (req, res) { try { - const { courseId } = req.body; + const { courseId } = req.body - const course = await Course.findById(courseId); // Find the course + const course = await Course.findById(courseId) // Find the course if (!course) { - return res.status(404).json({ message: "Course not found" }); + return res.status(404).json({ message: "Course not found" }) } - const studentsEnrolled = course.studentsEnrolled; // Unenroll students from the course + const studentsEnrolled = course.studentsEnrolled // Unenroll students from the course for (const studentId of studentsEnrolled) { - await User.findByIdAndUpdate(studentId, { $pull: { courses: courseId } }); + await User.findByIdAndUpdate(studentId, { $pull: { courses: courseId } }) } - const courseSections = course.courseContent; // Delete sections and sub-sections + const courseSections = course.courseContent // Delete sections and sub-sections for (const sectionId of courseSections) { - const section = await Section.findById(sectionId); // Delete sub-sections of the section + const section = await Section.findById(sectionId) // Delete sub-sections of the section if (section) { - const subSections = section.subSections; + const subSections = section.subSections for (const subSectionId of subSections) { - await SubSection.findByIdAndDelete(subSectionId); + await SubSection.findByIdAndDelete(subSectionId) } } - await Section.findByIdAndDelete(sectionId); // Delete the section + await Section.findByIdAndDelete(sectionId) // Delete the section } - await Course.findByIdAndDelete(courseId); // Delete the course + await Course.findByIdAndDelete(courseId) // Delete the course return res.status(200).json({ success: true, message: "Course deleted successfully", - }); + }) } catch (error) { - console.error(error); + console.error(error) return res.status(500).json({ success: false, message: "Server error", error: error.message, - }); + }) } } // Edit Course Details export async function editCourse (req, res) { try { - const { courseId } = req.body; - const updates = req.body; - const course = await Course.findById(courseId); + const { courseId } = req.body + const updates = req.body + const course = await Course.findById(courseId) if (!course) { - return res.status(404).json({ error: "Course not found" }); + return res.status(404).json({ error: "Course not found" }) } // If Thumbnail Image is found, update it if (req.files) { - const thumbnail = req.files.thumbnailImage; + const thumbnail = req.files.thumbnailImage const thumbnailImage = await uploadFileToCloudinary( thumbnail, process.env.FOLDER_NAME, - ); - course.thumbnail = thumbnailImage.secure_url; + ) + course.thumbnail = thumbnailImage.secure_url } // Update only the fields that are present in the request body for (const key in updates) { if (Object.prototype.hasOwnProperty.call(updates, key)) { if (key === "tags" || key === "instructions") { - course[key] = JSON.parse(updates[key]); + course[key] = JSON.parse(updates[key]) } else { - course[key] = updates[key]; + course[key] = updates[key] } } } - await course.save(); // save the course; + await course.save() // save the course; const updatedCourse = await Course.findOne({ _id: courseId }) .populate({ @@ -394,18 +394,18 @@ export async function editCourse (req, res) { path: "subSections", }, }) - .exec(); + .exec() res.json({ success: true, message: "Course updated successfully", data: updatedCourse, - }); + }) } catch (error) { res.status(500).json({ success: false, message: "Internal server error", error: error.message, - }); + }) } } diff --git a/backend/controllers/courseProgress.controller.js b/backend/controllers/courseProgress.controller.js index a1acb6a..1c62d52 100644 --- a/backend/controllers/courseProgress.controller.js +++ b/backend/controllers/courseProgress.controller.js @@ -1,49 +1,49 @@ -import SubSection from "../models/subSection.model.js"; -import CourseProgress from "../models/courseProgress.model.js"; +import SubSection from "../models/subSection.model.js" +import CourseProgress from "../models/courseProgress.model.js" export async function updateCourseProgress (req, res) { - const { courseId, subsectionId } = req.body; - const userId = req.user.id; + const { courseId, subsectionId } = req.body + const userId = req.user.id try { // Check if the subsection is valid - const subsection = await SubSection.findById(subsectionId); + const subsection = await SubSection.findById(subsectionId) if (!subsection) { return res .status(404) - .json({ success: false, error: "Invalid subsection" }); + .json({ success: false, error: "Invalid subsection" }) } // Find the course progress document for the user and course const courseProgress = await CourseProgress.findOne({ courseId, userId, - }); + }) if (!courseProgress) { // If course progress doesn't exist, create a new one return res.status(404).json({ success: false, message: "Course progress Does Not Exist", - }); + }) } else { // If course progress exists, check if the subsection is already completed if (courseProgress.completedVideos.includes(subsectionId)) { return res .status(400) - .json({ success: false, error: "Subsection already completed" }); + .json({ success: false, error: "Subsection already completed" }) } - courseProgress.completedVideos.push(subsectionId); // Push the subsection into the completedVideos array + courseProgress.completedVideos.push(subsectionId) // Push the subsection into the completedVideos array } - await courseProgress.save(); // Save the updated course progress + await courseProgress.save() // Save the updated course progress return res .status(200) - .json({ success: true, message: "Course progress updated" }); + .json({ success: true, message: "Course progress updated" }) } catch (error) { - console.error(error); + console.error(error) return res .status(500) - .json({ success: true, error: "Internal server error" }); + .json({ success: true, error: "Internal server error" }) } } diff --git a/backend/controllers/payments.controller.js b/backend/controllers/payments.controller.js index 985f5a7..e2d0250 100644 --- a/backend/controllers/payments.controller.js +++ b/backend/controllers/payments.controller.js @@ -1,74 +1,74 @@ -import instance from "../config/razorpay.js"; -import Course from "../models/course.model.js"; -import CourseProgress from "../models/courseProgress.model.js"; -import User from "../models/user.model.js"; -import mailSender from "../utils/mailSender.js"; -import crypto from "crypto"; -import courseEnrollmentEmail from "../mail/templates/courseEnrollmentEmail.js"; -import mongoose from "mongoose"; -import paymentSuccessEmail from "../mail/templates/paymentSuccessEmail.js"; +import instance from "../config/razorpay.js" +import Course from "../models/course.model.js" +import CourseProgress from "../models/courseProgress.model.js" +import User from "../models/user.model.js" +import mailSender from "../utils/mailSender.js" +import crypto from "crypto" +import courseEnrollmentEmail from "../mail/templates/courseEnrollmentEmail.js" +import mongoose from "mongoose" +import paymentSuccessEmail from "../mail/templates/paymentSuccessEmail.js" // initiate the razorpay order export async function capturePayment (req, res) { - const { courses } = req.body; - const userId = req.user.id; + const { courses } = req.body + const userId = req.user.id if (courses.length === 0) { - return res.json({ success: false, message: "Please provide Course Id" }); + return res.json({ success: false, message: "Please provide Course Id" }) } - let totalAmount = 0; + let totalAmount = 0 for (const courseId of courses) { - let course; + let course try { - course = await Course.findById(courseId); + course = await Course.findById(courseId) if (!course) { return res .status(200) - .json({ success: false, message: "Could not find the course" }); + .json({ success: false, message: "Could not find the course" }) } - const uid = new mongoose.Types.ObjectId(userId); + const uid = new mongoose.Types.ObjectId(userId) if (course.studentsEnrolled.includes(uid)) { return res .status(200) - .json({ success: false, message: "Student is already Enrolled" }); + .json({ success: false, message: "Student is already Enrolled" }) } - totalAmount += course.price; + totalAmount += course.price } catch (error) { - console.log(error); - return res.status(500).json({ success: false, message: error.message }); + console.log(error) + return res.status(500).json({ success: false, message: error.message }) } } - const currency = "INR"; + const currency = "INR" const options = { amount: totalAmount * 100, currency, receipt: Math.random(Date.now()).toString(), - }; + } try { - const paymentResponse = await instance.orders.create(options); + const paymentResponse = await instance.orders.create(options) res.json({ success: true, message: paymentResponse, - }); + }) } catch (error) { - console.log(error); + console.log(error) return res .status(500) - .json({ success: false, mesage: "Could not Initiate Order" }); + .json({ success: false, mesage: "Could not Initiate Order" }) } } // verify the payment export async function verifyPayment (req, res) { - const razorpayOrderId = req.body?.razorpay_order_id; - const razorpayPaymentId = req.body?.razorpay_payment_id; - const razorpaySignature = req.body?.razorpay_signature; - const courses = req.body?.courses; - const userId = req.user.id; + const razorpayOrderId = req.body?.razorpay_order_id + const razorpayPaymentId = req.body?.razorpay_payment_id + const razorpaySignature = req.body?.razorpay_signature + const courses = req.body?.courses + const userId = req.user.id if ( !razorpayOrderId || @@ -77,20 +77,20 @@ export async function verifyPayment (req, res) { !courses || !userId ) { - return res.status(500).json({ success: false, message: "Payment Failed" }); + return res.status(500).json({ success: false, message: "Payment Failed" }) } - const body = razorpayOrderId + "|" + razorpayPaymentId; + const body = razorpayOrderId + "|" + razorpayPaymentId const expectedSignature = crypto .createHmac("sha256", process.env.RAZORPAY_KEY_SECRET) .update(body.toString()) - .digest("hex"); + .digest("hex") if (expectedSignature === razorpaySignature) { - await enrollStudents(courses, userId, res); - return res.status(200).json({ success: true, message: "Payment Verified" }); // return res + await enrollStudents(courses, userId, res) + return res.status(200).json({ success: true, message: "Payment Verified" }) // return res } - return res.status(200).json({ success: false, message: "Payment Failed" }); + return res.status(200).json({ success: false, message: "Payment Failed" }) } const enrollStudents = async (courses, userId, res) => { @@ -98,7 +98,7 @@ const enrollStudents = async (courses, userId, res) => { return res.status(400).json({ success: false, message: "Please Provide data for Courses or UserId", - }); + }) } for (const courseId of courses) { @@ -108,26 +108,26 @@ const enrollStudents = async (courses, userId, res) => { { _id: courseId }, { $push: { studentsEnrolled: userId } }, { new: true }, - ); + ) if (!enrolledCourse) { return res .status(500) - .json({ success: false, message: "Course not Found" }); + .json({ success: false, message: "Course not Found" }) } // created courseProgress for enrolled Courses in DB; const courseProgress = await CourseProgress.create({ courseId, userId, completedVideos: [], - }); + }) // find the student and add the course to their list of enrolledCOurses const enrolledStudent = await User.findByIdAndUpdate( userId, { $push: { courses: courseId, courseProgress: courseProgress._id } }, { new: true }, - ); + ) /// Send mail to the Student; await mailSender( @@ -137,28 +137,28 @@ const enrollStudents = async (courses, userId, res) => { enrolledCourse.courseName, `${enrolledStudent.firstName}`, ), - ); + ) } catch (error) { - console.log(error); - return res.status(500).json({ success: false, message: error.message }); + console.log(error) + return res.status(500).json({ success: false, message: error.message }) } } -}; +} export async function sendPaymentSuccessEmail (req, res) { - const { orderId, paymentId, amount } = req.body; + const { orderId, paymentId, amount } = req.body - const userId = req.user.id; + const userId = req.user.id if (!orderId || !paymentId || !amount || !userId) { return res .status(400) - .json({ success: false, message: "Please provide all the fields" }); + .json({ success: false, message: "Please provide all the fields" }) } try { // student ko dhundo - const enrolledStudent = await User.findById(userId); + const enrolledStudent = await User.findById(userId) await mailSender( enrolledStudent.email, "Payment Recieved", @@ -168,12 +168,12 @@ export async function sendPaymentSuccessEmail (req, res) { orderId, paymentId, ), - ); + ) } catch (error) { - console.log("error in sending mail", error); + console.log("error in sending mail", error) return res .status(500) - .json({ success: false, message: "Could not send email" }); + .json({ success: false, message: "Could not send email" }) } } diff --git a/backend/controllers/profile.controller.js b/backend/controllers/profile.controller.js index f9c6b13..0832517 100644 --- a/backend/controllers/profile.controller.js +++ b/backend/controllers/profile.controller.js @@ -1,9 +1,9 @@ -import Profile from "../models/profile.model.js"; -import User from "../models/user.model.js"; -import Course from "../models/course.model.js"; -import CourseProgress from "../models/courseProgress.model.js"; -import uploadFileToCloudinary from "../utils/fileUploader.js"; -import convertSecondsToDuration from "../utils/secToDuration.js"; +import Profile from "../models/profile.model.js" +import User from "../models/user.model.js" +import Course from "../models/course.model.js" +import CourseProgress from "../models/courseProgress.model.js" +import uploadFileToCloudinary from "../utils/fileUploader.js" +import convertSecondsToDuration from "../utils/secToDuration.js" // Update Profile export async function updateProfile (req, res) { @@ -16,16 +16,16 @@ export async function updateProfile (req, res) { about = "", contactNumber = "", gender = "", - } = req.body; - const { id } = req.user; + } = req.body + const { id } = req.user - console.log("req.body", req.body); + console.log("req.body", req.body) // validation if (!id) { return res.status(400).json({ success: false, message: "User id is required", - }); + }) } else if ( contactNumber && (contactNumber.length < 10 || contactNumber.length > 10) @@ -33,81 +33,81 @@ export async function updateProfile (req, res) { return res.status(400).json({ success: false, message: "Contact number should be 10 digits", - }); + }) } // find profile - const userDetails = await User.findById(id); - const profileId = userDetails.additionalDetails; - const profileDetails = await Profile.findById(profileId); + const userDetails = await User.findById(id) + const profileId = userDetails.additionalDetails + const profileDetails = await Profile.findById(profileId) // update user - const user = await User.findByIdAndUpdate(id, { firstName, lastName }); - await user.save(); + const user = await User.findByIdAndUpdate(id, { firstName, lastName }) + await user.save() // update profile - profileDetails.dateOfBirth = dateOfBirth; - profileDetails.about = about; - profileDetails.contactNumber = contactNumber; - profileDetails.gender = gender; + profileDetails.dateOfBirth = dateOfBirth + profileDetails.about = about + profileDetails.contactNumber = contactNumber + profileDetails.gender = gender // save profile - await profileDetails.save(); + await profileDetails.save() // Find the updated user details const updatedUserDetails = await User.findById(id) .populate("additionalDetails") - .exec(); + .exec() // return response return res.status(201).json({ success: true, message: "Profile updated successfully", updatedUserDetails, - }); + }) } catch (error) { - console.log("Error in updateProfile", error); + console.log("Error in updateProfile", error) res.status(500).json({ success: false, message: "Unable to update profile", error: error.message, - }); + }) } } export async function updateDisplayPicture (req, res) { try { - const displayPicture = req.files.displayPicture; - const userId = req.user.id; + const displayPicture = req.files.displayPicture + const userId = req.user.id const image = await uploadFileToCloudinary( displayPicture, process.env.FOLDER_NAME, 1000, 1000, - ); + ) const updatedProfile = await User.findByIdAndUpdate( { _id: userId }, { image: image.secure_url }, { new: true }, - ); + ) res.send({ success: true, message: "Image Updated successfully", updatedProfile, - }); + }) } catch (error) { return res.status(500).json({ success: false, message: error.message, - }); + }) } } export async function getEnrolledCourses (req, res) { try { - const userId = req.user.id; + const userId = req.user.id let userDetails = await User.findOne({ _id: userId }) .populate({ path: "courses", @@ -118,39 +118,39 @@ export async function getEnrolledCourses (req, res) { }, }, }) - .exec(); - userDetails = userDetails.toObject(); - let SubsectionLength = 0; + .exec() + userDetails = userDetails.toObject() + let SubsectionLength = 0 for (let i = 0; i < userDetails.courses.length; i++) { - let totalDurationInSeconds = 0; - SubsectionLength = 0; + let totalDurationInSeconds = 0 + SubsectionLength = 0 for (let j = 0; j < userDetails.courses[i].courseContent.length; j++) { totalDurationInSeconds += userDetails.courses[i].courseContent[ j ].subSections.reduce( (acc, curr) => acc + parseInt(curr.timeDuration), 0, - ); + ) userDetails.courses[i].totalDuration = convertSecondsToDuration( totalDurationInSeconds, - ); + ) SubsectionLength += - userDetails.courses[i].courseContent[j].subSections.length; + userDetails.courses[i].courseContent[j].subSections.length } let courseProgressCount = await CourseProgress.findOne({ courseId: userDetails.courses[i]._id, userId, - }); - courseProgressCount = courseProgressCount?.completedVideos.length; + }) + courseProgressCount = courseProgressCount?.completedVideos.length if (SubsectionLength === 0) { - userDetails.courses[i].progressPercentage = 100; + userDetails.courses[i].progressPercentage = 100 } else { // To make it up to 2 decimal point - const multiplier = Math.pow(10, 2); + const multiplier = Math.pow(10, 2) userDetails.courses[i].progressPercentage = Math.round( (courseProgressCount / SubsectionLength) * 100 * multiplier, - ) / multiplier; + ) / multiplier } } @@ -158,28 +158,28 @@ export async function getEnrolledCourses (req, res) { return res.status(400).json({ success: false, message: `Could not find user with id: ${userDetails}`, - }); + }) } return res.status(200).json({ success: true, data: userDetails.courses, - }); + }) } catch (error) { return res.status(500).json({ success: false, message: error.message, - }); + }) } } export async function instructorDashboard (req, res) { try { - const courseDetails = await Course.find({ instructor: req.user.id }); + const courseDetails = await Course.find({ instructor: req.user.id }) const courseData = courseDetails.map((course) => { - const totalStudentsEnrolled = course?.studentsEnrolled?.length; - const totalAmountGenerated = totalStudentsEnrolled * course.price; + const totalStudentsEnrolled = course?.studentsEnrolled?.length + const totalAmountGenerated = totalStudentsEnrolled * course.price // Create a new object with the additional fields const courseDataWithStats = { @@ -188,15 +188,15 @@ export async function instructorDashboard (req, res) { courseDescription: course.courseDescription, totalStudentsEnrolled, // Include other course properties as needed totalAmountGenerated, - }; - return courseDataWithStats; - }); + } + return courseDataWithStats + }) res.status(200).json({ courses: courseData, - }); + }) } catch (error) { - console.error(error); - res.status(500).json({ message: "Server Error" }); + console.error(error) + res.status(500).json({ message: "Server Error" }) } } diff --git a/backend/controllers/ratingAndReview.controller.js b/backend/controllers/ratingAndReview.controller.js index 19ea11e..bfb35eb 100644 --- a/backend/controllers/ratingAndReview.controller.js +++ b/backend/controllers/ratingAndReview.controller.js @@ -1,44 +1,44 @@ -import RatingAndReview from "../models/ratingAndReview.model.js"; -import Course from "../models/course.model.js"; -import mongoose from "mongoose"; +import RatingAndReview from "../models/ratingAndReview.model.js" +import Course from "../models/course.model.js" +import mongoose from "mongoose" // create Rating and review export async function createRating (req, res) { - console.log("----------------------------------------"); + console.log("----------------------------------------") try { // get data - const { rating, review, courseId } = req.body; - const userId = req.user.id; + const { rating, review, courseId } = req.body + const userId = req.user.id // validate data if (!rating || !review || !courseId || !userId) { return res .status(400) - .json({ success: false, message: "Please enter all the fields" }); + .json({ success: false, message: "Please enter all the fields" }) } const courseDetails = await Course.findOne({ _id: courseId, studentsEnrolled: { $elemMatch: { $eq: userId } }, - }); // check if user is enrolled or not + }) // check if user is enrolled or not if (!courseDetails) { return res.status(404).json({ success: false, message: "Student is not enrolled in the course", - }); + }) } // check if user already reviewed const alreadyReviewed = await RatingAndReview.findOne({ user: userId, course: courseId, - }); + }) if (alreadyReviewed) { return res.status(400).json({ success: false, message: "You have already reviewed this course", - }); + }) } // create rating and review @@ -47,7 +47,7 @@ export async function createRating (req, res) { review, course: courseId, user: userId, - }); + }) // update course with this rating/review await Course.findByIdAndUpdate( @@ -56,17 +56,17 @@ export async function createRating (req, res) { $push: { ratingAndReviews: ratingAndReview._id }, }, { new: true }, - ); + ) // send response return res.status(200).json({ success: true, message: "Rating and review created successfully", data: ratingAndReview, - }); + }) } catch (error) { - console.log("Error in createRatingAndReview"); - return res.status(500).json({ success: false, message: error.message }); + console.log("Error in createRatingAndReview") + return res.status(500).json({ success: false, message: error.message }) } } @@ -74,13 +74,13 @@ export async function createRating (req, res) { export async function getAverageRating (req, res) { try { // get data - const { courseId } = req.body; + const { courseId } = req.body // validate data if (!courseId) { return res .status(400) - .json({ success: false, message: "Please enter all the fields" }); + .json({ success: false, message: "Please enter all the fields" }) } // get average rating and review @@ -94,7 +94,7 @@ export async function getAverageRating (req, res) { averageRating: { $avg: "$rating" }, }, }, - ]); + ]) // send response if (averageRating > 0) { @@ -102,16 +102,16 @@ export async function getAverageRating (req, res) { success: true, message: "Average rating and review fetched successfully", data: averageRating[0].averageRating, - }); + }) } else { return res.status(400).json({ success: false, message: "No rating and review found for this course", - }); + }) } } catch (error) { - console.log("Error in getAverageRating"); - return res.status(500).json({ success: false, message: error.message }); + console.log("Error in getAverageRating") + return res.status(500).json({ success: false, message: error.message }) } } @@ -122,21 +122,21 @@ export async function getAllRatingAndReview (req, res) { .sort({ rating: "desc" }) .populate({ path: "user", select: "firstName lastName email image" }) .populate({ path: "course", select: "courseName" }) - .exec(); + .exec() if (!allReviews) { return res.status(400).json({ success: false, message: "No rating and review found", - }); + }) } return res.status(200).json({ success: true, message: "All rating and review fetched successfully", data: allReviews, - }); + }) } catch (error) { - console.log("Error in getAllRatingAndReview"); - return res.status(500).json({ success: false, message: error.message }); + console.log("Error in getAllRatingAndReview") + return res.status(500).json({ success: false, message: error.message }) } } diff --git a/backend/controllers/resetPassword.controller.js b/backend/controllers/resetPassword.controller.js index 7da2a84..76c9084 100644 --- a/backend/controllers/resetPassword.controller.js +++ b/backend/controllers/resetPassword.controller.js @@ -1,31 +1,31 @@ -import resetPasswordTemplate from "../mail/templates/resetPasswordTemplate.js"; -import User from "../models/user.model.js"; -import mailSender from "../utils/mailSender.js"; -import bcrypt from "bcrypt"; -import crypto from "crypto"; +import resetPasswordTemplate from "../mail/templates/resetPasswordTemplate.js" +import User from "../models/user.model.js" +import mailSender from "../utils/mailSender.js" +import bcrypt from "bcrypt" +import crypto from "crypto" // ResetPasswordToken export async function resetPasswordToken (req, res) { try { // fetch email from request body - const { email } = req.body; + const { email } = req.body if (!email) { return res .status(400) - .json({ success: false, message: "Email is required" }); + .json({ success: false, message: "Email is required" }) } // check if user already exist - const user = await User.findOne({ email }); + const user = await User.findOne({ email }) if (!user) { return res .status(400) - .json({ success: false, message: "User does not exist" }); + .json({ success: false, message: "User does not exist" }) } // generate token - const token = crypto.randomBytes(20).toString("hex"); + const token = crypto.randomBytes(20).toString("hex") // update user by adding token and expiration time await User.findOneAndUpdate( @@ -35,29 +35,29 @@ export async function resetPasswordToken (req, res) { resetPasswordExpires: Date.now() + 5 * 60 * 1000, }, { new: true }, - ); + ) // create url - const url = `http://localhost:3000/update-password/${token}`; + const url = `http://localhost:3000/update-password/${token}` // send email to user await mailSender( email, "Password Reset Link", resetPasswordTemplate(email, url), - ); + ) // return response successful res.status(200).json({ success: true, message: "Reset Password Email sent successfully", - }); + }) } catch (error) { - console.log("Error in sending reset password email: " + error); + console.log("Error in sending reset password email: " + error) return res.status(500).json({ success: false, message: error.message, - }); + }) } } @@ -65,30 +65,30 @@ export async function resetPasswordToken (req, res) { export async function resetPassword (req, res) { try { // data fetch - const { password, confirmPassword, token } = req.body; + const { password, confirmPassword, token } = req.body // validation if (!password || !confirmPassword || !token) { return res.status(400).json({ success: false, message: "Fields are required", - }); + }) } else if (password !== confirmPassword) { return res.status(400).json({ success: false, message: "Password does not match", - }); + }) } // get userdetails from db using token - const userDetails = await User.findOne({ token }); + const userDetails = await User.findOne({ token }) // if no entry - invalid token if (!userDetails) { return res.status(400).json({ success: false, message: "Invalid token", - }); + }) } // token time expires @@ -96,29 +96,29 @@ export async function resetPassword (req, res) { return res.status(400).json({ success: false, message: "Token is expired, please regenerate your token'", - }); + }) } // Hash password - const hashedPassword = await bcrypt.hash(password, 10); + const hashedPassword = await bcrypt.hash(password, 10) // update user password await User.findOneAndUpdate( { token }, { password: hashedPassword }, { new: true }, - ); + ) // return response successful res.status(200).json({ success: true, message: "Password reset successfully", - }); + }) } catch (error) { - console.log("Error in reset password: " + error); + console.log("Error in reset password: " + error) return res.status(500).json({ success: false, message: error.message, - }); + }) } } diff --git a/backend/controllers/section.controller.js b/backend/controllers/section.controller.js index fd3d7b7..2740f81 100644 --- a/backend/controllers/section.controller.js +++ b/backend/controllers/section.controller.js @@ -1,30 +1,30 @@ -import Section from "../models/section.model.js"; -import Course from "../models/course.model.js"; -import SubSection from "../models/subSection.model.js"; +import Section from "../models/section.model.js" +import Course from "../models/course.model.js" +import SubSection from "../models/subSection.model.js" // Create Section export async function createSection (req, res) { try { // data fetch - const { sectionName, courseId } = req.body; + const { sectionName, courseId } = req.body // data validation if (!sectionName || !courseId) { return res .status(400) - .json({ success: false, error: "All fields are required" }); + .json({ success: false, error: "All fields are required" }) } // check if course exist - const course = await Course.findById({ _id: courseId }); + const course = await Course.findById({ _id: courseId }) if (!course) { return res .status(404) - .json({ success: false, error: "Course not found" }); + .json({ success: false, error: "Course not found" }) } // create Section - const newSection = await Section.create({ sectionName }); + const newSection = await Section.create({ sectionName }) // update course with newSection const updatedCourseDetails = await Course.findByIdAndUpdate( @@ -36,21 +36,21 @@ export async function createSection (req, res) { path: "courseContent", populate: { path: "subSections" }, }) - .exec(); + .exec() // send response res.status(201).json({ success: true, message: "Section created successfully", updatedCourseDetails, - }); + }) } catch (error) { - console.log("Error in createSection", error); + console.log("Error in createSection", error) res.status(500).json({ success: false, message: "Unable to create new section", error: error.message, - }); + }) } } @@ -58,21 +58,21 @@ export async function createSection (req, res) { export async function updateSection (req, res) { try { // data fetch - const { sectionName, sectionId, courseId } = req.body; + const { sectionName, sectionId, courseId } = req.body // data validation if (!sectionName || !sectionId) { return res .status(400) - .json({ success: false, error: "All fields are required" }); + .json({ success: false, error: "All fields are required" }) } // check if section exist - const section = await Section.findById(sectionId); + const section = await Section.findById(sectionId) if (!section) { return res .status(404) - .json({ success: false, error: "Section not found" }); + .json({ success: false, error: "Section not found" }) } // update Section @@ -80,7 +80,7 @@ export async function updateSection (req, res) { sectionId, { sectionName }, { new: true }, - ); + ) // update course with EditSection const updatedCourseDetails = await Course.findByIdAndUpdate(courseId) @@ -88,21 +88,21 @@ export async function updateSection (req, res) { path: "courseContent", populate: { path: "subSections" }, }) - .exec(); + .exec() // send response res.status(201).json({ success: true, message: "SubSection Edited successfully", updatedCourseDetails, - }); + }) } catch (error) { - console.log("Error in updateSection", error); + console.log("Error in updateSection", error) res.status(500).json({ success: false, message: "Unable to update new section", error: error.message, - }); + }) } } @@ -110,32 +110,32 @@ export async function updateSection (req, res) { export async function deleteSection (req, res) { try { // data fetch - const { sectionId, courseId } = req.body; + const { sectionId, courseId } = req.body // data validation if (!sectionId) { return res .status(400) - .json({ success: false, error: "All fields are required" }); + .json({ success: false, error: "All fields are required" }) } // check if section exist - const section = await Section.findById(sectionId); + const section = await Section.findById(sectionId) if (!section) { return res .status(404) - .json({ success: false, error: "Section not found" }); + .json({ success: false, error: "Section not found" }) } await Course.findByIdAndUpdate(courseId, { $pull: { courseContent: sectionId }, - }); + }) // delete sub section - await SubSection.deleteMany({ _id: { $in: section.subSection } }); + await SubSection.deleteMany({ _id: { $in: section.subSection } }) // delete Section - await Section.findByIdAndDelete(sectionId); + await Section.findByIdAndDelete(sectionId) // find the updated course and return const updatedCourseDetails = await Course.findById(courseId) @@ -145,21 +145,21 @@ export async function deleteSection (req, res) { path: "subSections", }, }) - .exec(); + .exec() // send response return res.status(201).json({ success: true, message: "Section deleted successfully", updatedCourseDetails, - }); + }) } catch (error) { - console.log("Error in deleteSection", error); + console.log("Error in deleteSection", error) res.status(500).json({ success: false, message: "Unable to Delete section", error: error.message, - }); + }) } } @@ -167,38 +167,38 @@ export async function deleteSection (req, res) { export async function getAllSections (req, res) { try { // data fetch - const { courseId } = req.body; + const { courseId } = req.body // data validation if (!courseId) { return res .status(400) - .json({ success: false, error: "All fields are required" }); + .json({ success: false, error: "All fields are required" }) } // check if course exist - const course = await Course.findById(courseId); + const course = await Course.findById(courseId) if (!course) { return res .status(404) - .json({ success: false, error: "Course not found" }); + .json({ success: false, error: "Course not found" }) } // get all Sections - const sections = await Section.find({ courseId }); + const sections = await Section.find({ courseId }) // send response res.status(201).json({ success: true, message: "All Sections", sections, - }); + }) } catch (error) { - console.log("Error in getAllSections", error); + console.log("Error in getAllSections", error) res.status(500).json({ success: false, message: "Unable to get all sections", error: error.message, - }); + }) } } diff --git a/backend/controllers/subSection.controller.js b/backend/controllers/subSection.controller.js index 654b5a1..b66d693 100644 --- a/backend/controllers/subSection.controller.js +++ b/backend/controllers/subSection.controller.js @@ -1,45 +1,45 @@ -import SubSection from "../models/subSection.model.js"; -import Section from "../models/section.model.js"; -import uploadFileToCloudinary from "../utils/fileUploader.js"; +import SubSection from "../models/subSection.model.js" +import Section from "../models/section.model.js" +import uploadFileToCloudinary from "../utils/fileUploader.js" // Create SubSection export async function createSubSection (req, res) { try { // fetch data from request body - const { sectionId, title, description } = req.body; + const { sectionId, title, description } = req.body // extract file/video - const video = req.files.video; + const video = req.files.video // validation if (!sectionId || !title || !video || !description) { return res.status(400).json({ success: false, message: "All fields are required", - }); + }) } // check if section exist - const section = await Section.findById(sectionId); + const section = await Section.findById(sectionId) if (!section) { return res.status(404).json({ success: false, message: "Section not found", - }); + }) } // upload video to clodinary const uploadVideo = await uploadFileToCloudinary( video, process.env.CLOUDINARY_COURSE_THUMBNAIL_FOLDER, - ); + ) // create a sub section const subSection = await SubSection.create({ title, timeDuration: `${uploadVideo.duration}`, description, videoUrl: uploadVideo.secure_url, - }); + }) // update section with this subsection ObjectId const updatedSection = await Section.findByIdAndUpdate( @@ -50,21 +50,21 @@ export async function createSubSection (req, res) { { new: true }, ) .populate("subSections") - .exec(); + .exec() // return response return res.status(201).json({ success: true, message: "Subsection created successfully", data: updatedSection, - }); + }) } catch (error) { - console.log("Error in createSubSection", error); + console.log("Error in createSubSection", error) res.status(500).json({ success: false, message: "Unable to create new subsection", error: error.message, - }); + }) } } @@ -72,58 +72,58 @@ export async function createSubSection (req, res) { export async function updateSubSection (req, res) { try { // fetch data from request body - const { sectionId, subSectionId, title, description } = req.body; + const { sectionId, subSectionId, title, description } = req.body // validation if (!subSectionId) { return res.status(400).json({ success: false, message: " SubSectionId is required", - }); + }) } // check if subSection exist - const subSection = await SubSection.findById(subSectionId); + const subSection = await SubSection.findById(subSectionId) if (!subSection) { return res.status(404).json({ success: false, message: "subSection not found", - }); + }) } - if (title) subSection.title = title; - if (description) subSection.description = description; + if (title) subSection.title = title + if (description) subSection.description = description // upload video to clodinary if (req.files && req.files.video !== undefined) { - const video = req.files.video; + const video = req.files.video const uploadVideo = await uploadFileToCloudinary( video, process.env.CLOUDINARY_COURSE_THUMBNAIL_FOLDER, - ); - subSection.videoUrl = uploadVideo.secure_url; - subSection.timeDuration = `${uploadVideo.duration}`; + ) + subSection.videoUrl = uploadVideo.secure_url + subSection.timeDuration = `${uploadVideo.duration}` } else { - subSection.videoUrl = null; + subSection.videoUrl = null } - await subSection.save(); + await subSection.save() const updatedSubSection = - await Section.findById(sectionId).populate("subSections"); + await Section.findById(sectionId).populate("subSections") // return response return res.status(201).json({ success: true, message: "Subsection updated successfully", data: updatedSubSection, - }); + }) } catch (error) { - console.log("Error in updateSubSection", error); + console.log("Error in updateSubSection", error) res.status(500).json({ success: false, message: "Unable to update subsection", error: error.message, - }); + }) } } @@ -131,27 +131,27 @@ export async function updateSubSection (req, res) { export async function deleteSubSection (req, res) { try { // fetch data from request body - const { subSectionId, sectionId } = req.body; + const { subSectionId, sectionId } = req.body // validation if (!subSectionId || !sectionId) { return res.status(400).json({ success: false, message: " SubSectionId and sectionId are required", - }); + }) } // check if subSection exist - const subSection = await SubSection.findById(subSectionId); + const subSection = await SubSection.findById(subSectionId) if (!subSection) { return res.status(404).json({ success: false, message: "SubSection not found", - }); + }) } // delete sub section - await SubSection.findByIdAndDelete({ _id: subSectionId }); + await SubSection.findByIdAndDelete({ _id: subSectionId }) // update Section with this subsection ObjectId @@ -161,21 +161,21 @@ export async function deleteSubSection (req, res) { $pull: { subSections: subSectionId }, }, { new: true }, - ); + ) // return response return res.status(201).json({ success: true, message: "Subsection updated successfully", data: updatedSection, - }); + }) } catch (error) { - console.log("Error in deleteSection", error); + console.log("Error in deleteSection", error) res.status(500).json({ success: false, message: "Unable to delete subsection", error: error.message, - }); + }) } } @@ -183,40 +183,40 @@ export async function deleteSubSection (req, res) { export async function getAllSubSections (req, res) { try { // fetch data from request body - const { sectionId } = req.body; + const { sectionId } = req.body // validation if (!sectionId) { return res.status(400).json({ success: false, message: " sectionId is required", - }); + }) } // check if section exist - const section = await Section.findById(sectionId); + const section = await Section.findById(sectionId) if (!section) { return res.status(404).json({ success: false, message: "Section not found", - }); + }) } // get all sub sections - const subSections = await SubSection.find({ sectionId }); + const subSections = await SubSection.find({ sectionId }) // return response return res.status(201).json({ success: true, message: "Subsections fetched successfully", data: subSections, - }); + }) } catch (error) { - console.log("Error in getAllSubSections", error); + console.log("Error in getAllSubSections", error) res.status(500).json({ success: false, message: "Unable to fetch subsections", error: error.message, - }); + }) } } diff --git a/backend/controllers/user.controller.js b/backend/controllers/user.controller.js index 8fa9edd..f7c05fd 100644 --- a/backend/controllers/user.controller.js +++ b/backend/controllers/user.controller.js @@ -1,37 +1,37 @@ -import User from "../models/user.model.js"; -import Profile from "../models/profile.model.js"; -import Course from "../models/course.model.js"; -import mongoose from "mongoose"; +import User from "../models/user.model.js" +import Profile from "../models/profile.model.js" +import Course from "../models/course.model.js" +import mongoose from "mongoose" // Delete Account export async function deleteUserAccount (req, res) { try { // Get user id - const { id } = req.user; + const { id } = req.user // validation if (!id) { return res.status(400).json({ success: false, message: "User id is required", - }); + }) } // find profile - const userDetails = await User.findById(id); + const userDetails = await User.findById(id) if (!userDetails) { return res.status(400).json({ success: false, message: "User not found", - }); + }) } - const profileId = userDetails.additionalDetails; + const profileId = userDetails.additionalDetails if (!profileId) { return res.status(400).json({ success: false, message: "Profile not found", - }); + }) } // if user is students then remove from enrolled courses @@ -41,27 +41,27 @@ export async function deleteUserAccount (req, res) { courseId, { $pull: { studentsEnrolled: id } }, { new: true }, - ); + ) } } // delete profile and account await Profile.findByIdAndDelete({ _id: new mongoose.Types.ObjectId(profileId), - }); - await User.findByIdAndDelete({ _id: id }); + }) + await User.findByIdAndDelete({ _id: id }) // return response return res.status(201).json({ success: true, message: "Account deleted successfully", - }); + }) } catch (error) { - console.log("Error in deleteAccount", error); + console.log("Error in deleteAccount", error) res.status(500).json({ success: false, message: "Unable to delete Account", error: error.message, - }); + }) } } @@ -69,31 +69,31 @@ export async function deleteUserAccount (req, res) { export async function getAllUserDetails (req, res) { try { // get id - const { id } = req.user; - console.log("id", id); + const { id } = req.user + console.log("id", id) // validation and get user details if (!id) { return res.status(400).json({ success: false, message: "User id is required", - }); + }) } const userDetails = await User.findById(id) .populate("additionalDetails") - .exec(); + .exec() // return response return res.status(201).json({ success: true, message: "User details fetched successfully", data: userDetails, - }); + }) } catch (error) { - console.log("Error in getUserDetails", error); + console.log("Error in getUserDetails", error) res.status(500).json({ success: false, message: "Unable to fetch user details", error: error.message, - }); + }) } } diff --git a/backend/index.js b/backend/index.js index 0e9751e..a15db01 100644 --- a/backend/index.js +++ b/backend/index.js @@ -1,64 +1,64 @@ -import express from "express"; -import userRoutes from "./routes/user.route.js"; -import profileRoutes from "./routes/profile.route.js"; -import paymentRoutes from "./routes/payment.route.js"; -import courseRoutes from "./routes/course.route.js"; -import contactUsRoute from "./routes/contactUs.route.js"; -import connectDB from "./config/database.js"; -import cookieParser from "cookie-parser"; -import cors from "cors"; -import { cloudinaryConnect } from "./config/cloudinary.js"; -import fileUpload from "express-fileupload"; -import dotenv from "dotenv"; +import express from "express" +import userRoutes from "./routes/user.route.js" +import profileRoutes from "./routes/profile.route.js" +import paymentRoutes from "./routes/payment.route.js" +import courseRoutes from "./routes/course.route.js" +import contactUsRoute from "./routes/contactUs.route.js" +import connectDB from "./config/database.js" +import cookieParser from "cookie-parser" +import cors from "cors" +import { cloudinaryConnect } from "./config/cloudinary.js" +import fileUpload from "express-fileupload" +import dotenv from "dotenv" dotenv.config({ path: "./env", -}); +}) -const app = express(); +const app = express() // database connect connectDB() .then(() => { app.listen(process.env.PORT || 4000, () => { - console.log(`⚙️ Server is running at port : ${process.env.PORT}`); - }); + console.log(`⚙️ Server is running at port : ${process.env.PORT}`) + }) }) .catch((err) => { - console.log("MONGO db connection failed !!! ", err); - }); + console.log("MONGO db connection failed !!! ", err) + }) // middlewares -app.use(express.json()); -app.use(cookieParser()); +app.use(express.json()) +app.use(cookieParser()) app.use( cors({ origin: process.env.REACT_FRONTED_URL, credentials: true, }), -); +) app.use( fileUpload({ useTempFiles: true, // this middeare is for fileupload in local media tempFileDir: "/tmp", }), -); +) // cloudinary connection -cloudinaryConnect(); +cloudinaryConnect() // routes -app.use("/api/v1/auth", userRoutes); -app.use("/api/v1/profile", profileRoutes); -app.use("/api/v1/course", courseRoutes); -app.use("/api/v1/payment", paymentRoutes); -app.use("/api/v1/reach", contactUsRoute); +app.use("/api/v1/auth", userRoutes) +app.use("/api/v1/profile", profileRoutes) +app.use("/api/v1/course", courseRoutes) +app.use("/api/v1/payment", paymentRoutes) +app.use("/api/v1/reach", contactUsRoute) // def route app.get("/", (req, res) => { return res.json({ success: true, message: "Your server is up and running....", - }); -}); + }) +}) diff --git a/backend/mail/templates/contactFormRes.js b/backend/mail/templates/contactFormRes.js index 48f0002..1fbe3c5 100644 --- a/backend/mail/templates/contactFormRes.js +++ b/backend/mail/templates/contactFormRes.js @@ -93,5 +93,5 @@ export default function contactUsEmail ( - `; + ` } diff --git a/backend/mail/templates/courseEnrollmentEmail.js b/backend/mail/templates/courseEnrollmentEmail.js index 0440646..df309db 100644 --- a/backend/mail/templates/courseEnrollmentEmail.js +++ b/backend/mail/templates/courseEnrollmentEmail.js @@ -83,5 +83,5 @@ export default function courseEnrollmentEmail (courseName, name) { - `; + ` } diff --git a/backend/mail/templates/emailVerficationTemplate.js b/backend/mail/templates/emailVerficationTemplate.js index c6fcdcb..12df972 100644 --- a/backend/mail/templates/emailVerficationTemplate.js +++ b/backend/mail/templates/emailVerficationTemplate.js @@ -71,5 +71,5 @@ export default function otpTemplate (otp) { href="mailto:info@studynotion.store">info@studynotion.store. We are here to help! - `; + ` } diff --git a/backend/mail/templates/passwordUpdate.js b/backend/mail/templates/passwordUpdate.js index 60ee667..2b28214 100644 --- a/backend/mail/templates/passwordUpdate.js +++ b/backend/mail/templates/passwordUpdate.js @@ -71,5 +71,5 @@ export default function passwordUpdated (email, name) { - `; + ` } diff --git a/backend/mail/templates/paymentSuccessEmail.js b/backend/mail/templates/paymentSuccessEmail.js index 237edc7..6e78a40 100644 --- a/backend/mail/templates/paymentSuccessEmail.js +++ b/backend/mail/templates/paymentSuccessEmail.js @@ -81,5 +81,5 @@ export default function paymentSuccessEmail (name, amount, orderId, paymentId) { - `; + ` } diff --git a/backend/mail/templates/resetPasswordTemplate.js b/backend/mail/templates/resetPasswordTemplate.js index 360dc9c..87c6d27 100644 --- a/backend/mail/templates/resetPasswordTemplate.js +++ b/backend/mail/templates/resetPasswordTemplate.js @@ -78,5 +78,5 @@ export default function resetPasswordTemplate (email, url) { href="mailto:info@studynotion.store">info@studynotion.store. We are here to help! - `; + ` } diff --git a/backend/middlewares/auth.middelware.js b/backend/middlewares/auth.middelware.js index cff79b3..f807152 100644 --- a/backend/middlewares/auth.middelware.js +++ b/backend/middlewares/auth.middelware.js @@ -1,4 +1,4 @@ -import jwt from "jsonwebtoken"; +import jwt from "jsonwebtoken" // auth export async function auth (req, res, next) { @@ -7,32 +7,32 @@ export async function auth (req, res, next) { const token = req.cookies.token || req.body.token || - req.header("authorization").replace("Bearer ", ""); + req.header("authorization").replace("Bearer ", "") // check if token exist if (!token) { return res.status(401).json({ success: false, message: "No token, authorization denied", - }); + }) } try { // verify token - const decoded = jwt.verify(token, process.env.JWT_SECRET); - console.log(decoded); - req.user = decoded; + const decoded = jwt.verify(token, process.env.JWT_SECRET) + console.log(decoded) + req.user = decoded } catch (error) { // verfiy token failed return res.status(401).json({ success: false, message: "Token is not valid", - }); + }) } - next(); + next() } catch (error) { - console.log("Error in auth middleware: " + error); - return res.status(500).json({ success: false, message: error.message }); + console.log("Error in auth middleware: " + error) + return res.status(500).json({ success: false, message: error.message }) } } @@ -40,19 +40,19 @@ export async function auth (req, res, next) { export async function isStudent (req, res, next) { try { // get user from request object - const user = req.user; + const user = req.user // check if user is student if (user.accountType !== "Student") { return res.status(401).json({ success: false, message: "This is a protected router for Students only", - }); + }) } - next(); + next() } catch (error) { - console.log("Error in isStudent middleware: " + error); - return res.status(500).json({ success: false, message: error.message }); + console.log("Error in isStudent middleware: " + error) + return res.status(500).json({ success: false, message: error.message }) } } @@ -60,19 +60,19 @@ export async function isStudent (req, res, next) { export async function isInstructor (req, res, next) { try { // get user from request object - const user = req.user; + const user = req.user // check if user is instructor if (user.accountType !== "Instructor") { return res.status(401).json({ success: false, message: "This is a protected router for instructor only", - }); + }) } - next(); + next() } catch (error) { - console.log("Error in isInstructor middleware: " + error); - return res.status(500).json({ success: false, message: error.message }); + console.log("Error in isInstructor middleware: " + error) + return res.status(500).json({ success: false, message: error.message }) } } @@ -80,18 +80,18 @@ export async function isInstructor (req, res, next) { export async function isAdmin (req, res, next) { try { // get user from request object - const user = req.user; + const user = req.user // check if user is admin if (user.accountType !== "Admin") { return res.status(401).json({ success: false, message: "This is a protected router for admin only", - }); + }) } - next(); + next() } catch (error) { - console.log("Error in isAdmin middleware: " + error); - return res.status(500).json({ success: false, message: error.message }); + console.log("Error in isAdmin middleware: " + error) + return res.status(500).json({ success: false, message: error.message }) } } diff --git a/backend/models/category.model.js b/backend/models/category.model.js index 6d1d111..97e5039 100644 --- a/backend/models/category.model.js +++ b/backend/models/category.model.js @@ -1,4 +1,4 @@ -import { Schema, model } from "mongoose"; +import { Schema, model } from "mongoose" const categorySchems = new Schema({ name: { @@ -15,6 +15,6 @@ const categorySchems = new Schema({ ref: "Course", }, ], -}); +}) -export default model("Category", categorySchems); +export default model("Category", categorySchems) diff --git a/backend/models/course.model.js b/backend/models/course.model.js index b459a1c..bc57805 100644 --- a/backend/models/course.model.js +++ b/backend/models/course.model.js @@ -1,4 +1,4 @@ -import { Schema, model } from "mongoose"; +import { Schema, model } from "mongoose" const courseSchems = new Schema({ courseName: { @@ -76,6 +76,6 @@ const courseSchems = new Schema({ type: Date, default: Date.now, }, -}); +}) -export default model("Course", courseSchems); +export default model("Course", courseSchems) diff --git a/backend/models/courseProgress.model.js b/backend/models/courseProgress.model.js index f5fa58d..cae3cb2 100644 --- a/backend/models/courseProgress.model.js +++ b/backend/models/courseProgress.model.js @@ -1,4 +1,4 @@ -import { Schema, model } from "mongoose"; +import { Schema, model } from "mongoose" const courseProgressSchems = new Schema({ courseId: { @@ -16,6 +16,6 @@ const courseProgressSchems = new Schema({ ref: "SubSection", }, ], -}); +}) -export default model("CourseProgress", courseProgressSchems); +export default model("CourseProgress", courseProgressSchems) diff --git a/backend/models/otp.model.js b/backend/models/otp.model.js index d55cb55..60c496f 100644 --- a/backend/models/otp.model.js +++ b/backend/models/otp.model.js @@ -1,6 +1,6 @@ -import { Schema, model } from "mongoose"; -import mailSender from "../utils/mailSender.js"; -import otpTemplate from "../mail/templates/emailVerficationTemplate.js"; +import { Schema, model } from "mongoose" +import mailSender from "../utils/mailSender.js" +import otpTemplate from "../mail/templates/emailVerficationTemplate.js" const OTPShema = new Schema({ email: { @@ -18,7 +18,7 @@ const OTPShema = new Schema({ default: Date.now, expires: 5 * 60, }, -}); +}) async function sendVerificationEmail (email, otp) { try { @@ -26,17 +26,17 @@ async function sendVerificationEmail (email, otp) { email, "Verification Email from StudyNotion", otpTemplate(otp), - ); - console.log("Email sent Successfully: ", mailResponse); + ) + console.log("Email sent Successfully: ", mailResponse) } catch (error) { - console.log("error occured while sending mails: ", error); - throw error; + console.log("error occured while sending mails: ", error) + throw error } } OTPShema.pre("save", async function (next) { - await sendVerificationEmail(this.email, this.otp); - next(); -}); + await sendVerificationEmail(this.email, this.otp) + next() +}) -export default model("OTP", OTPShema); +export default model("OTP", OTPShema) diff --git a/backend/models/profile.model.js b/backend/models/profile.model.js index 9c9c5b2..9c74ac2 100644 --- a/backend/models/profile.model.js +++ b/backend/models/profile.model.js @@ -1,4 +1,4 @@ -import { Schema, model } from "mongoose"; +import { Schema, model } from "mongoose" const profileSchems = new Schema({ gender: { @@ -15,6 +15,6 @@ const profileSchems = new Schema({ type: Number, trim: true, }, -}); +}) -export default model("Profile", profileSchems); +export default model("Profile", profileSchems) diff --git a/backend/models/ratingAndReview.model.js b/backend/models/ratingAndReview.model.js index 90a946b..43a69e8 100644 --- a/backend/models/ratingAndReview.model.js +++ b/backend/models/ratingAndReview.model.js @@ -1,4 +1,4 @@ -import { Schema, model } from "mongoose"; +import { Schema, model } from "mongoose" const ratingAndReviewSchema = new Schema({ user: { @@ -19,6 +19,6 @@ const ratingAndReviewSchema = new Schema({ type: String, required: true, }, -}); +}) -export default model("RatingAndReview", ratingAndReviewSchema); +export default model("RatingAndReview", ratingAndReviewSchema) diff --git a/backend/models/section.model.js b/backend/models/section.model.js index 06dded4..4136723 100644 --- a/backend/models/section.model.js +++ b/backend/models/section.model.js @@ -1,4 +1,4 @@ -import { Schema, model } from "mongoose"; +import { Schema, model } from "mongoose" const sectionSchems = new Schema({ sectionName: { @@ -11,6 +11,6 @@ const sectionSchems = new Schema({ ref: "SubSection", }, ], -}); +}) -export default model("Section", sectionSchems); +export default model("Section", sectionSchems) diff --git a/backend/models/subSection.model.js b/backend/models/subSection.model.js index 8961701..664faf9 100644 --- a/backend/models/subSection.model.js +++ b/backend/models/subSection.model.js @@ -1,4 +1,4 @@ -import { Schema, model } from "mongoose"; +import { Schema, model } from "mongoose" const subSectionSchems = new Schema({ title: { @@ -16,6 +16,6 @@ const subSectionSchems = new Schema({ videoUrl: { type: String, }, -}); +}) -export default model("SubSection", subSectionSchems); +export default model("SubSection", subSectionSchems) diff --git a/backend/models/tags.model.js b/backend/models/tags.model.js index 3e103a8..48fa22e 100644 --- a/backend/models/tags.model.js +++ b/backend/models/tags.model.js @@ -1,4 +1,4 @@ -import { Schema, model } from "mongoose"; +import { Schema, model } from "mongoose" const tagsSchema = new Schema({ name: { @@ -12,6 +12,6 @@ const tagsSchema = new Schema({ type: Schema.Types.ObjectId, ref: "Course", }, -}); +}) -export default model("Tag", tagsSchema); +export default model("Tag", tagsSchema) diff --git a/backend/models/user.model.js b/backend/models/user.model.js index 763b7a3..fd7a774 100644 --- a/backend/models/user.model.js +++ b/backend/models/user.model.js @@ -1,4 +1,4 @@ -import { Schema, model } from "mongoose"; +import { Schema, model } from "mongoose" const userSchems = new Schema({ firstName: { @@ -59,6 +59,6 @@ const userSchems = new Schema({ resetPasswordExpires: { type: Date, }, -}); +}) -export default model("User", userSchems); +export default model("User", userSchems) diff --git a/backend/routes/contactUs.route.js b/backend/routes/contactUs.route.js index 97abf87..a0a573b 100644 --- a/backend/routes/contactUs.route.js +++ b/backend/routes/contactUs.route.js @@ -1,7 +1,7 @@ -import { Router } from "express"; -import { contactUsController } from "../controllers/contactUs.controller.js"; -const router = Router(); +import { Router } from "express" +import { contactUsController } from "../controllers/contactUs.controller.js" +const router = Router() -router.post("/contact", contactUsController); +router.post("/contact", contactUsController) -export default router; +export default router diff --git a/backend/routes/course.route.js b/backend/routes/course.route.js index 7f4edf4..cedbd33 100644 --- a/backend/routes/course.route.js +++ b/backend/routes/course.route.js @@ -1,4 +1,4 @@ -import { Router } from "express"; +import { Router } from "express" import { createCourse, @@ -8,73 +8,73 @@ import { editCourse, getInstructorCourses, deleteCourse, -} from "../controllers/course.controller.js"; // Course Controllers Import +} from "../controllers/course.controller.js" // Course Controllers Import import { showAllCategories, createCategory, categoryPageDetails, -} from "../controllers/category.controller.js"; // Categories Controllers Import +} from "../controllers/category.controller.js" // Categories Controllers Import import { createSection, updateSection, deleteSection, -} from "../controllers/section.controller.js"; // Sections Controllers Import +} from "../controllers/section.controller.js" // Sections Controllers Import import { createSubSection, updateSubSection, deleteSubSection, -} from "../controllers/subSection.controller.js"; // Sub-Sections Controllers Import +} from "../controllers/subSection.controller.js" // Sub-Sections Controllers Import import { createRating, getAverageRating, getAllRatingAndReview, -} from "../controllers/ratingAndReview.controller.js"; // Rating Controllers Import +} from "../controllers/ratingAndReview.controller.js" // Rating Controllers Import import { addCourseIntoCart, removeCourseFromCart, clearCart, -} from "../controllers/cart.controller.js"; // Cart Controllers Import +} from "../controllers/cart.controller.js" // Cart Controllers Import -import { auth, isInstructor, isStudent, isAdmin } from "../middlewares/auth.middelware.js"; // Importing Middlewares +import { auth, isInstructor, isStudent, isAdmin } from "../middlewares/auth.middelware.js" // Importing Middlewares -import { updateCourseProgress } from "../controllers/courseProgress.controller.js"; -const router = Router(); +import { updateCourseProgress } from "../controllers/courseProgress.controller.js" +const router = Router() // Course routes (only by Instructors) -router.post("/createCourse", auth, isInstructor, createCourse); -router.post("/addSection", auth, isInstructor, createSection); -router.post("/updateSection", auth, isInstructor, updateSection); -router.post("/deleteSection", auth, isInstructor, deleteSection); -router.post("/updateSubSection", auth, isInstructor, updateSubSection); -router.post("/deleteSubSection", auth, isInstructor, deleteSubSection); -router.post("/addSubSection", auth, isInstructor, createSubSection); -router.get("/getAllCourses", getAllCourses); -router.post("/getCourseDetails", getCourseDetails); -router.post("/editCourse", auth, isInstructor, editCourse); -router.get("/getInstructorCourses", auth, isInstructor, getInstructorCourses); -router.post("/getFullCourseDetails", auth, getFullCourseDetails); -router.delete("/deleteCourse", deleteCourse); +router.post("/createCourse", auth, isInstructor, createCourse) +router.post("/addSection", auth, isInstructor, createSection) +router.post("/updateSection", auth, isInstructor, updateSection) +router.post("/deleteSection", auth, isInstructor, deleteSection) +router.post("/updateSubSection", auth, isInstructor, updateSubSection) +router.post("/deleteSubSection", auth, isInstructor, deleteSubSection) +router.post("/addSubSection", auth, isInstructor, createSubSection) +router.get("/getAllCourses", getAllCourses) +router.post("/getCourseDetails", getCourseDetails) +router.post("/editCourse", auth, isInstructor, editCourse) +router.get("/getInstructorCourses", auth, isInstructor, getInstructorCourses) +router.post("/getFullCourseDetails", auth, getFullCourseDetails) +router.delete("/deleteCourse", deleteCourse) // Category routes (Only by Admin) -router.post("/createCategory", auth, isAdmin, createCategory); -router.get("/showAllCategories", showAllCategories); -router.post("/getCategoryPageDetails", categoryPageDetails); +router.post("/createCategory", auth, isAdmin, createCategory) +router.get("/showAllCategories", showAllCategories) +router.post("/getCategoryPageDetails", categoryPageDetails) // Cart routes (only by Student) -router.post("/addCourseIntoCart", auth, isStudent, addCourseIntoCart); -router.post("/removeCourseFromCart", auth, isStudent, removeCourseFromCart); -router.post("/clearCart", auth, isStudent, clearCart); +router.post("/addCourseIntoCart", auth, isStudent, addCourseIntoCart) +router.post("/removeCourseFromCart", auth, isStudent, removeCourseFromCart) +router.post("/clearCart", auth, isStudent, clearCart) // Rating and Review (only by Student) -router.post("/createRating", auth, isStudent, createRating); -router.get("/getAverageRating", getAverageRating); -router.get("/getReviews", getAllRatingAndReview); +router.post("/createRating", auth, isStudent, createRating) +router.get("/getAverageRating", getAverageRating) +router.get("/getReviews", getAllRatingAndReview) -router.post("/updateCourseProgress", auth, isStudent, updateCourseProgress); +router.post("/updateCourseProgress", auth, isStudent, updateCourseProgress) -export default router; +export default router diff --git a/backend/routes/payment.route.js b/backend/routes/payment.route.js index ef19f6e..0f30660 100644 --- a/backend/routes/payment.route.js +++ b/backend/routes/payment.route.js @@ -1,20 +1,20 @@ -import { Router } from "express"; +import { Router } from "express" import { capturePayment, verifyPayment, sendPaymentSuccessEmail, -} from "../controllers/payments.controller.js"; -import { auth, isStudent } from "../middlewares/auth.middelware.js"; -const router = Router(); +} from "../controllers/payments.controller.js" +import { auth, isStudent } from "../middlewares/auth.middelware.js" +const router = Router() -router.post("/capturePayment", auth, isStudent, capturePayment); -router.post("/verifyPayment", auth, isStudent, verifyPayment); +router.post("/capturePayment", auth, isStudent, capturePayment) +router.post("/verifyPayment", auth, isStudent, verifyPayment) router.post( "/sendPaymentSuccessEmail", auth, isStudent, sendPaymentSuccessEmail, -); +) -export default router; +export default router diff --git a/backend/routes/profile.route.js b/backend/routes/profile.route.js index d62d94a..f71513f 100644 --- a/backend/routes/profile.route.js +++ b/backend/routes/profile.route.js @@ -1,18 +1,18 @@ -import { Router } from "express"; +import { Router } from "express" -import { auth, isInstructor } from "../middlewares/auth.middelware.js"; +import { auth, isInstructor } from "../middlewares/auth.middelware.js" import { updateProfile, updateDisplayPicture, getEnrolledCourses, instructorDashboard, -} from "../controllers/profile.controller.js"; -const router = Router(); +} from "../controllers/profile.controller.js" +const router = Router() // Profile routes -router.put("/updateProfile", auth, updateProfile); -router.get("/getEnrolledCourses", auth, getEnrolledCourses); -router.put("/updateDisplayPicture", auth, updateDisplayPicture); -router.get("/instructorDashboard", auth, isInstructor, instructorDashboard); +router.put("/updateProfile", auth, updateProfile) +router.get("/getEnrolledCourses", auth, getEnrolledCourses) +router.put("/updateDisplayPicture", auth, updateDisplayPicture) +router.get("/instructorDashboard", auth, isInstructor, instructorDashboard) -export default router; +export default router diff --git a/backend/routes/user.route.js b/backend/routes/user.route.js index f28fae7..c51b849 100644 --- a/backend/routes/user.route.js +++ b/backend/routes/user.route.js @@ -1,37 +1,37 @@ -import { Router } from "express"; +import { Router } from "express" import { login, signUp, sendOTP, changePassword, -} from "../controllers/auth.controller.js"; +} from "../controllers/auth.controller.js" import { resetPasswordToken, resetPassword, -} from "../controllers/resetPassword.controller.js"; +} from "../controllers/resetPassword.controller.js" import { deleteUserAccount, getAllUserDetails, -} from "../controllers/user.controller.js"; +} from "../controllers/user.controller.js" -import { auth } from "../middlewares/auth.middelware.js"; -const router = Router(); +import { auth } from "../middlewares/auth.middelware.js" +const router = Router() // Authentication routes -router.post("/login", login); -router.post("/signup", signUp); -router.post("/sendotp", sendOTP); -router.post("/changepassword", auth, changePassword); +router.post("/login", login) +router.post("/signup", signUp) +router.post("/sendotp", sendOTP) +router.post("/changepassword", auth, changePassword) // Reset Password -router.post("/reset-password-token", resetPasswordToken); -router.post("/reset-password", resetPassword); +router.post("/reset-password-token", resetPasswordToken) +router.post("/reset-password", resetPassword) // User routes -router.delete("/deleteUserAccount", auth, deleteUserAccount); -router.get("/getUserDetails", auth, getAllUserDetails); +router.delete("/deleteUserAccount", auth, deleteUserAccount) +router.get("/getUserDetails", auth, getAllUserDetails) -export default router; +export default router diff --git a/backend/test/models/category.model.test.js b/backend/test/models/category.model.test.js index ca7413d..b992044 100644 --- a/backend/test/models/category.model.test.js +++ b/backend/test/models/category.model.test.js @@ -1,31 +1,31 @@ /* eslint-env jest */ -import mongoose from "mongoose"; -import Category from "../../models/category.model.js"; +import mongoose from "mongoose" +import Category from "../../models/category.model.js" describe("Category Model Test", () => { beforeAll(async () => { - const url = "mongodb://127.0.0.1/testDB"; - await mongoose.connect(url, { useNewUrlParser: true }); - }); + const url = "mongodb://127.0.0.1/testDB" + await mongoose.connect(url, { useNewUrlParser: true }) + }) afterAll(async () => { - await mongoose.connection.close(); - }); + await mongoose.connection.close() + }) it("create & save category successfully", async () => { const categoryData = { name: "Test Category", description: "Test Description", courses: [], - }; - const validCategory = new Category(categoryData); - const savedCategory = await validCategory.save(); + } + const validCategory = new Category(categoryData) + const savedCategory = await validCategory.save() // Object Id should be defined when successfully saved to MongoDB. - expect(savedCategory._id).toBeDefined(); - expect(savedCategory.name).toBe(categoryData.name); - expect(savedCategory.description).toBe(categoryData.description); - expect(savedCategory.courses).toStrictEqual(categoryData.courses); - }); -}); + expect(savedCategory._id).toBeDefined() + expect(savedCategory.name).toBe(categoryData.name) + expect(savedCategory.description).toBe(categoryData.description) + expect(savedCategory.courses).toStrictEqual(categoryData.courses) + }) +}) diff --git a/backend/utils/fileUploader.js b/backend/utils/fileUploader.js index 53c64a0..22aab0c 100644 --- a/backend/utils/fileUploader.js +++ b/backend/utils/fileUploader.js @@ -1,22 +1,22 @@ -import { v2 as cloudinary } from "cloudinary"; +import { v2 as cloudinary } from "cloudinary" // Upload any files and images to cloudinary export default async function uploadFileToCloudinary (file, folder, height, quality) { try { - const options = { folder }; + const options = { folder } if (height) { - options.height = height; + options.height = height } if (quality) { - options.quality = quality; + options.quality = quality } - options.resource_type = "auto"; + options.resource_type = "auto" - return await cloudinary.uploader.upload(file.tempFilePath, options); + return await cloudinary.uploader.upload(file.tempFilePath, options) } catch (error) { - console.log("Error in uploading image to cloudinary: " + error.message); - throw error; + console.log("Error in uploading image to cloudinary: " + error.message) + throw error } } diff --git a/backend/utils/mailSender.js b/backend/utils/mailSender.js index d1df8de..e345a47 100644 --- a/backend/utils/mailSender.js +++ b/backend/utils/mailSender.js @@ -1,4 +1,4 @@ -import nodemailer from "nodemailer"; +import nodemailer from "nodemailer" export default async function mailSender (email, title, body) { try { @@ -10,7 +10,7 @@ export default async function mailSender (email, title, body) { user: process.env.MAIL_USER, pass: process.env.MAIL_PASS, }, - }); + }) // send mail with defined transport object const info = await transporter.sendMail({ @@ -18,10 +18,10 @@ export default async function mailSender (email, title, body) { to: `${email}`, subject: `${title}`, html: `${body}`, - }); - console.log(info); - return info; + }) + console.log(info) + return info } catch (error) { - console.log(error); + console.log(error) } } diff --git a/backend/utils/secToDuration.js b/backend/utils/secToDuration.js index 4610dde..ebb5d64 100644 --- a/backend/utils/secToDuration.js +++ b/backend/utils/secToDuration.js @@ -1,15 +1,15 @@ // Helper function to convert total seconds to the duration format export default function convertSecondsToDuration (totalSeconds) { - const hours = Math.floor(totalSeconds / 3600); - const minutes = Math.floor((totalSeconds % 3600) / 60); - const seconds = Math.floor((totalSeconds % 3600) % 60); + const hours = Math.floor(totalSeconds / 3600) + const minutes = Math.floor((totalSeconds % 3600) / 60) + const seconds = Math.floor((totalSeconds % 3600) % 60) if (hours > 0) { - return `${hours}h ${minutes}m`; + return `${hours}h ${minutes}m` } else if (minutes > 0) { - return `${minutes}m ${seconds}s`; + return `${minutes}m ${seconds}s` } else { - return `${seconds}s`; + return `${seconds}s` } } diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js index 2aa7205..2e7af2b 100644 --- a/frontend/postcss.config.js +++ b/frontend/postcss.config.js @@ -3,4 +3,4 @@ export default { tailwindcss: {}, autoprefixer: {}, }, -}; +} diff --git a/frontend/src/data/dashboard-links.js b/frontend/src/data/dashboard-links.js index dcb4da4..b385b1f 100644 --- a/frontend/src/data/dashboard-links.js +++ b/frontend/src/data/dashboard-links.js @@ -1,4 +1,4 @@ -import { ACCOUNT_TYPE } from "../utils/constants"; +import { ACCOUNT_TYPE } from "../utils/constants" export const sidebarLinks = [ { @@ -43,4 +43,4 @@ export const sidebarLinks = [ icon: "VscArchive", }, -]; +] diff --git a/frontend/src/data/footer-links.js b/frontend/src/data/footer-links.js index 12c34f8..a610bf1 100644 --- a/frontend/src/data/footer-links.js +++ b/frontend/src/data/footer-links.js @@ -43,4 +43,4 @@ export const FooterLink2 = [ { title: "Beta Content", link: "/beta-content" }, ], }, -]; +] diff --git a/frontend/src/data/homepage-explore.js b/frontend/src/data/homepage-explore.js index af426cc..b625333 100644 --- a/frontend/src/data/homepage-explore.js +++ b/frontend/src/data/homepage-explore.js @@ -129,4 +129,4 @@ export const HomePageExplore = [ }, ], }, -]; +] diff --git a/frontend/src/data/navbar-links.js b/frontend/src/data/navbar-links.js index 3d710a4..4673216 100644 --- a/frontend/src/data/navbar-links.js +++ b/frontend/src/data/navbar-links.js @@ -15,4 +15,4 @@ export const NavbarLinks = [ title: "Contact Us", path: "/contact", }, -]; +] diff --git a/frontend/src/hooks/useOnClickOutside.js b/frontend/src/hooks/useOnClickOutside.js index 9ed76f8..03f55b6 100644 --- a/frontend/src/hooks/useOnClickOutside.js +++ b/frontend/src/hooks/useOnClickOutside.js @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { useEffect } from "react" // This hook detects clicks outside of the specified component and calls the provided handler function. export default function useOnClickOutside (ref, handler) { @@ -7,20 +7,20 @@ export default function useOnClickOutside (ref, handler) { const listener = (event) => { // If the click/touch event originated inside the ref element, do nothing if (!ref.current || ref.current.contains(event.target)) { - return; + return } // Otherwise, call the provided handler function - handler(event); - }; + handler(event) + } // Add event listeners for mousedown and touchstart events on the document - document.addEventListener("mousedown", listener); - document.addEventListener("touchstart", listener); + document.addEventListener("mousedown", listener) + document.addEventListener("touchstart", listener) // Cleanup function to remove the event listeners when the component unmounts or when the ref/handler dependencies change return () => { - document.removeEventListener("mousedown", listener); - document.removeEventListener("touchstart", listener); - }; - }, [ref, handler]); // Only run this effect when the ref or handler function changes + document.removeEventListener("mousedown", listener) + document.removeEventListener("touchstart", listener) + } + }, [ref, handler]) // Only run this effect when the ref or handler function changes } diff --git a/frontend/src/hooks/useRouteMatch.js b/frontend/src/hooks/useRouteMatch.js index b6bf04f..bbed36d 100644 --- a/frontend/src/hooks/useRouteMatch.js +++ b/frontend/src/hooks/useRouteMatch.js @@ -1,7 +1,7 @@ -import { useLocation, matchPath } from "react-router-dom"; +import { useLocation, matchPath } from "react-router-dom" export default function useRouteMatch (path) { - const location = useLocation(); - return matchPath(location.pathname, { path }); + const location = useLocation() + return matchPath(location.pathname, { path }) } // this custom hook check if current location is same as path or not; diff --git a/frontend/src/reducer/index.js b/frontend/src/reducer/index.js index c76bd88..b3f620b 100644 --- a/frontend/src/reducer/index.js +++ b/frontend/src/reducer/index.js @@ -1,9 +1,9 @@ -import { combineReducers } from "@reduxjs/toolkit"; -import authReducer from "../slices/authSlice.js"; -import profileReducer from "../slices/profileSlice.js"; -import cartReducer from "../slices/cartSlice.js"; -import courseReducer from "../slices/courseSlice.js"; -import viewCourseReducer from "../slices/viewCourseSlice.js"; +import { combineReducers } from "@reduxjs/toolkit" +import authReducer from "../slices/authSlice.js" +import profileReducer from "../slices/profileSlice.js" +import cartReducer from "../slices/cartSlice.js" +import courseReducer from "../slices/courseSlice.js" +import viewCourseReducer from "../slices/viewCourseSlice.js" const rootReducer = combineReducers({ // combining all reducer; @@ -12,6 +12,6 @@ const rootReducer = combineReducers({ cart: cartReducer, course: courseReducer, viewCourse: viewCourseReducer, -}); +}) -export default rootReducer; +export default rootReducer diff --git a/frontend/src/services/apiconnector.js b/frontend/src/services/apiconnector.js index e3e51b2..a6c02f0 100644 --- a/frontend/src/services/apiconnector.js +++ b/frontend/src/services/apiconnector.js @@ -1,6 +1,6 @@ -import axios from "axios"; +import axios from "axios" -export const axiosInstance = axios.create({}); +export const axiosInstance = axios.create({}) export const apiConnector = (method, url, bodyData, headers, params) => { return axiosInstance({ @@ -9,5 +9,5 @@ export const apiConnector = (method, url, bodyData, headers, params) => { data: bodyData || null, headers: headers || null, params: params || null, - }); -}; + }) +} diff --git a/frontend/src/services/apis.js b/frontend/src/services/apis.js index af45240..582ab28 100644 --- a/frontend/src/services/apis.js +++ b/frontend/src/services/apis.js @@ -1,4 +1,4 @@ -const BASE_URL = String(import.meta.env.VITE_REACT_APP_BASE_URL); +const BASE_URL = String(import.meta.env.VITE_REACT_APP_BASE_URL) // AUTH ENDPOINTS export const authEndpoints = { @@ -7,21 +7,21 @@ export const authEndpoints = { LOGIN_API: BASE_URL + "/auth/login", RESETPASSTOKEN_API: BASE_URL + "/auth/reset-password-token", RESETPASSWORD_API: BASE_URL + "/auth/reset-password", -}; +} // PROFILE ENDPOINTS export const profileEndpoints = { GET_USER_DETAILS_API: BASE_URL + "/profile/getUserDetails", GET_USER_ENROLLED_COURSES_API: BASE_URL + "/profile/getEnrolledCourses", GET_INSTRUCTOR_DATA_API: BASE_URL + "/profile/instructorDashboard", -}; +} // STUDENTS ENDPOINTS export const studentEndpoints = { COURSE_PAYMENT_API: BASE_URL + "/payment/capturePayment", COURSE_VERIFY_API: BASE_URL + "/payment/verifyPayment", SEND_PAYMENT_SUCCESS_EMAIL_API: BASE_URL + "/payment/sendPaymentSuccessEmail", -}; +} // COURSE ENDPOINTS export const courseEndpoints = { @@ -42,34 +42,34 @@ export const courseEndpoints = { BASE_URL + "/course/getFullCourseDetails", LECTURE_COMPLETION_API: BASE_URL + "/course/updateCourseProgress", CREATE_RATING_API: BASE_URL + "/course/createRating", -}; +} // RATINGS AND REVIEWS export const ratingsEndpoints = { REVIEWS_DETAILS_API: BASE_URL + "/course/getReviews", -}; +} // CATAGORIES API export const categories = { CATEGORIES_API: BASE_URL + "/course/showAllCategories", -}; +} // CATALOG PAGE DATA export const catalogData = { CATALOGPAGEDATA_API: BASE_URL + "/course/getCategoryPageDetails", -}; +} // CONTACT-US API export const contactusEndpoint = { CONTACT_US_API: BASE_URL + "/reach/contact", -}; +} // CART API export const cartEndpoints = { ADD_TO_CART_API: BASE_URL + "/course/addCourseIntoCart", REMOVE_FROM_CART_API: BASE_URL + "/course/removeCourseFromCart", CLEAR_CART_API: BASE_URL + "/course/clearCart", -}; +} // SETTINGS PAGE API export const settingsEndpoints = { @@ -77,4 +77,4 @@ export const settingsEndpoints = { UPDATE_PROFILE_API: BASE_URL + "/profile/updateProfile", CHANGE_PASSWORD_API: BASE_URL + "/auth/changepassword", DELETE_USER_API: BASE_URL + "/auth/deleteUserAccount", -}; +} diff --git a/frontend/src/services/formatDate.js b/frontend/src/services/formatDate.js index 4588c22..958cf8d 100644 --- a/frontend/src/services/formatDate.js +++ b/frontend/src/services/formatDate.js @@ -1,14 +1,14 @@ export const formatDate = (dateString) => { - const options = { year: "numeric", month: "long", day: "numeric" }; - const date = new Date(dateString); - const formattedDate = date.toLocaleDateString("en-US", options); + const options = { year: "numeric", month: "long", day: "numeric" } + const date = new Date(dateString) + const formattedDate = date.toLocaleDateString("en-US", options) - const hour = date.getHours(); - const minutes = date.getMinutes(); - const period = hour >= 12 ? "PM" : "AM"; + const hour = date.getHours() + const minutes = date.getMinutes() + const period = hour >= 12 ? "PM" : "AM" const formattedTime = `${hour % 12}:${minutes .toString() - .padStart(2, "0")} ${period}`; + .padStart(2, "0")} ${period}` - return `${formattedDate} | ${formattedTime}`; -}; + return `${formattedDate} | ${formattedTime}` +} diff --git a/frontend/src/services/operations/SettingsAPI.js b/frontend/src/services/operations/SettingsAPI.js index 3e82b05..cd017b4 100644 --- a/frontend/src/services/operations/SettingsAPI.js +++ b/frontend/src/services/operations/SettingsAPI.js @@ -1,19 +1,19 @@ -import { toast } from "react-hot-toast"; -import { setUser } from "../../slices/profileSlice"; -import { apiConnector } from "../apiconnector"; -import { settingsEndpoints } from "../apis"; -import { logout } from "./authAPI"; +import { toast } from "react-hot-toast" +import { setUser } from "../../slices/profileSlice" +import { apiConnector } from "../apiconnector" +import { settingsEndpoints } from "../apis" +import { logout } from "./authAPI" const { UPDATE_DISPLAY_PICTURE_API, UPDATE_PROFILE_API, CHANGE_PASSWORD_API, DELETE_USER_API, -} = settingsEndpoints; +} = settingsEndpoints export function updateDisplayPicture (token, formData) { return async (dispatch) => { - const toastId = toast.loading("Loading..."); + const toastId = toast.loading("Loading...") try { const response = await apiConnector( "PUT", @@ -23,103 +23,103 @@ export function updateDisplayPicture (token, formData) { "Content-Type": "multipart/form-data", authorization: `Bearer ${token}`, }, - ); + ) console.log( "UPDATE_DISPLAY_PICTURE_API API RESPONSE............", response, - ); + ) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - toast.success("Display Picture Updated Successfully"); - dispatch(setUser(response.data.data)); + toast.success("Display Picture Updated Successfully") + dispatch(setUser(response.data.data)) // Update user profile in local storage localStorage.setItem( "user", JSON.stringify(response.data.updatedProfile), - ); + ) } catch (error) { - console.log("UPDATE_DISPLAY_PICTURE_API API ERROR............", error); - toast.error("Could Not Update Display Picture"); + console.log("UPDATE_DISPLAY_PICTURE_API API ERROR............", error) + toast.error("Could Not Update Display Picture") } - toast.dismiss(toastId); - }; + toast.dismiss(toastId) + } } export function updateProfile (token, formData) { return async (dispatch) => { - const toastId = toast.loading("Loading..."); + const toastId = toast.loading("Loading...") try { const response = await apiConnector("PUT", UPDATE_PROFILE_API, formData, { authorization: `Bearer ${token}`, - }); - console.log("UPDATE_PROFILE_API API RESPONSE............", response); + }) + console.log("UPDATE_PROFILE_API API RESPONSE............", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } const userImage = response.data.updatedUserDetails.image ? response.data.updatedUserDetails.image - : `https://api.dicebear.com/5.x/initials/svg?seed=${response.data.updatedUserDetails.firstName}+${response.data.updatedUserDetails.lastName}`; + : `https://api.dicebear.com/5.x/initials/svg?seed=${response.data.updatedUserDetails.firstName}+${response.data.updatedUserDetails.lastName}` dispatch( setUser({ ...response.data.updatedUserDetails, image: userImage }), - ); + ) // Update user profile in local storage localStorage.setItem( "user", JSON.stringify(response.data.updatedUserDetails), - ); + ) - toast.success("Profile Updated Successfully"); + toast.success("Profile Updated Successfully") } catch (error) { - console.log("UPDATE_PROFILE_API API ERROR............", error); - toast.error("Could Not Update Profile"); + console.log("UPDATE_PROFILE_API API ERROR............", error) + toast.error("Could Not Update Profile") } - toast.dismiss(toastId); - }; + toast.dismiss(toastId) + } } export async function changePassword (token, formData) { - const toastId = toast.loading("Loading..."); + const toastId = toast.loading("Loading...") try { const response = await apiConnector("POST", CHANGE_PASSWORD_API, formData, { authorization: `Bearer ${token}`, - }); - console.log("CHANGE_PASSWORD_API API RESPONSE............", response); + }) + console.log("CHANGE_PASSWORD_API API RESPONSE............", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - toast.success("Password Changed Successfully"); + toast.success("Password Changed Successfully") } catch (error) { - console.log("CHANGE_PASSWORD_API API ERROR............", error); - toast.error(error.response.data.message); + console.log("CHANGE_PASSWORD_API API ERROR............", error) + toast.error(error.response.data.message) } - toast.dismiss(toastId); + toast.dismiss(toastId) } export function deleteUserAccount (token, navigate) { return async (dispatch) => { - const toastId = toast.loading("Loading..."); + const toastId = toast.loading("Loading...") try { const response = await apiConnector("DELETE", DELETE_USER_API, null, { authorization: `Bearer ${token}`, - }); - console.log("DELETE_PROFILE_API API RESPONSE............", response); + }) + console.log("DELETE_PROFILE_API API RESPONSE............", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - toast.success("Profile Deleted Successfully"); - localStorage.removeItem("token"); - localStorage.removeItem("user"); - dispatch(logout(navigate)); + toast.success("Profile Deleted Successfully") + localStorage.removeItem("token") + localStorage.removeItem("user") + dispatch(logout(navigate)) } catch (error) { - console.log("DELETE_PROFILE_API API ERROR............", error); - toast.error("Could Not Delete Profile"); + console.log("DELETE_PROFILE_API API ERROR............", error) + toast.error("Could Not Delete Profile") } - toast.dismiss(toastId); - }; + toast.dismiss(toastId) + } } diff --git a/frontend/src/services/operations/authAPI.js b/frontend/src/services/operations/authAPI.js index 82ae698..b2137ee 100644 --- a/frontend/src/services/operations/authAPI.js +++ b/frontend/src/services/operations/authAPI.js @@ -1,9 +1,9 @@ -import { toast } from "react-hot-toast"; -import { setLoading, setToken } from "../../slices/authSlice"; -import { resetCart } from "../../slices/cartSlice"; -import { setUser } from "../../slices/profileSlice"; -import { apiConnector } from "../apiconnector"; -import { authEndpoints } from "../apis"; +import { toast } from "react-hot-toast" +import { setLoading, setToken } from "../../slices/authSlice" +import { resetCart } from "../../slices/cartSlice" +import { setUser } from "../../slices/profileSlice" +import { apiConnector } from "../apiconnector" +import { authEndpoints } from "../apis" const { SENDOTP_API, @@ -11,31 +11,31 @@ const { LOGIN_API, RESETPASSTOKEN_API, RESETPASSWORD_API, -} = authEndpoints; +} = authEndpoints export function sendOtp (email, navigate) { return async (dispatch) => { - const toastId = toast.loading("Loading..."); - dispatch(setLoading(true)); + const toastId = toast.loading("Loading...") + dispatch(setLoading(true)) try { const response = await apiConnector("POST", SENDOTP_API, { email, checkUserPresent: true, - }); - console.log("SENDOTP API RESPONSE............", response); + }) + console.log("SENDOTP API RESPONSE............", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - toast.success("OTP Sent Successfully"); - navigate("/verify-email"); + toast.success("OTP Sent Successfully") + navigate("/verify-email") } catch (error) { - console.log("SENDOTP API ERROR............", error); - toast.error("Could Not Send OTP"); + console.log("SENDOTP API ERROR............", error) + toast.error("Could Not Send OTP") } - dispatch(setLoading(false)); - toast.dismiss(toastId); - }; + dispatch(setLoading(false)) + toast.dismiss(toastId) + } } export function signUp ( @@ -49,8 +49,8 @@ export function signUp ( navigate, ) { return async (dispatch) => { - const toastId = toast.loading("Loading..."); - dispatch(setLoading(true)); + const toastId = toast.loading("Loading...") + dispatch(setLoading(true)) try { const response = await apiConnector("POST", SIGNUP_API, { accountType, @@ -60,112 +60,112 @@ export function signUp ( password, confirmPassword, otp, - }); - console.log("SIGNUP API RESPONSE............", response); + }) + console.log("SIGNUP API RESPONSE............", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - toast.success("Signup Successful"); - navigate("/login"); + toast.success("Signup Successful") + navigate("/login") } catch (error) { - console.log("SIGNUP API ERROR............", error); - toast.error("Signup Failed"); - navigate("/signup"); + console.log("SIGNUP API ERROR............", error) + toast.error("Signup Failed") + navigate("/signup") } - dispatch(setLoading(false)); - toast.dismiss(toastId); - }; + dispatch(setLoading(false)) + toast.dismiss(toastId) + } } export function login (email, password, navigate) { return async (dispatch) => { - const toastId = toast.loading("Loading..."); - dispatch(setLoading(true)); + const toastId = toast.loading("Loading...") + dispatch(setLoading(true)) try { const response = await apiConnector("POST", LOGIN_API, { email, password, - }); - console.log("LOGIN API RESPONSE............", response); + }) + console.log("LOGIN API RESPONSE............", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - toast.success("Login Successful"); - dispatch(setToken(response.data.token)); + toast.success("Login Successful") + dispatch(setToken(response.data.token)) const userImage = response.data?.user?.image ? response.data.user.image - : `https://api.dicebear.com/5.x/initials/svg?seed=${response.data.user.firstName}+${response.data.user.lastName}`; - dispatch(setUser({ ...response.data.user, image: userImage })); + : `https://api.dicebear.com/5.x/initials/svg?seed=${response.data.user.firstName}+${response.data.user.lastName}` + dispatch(setUser({ ...response.data.user, image: userImage })) - localStorage.setItem("token", JSON.stringify(response.data.token)); - localStorage.setItem("user", JSON.stringify(response.data.user)); - navigate("/dashboard/my-profile"); + localStorage.setItem("token", JSON.stringify(response.data.token)) + localStorage.setItem("user", JSON.stringify(response.data.user)) + navigate("/dashboard/my-profile") } catch (error) { - console.log("LOGIN API ERROR............", error); - toast.error("Login Failed"); + console.log("LOGIN API ERROR............", error) + toast.error("Login Failed") } - dispatch(setLoading(false)); - toast.dismiss(toastId); - }; + dispatch(setLoading(false)) + toast.dismiss(toastId) + } } export function logout (navigate) { return (dispatch) => { - dispatch(setToken(null)); - dispatch(setUser(null)); - dispatch(resetCart()); - localStorage.removeItem("token"); - localStorage.removeItem("user"); - toast.success("Logged Out"); - navigate("/"); - }; + dispatch(setToken(null)) + dispatch(setUser(null)) + dispatch(resetCart()) + localStorage.removeItem("token") + localStorage.removeItem("user") + toast.success("Logged Out") + navigate("/") + } } export function getPasswordResetToken (email, setEmailSent) { return async (dispatch) => { - dispatch(setLoading(true)); + dispatch(setLoading(true)) try { const response = await apiConnector("POST", RESETPASSTOKEN_API, { email, - }); - console.log("RESET PASSWORD TOKEN RESPONSE....", response); + }) + console.log("RESET PASSWORD TOKEN RESPONSE....", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - toast.success("Reset Email Sent"); - setEmailSent(true); + toast.success("Reset Email Sent") + setEmailSent(true) } catch (error) { - console.log("RESET PASSWORD TOKEN Error", error); - toast.error("Failed to send email for resetting password"); + console.log("RESET PASSWORD TOKEN Error", error) + toast.error("Failed to send email for resetting password") } - dispatch(setLoading(false)); - }; + dispatch(setLoading(false)) + } } export function resetPassword (password, confirmPassword, token, navigate) { return async (dispatch) => { - dispatch(setLoading(true)); + dispatch(setLoading(true)) try { const response = await apiConnector("POST", RESETPASSWORD_API, { password, confirmPassword, token, - }); - console.log("RESET Password RESPONSE ... ", response); + }) + console.log("RESET Password RESPONSE ... ", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - toast.success("Password has been reset successfully"); - navigate("/login"); + toast.success("Password has been reset successfully") + navigate("/login") } catch (error) { - console.log("RESET PASSWORD TOKEN Error", error); - toast.error("Unable to reset password"); + console.log("RESET PASSWORD TOKEN Error", error) + toast.error("Unable to reset password") } - dispatch(setLoading(false)); - }; + dispatch(setLoading(false)) + } } diff --git a/frontend/src/services/operations/courseDetailsAPI.js b/frontend/src/services/operations/courseDetailsAPI.js index bc7bb59..2c77d84 100644 --- a/frontend/src/services/operations/courseDetailsAPI.js +++ b/frontend/src/services/operations/courseDetailsAPI.js @@ -1,6 +1,6 @@ -import { toast } from "react-hot-toast"; -import { apiConnector } from "../apiconnector"; -import { cartEndpoints, courseEndpoints } from "../apis"; +import { toast } from "react-hot-toast" +import { apiConnector } from "../apiconnector" +import { cartEndpoints, courseEndpoints } from "../apis" const { COURSE_DETAILS_API, @@ -19,259 +19,259 @@ const { GET_FULL_COURSE_DETAILS_AUTHENTICATED, CREATE_RATING_API, LECTURE_COMPLETION_API, -} = courseEndpoints; +} = courseEndpoints -const { ADD_TO_CART_API, REMOVE_FROM_CART_API, CLEAR_CART_API } = cartEndpoints; +const { ADD_TO_CART_API, REMOVE_FROM_CART_API, CLEAR_CART_API } = cartEndpoints export const getAllCourses = async () => { - const toastId = toast.loading("Loading..."); - let result = []; + const toastId = toast.loading("Loading...") + let result = [] try { - const response = await apiConnector("GET", GET_ALL_COURSE_API); + const response = await apiConnector("GET", GET_ALL_COURSE_API) if (!response?.data?.success) { - throw new Error("Could Not Fetch Course Categories"); + throw new Error("Could Not Fetch Course Categories") } - console.log("GET_ALL_COURSE_API API RESPONSE............", response); - result = response?.data?.data; + console.log("GET_ALL_COURSE_API API RESPONSE............", response) + result = response?.data?.data } catch (error) { - console.log("GET_ALL_COURSE_API API ERROR............", error); - toast.error(error.message); + console.log("GET_ALL_COURSE_API API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} export const fetchCourseDetails = async (courseId) => { - const toastId = toast.loading("Loading..."); - let result = null; + const toastId = toast.loading("Loading...") + let result = null try { const response = await apiConnector("POST", COURSE_DETAILS_API, { courseId, - }); - console.log("COURSE_DETAILS_API API RESPONSE............", response); + }) + console.log("COURSE_DETAILS_API API RESPONSE............", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - result = response.data; + result = response.data } catch (error) { - console.log("COURSE_DETAILS_API API ERROR............", error); - result = error.response.data; - toast.error(error.response.data.message); + console.log("COURSE_DETAILS_API API ERROR............", error) + result = error.response.data + toast.error(error.response.data.message) } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} // fetching the available course categories export const fetchCourseCategories = async () => { - let result = []; + let result = [] try { - const response = await apiConnector("GET", COURSE_CATEGORIES_API); - console.log("COURSE_CATEGORIES_API API RESPONSE............", response); + const response = await apiConnector("GET", COURSE_CATEGORIES_API) + console.log("COURSE_CATEGORIES_API API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Fetch Course Categories"); + throw new Error("Could Not Fetch Course Categories") } - result = response?.data?.allCategories; + result = response?.data?.allCategories } catch (error) { - console.log("COURSE_CATEGORY_API API ERROR............", error); - toast.error(error.message); + console.log("COURSE_CATEGORY_API API ERROR............", error) + toast.error(error.message) } - return result; -}; + return result +} // add the course details export const addCourseDetails = async (data, token) => { - let result = null; - const toastId = toast.loading("Loading..."); + let result = null + const toastId = toast.loading("Loading...") try { const response = await apiConnector("POST", CREATE_COURSE_API, data, { "Content-Type": "multipart/form-data", Authorization: `Bearer ${token}`, - }); - console.log("CREATE COURSE API RESPONSE............", response); + }) + console.log("CREATE COURSE API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Add Course Details"); + throw new Error("Could Not Add Course Details") } - toast.success("Course Details Added Successfully"); - result = response?.data?.data; + toast.success("Course Details Added Successfully") + result = response?.data?.data } catch (error) { - console.log("CREATE COURSE API ERROR............", error); - toast.error(error.message); + console.log("CREATE COURSE API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} // edit the course details export const editCourseDetails = async (data, token) => { - let result = null; - const toastId = toast.loading("Loading..."); + let result = null + const toastId = toast.loading("Loading...") try { const response = await apiConnector("POST", EDIT_COURSE_API, data, { "Content-Type": "multipart/form-data", Authorization: `Bearer ${token}`, - }); - console.log("EDIT COURSE API RESPONSE............", response); + }) + console.log("EDIT COURSE API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Update Course Details"); + throw new Error("Could Not Update Course Details") } - toast.success("Course Details Updated Successfully"); - console.log("EDIT COURSE API RESPONSE............", response); - result = response?.data?.data; + toast.success("Course Details Updated Successfully") + console.log("EDIT COURSE API RESPONSE............", response) + result = response?.data?.data } catch (error) { - console.log("EDIT COURSE API ERROR............", error); - toast.error(error.message); + console.log("EDIT COURSE API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} // create a section export const createSection = async (data, token) => { - let result = null; - const toastId = toast.loading("Loading..."); + let result = null + const toastId = toast.loading("Loading...") try { const response = await apiConnector("POST", CREATE_SECTION_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("CREATE SECTION API RESPONSE............", response); + }) + console.log("CREATE SECTION API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Create Section"); + throw new Error("Could Not Create Section") } - toast.success("Course Section Created"); - result = response?.data?.updatedCourseDetails; + toast.success("Course Section Created") + result = response?.data?.updatedCourseDetails } catch (error) { - console.log("CREATE SECTION API ERROR............", error); - toast.error(error.message); + console.log("CREATE SECTION API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} // create a subsection export const createSubSection = async (data, token) => { - console.log("createSubSection data", data); - let result = null; - const toastId = toast.loading("Loading..."); + console.log("createSubSection data", data) + let result = null + const toastId = toast.loading("Loading...") try { const response = await apiConnector("POST", CREATE_SUBSECTION_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("CREATE SUB-SECTION API RESPONSE............", response); + }) + console.log("CREATE SUB-SECTION API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Add Lecture"); + throw new Error("Could Not Add Lecture") } - toast.success("Lecture Added"); - result = response?.data?.data; + toast.success("Lecture Added") + result = response?.data?.data } catch (error) { - console.log("CREATE SUB-SECTION API ERROR............", error); - toast.error(error.message); + console.log("CREATE SUB-SECTION API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} // update a section export const updateSection = async (data, token) => { - let result = null; - const toastId = toast.loading("Loading..."); + let result = null + const toastId = toast.loading("Loading...") try { const response = await apiConnector("POST", UPDATE_SECTION_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("UPDATE SECTION API RESPONSE............", response); + }) + console.log("UPDATE SECTION API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Update Section"); + throw new Error("Could Not Update Section") } - toast.success("Course Section Updated"); - result = response?.data?.updatedCourseDetails; + toast.success("Course Section Updated") + result = response?.data?.updatedCourseDetails } catch (error) { - console.log("UPDATE SECTION API ERROR............", error); - toast.error(error.message); + console.log("UPDATE SECTION API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} // update a subsection export const updateSubSection = async (data, token) => { - let result = null; - const toastId = toast.loading("Loading..."); + let result = null + const toastId = toast.loading("Loading...") try { const response = await apiConnector("POST", UPDATE_SUBSECTION_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("UPDATE SUB-SECTION API RESPONSE............", response); + }) + console.log("UPDATE SUB-SECTION API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Update Lecture"); + throw new Error("Could Not Update Lecture") } - toast.success("Lecture Updated"); - result = response?.data?.data; + toast.success("Lecture Updated") + result = response?.data?.data } catch (error) { - console.log("UPDATE SUB-SECTION API ERROR............", error); - toast.error(error.message); + console.log("UPDATE SUB-SECTION API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} // delete a section export const deleteSection = async (data, token) => { - let result = null; - const toastId = toast.loading("Loading..."); + let result = null + const toastId = toast.loading("Loading...") try { const response = await apiConnector("POST", DELETE_SECTION_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("DELETE SECTION API RESPONSE............", response); + }) + console.log("DELETE SECTION API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Delete Section"); + throw new Error("Could Not Delete Section") } - toast.success("Course Section Deleted"); - result = response?.data?.updatedCourseDetails; + toast.success("Course Section Deleted") + result = response?.data?.updatedCourseDetails } catch (error) { - console.log("DELETE SECTION API ERROR............", error); - toast.error(error.message); + console.log("DELETE SECTION API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} // delete a subsection export const deleteSubSection = async (data, token) => { - let result = null; - const toastId = toast.loading("Loading..."); + let result = null + const toastId = toast.loading("Loading...") try { const response = await apiConnector("POST", DELETE_SUBSECTION_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("DELETE SUB-SECTION API RESPONSE............", response); + }) + console.log("DELETE SUB-SECTION API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Delete Lecture"); + throw new Error("Could Not Delete Lecture") } - toast.success("Lecture Deleted"); - result = response?.data?.data; + toast.success("Lecture Deleted") + result = response?.data?.data } catch (error) { - console.log("DELETE SUB-SECTION API ERROR............", error); - toast.error(error.message); + console.log("DELETE SUB-SECTION API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} // fetching all courses under a specific instructor export const fetchInstructorCourses = async (token) => { - let result = []; + let result = [] // const toastId = toast.loading("Loading...") try { const response = await apiConnector( @@ -279,184 +279,184 @@ export const fetchInstructorCourses = async (token) => { GET_ALL_INSTRUCTOR_COURSES_API, null, { Authorization: `Bearer ${token}` }, - ); - console.log("INSTRUCTOR COURSES API RESPONSE............", response); + ) + console.log("INSTRUCTOR COURSES API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Fetch Instructor Courses"); + throw new Error("Could Not Fetch Instructor Courses") } - result = response?.data?.data; + result = response?.data?.data } catch (error) { - console.log("INSTRUCTOR COURSES API ERROR............", error); - toast.error(error.message); + console.log("INSTRUCTOR COURSES API ERROR............", error) + toast.error(error.message) } // toast.dismiss(toastId) - return result; -}; + return result +} // delete a course export const deleteCourse = async (data, token) => { - const toastId = toast.loading("Loading..."); + const toastId = toast.loading("Loading...") try { const response = await apiConnector("DELETE", DELETE_COURSE_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("DELETE COURSE API RESPONSE............", response); + }) + console.log("DELETE COURSE API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Delete Course"); + throw new Error("Could Not Delete Course") } - toast.success("Course Deleted"); + toast.success("Course Deleted") } catch (error) { - console.log("DELETE COURSE API ERROR............", error); - toast.error(error.message); + console.log("DELETE COURSE API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); -}; + toast.dismiss(toastId) +} // get full details of a course export const getFullDetailsOfCourse = async (courseId, token) => { - const toastId = toast.loading("Loading..."); + const toastId = toast.loading("Loading...") // dispatch(setLoading(true)); - let result = null; + let result = null try { const response = await apiConnector( "POST", GET_FULL_COURSE_DETAILS_AUTHENTICATED, { courseId }, { Authorization: `Bearer ${token}` }, - ); - console.log("COURSE_FULL_DETAILS_API API RESPONSE............", response); + ) + console.log("COURSE_FULL_DETAILS_API API RESPONSE............", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - result = response?.data?.data; + result = response?.data?.data } catch (error) { - console.log("COURSE_FULL_DETAILS_API API ERROR............", error); - result = error.response.data; - toast.error(error.response.data.message); + console.log("COURSE_FULL_DETAILS_API API ERROR............", error) + result = error.response.data + toast.error(error.response.data.message) } - toast.dismiss(toastId); + toast.dismiss(toastId) // dispatch(setLoading(false)); - return result; -}; + return result +} // mark a lecture as complete export const markLectureAsComplete = async (data, token) => { - let result = null; - const toastId = toast.loading("Loading..."); + let result = null + const toastId = toast.loading("Loading...") try { const response = await apiConnector("POST", LECTURE_COMPLETION_API, data, { Authorization: `Bearer ${token}`, - }); + }) if (!response.data.message) { - throw new Error(response.data.error); + throw new Error(response.data.error) } - toast.success("Lecture Completed"); - result = true; + toast.success("Lecture Completed") + result = true } catch (error) { - console.log("MARK_LECTURE_AS_COMPLETE_API API ERROR............", error); - toast.error(error.message); - result = false; + console.log("MARK_LECTURE_AS_COMPLETE_API API ERROR............", error) + toast.error(error.message) + result = false } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} // create a rating for course export const createRating = async (data, token) => { - const toastId = toast.loading("Loading..."); - let success = false; + const toastId = toast.loading("Loading...") + let success = false try { const response = await apiConnector("POST", CREATE_RATING_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("CREATE RATING API RESPONSE............", response); + }) + console.log("CREATE RATING API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Create Rating"); + throw new Error("Could Not Create Rating") } - toast.success("Rating Created"); - success = true; + toast.success("Rating Created") + success = true } catch (error) { - success = false; - console.log("CREATE RATING API ERROR............", error); - toast.error(error.message); + success = false + console.log("CREATE RATING API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return success; -}; + toast.dismiss(toastId) + return success +} // add course to cart export const addCourseToCart = async (data, token) => { - const toastId = toast.loading("Loading..."); - let success = false; + const toastId = toast.loading("Loading...") + let success = false try { const response = await apiConnector("POST", ADD_TO_CART_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("ADD_TO_CART_API API RESPONSE............", response); + }) + console.log("ADD_TO_CART_API API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Add Course To Cart"); + throw new Error("Could Not Add Course To Cart") } - toast.success("Course Added To Cart"); - success = true; + toast.success("Course Added To Cart") + success = true } catch (error) { - success = false; - console.log("ADD_TO_CART_API API ERROR............", error); - toast.error(error.message); + success = false + console.log("ADD_TO_CART_API API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return success; -}; + toast.dismiss(toastId) + return success +} // remove course from cart export const removeCourseFromCart = async (data, token) => { - const toastId = toast.loading("Loading..."); - let success = false; + const toastId = toast.loading("Loading...") + let success = false try { const response = await apiConnector("POST", REMOVE_FROM_CART_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("REMOVE_FROM_CART_API API RESPONSE............", response); + }) + console.log("REMOVE_FROM_CART_API API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Remove Course From Cart"); + throw new Error("Could Not Remove Course From Cart") } - toast.success("Course Removed From Cart"); - success = true; + toast.success("Course Removed From Cart") + success = true } catch (error) { - success = false; - console.log("REMOVE_FROM_CART_API API ERROR............", error); - toast.error(error.message); + success = false + console.log("REMOVE_FROM_CART_API API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return success; -}; + toast.dismiss(toastId) + return success +} // clear cart export const clearCart = async (data, token) => { - const toastId = toast.loading("Loading..."); - let success = false; + const toastId = toast.loading("Loading...") + let success = false try { const response = await apiConnector("POST", CLEAR_CART_API, data, { Authorization: `Bearer ${token}`, - }); - console.log("CLEAR_CART_API API RESPONSE............", response); + }) + console.log("CLEAR_CART_API API RESPONSE............", response) if (!response?.data?.success) { - throw new Error("Could Not Clear Cart"); + throw new Error("Could Not Clear Cart") } - toast.success("Cart Cleared"); - success = true; + toast.success("Cart Cleared") + success = true } catch (error) { - success = false; - console.log("CLEAR_CART_API API ERROR............", error); - toast.error(error.message); + success = false + console.log("CLEAR_CART_API API ERROR............", error) + toast.error(error.message) } - toast.dismiss(toastId); - return success; -}; + toast.dismiss(toastId) + return success +} diff --git a/frontend/src/services/operations/pageAndComponentData.js b/frontend/src/services/operations/pageAndComponentData.js index 85125dc..6ee5c71 100644 --- a/frontend/src/services/operations/pageAndComponentData.js +++ b/frontend/src/services/operations/pageAndComponentData.js @@ -1,26 +1,26 @@ -import { toast } from "react-hot-toast"; -import { apiConnector } from "../apiconnector"; -import { catalogData } from "../apis"; +import { toast } from "react-hot-toast" +import { apiConnector } from "../apiconnector" +import { catalogData } from "../apis" export const getCatalogaPageData = async (categoryId) => { - const toastId = toast.loading("Loading..."); - let result = []; + const toastId = toast.loading("Loading...") + let result = [] try { const response = await apiConnector( "POST", catalogData.CATALOGPAGEDATA_API, { categoryId }, - ); + ) if (!response?.data?.success) { - throw new Error("Could not Fetch Category page data"); + throw new Error("Could not Fetch Category page data") } - result = response?.data; + result = response?.data } catch (error) { - console.log("CATALOG PAGE DATA API ERROR....", error); - toast.error(error.message); - result = error.response?.data; + console.log("CATALOG PAGE DATA API ERROR....", error) + toast.error(error.message) + result = error.response?.data } - toast.dismiss(toastId); - return result; -}; + toast.dismiss(toastId) + return result +} diff --git a/frontend/src/services/operations/profileAPI.js b/frontend/src/services/operations/profileAPI.js index 96322a6..4457d0b 100644 --- a/frontend/src/services/operations/profileAPI.js +++ b/frontend/src/services/operations/profileAPI.js @@ -1,82 +1,82 @@ -import { toast } from "react-hot-toast"; +import { toast } from "react-hot-toast" -import { setLoading, setUser } from "../../slices/profileSlice"; -import { apiConnector } from "../apiconnector"; -import { profileEndpoints } from "../apis"; -import { logout } from "./authAPI"; +import { setLoading, setUser } from "../../slices/profileSlice" +import { apiConnector } from "../apiconnector" +import { profileEndpoints } from "../apis" +import { logout } from "./authAPI" const { GET_USER_DETAILS_API, GET_USER_ENROLLED_COURSES_API, GET_INSTRUCTOR_DATA_API, -} = profileEndpoints; +} = profileEndpoints export function getUserDetails (token, navigate) { return async (dispatch) => { - const toastId = toast.loading("Loading..."); - dispatch(setLoading(true)); + const toastId = toast.loading("Loading...") + dispatch(setLoading(true)) try { const response = await apiConnector("GET", GET_USER_DETAILS_API, null, { authorization: `Bearer ${token}`, - }); - console.log("GET_USER_DETAILS API RESPONSE............", response); + }) + console.log("GET_USER_DETAILS API RESPONSE............", response) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } const userImage = response.data.data.image ? response.data.data.image - : `https://api.dicebear.com/5.x/initials/svg?seed=${response.data.data.firstName} ${response.data.data.lastName}`; - dispatch(setUser({ ...response.data.data, image: userImage })); + : `https://api.dicebear.com/5.x/initials/svg?seed=${response.data.data.firstName} ${response.data.data.lastName}` + dispatch(setUser({ ...response.data.data, image: userImage })) } catch (error) { - dispatch(logout(navigate)); - console.log("GET_USER_DETAILS API ERROR............", error); - toast.error("Could Not Get User Details"); + dispatch(logout(navigate)) + console.log("GET_USER_DETAILS API ERROR............", error) + toast.error("Could Not Get User Details") } - toast.dismiss(toastId); - dispatch(setLoading(false)); - }; + toast.dismiss(toastId) + dispatch(setLoading(false)) + } } export async function getUserEnrolledCourses (token) { - const toastId = toast.loading("Loading..."); - let result = []; + const toastId = toast.loading("Loading...") + let result = [] try { const response = await apiConnector( "GET", GET_USER_ENROLLED_COURSES_API, null, { authorization: `Bearer ${token}` }, - ); + ) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } console.log( "GET_USER_ENROLLED_COURSES_API API SUCCESS............", response.data, - ); - result = response.data.data; + ) + result = response.data.data } catch (error) { - console.log("GET_USER_ENROLLED_COURSES_API API ERROR............", error); - toast.error("Could Not Get Enrolled Courses"); + console.log("GET_USER_ENROLLED_COURSES_API API ERROR............", error) + toast.error("Could Not Get Enrolled Courses") } - toast.dismiss(toastId); - return result; + toast.dismiss(toastId) + return result } export async function getInstructorData (token) { - const toastId = toast.loading("Loading..."); - let result = []; + const toastId = toast.loading("Loading...") + let result = [] try { const response = await apiConnector("GET", GET_INSTRUCTOR_DATA_API, null, { authorization: `Bearer ${token}`, - }); - console.log("GET_INSTRUCTOR_DATA_API API RESPONSE............", response); - result = response?.data?.courses; + }) + console.log("GET_INSTRUCTOR_DATA_API API RESPONSE............", response) + result = response?.data?.courses } catch (error) { - console.log("GET_INSTRUCTOR_DATA_API API ERROR............", error); - toast.error("Could Not Get Instructor Data"); + console.log("GET_INSTRUCTOR_DATA_API API ERROR............", error) + toast.error("Could Not Get Instructor Data") } - toast.dismiss(toastId); - return result; + toast.dismiss(toastId) + return result } diff --git a/frontend/src/services/operations/studentFeaturesAPI.js b/frontend/src/services/operations/studentFeaturesAPI.js index 778b4df..31c8e54 100644 --- a/frontend/src/services/operations/studentFeaturesAPI.js +++ b/frontend/src/services/operations/studentFeaturesAPI.js @@ -1,29 +1,29 @@ -import { toast } from "react-hot-toast"; -import { studentEndpoints } from "../apis"; -import { apiConnector } from "../apiconnector"; -import rzpLogo from "../../assets/Logo/rzp_logo.png"; -import { setPaymentLoading } from "../../slices/courseSlice"; -import { resetCart } from "../../slices/cartSlice"; +import { toast } from "react-hot-toast" +import { studentEndpoints } from "../apis" +import { apiConnector } from "../apiconnector" +import rzpLogo from "../../assets/Logo/rzp_logo.png" +import { setPaymentLoading } from "../../slices/courseSlice" +import { resetCart } from "../../slices/cartSlice" const { COURSE_PAYMENT_API, COURSE_VERIFY_API, SEND_PAYMENT_SUCCESS_EMAIL_API, -} = studentEndpoints; +} = studentEndpoints function loadScript (src) { return new Promise((resolve) => { - const script = document.createElement("script"); - script.src = src; + const script = document.createElement("script") + script.src = src script.onload = () => { - resolve(true); - }; + resolve(true) + } script.onerror = () => { - resolve(false); - }; - document.body.appendChild(script); - }); + resolve(false) + } + document.body.appendChild(script) + }) } export async function buyCourse ( @@ -33,16 +33,16 @@ export async function buyCourse ( navigate, dispatch, ) { - const toastId = toast.loading("Loading..."); + const toastId = toast.loading("Loading...") try { // load the script const res = await loadScript( "https://checkout.razorpay.com/v1/checkout.js", - ); + ) if (!res) { - toast.error("RazorPay SDK failed to load"); - return; + toast.error("RazorPay SDK failed to load") + return } // initiate the order @@ -51,10 +51,10 @@ export async function buyCourse ( COURSE_PAYMENT_API, { courses }, { Authorization: `Bearer ${token}` }, - ); + ) if (!orderResponse.data.success) { - throw new Error(orderResponse.data.message); + throw new Error(orderResponse.data.message) } // options @@ -76,22 +76,22 @@ export async function buyCourse ( response, orderResponse.data.message.amount, token, - ); + ) // verifyPayment - verifyPayment({ ...response, courses }, token, navigate, dispatch); + verifyPayment({ ...response, courses }, token, navigate, dispatch) }, - }; - const paymentObject = new window.Razorpay(options); - paymentObject.open(); + } + const paymentObject = new window.Razorpay(options) + paymentObject.open() paymentObject.on("payment.failed", function (response) { - toast.error("oops, payment failed"); - console.log(response.error); - }); + toast.error("oops, payment failed") + console.log(response.error) + }) } catch (error) { - console.log("PAYMENT API ERROR.....", error); - toast.error("Could not make Payment"); + console.log("PAYMENT API ERROR.....", error) + toast.error("Could not make Payment") } - toast.dismiss(toastId); + toast.dismiss(toastId) } async function sendPaymentSuccessEmail (response, amount, token) { @@ -107,30 +107,30 @@ async function sendPaymentSuccessEmail (response, amount, token) { { Authorization: `Bearer ${token}`, }, - ); + ) } catch (error) { - console.log("PAYMENT SUCCESS EMAIL ERROR....", error); + console.log("PAYMENT SUCCESS EMAIL ERROR....", error) } } // verify payment async function verifyPayment (bodyData, token, navigate, dispatch) { - const toastId = toast.loading("Verifying Payment...."); - dispatch(setPaymentLoading(true)); + const toastId = toast.loading("Verifying Payment....") + dispatch(setPaymentLoading(true)) try { const response = await apiConnector("POST", COURSE_VERIFY_API, bodyData, { Authorization: `Bearer ${token}`, - }); + }) if (!response.data.success) { - throw new Error(response.data.message); + throw new Error(response.data.message) } - toast.success("Payment Successful, you are addded to the course"); - navigate("/dashboard/enrolled-courses"); - dispatch(resetCart()); + toast.success("Payment Successful, you are addded to the course") + navigate("/dashboard/enrolled-courses") + dispatch(resetCart()) } catch (error) { - console.log("PAYMENT VERIFY ERROR....", error); - toast.error("Could not verify Payment"); + console.log("PAYMENT VERIFY ERROR....", error) + toast.error("Could not verify Payment") } - toast.dismiss(toastId); - dispatch(setPaymentLoading(false)); + toast.dismiss(toastId) + dispatch(setPaymentLoading(false)) } diff --git a/frontend/src/slices/authSlice.js b/frontend/src/slices/authSlice.js index a24bc2f..0c7677a 100644 --- a/frontend/src/slices/authSlice.js +++ b/frontend/src/slices/authSlice.js @@ -1,4 +1,4 @@ -import { createSlice } from "@reduxjs/toolkit"; +import { createSlice } from "@reduxjs/toolkit" const initialState = { signupData: null, @@ -6,7 +6,7 @@ const initialState = { token: localStorage.getItem("token") ? JSON.parse(localStorage.getItem("token")) : null, -}; +} const authSlice = createSlice({ name: "auth", @@ -14,17 +14,17 @@ const authSlice = createSlice({ reducers: { setSignupData (state, value) { - state.signupData = value.payload; + state.signupData = value.payload }, setLoading (state, value) { - state.loading = value.payload; + state.loading = value.payload }, setToken (state, value) { - state.token = value.payload; + state.token = value.payload }, }, -}); +}) -export const { setSignupData, setLoading, setToken } = authSlice.actions; +export const { setSignupData, setLoading, setToken } = authSlice.actions -export default authSlice.reducer; +export default authSlice.reducer diff --git a/frontend/src/slices/cartSlice.js b/frontend/src/slices/cartSlice.js index e500923..5648128 100644 --- a/frontend/src/slices/cartSlice.js +++ b/frontend/src/slices/cartSlice.js @@ -1,5 +1,5 @@ -import { createSlice } from "@reduxjs/toolkit"; -import { toast } from "react-hot-toast"; +import { createSlice } from "@reduxjs/toolkit" +import { toast } from "react-hot-toast" const initialState = { cart: localStorage.getItem("cart") @@ -11,7 +11,7 @@ const initialState = { totalItems: localStorage.getItem("totalItems") ? JSON.parse(localStorage.getItem("totalItems")) : 0, -}; +} const cartSlice = createSlice({ name: "cart", @@ -19,51 +19,51 @@ const cartSlice = createSlice({ reducers: { addToCart: (state, action) => { - const course = action.payload; - const index = state.cart.findIndex((item) => item._id === course._id); + const course = action.payload + const index = state.cart.findIndex((item) => item._id === course._id) if (index >= 0) { // If the course is already in the cart, do not modify the quantity - toast.error("Course already in cart"); - return; + toast.error("Course already in cart") + return } // If the course is not in the cart, add it to the cart - state.cart.push(course); - state.totalItems++; // Update the total quantity and price - state.total += course.price; + state.cart.push(course) + state.totalItems++ // Update the total quantity and price + state.total += course.price - localStorage.setItem("cart", JSON.stringify(state.cart)); // Update to localstorage - localStorage.setItem("total", JSON.stringify(state.total)); - localStorage.setItem("totalItems", JSON.stringify(state.totalItems)); + localStorage.setItem("cart", JSON.stringify(state.cart)) // Update to localstorage + localStorage.setItem("total", JSON.stringify(state.total)) + localStorage.setItem("totalItems", JSON.stringify(state.totalItems)) }, removeFromCart: (state, action) => { - const courseId = action.payload; - const index = state.cart.findIndex((item) => item._id === courseId); + const courseId = action.payload + const index = state.cart.findIndex((item) => item._id === courseId) if (index >= 0) { // If the course is found in the cart, remove it - state.totalItems--; - state.total -= state.cart[index].price; - state.cart.splice(index, 1); + state.totalItems-- + state.total -= state.cart[index].price + state.cart.splice(index, 1) - localStorage.setItem("cart", JSON.stringify(state.cart)); // Update to localstorage - localStorage.setItem("total", JSON.stringify(state.total)); - localStorage.setItem("totalItems", JSON.stringify(state.totalItems)); + localStorage.setItem("cart", JSON.stringify(state.cart)) // Update to localstorage + localStorage.setItem("total", JSON.stringify(state.total)) + localStorage.setItem("totalItems", JSON.stringify(state.totalItems)) } }, resetCart: (state) => { - state.cart = []; - state.total = 0; - state.totalItems = 0; + state.cart = [] + state.total = 0 + state.totalItems = 0 - localStorage.removeItem("cart"); // Update to localstorage - localStorage.removeItem("total"); - localStorage.removeItem("totalItems"); + localStorage.removeItem("cart") // Update to localstorage + localStorage.removeItem("total") + localStorage.removeItem("totalItems") }, }, -}); +}) -export const { addToCart, removeFromCart, resetCart } = cartSlice.actions; -export default cartSlice.reducer; +export const { addToCart, removeFromCart, resetCart } = cartSlice.actions +export default cartSlice.reducer diff --git a/frontend/src/slices/courseSlice.js b/frontend/src/slices/courseSlice.js index 86252ff..aff1789 100644 --- a/frontend/src/slices/courseSlice.js +++ b/frontend/src/slices/courseSlice.js @@ -1,35 +1,35 @@ -import { createSlice } from "@reduxjs/toolkit"; +import { createSlice } from "@reduxjs/toolkit" const initialState = { step: 1, course: null, editCourse: false, paymentLoading: false, -}; +} const courseSlice = createSlice({ name: "course", initialState, reducers: { setStep: (state, action) => { - state.step = action.payload; + state.step = action.payload }, setCourse: (state, action) => { - state.course = action.payload; + state.course = action.payload }, setEditCourse: (state, action) => { - state.editCourse = action.payload; + state.editCourse = action.payload }, setPaymentLoading: (state, action) => { - state.paymentLoading = action.payload; + state.paymentLoading = action.payload }, resetCourseState: (state) => { - state.step = 1; - state.course = null; - state.editCourse = false; + state.step = 1 + state.course = null + state.editCourse = false }, }, -}); +}) export const { setStep, @@ -37,6 +37,6 @@ export const { setEditCourse, setPaymentLoading, resetCourseState, -} = courseSlice.actions; +} = courseSlice.actions -export default courseSlice.reducer; +export default courseSlice.reducer diff --git a/frontend/src/slices/profileSlice.js b/frontend/src/slices/profileSlice.js index 49c50e8..76daa7f 100644 --- a/frontend/src/slices/profileSlice.js +++ b/frontend/src/slices/profileSlice.js @@ -1,11 +1,11 @@ -import { createSlice } from "@reduxjs/toolkit"; +import { createSlice } from "@reduxjs/toolkit" const initialState = { user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : null, loading: false, -}; +} const profileSlice = createSlice({ name: "profile", @@ -13,13 +13,13 @@ const profileSlice = createSlice({ reducers: { setUser (state, value) { - state.user = value.payload; + state.user = value.payload }, setLoading (state, value) { - state.loading = value.payload; + state.loading = value.payload }, }, -}); +}) -export const { setUser, setLoading } = profileSlice.actions; -export default profileSlice.reducer; +export const { setUser, setLoading } = profileSlice.actions +export default profileSlice.reducer diff --git a/frontend/src/slices/viewCourseSlice.js b/frontend/src/slices/viewCourseSlice.js index 4822126..ce797c3 100644 --- a/frontend/src/slices/viewCourseSlice.js +++ b/frontend/src/slices/viewCourseSlice.js @@ -1,33 +1,33 @@ -import { createSlice } from "@reduxjs/toolkit"; +import { createSlice } from "@reduxjs/toolkit" const initialState = { courseSectionData: [], courseEntireData: [], completedLectures: [], totalNoOfLectures: 0, -}; +} const viewCourseSlice = createSlice({ name: "viewCourse", initialState, reducers: { setCourseSectionData: (state, action) => { - state.courseSectionData = action.payload; + state.courseSectionData = action.payload }, setEntireCourseData: (state, action) => { - state.courseEntireData = action.payload; + state.courseEntireData = action.payload }, setTotalNoOfLectures: (state, action) => { - state.totalNoOfLectures = action.payload; + state.totalNoOfLectures = action.payload }, setCompletedLectures: (state, action) => { - state.completedLectures = action.payload; + state.completedLectures = action.payload }, updateCompletedLectures: (state, action) => { - state.completedLectures = [...state.completedLectures, action.payload]; + state.completedLectures = [...state.completedLectures, action.payload] }, }, -}); +}) export const { setCourseSectionData, @@ -35,6 +35,6 @@ export const { setTotalNoOfLectures, setCompletedLectures, updateCompletedLectures, -} = viewCourseSlice.actions; +} = viewCourseSlice.actions -export default viewCourseSlice.reducer; +export default viewCourseSlice.reducer diff --git a/frontend/src/utils/avgRating.js b/frontend/src/utils/avgRating.js index 0501874..aeb0115 100644 --- a/frontend/src/utils/avgRating.js +++ b/frontend/src/utils/avgRating.js @@ -1,13 +1,13 @@ export default function GetAvgRating (ratingArr) { - if (ratingArr?.length === 0) return 0; + if (ratingArr?.length === 0) return 0 const totalReviewCount = ratingArr?.reduce((acc, curr) => { - acc += curr.rating; - return acc; - }, 0); + acc += curr.rating + return acc + }, 0) - const multiplier = Math.pow(10, 1); + const multiplier = Math.pow(10, 1) const avgReviewCount = - Math.round((totalReviewCount / ratingArr?.length) * multiplier) / multiplier; + Math.round((totalReviewCount / ratingArr?.length) * multiplier) / multiplier - return avgReviewCount; + return avgReviewCount } diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 822475c..7df422f 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -2,9 +2,9 @@ export const ACCOUNT_TYPE = { STUDENT: "Student", INSTRUCTOR: "Instructor", ADMIN: "Admin", -}; +} export const COURSE_STATUS = { DRAFT: "Draft", PUBLISHED: "Published", -}; +} diff --git a/frontend/src/utils/dateFormatter.js b/frontend/src/utils/dateFormatter.js index 76de06a..915ef15 100644 --- a/frontend/src/utils/dateFormatter.js +++ b/frontend/src/utils/dateFormatter.js @@ -3,5 +3,5 @@ export const formattedDate = (date) => { month: "long", day: "numeric", year: "numeric", - }); -}; + }) +} diff --git a/frontend/src/utils/totalDuration.js b/frontend/src/utils/totalDuration.js index 7e7d09f..50ee242 100644 --- a/frontend/src/utils/totalDuration.js +++ b/frontend/src/utils/totalDuration.js @@ -1,27 +1,27 @@ function convertSecondsToDuration (totalSeconds) { - const hours = Math.floor(totalSeconds / 3600); - const minutes = Math.floor((totalSeconds % 3600) / 60); - const seconds = Math.floor((totalSeconds % 3600) % 60); + const hours = Math.floor(totalSeconds / 3600) + const minutes = Math.floor((totalSeconds % 3600) / 60) + const seconds = Math.floor((totalSeconds % 3600) % 60) if (hours > 0) { - return `${hours}h ${minutes}m`; + return `${hours}h ${minutes}m` } else if (minutes > 0) { - return `${minutes}m ${seconds}s`; + return `${minutes}m ${seconds}s` } else { - return `${seconds}s`; + return `${seconds}s` } } export function GetCourseTotalDuration (course) { - let totalDurationInSeconds = 0; - let totalDuration; + let totalDurationInSeconds = 0 + let totalDuration for (let j = 0; j < course.courseContent.length; j++) { totalDurationInSeconds += course.courseContent[j].subSections.reduce( (acc, curr) => acc + parseInt(curr.timeDuration), 0, - ); - totalDuration = convertSecondsToDuration(totalDurationInSeconds); + ) + totalDuration = convertSecondsToDuration(totalDurationInSeconds) } - if (totalDuration) return totalDuration; - else return "0s"; + if (totalDuration) return totalDuration + else return "0s" } diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index c50fdfe..82b1d72 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -132,4 +132,4 @@ export default { }, }, plugins: [], -}; +} diff --git a/frontend/vite.config.js b/frontend/vite.config.js index d1e437a..400f3dd 100644 --- a/frontend/vite.config.js +++ b/frontend/vite.config.js @@ -1,5 +1,5 @@ -import { defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite" +import react from "@vitejs/plugin-react" // https://vitejs.dev/config/ export default defineConfig({ @@ -15,7 +15,7 @@ export default defineConfig({ origin: "http://localhost:3000", }, define: { - global: "globalThis" + global: "globalThis", }, optimizeDeps: { include: ["react-dom"], @@ -30,10 +30,10 @@ export default defineConfig({ .toString() .split("node_modules/")[1] .split("/")[0] - .toString(); + .toString() } }, }, }, }, -}); +}) diff --git a/package.json b/package.json index 3a79b1a..e6d3cd9 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "format": "npx eslint . --ext .js,.jsx" }, "devDependencies": { + "@babel/core": "^7.23.9", + "@babel/eslint-parser": "^7.23.10", "eslint-config-standard": "^17.1.0", "eslint-plugin-import": "^2.29.1", "eslint-plugin-n": "^16.6.2", @@ -21,4 +23,4 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.5" } -} +} \ No newline at end of file