├── src ├── index.css ├── .DS_Store ├── assets │ ├── Images │ │ ├── frame.png │ │ ├── banner.mp4 │ │ ├── login.webp │ │ ├── signup.webp │ │ ├── Instructor.png │ │ ├── aboutus1.webp │ │ ├── aboutus2.webp │ │ ├── aboutus3.webp │ │ ├── boxoffice.png │ │ ├── FoundingStory.png │ │ ├── TimelineImage.png │ │ ├── Know_your_progress.png │ │ ├── Plan_your_lessons.png │ │ └── Compare_with_others.png │ ├── Logo │ │ ├── rzp_logo.png │ │ ├── Logo-Full-Dark.png │ │ ├── Logo-Full-Light.png │ │ ├── Logo-Small-Dark.png │ │ └── Logo-Small-Light.png │ └── TimeLineLogo │ │ ├── Logo4.svg │ │ ├── Logo3.svg │ │ ├── Logo1.svg │ │ └── Logo2.svg ├── utils │ ├── dateFormatter.js │ ├── constants.js │ └── avgRating.js ├── hooks │ ├── useRouteMatch.js │ └── useOnClickOutside.js ├── pages │ ├── Error.jsx │ ├── Login.jsx │ ├── Signup.jsx │ ├── Dashboard.jsx │ ├── Contact.jsx │ ├── ViewCourse.jsx │ ├── ForgotPassword.jsx │ └── VerifyEmail.jsx ├── data │ ├── navbar-links.js │ ├── dashboard-links.js │ └── footer-links.js ├── components │ ├── core │ │ ├── HomePage │ │ │ ├── HighlightText.jsx │ │ │ ├── Button.jsx │ │ │ ├── InstructorSection.jsx │ │ │ ├── CourseCard.jsx │ │ │ ├── LearningLanguageSection.jsx │ │ │ ├── CodeBlocks.jsx │ │ │ ├── ExploreMore.jsx │ │ │ └── TimelineSection.jsx │ │ ├── Auth │ │ │ ├── PrivateRoute.jsx │ │ │ ├── OpenRoute.jsx │ │ │ ├── Template.jsx │ │ │ ├── ProfileDropDown.jsx │ │ │ └── LoginForm.jsx │ │ ├── AboutPage │ │ │ ├── ContactFormSection.jsx │ │ │ ├── Quote.jsx │ │ │ ├── Stats.jsx │ │ │ └── LearningGrid.jsx │ │ ├── Course │ │ │ ├── CourseSubSectionAccordion.jsx │ │ │ ├── CourseAccordionBar.jsx │ │ │ └── CourseDetailsCard.js │ │ ├── Dashboard │ │ │ ├── Settings │ │ │ │ ├── index.jsx │ │ │ │ ├── DeleteAccount.jsx │ │ │ │ ├── ChangeProfilePicture.jsx │ │ │ │ └── UpdatePassword.jsx │ │ │ ├── Cart │ │ │ │ ├── index.jsx │ │ │ │ ├── RenderTotalAmount.jsx │ │ │ │ └── RenderCartCourses.jsx │ │ │ ├── SidebarLink.jsx │ │ │ ├── MyCourses.jsx │ │ │ ├── AddCourse │ │ │ │ ├── index.jsx │ │ │ │ ├── CourseInformation │ │ │ │ │ ├── RequirementField.jsx │ │ │ │ │ └── ChipInput.jsx │ │ │ │ ├── RenderSteps.jsx │ │ │ │ ├── PublishCourse │ │ │ │ │ └── index.jsx │ │ │ │ └── Upload.jsx │ │ │ ├── EditCourse │ │ │ │ └── index.js │ │ │ ├── Sidebar.jsx │ │ │ ├── InstructorDashboard │ │ │ │ └── InstructorChart.jsx │ │ │ └── EnrolledCourses.jsx │ │ ├── Catalog │ │ │ ├── CourseSlider.jsx │ │ │ └── Course_Card.jsx │ │ └── ViewCourse │ │ │ └── CourseReviewModal.jsx │ ├── ContactPage │ │ ├── ContactForm.jsx │ │ └── ContactDetails.jsx │ └── common │ │ ├── IconBtn.jsx │ │ ├── Tab.jsx │ │ ├── ConfirmationModal.jsx │ │ ├── RatingStars.jsx │ │ └── ReviewSlider.jsx ├── services │ ├── apiconnector.js │ ├── formatDate.js │ ├── operations │ │ ├── pageAndComponentData.js │ │ ├── profileAPI.js │ │ ├── SettingsAPI.js │ │ └── studentFeaturesAPI.js │ └── apis.js ├── reducer │ └── index.js ├── slices │ ├── profileSlice.js │ ├── authSlice.js │ ├── courseSlice.js │ ├── viewCourseSlice.js │ └── cartSlice.js └── index.js ├── images ├── schema.png └── mainpage.png ├── public ├── robots.txt └── index.html ├── server ├── config │ ├── razorpay.js │ ├── cloudinary.js │ └── database.js ├── routes │ ├── Contact.js │ ├── Payments.js │ ├── Profile.js │ ├── User.js │ └── Course.js ├── models │ ├── SubSection.js │ ├── Section.js │ ├── Category.js │ ├── Profile.js │ ├── CourseProgress.js │ ├── RatingAndRaview.js │ ├── Course.js │ ├── OTP.js │ └── User.js ├── utils │ ├── imageUploader.js │ ├── secToDuration.js │ └── mailSender.js ├── package.json ├── controllers │ ├── ContactUs.js │ ├── ResetPassword.js │ ├── courseProgress.js │ ├── Section.js │ └── Category.js ├── index.js ├── mail │ └── templates │ │ ├── emailVerificationTemplate.js │ │ ├── passwordUpdate.js │ │ ├── paymentSuccessEmail.js │ │ ├── courseEnrollmentEmail.js │ │ └── contactFormRes.js └── middlewares │ └── auth.js ├── package.json └── tailwind.config.js /src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/.DS_Store -------------------------------------------------------------------------------- /images/schema.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/images/schema.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /images/mainpage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/images/mainpage.png -------------------------------------------------------------------------------- /src/assets/Images/frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/frame.png -------------------------------------------------------------------------------- /src/assets/Images/banner.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/banner.mp4 -------------------------------------------------------------------------------- /src/assets/Images/login.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/login.webp -------------------------------------------------------------------------------- /src/assets/Images/signup.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/signup.webp -------------------------------------------------------------------------------- /src/assets/Logo/rzp_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Logo/rzp_logo.png -------------------------------------------------------------------------------- /src/assets/Images/Instructor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/Instructor.png -------------------------------------------------------------------------------- /src/assets/Images/aboutus1.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/aboutus1.webp -------------------------------------------------------------------------------- /src/assets/Images/aboutus2.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/aboutus2.webp -------------------------------------------------------------------------------- /src/assets/Images/aboutus3.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/aboutus3.webp -------------------------------------------------------------------------------- /src/assets/Images/boxoffice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/boxoffice.png -------------------------------------------------------------------------------- /src/assets/Images/FoundingStory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/FoundingStory.png -------------------------------------------------------------------------------- /src/assets/Images/TimelineImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/TimelineImage.png -------------------------------------------------------------------------------- /src/assets/Logo/Logo-Full-Dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Logo/Logo-Full-Dark.png -------------------------------------------------------------------------------- /src/assets/Logo/Logo-Full-Light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Logo/Logo-Full-Light.png -------------------------------------------------------------------------------- /src/assets/Logo/Logo-Small-Dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Logo/Logo-Small-Dark.png -------------------------------------------------------------------------------- /src/assets/Logo/Logo-Small-Light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Logo/Logo-Small-Light.png -------------------------------------------------------------------------------- /src/assets/Images/Know_your_progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/Know_your_progress.png -------------------------------------------------------------------------------- /src/assets/Images/Plan_your_lessons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/Plan_your_lessons.png -------------------------------------------------------------------------------- /src/assets/Images/Compare_with_others.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahildahake2003/studynotion/HEAD/src/assets/Images/Compare_with_others.png -------------------------------------------------------------------------------- /server/config/razorpay.js: -------------------------------------------------------------------------------- 1 | const Razorpay = require("razorpay"); 2 | 3 | 4 | exports.instance = new Razorpay({ 5 | key_id: process.env.RAZORPAY_KEY, 6 | key_secret: process.env.RAZORPAY_SECRET, 7 | }); -------------------------------------------------------------------------------- /src/utils/dateFormatter.js: -------------------------------------------------------------------------------- 1 | export const formattedDate = (date) => { 2 | return new Date(date).toLocaleDateString("en-US", { 3 | month: "long", 4 | day: "numeric", 5 | year: "numeric", 6 | }) 7 | } -------------------------------------------------------------------------------- /src/hooks/useRouteMatch.js: -------------------------------------------------------------------------------- 1 | import { useLocation, matchPath } from "react-router-dom"; 2 | 3 | export default function useRouteMatch(path) { 4 | const location = useLocation(); 5 | return matchPath(location.pathname, { path }); 6 | } -------------------------------------------------------------------------------- /src/utils/constants.js: -------------------------------------------------------------------------------- 1 | export const ACCOUNT_TYPE = { 2 | STUDENT: "Student", 3 | INSTRUCTOR: "Instructor", 4 | ADMIN: "Admin", 5 | } 6 | 7 | export const COURSE_STATUS = { 8 | DRAFT: "Draft", 9 | PUBLISHED: "Published", 10 | } -------------------------------------------------------------------------------- /server/routes/Contact.js: -------------------------------------------------------------------------------- 1 | const express = require("express") 2 | const router = express.Router() 3 | const { contactUsController } = require("../controllers/ContactUs") 4 | 5 | router.post("/contact", contactUsController) 6 | 7 | module.exports = router -------------------------------------------------------------------------------- /src/pages/Error.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Error = () => { 4 | return ( 5 |
6 | Error - 404 Not found 7 |
8 | ) 9 | } 10 | 11 | export default Error 12 | -------------------------------------------------------------------------------- /server/models/SubSection.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const SubSectionSchema = new mongoose.Schema({ 4 | title: { type: String }, 5 | timeDuration: { type: String }, 6 | description: { type: String }, 7 | videoUrl: { type: String }, 8 | }); 9 | 10 | module.exports = mongoose.model("SubSection", SubSectionSchema); -------------------------------------------------------------------------------- /src/data/navbar-links.js: -------------------------------------------------------------------------------- 1 | export const NavbarLinks = [ 2 | { 3 | title: "Home", 4 | path: "/", 5 | }, 6 | { 7 | title: "Catalog", 8 | // path: '/catalog', 9 | }, 10 | { 11 | title: "About Us", 12 | path: "/about", 13 | }, 14 | { 15 | title: "Contact Us", 16 | path: "/contact", 17 | }, 18 | ]; 19 | -------------------------------------------------------------------------------- /src/components/core/HomePage/HighlightText.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const HighlightText = ({text}) => { 4 | return ( 5 | 6 | {" "} 7 | {text} 8 | 9 | ); 10 | }; 11 | 12 | export default HighlightText; -------------------------------------------------------------------------------- /src/services/apiconnector.js: -------------------------------------------------------------------------------- 1 | import axios from "axios" 2 | 3 | export const axiosInstance = axios.create({}); 4 | 5 | export const apiConnector = (method, url, bodyData, headers, params) => { 6 | return axiosInstance({ 7 | method:`${method}`, 8 | url:`${url}`, 9 | data: bodyData ? bodyData : null, 10 | headers: headers ? headers: null, 11 | params: params ? params : null, 12 | }); 13 | } -------------------------------------------------------------------------------- /server/models/Section.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | // Define the Section schema 4 | const sectionSchema = new mongoose.Schema({ 5 | sectionName: { 6 | type: String, 7 | }, 8 | subSection: [ 9 | { 10 | type: mongoose.Schema.Types.ObjectId, 11 | required: true, 12 | ref: "SubSection", 13 | }, 14 | ], 15 | }); 16 | 17 | // Export the Section model 18 | module.exports = mongoose.model("Section", sectionSchema); -------------------------------------------------------------------------------- /src/components/core/Auth/PrivateRoute.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useSelector } from 'react-redux' 3 | import { Navigate } from 'react-router-dom'; 4 | 5 | const PrivateRoute = ({children}) => { 6 | 7 | const {token} = useSelector((state) => state.auth); 8 | 9 | if(token !== null) 10 | return children 11 | else 12 | return 13 | 14 | } 15 | 16 | export default PrivateRoute 17 | -------------------------------------------------------------------------------- /server/config/cloudinary.js: -------------------------------------------------------------------------------- 1 | const cloudinary = require("cloudinary").v2; //! Cloudinary is being required 2 | 3 | exports.cloudinaryConnect = () => { 4 | try { 5 | cloudinary.config({ 6 | //! ######## Configuring the Cloudinary to Upload MEDIA ######## 7 | cloud_name: process.env.CLOUD_NAME, 8 | api_key: process.env.API_KEY, 9 | api_secret: process.env.API_SECRET, 10 | }); 11 | } catch (error) { 12 | console.log(error); 13 | } 14 | }; -------------------------------------------------------------------------------- /src/utils/avgRating.js: -------------------------------------------------------------------------------- 1 | export default function GetAvgRating(ratingArr) { 2 | if (ratingArr?.length === 0) return 0 3 | const totalReviewCount = ratingArr?.reduce((acc, curr) => { 4 | acc += curr.rating 5 | return acc 6 | }, 0) 7 | 8 | const multiplier = Math.pow(10, 1) 9 | const avgReviewCount = 10 | Math.round((totalReviewCount / ratingArr?.length) * multiplier) / multiplier 11 | 12 | return avgReviewCount 13 | } -------------------------------------------------------------------------------- /server/models/Category.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | // Define the Tags schema 4 | const categorySchema = new mongoose.Schema({ 5 | name: { 6 | type: String, 7 | required: true, 8 | }, 9 | description: { type: String }, 10 | courses: [ 11 | { 12 | type: mongoose.Schema.Types.ObjectId, 13 | ref: "Course", 14 | }, 15 | ], 16 | }); 17 | 18 | // Export the Tags model 19 | module.exports = mongoose.model("Category", categorySchema); -------------------------------------------------------------------------------- /server/utils/imageUploader.js: -------------------------------------------------------------------------------- 1 | const cloudinary = require('cloudinary').v2 2 | 3 | 4 | exports.uploadImageToCloudinary = async (file, folder, height, quality) => { 5 | const options = {folder}; 6 | if(height) { 7 | options.height = height; 8 | } 9 | if(quality) { 10 | options.quality = quality; 11 | } 12 | options.resource_type = "auto"; 13 | 14 | return await cloudinary.uploader.upload(file.tempFilePath, options); 15 | } -------------------------------------------------------------------------------- /src/pages/Login.jsx: -------------------------------------------------------------------------------- 1 | import loginImg from "../assets/Images/login.webp" 2 | import Template from "../components/core/Auth/Template" 3 | 4 | function Login() { 5 | return ( 6 |