├── backend ├── .gitkeep ├── public │ └── .gitkeep ├── vercel.json ├── src │ ├── utils │ │ ├── ApiResponse.js │ │ ├── asyncHandler.js │ │ ├── ApiError.js │ │ ├── cloudinary.js │ │ └── Nodemailer.js │ ├── middlewares │ │ ├── multer.middleware.js │ │ ├── joiLogin.middleware.js │ │ ├── adminAuth.middleware.js │ │ ├── stdAuth.middleware.js │ │ └── teacherAuth.middleware.js │ ├── database │ │ └── db.js │ ├── index.js │ ├── models │ │ ├── contact.model.js │ │ ├── payment.model.js │ │ ├── course.model.js │ │ ├── admin.model.js │ │ ├── student.model.js │ │ └── teacher.model.js │ ├── routes │ │ ├── payment.routes.js │ │ ├── student.routes.js │ │ ├── course.routes.js │ │ ├── admin.routes.js │ │ └── teacher.routes.js │ ├── app.js │ └── controllers │ │ └── payment.controller.js ├── package.json └── .gitignore ├── .vscode └── extensions.json ├── frontend ├── postcss.config.js ├── src │ ├── Pages │ │ ├── Dashboard │ │ │ ├── Images │ │ │ │ ├── Clock.png │ │ │ │ └── Camera.png │ │ │ ├── StudentDashboard │ │ │ │ ├── StudentLayout.jsx │ │ │ │ ├── Popup.jsx │ │ │ │ ├── StudentCourses.jsx │ │ │ │ ├── StudentClasses.jsx │ │ │ │ ├── StudentDashboard.jsx │ │ │ │ └── SearchTeacher.jsx │ │ │ └── TeacherDashboard │ │ │ │ ├── TeacherLayout.jsx │ │ │ │ ├── DateTime.jsx │ │ │ │ ├── TeacherCourses.jsx │ │ │ │ ├── Withdrawal.jsx │ │ │ │ ├── TeacherDashboard.jsx │ │ │ │ ├── TeacherClasses.jsx │ │ │ │ ├── AddClass.jsx │ │ │ │ └── DashboardTeacher.jsx │ │ ├── ErrorPage │ │ │ └── ErrorPage.jsx │ │ ├── Components │ │ │ ├── DocumentVerification │ │ │ │ ├── InputComponent │ │ │ │ │ └── Input.jsx │ │ │ │ ├── Inputupload │ │ │ │ │ └── InputUpload.jsx │ │ │ │ └── StudentDocument.jsx │ │ │ ├── Searchbtn │ │ │ │ ├── Search.css │ │ │ │ └── Success.jsx │ │ │ ├── VarifyEmail │ │ │ │ └── VarifyEmail.jsx │ │ │ ├── RadioBtn │ │ │ │ ├── Radiobtn.jsx │ │ │ │ └── Radiobtn.css │ │ │ └── Admin │ │ │ │ ├── Course.jsx │ │ │ │ ├── Admin.jsx │ │ │ │ └── VarifyDoc.jsx │ │ ├── Home │ │ │ ├── Header │ │ │ │ ├── Header.css │ │ │ │ └── Header.jsx │ │ │ ├── About │ │ │ │ └── About.jsx │ │ │ ├── Contact │ │ │ │ └── Contact.jsx │ │ │ ├── Courses │ │ │ │ └── Courses.jsx │ │ │ ├── Landing │ │ │ │ └── Landing.css │ │ │ └── Search │ │ │ │ └── Search.jsx │ │ ├── Response │ │ │ ├── Pending.jsx │ │ │ └── Rejected.jsx │ │ ├── Images │ │ │ ├── logo.svg │ │ │ ├── Plant2.svg │ │ │ └── Plant.svg │ │ ├── Login │ │ │ ├── Images │ │ │ │ └── Apple.svg │ │ │ ├── Login.css │ │ │ ├── AdminLogin.jsx │ │ │ └── Login.jsx │ │ ├── Footer │ │ │ └── Footer.jsx │ │ ├── Signup │ │ │ ├── Styles.css │ │ │ └── Signup.jsx │ │ └── ForgetPassword │ │ │ ├── Forgetpassword.jsx │ │ │ ├── ResetPassword.jsx │ │ │ └── ResetTeacher.jsx │ ├── Layout.jsx │ ├── index.css │ └── main.jsx ├── tailwind.config.js ├── vite.config.js ├── .gitignore ├── README.md ├── index.html ├── .eslintrc.cjs └── package.json ├── package.json ├── .env.example └── README.md /backend/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /backend/public/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "postman.postman-for-vscode" 4 | ] 5 | } -------------------------------------------------------------------------------- /frontend/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /frontend/src/Pages/Dashboard/Images/Clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pika003/e-Learning-Platform/HEAD/frontend/src/Pages/Dashboard/Images/Clock.png -------------------------------------------------------------------------------- /frontend/src/Pages/Dashboard/Images/Camera.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Pika003/e-Learning-Platform/HEAD/frontend/src/Pages/Dashboard/Images/Camera.png -------------------------------------------------------------------------------- /frontend/src/Layout.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Outlet} from 'react-router-dom' 3 | 4 | function Layout() { 5 | return ( 6 | <> 7 | 8 | 9 | ) 10 | } 11 | 12 | export default Layout -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@emotion/react": "^11.11.4", 4 | "@emotion/styled": "^11.11.5", 5 | "@mui/material": "^5.15.19", 6 | "axios": "^1.7.2", 7 | "react-hot-toast": "^2.4.1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /backend/vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "version":2, 3 | "builds": [ 4 | { "src": "*.js", "use": "@vercel/node" } 5 | ], 6 | "routes": [ 7 | { 8 | "src": "/(.*)", 9 | "dest": "/" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /frontend/tailwind.config.js: -------------------------------------------------------------------------------- 1 | const withMT = require("@material-tailwind/react/utils/withMT"); 2 | 3 | module.exports = withMT({ 4 | content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"], 5 | theme: { 6 | extend: {}, 7 | }, 8 | plugins: [], 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | server:{ 7 | proxy:{ 8 | '/api': 'http://localhost:4400' 9 | } 10 | }, 11 | plugins: [react()], 12 | }) 13 | -------------------------------------------------------------------------------- /backend/src/utils/ApiResponse.js: -------------------------------------------------------------------------------- 1 | class ApiResponse{ 2 | constructor(statusCode, data, message = "Success"){ 3 | this.statusCode = statusCode 4 | this.data = data 5 | this.message = message 6 | this.success = statusCode < 399 7 | 8 | } 9 | } 10 | 11 | export {ApiResponse} -------------------------------------------------------------------------------- /frontend/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | 6 | 7 | 8 | *{ 9 | margin: 0; 10 | padding: 0; 11 | } 12 | body{ 13 | background:linear-gradient(90deg, #053a4f 8.26%, rgba(20, 120, 118, 0.58) 99.96%); 14 | overflow: scroll; 15 | } 16 | body::-webkit-scrollbar{ 17 | display: none; 18 | } 19 | -------------------------------------------------------------------------------- /frontend/src/Pages/Dashboard/StudentDashboard/StudentLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Outlet} from 'react-router-dom' 3 | import StudentDashboard from './StudentDashboard' 4 | 5 | function StudentLayout() { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | ) 12 | } 13 | 14 | export default StudentLayout -------------------------------------------------------------------------------- /frontend/src/Pages/Dashboard/TeacherDashboard/TeacherLayout.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Outlet} from 'react-router-dom' 3 | import TeacherDashboard from './TeacherDashboard' 4 | 5 | function TeacherLayout() { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | ) 12 | } 13 | 14 | export default TeacherLayout -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | TEST = 2 | DB_NAME = 3 | PORT = 4 | MONGODB_URL = 5 | ACCESS_TOKEN_SECRET = 6 | ACCESS_TOKEN_EXPIRY = 7 | REFRESH_TOKEN_SECRET = 8 | REFRESH_TOKEN_EXPIRY = 9 | 10 | CORS =* 11 | SMTP_EMAIL = 12 | SMTP_PASS = 13 | 14 | CLOUDINARY_NAME= 15 | CLOUDINARY_API_KEY= 16 | CLOUDINARY_SECRET_KEY= 17 | 18 | KEY_ID = 19 | KEY_SECRET = 20 | 21 | FRONTEND_URL= 22 | -------------------------------------------------------------------------------- /backend/src/middlewares/multer.middleware.js: -------------------------------------------------------------------------------- 1 | import multer from "multer"; 2 | 3 | const storage = multer.diskStorage({ 4 | destination: function (req, file, cb) { 5 | cb(null, "./public") 6 | }, 7 | filename: function (req, file, cb) { 8 | 9 | cb(null, file.originalname) 10 | } 11 | }) 12 | 13 | export const upload = multer({ 14 | storage, 15 | }) -------------------------------------------------------------------------------- /backend/src/database/db.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const db = async() => { 4 | try{ 5 | const connectionInstance = await mongoose.connect(`${process.env.MONGODB_URL}/eLearning`) 6 | console.log(`\n MongoDB connected !! DB HOST :: ${connectionInstance.connection.host}`) 7 | } catch (error){ 8 | console.log("Mongodb connection error", error); 9 | process.exit(1) 10 | } 11 | } 12 | 13 | 14 | 15 | export default db -------------------------------------------------------------------------------- /frontend/README.md: -------------------------------------------------------------------------------- 1 | # React + Vite 2 | 3 | This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. 4 | 5 | Currently, two official plugins are available: 6 | 7 | - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh 8 | - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh 9 | -------------------------------------------------------------------------------- /backend/src/index.js: -------------------------------------------------------------------------------- 1 | import dotenv from "dotenv" 2 | import db from './database/db.js'; 3 | import {app} from './app.js' 4 | dotenv.config({ 5 | path: './.env' 6 | }) 7 | 8 | console.log(`${process.env.DB_NAME}`); 9 | 10 | 11 | db() 12 | .then(() => { 13 | app.listen(process.env.PORT || 8000, () => { 14 | console.log(`⚙️ Server is running at port : ${process.env.PORT}`); 15 | }) 16 | }) 17 | .catch((err) => { 18 | console.log(" mongodb connection failed !!! ", err); 19 | }) -------------------------------------------------------------------------------- /backend/src/utils/asyncHandler.js: -------------------------------------------------------------------------------- 1 | const asyncHandler = (fn) => async (req, res, next) => { 2 | try { 3 | await fn(req, res, next); 4 | } catch (error) { 5 | if (error.isJoi === true) { 6 | error.statusCode = 422; 7 | } 8 | res.status(error.statusCode || 500).json({ 9 | statusCode: error.statusCode || 500, 10 | message: error.message || 'Internal Server Error' 11 | }); 12 | } 13 | }; 14 | 15 | export { asyncHandler }; 16 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Shiksharthee 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /frontend/src/Pages/ErrorPage/ErrorPage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { NavLink } from "react-router-dom"; 3 | import Error from './Images/error.svg' 4 | 5 | function ErrorPage() { 6 | return ( 7 | <> 8 |
9 | 10 | Back To Home 11 |
12 | 13 | ) 14 | } 15 | 16 | export default ErrorPage -------------------------------------------------------------------------------- /backend/src/models/contact.model.js: -------------------------------------------------------------------------------- 1 | import mongoose, { Schema } from "mongoose"; 2 | 3 | const contactSchema = new Schema({ 4 | name:{ 5 | type:String, 6 | required:true, 7 | }, 8 | 9 | email:{ 10 | type:String, 11 | required:true, 12 | }, 13 | message:{ 14 | type:String, 15 | required:true, 16 | }, 17 | status: { 18 | type: Boolean, 19 | default: false 20 | } 21 | }) 22 | 23 | const contact = mongoose.model("contact", contactSchema) 24 | 25 | export {contact} 26 | -------------------------------------------------------------------------------- /backend/src/middlewares/joiLogin.middleware.js: -------------------------------------------------------------------------------- 1 | import joi from "@hapi/joi" 2 | import { asyncHandler } from "../utils/asyncHandler.js" 3 | 4 | 5 | 6 | const authSchema = asyncHandler(async(req,_, next) =>{ 7 | 8 | const schema = joi.object({ 9 | Email: joi.string().email().lowercase().required(), 10 | Password: joi.string().min(6).max(16).required() 11 | }) 12 | 13 | const result = await schema.validateAsync(req.body) 14 | 15 | 16 | req.user = result 17 | next() 18 | }) 19 | 20 | 21 | export {authSchema} 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /backend/src/utils/ApiError.js: -------------------------------------------------------------------------------- 1 | class ApiError extends Error{ 2 | constructor( 3 | statusCode, 4 | message = "Something went wrong", 5 | errors = [], 6 | stack = "" 7 | ){ 8 | super(message) 9 | this.statusCode = statusCode 10 | this.data = null, 11 | this.message = message 12 | this.success = false 13 | this.errors = errors 14 | 15 | if(stack){ 16 | this.stack = stack 17 | } 18 | else{ 19 | Error.captureStackTrace(this,this.constructor) 20 | } 21 | 22 | } 23 | } 24 | 25 | export {ApiError} -------------------------------------------------------------------------------- /frontend/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { browser: true, es2020: true }, 4 | extends: [ 5 | 'eslint:recommended', 6 | 'plugin:react/recommended', 7 | 'plugin:react/jsx-runtime', 8 | 'plugin:react-hooks/recommended', 9 | ], 10 | ignorePatterns: ['dist', '.eslintrc.cjs'], 11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 12 | settings: { react: { version: '18.2' } }, 13 | plugins: ['react-refresh'], 14 | rules: { 15 | 'react-refresh/only-export-components': [ 16 | 'warn', 17 | { allowConstantExport: true }, 18 | ], 19 | }, 20 | } 21 | -------------------------------------------------------------------------------- /frontend/src/Pages/Components/DocumentVerification/InputComponent/Input.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | const Input = ({label ,placeholder,value,onChange}) => { 4 | return ( 5 |
6 | 7 | 9 | 10 |
11 | ) 12 | } 13 | 14 | export default Input 15 | -------------------------------------------------------------------------------- /frontend/src/Pages/Components/Searchbtn/Search.css: -------------------------------------------------------------------------------- 1 | /* === search btn === */ 2 | .search{ 3 | display: flex; 4 | padding-top: 4rem; 5 | width: 450px; 6 | position: relative; 7 | } 8 | .search img{ 9 | position: absolute; 10 | margin: 5px; 11 | } 12 | .search input{ 13 | width: 450px; 14 | height: 3rem; 15 | border: none; 16 | border-radius: 3px; 17 | padding-left: 50px; 18 | background-color: #fff; 19 | color:#042439; 20 | font-weight: 600; 21 | } 22 | 23 | .search button{ 24 | position: absolute; 25 | right: 0; 26 | border-radius: 2px; 27 | margin: 5.5px 5.5px; 28 | height: 35px; 29 | } 30 | -------------------------------------------------------------------------------- /backend/src/models/payment.model.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const paymentSchema = new mongoose.Schema({ 4 | razorpay_order_id: { 5 | type: String, 6 | required: true, 7 | }, 8 | razorpay_payment_id: { 9 | type: String, 10 | required: true, 11 | }, 12 | razorpay_signature: { 13 | type: String, 14 | required: true, 15 | }, 16 | courseID: { 17 | type:mongoose.Schema.Types.ObjectId, 18 | ref: "course", 19 | require:true, 20 | }, 21 | studentID: { 22 | type: mongoose.Schema.Types.ObjectId, 23 | ref: 'student', 24 | require:true, 25 | } 26 | }); 27 | 28 | export const payment = mongoose.model("payment", paymentSchema); -------------------------------------------------------------------------------- /frontend/src/Pages/Home/Header/Header.css: -------------------------------------------------------------------------------- 1 | .gapError{ 2 | height: 10vh; 3 | } 4 | .logo{ 5 | display: flex; 6 | align-items: center; 7 | gap: 1rem; 8 | } 9 | .logo img{ 10 | height: 50px; 11 | } 12 | .logo h3{ 13 | color: #fff; 14 | font-family: 'Gill Sans MT', sans-serif; 15 | text-decoration: none; 16 | } 17 | .link-nav ul{ 18 | list-style: none; 19 | color: #fff; 20 | display: flex; 21 | gap: 2rem; 22 | } 23 | 24 | button{ 25 | background-color: #4979D1; 26 | border: none; 27 | height: 40px; 28 | width: 90px; 29 | border-radius: 5px; 30 | color: #fff; 31 | } 32 | 33 | .deactive{ 34 | color: #fff; 35 | text-decoration: none; 36 | } 37 | .active{ 38 | color:#4979D1; 39 | text-decoration: none; 40 | } -------------------------------------------------------------------------------- /backend/src/routes/payment.routes.js: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | import { authSTD } from "../middlewares/stdAuth.middleware.js"; 3 | import { coursePayment, coursePaymentConfirmation, getkey, teacherAmount, withdrawAmount } from "../controllers/payment.controller.js"; 4 | import { authTeacher } from "../middlewares/teacherAuth.middleware.js"; 5 | 6 | 7 | const router = Router() 8 | 9 | router.route("/course/:courseID/:coursename").post(authSTD, coursePayment) 10 | 11 | router.route("/razorkey").get(authSTD, getkey) 12 | 13 | router.route("/confirmation/course/:courseID").post(authSTD, coursePaymentConfirmation) 14 | 15 | router.route("/teacher/:teacherID/balance").post(authTeacher, teacherAmount) 16 | 17 | router.route("/teacher/:teacherID/withdraw").post(authTeacher, withdrawAmount) 18 | 19 | 20 | 21 | 22 | export default router; -------------------------------------------------------------------------------- /backend/src/utils/cloudinary.js: -------------------------------------------------------------------------------- 1 | import {v2 as cloudinary} from 'cloudinary'; 2 | import fs from "fs" 3 | 4 | 5 | 6 | cloudinary.config({ 7 | cloud_name: process.env.CLOUDINARY_NAME, 8 | api_key: process.env.CLOUDINARY_API_KEY, 9 | api_secret: process.env.CLOUDINARY_SECRET_KEY 10 | }); 11 | 12 | 13 | const uploadOnCloudinary = async (localFilePath) => { 14 | 15 | try{ 16 | if(!localFilePath) return null; 17 | const response = await cloudinary.uploader.upload(localFilePath, { 18 | resource_type: "auto" 19 | }) 20 | fs.unlinkSync(localFilePath) 21 | return response; 22 | } catch(err){ 23 | fs.unlinkSync(localFilePath) 24 | console.log("cloudinary upload error ", err) 25 | return null; 26 | } 27 | } 28 | 29 | 30 | export {uploadOnCloudinary} 31 | -------------------------------------------------------------------------------- /backend/src/middlewares/adminAuth.middleware.js: -------------------------------------------------------------------------------- 1 | import {asyncHandler} from "../utils/asyncHandler.js"; 2 | import {ApiError} from "../utils/ApiError.js"; 3 | import { admin } from "../models/admin.model.js"; 4 | import jwt from "jsonwebtoken"; 5 | 6 | const authAdmin = asyncHandler(async(req,_,next) =>{ 7 | 8 | const accToken = req.cookies?.Accesstoken 9 | 10 | if(!accToken) { 11 | throw new ApiError(401, "unauthorized req") 12 | } 13 | 14 | 15 | const decodedAccToken = jwt.verify(accToken, 16 | process.env.ACCESS_TOKEN_SECRET) 17 | 18 | const Admin = await admin.findById(decodedAccToken?._id).select("-password -Refreshtoken") 19 | 20 | if(!Admin){ 21 | throw new ApiError(401, "invalid access token") 22 | } 23 | 24 | req.Admin = Admin 25 | next() 26 | 27 | 28 | }) 29 | 30 | export { authAdmin } -------------------------------------------------------------------------------- /backend/src/middlewares/stdAuth.middleware.js: -------------------------------------------------------------------------------- 1 | import {asyncHandler} from "../utils/asyncHandler.js"; 2 | import {ApiError} from "../utils/ApiError.js"; 3 | import {student} from "../models/student.model.js"; 4 | import jwt from "jsonwebtoken"; 5 | 6 | const authSTD = asyncHandler(async(req,_,next) =>{ 7 | 8 | const accToken = req.cookies?.Accesstoken 9 | 10 | if(!accToken) { 11 | throw new ApiError(401, "unauthorized req") 12 | } 13 | 14 | const decodedAccToken = jwt.verify(accToken, 15 | process.env.ACCESS_TOKEN_SECRET) 16 | 17 | const Student = await student.findById(decodedAccToken?._id).select("-Password -Refreshtoken") 18 | 19 | if(!Student){ 20 | throw new ApiError(401, "invalid access token") 21 | } 22 | 23 | req.Student = Student 24 | next() 25 | 26 | 27 | }) 28 | 29 | export { authSTD } -------------------------------------------------------------------------------- /backend/src/middlewares/teacherAuth.middleware.js: -------------------------------------------------------------------------------- 1 | import { ApiError } from "../utils/ApiError.js"; 2 | import {Teacher} from "../models/teacher.model.js"; 3 | import jwt from "jsonwebtoken"; 4 | import { asyncHandler } from "../utils/asyncHandler.js"; 5 | 6 | const authTeacher = asyncHandler(async(req,_,next)=>{ 7 | const accToken = req.cookies?.Accesstoken 8 | 9 | if(!accToken){ 10 | throw new ApiError(401, "unauthorized req") 11 | } 12 | 13 | const decodedAccToken = jwt.verify(accToken, 14 | process.env.ACCESS_TOKEN_SECRET) 15 | 16 | const teacher = await Teacher.findById(decodedAccToken?._id).select("-Password -Refreshtoken") 17 | 18 | if(!teacher){ 19 | throw new ApiError(401, "invalid access token") 20 | } 21 | 22 | 23 | req.teacher = teacher 24 | next() 25 | }) 26 | 27 | export {authTeacher} -------------------------------------------------------------------------------- /frontend/src/Pages/Response/Pending.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import pending from "../Images/pending.svg"; 3 | import { NavLink } from "react-router-dom"; 4 | 5 | function Pending() { 6 | return ( 7 | <> 8 |
9 | 10 |

Response Pending

11 |

12 | We take your response, now wait a little bit. when your Admin check your response and approve it or reject any reason we will notify you by your email it. 13 |

14 | 15 |

◀ go to home

16 |
17 |
18 | 19 | ); 20 | } 21 | 22 | export default Pending; 23 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elearning", 3 | "version": "1.0.0", 4 | "description": "", 5 | "type": "module", 6 | "main": "index.js", 7 | "scripts": { 8 | "dev": "nodemon -r dotenv/config --experimental-json-modules src/index.js" 9 | }, 10 | "github": "https://github.com/Pika003/e-Learning-Platform.git", 11 | "author": "Parag, Satyajit, Gopi, Aditya", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@hapi/joi": "^17.1.1", 15 | "bcrypt": "^5.1.1", 16 | "cloudinary": "^2.0.3", 17 | "cookie-parser": "^1.4.6", 18 | "cors": "^2.8.5", 19 | "crypto": "^1.0.1", 20 | "dotenv": "^16.4.4", 21 | "express": "^4.18.2", 22 | "jsonwebtoken": "^9.0.2", 23 | "mongoose": "^8.1.2", 24 | "mongoose-aggregate-paginate-v2": "^1.0.7", 25 | "multer": "^1.4.5-lts.1", 26 | "nodemailer": "^6.9.9", 27 | "nodemon": "^3.1.0", 28 | "razorpay": "^2.9.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /frontend/src/Pages/Components/Searchbtn/Success.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | function Success({onClose}) { 4 | return ( 5 |
6 |
7 | 8 |

Payment Successful

9 |

Payment successfully completed! Now you can join the classes.
Wishing a happy journey with Shiksharthee 10 |

11 |
Back to Dashboard
12 |
13 |
14 | ) 15 | } 16 | 17 | export default Success -------------------------------------------------------------------------------- /frontend/src/Pages/Components/VarifyEmail/VarifyEmail.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Email from '../../Images/email.svg' 3 | import { NavLink } from "react-router-dom" 4 | import Header from '../../Home/Header/Header' 5 | 6 | function VarifyEmail() { 7 | return ( 8 | <> 9 |
10 |
11 |
12 | email 13 |

Send Email

14 |

We have sent a verification link to your Email. Click on the link to complete the verification process. You might need to check your spam folder.

15 | 16 |

◀ Back to Login

17 |
18 |
19 |
20 | 21 | ) 22 | } 23 | 24 | export default VarifyEmail -------------------------------------------------------------------------------- /backend/src/utils/Nodemailer.js: -------------------------------------------------------------------------------- 1 | 2 | import nodemailer from "nodemailer" 3 | 4 | 5 | export const Sendmail =async function(email,subject,message){ 6 | 7 | 8 | const transporter = nodemailer.createTransport({ 9 | host:'smtp.gmail.com', 10 | secure: true, // Use `true` for port 465, `false` for all other ports 11 | port:465, 12 | auth: { 13 | user: process.env.SMTP_EMAIL, 14 | pass: process.env.SMTP_PASS, 15 | }, 16 | }); 17 | 18 | const receiver={ 19 | from: process.env.SMTP_EMAIL, // sender address 20 | to: email, // list of receivers 21 | subject: subject, // Subject line 22 | html: message // html body 23 | } 24 | 25 | console.log(email,subject,message); 26 | try { 27 | const info = await transporter.sendMail(receiver); 28 | console.log('email sent:', info.response); 29 | return { success: true, message: 'Forget password email sent successfully' }; 30 | } catch (error) { 31 | console.error('Error sending email:', error); 32 | return { success: false, error: 'Error sending email' }; 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /frontend/src/Pages/Response/Rejected.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import rejected from "../Images/rejected.svg"; 3 | import { NavLink, useParams } from "react-router-dom"; 4 | 5 | function Rejected() { 6 | const { ID, user } = useParams(); 7 | let type = ''; 8 | if(user === 'student'){ 9 | type = 'StudentDocument'; 10 | }else{ 11 | type = 'TeacherDocument'; 12 | } 13 | 14 | return ( 15 | <> 16 |
17 | 18 |

Response Rejected

19 |

20 | We take your response, but the image of your Aadhaar card is little 21 | unclear. Please submit one more time. 22 |

23 | 24 |

◀ go to document verification page

25 |
26 |
27 | 28 | ); 29 | } 30 | 31 | export default Rejected; 32 | -------------------------------------------------------------------------------- /frontend/src/Pages/Components/DocumentVerification/Inputupload/InputUpload.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | 3 | const InputUpload = ({ label, placeholder,value,onChange}) => { 4 | 5 | 6 | 7 | return ( 8 |
9 | 10 |
11 | 12 | 18 | 19 |
20 | 21 | {value ? value.name : placeholder} 22 | 23 | Choose File 24 |
25 |
26 |
27 | ); 28 | 29 | } 30 | 31 | export default InputUpload; 32 | 33 | 34 | -------------------------------------------------------------------------------- /backend/src/app.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import cors from "cors"; 3 | import cookieParser from "cookie-parser"; 4 | import Razorpay from "razorpay" 5 | 6 | const app = express(); 7 | 8 | app.use(cors()) 9 | 10 | app.use(express.json({limit: "16kb"})) 11 | app.use(express.urlencoded({extended: true, limit: "16kb"})) 12 | app.use(express.static("public")) 13 | app.use(cookieParser()) 14 | 15 | 16 | export const instance = new Razorpay({ 17 | key_id: process.env.KEY_ID, 18 | key_secret: process.env.KEY_SECRET 19 | }) 20 | 21 | //student routes 22 | import studentRouter from "./routes/student.routes.js"; 23 | app.use("/api/student", studentRouter) 24 | 25 | 26 | //teacher routes 27 | import teacherRouter from "./routes/teacher.routes.js" 28 | app.use("/api/teacher", teacherRouter) 29 | 30 | //course routes 31 | import courseRouter from "./routes/course.routes.js" 32 | app.use("/api/course", courseRouter) 33 | 34 | import adminRouter from "./routes/admin.routes.js" 35 | app.use("/api/admin", adminRouter) 36 | 37 | import paymentRouter from "./routes/payment.routes.js" 38 | app.use("/api/payment", paymentRouter) 39 | 40 | 41 | export {app} -------------------------------------------------------------------------------- /frontend/src/Pages/Images/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fontent", 3 | "private": true, 4 | "proxy": "https://localhost:4400", 5 | "version": "0.0.0", 6 | "type": "module", 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "vite build", 10 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", 11 | "preview": "vite preview" 12 | }, 13 | "dependencies": { 14 | "@material-tailwind/react": "^2.1.9", 15 | "axios": "^1.6.8", 16 | "date-fns": "^3.6.0", 17 | "razorpay": "^2.9.3", 18 | "react": "^18.2.0", 19 | "react-datepicker": "^7.1.0", 20 | "react-dom": "^18.2.0", 21 | "react-hot-toast": "^2.4.1", 22 | "react-icons": "^5.0.1", 23 | "react-loader-spinner": "^6.1.6", 24 | "react-router-dom": "^6.22.0", 25 | "yup": "^1.4.0" 26 | }, 27 | "devDependencies": { 28 | "@types/react": "^18.2.43", 29 | "@types/react-dom": "^18.2.17", 30 | "@vitejs/plugin-react": "^4.2.1", 31 | "autoprefixer": "^10.4.18", 32 | "eslint": "^8.55.0", 33 | "eslint-plugin-react": "^7.33.2", 34 | "eslint-plugin-react-hooks": "^4.6.0", 35 | "eslint-plugin-react-refresh": "^0.4.5", 36 | "postcss": "^8.4.35", 37 | "tailwindcss": "^3.4.1", 38 | "vite": "^5.0.8" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /backend/src/models/course.model.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | 3 | const courseSchema= new mongoose.Schema({ 4 | 5 | coursename:{ 6 | type:String, 7 | require:true 8 | }, 9 | 10 | description: { 11 | type: String, 12 | required: true 13 | }, 14 | 15 | isapproved: { 16 | type: Boolean, 17 | default: false 18 | }, 19 | 20 | liveClasses: [{ 21 | title: String, 22 | timing: Number, 23 | date:Date, 24 | link: String, 25 | status: { 26 | type: String, 27 | enum: ['upcoming', 'in-progress', 'completed'], 28 | default: 'upcoming' 29 | } 30 | }], 31 | 32 | enrolledteacher:{ 33 | type:mongoose.Schema.Types.ObjectId, 34 | ref: "teacher", 35 | require:true 36 | }, 37 | 38 | enrolledStudent: [{ 39 | type: mongoose.Schema.Types.ObjectId, 40 | ref: 'student' 41 | }], 42 | 43 | schedule: [{ 44 | day: { 45 | type: Number, 46 | enum: [0, 1, 2, 3, 4, 5, 6] 47 | }, 48 | starttime: { 49 | type: Number, 50 | min: 0, 51 | max: 24 * 60 52 | }, 53 | endtime: { 54 | type: Number, 55 | min: 0, 56 | max: 24 * 60 57 | } 58 | }], 59 | 60 | 61 | 62 | },{timestamps:true}) 63 | 64 | const course= mongoose.model('course',courseSchema) 65 | 66 | export {course} -------------------------------------------------------------------------------- /backend/src/routes/student.routes.js: -------------------------------------------------------------------------------- 1 | import {Router} from "express"; 2 | import {signup, mailVerified, login,logout, addStudentDetails, getStudent, forgetPassword, resetPassword } from "../controllers/student.controller.js"; 3 | import {upload} from "../middlewares/multer.middleware.js" 4 | import {authSTD} from "../middlewares/stdAuth.middleware.js" 5 | import { authSchema } from "../middlewares/joiLogin.middleware.js"; 6 | 7 | const router = Router() 8 | 9 | router.route("/signup").post( 10 | signup 11 | ) 12 | 13 | router.route("/verify").get( 14 | mailVerified 15 | ) 16 | 17 | router.route("/login").post( 18 | authSchema, login 19 | ) 20 | 21 | router.route("/logout").post(authSTD, logout) 22 | 23 | router.route("/Verification/:id").post(authSTD, 24 | upload.fields([ 25 | { 26 | name:"Aadhaar", 27 | maxCount:1, 28 | }, 29 | { 30 | name:"Secondary", 31 | maxCount:1, 32 | }, 33 | { 34 | name:"Higher", 35 | maxCount:1 36 | } 37 | ]) , 38 | addStudentDetails) 39 | 40 | router.route("/StudentDocument/:id").get(authSTD, getStudent) 41 | 42 | router.route('/forgetpassword').post(forgetPassword) 43 | 44 | router.route('/forgetpassword/:token').post(resetPassword) 45 | 46 | 47 | 48 | export default router; -------------------------------------------------------------------------------- /frontend/src/Pages/Components/RadioBtn/Radiobtn.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import './Radiobtn.css' 3 | 4 | function Radiobtn({userType,setUserType}) { 5 | return ( 6 | <> 7 |
8 |
9 | setUserType('student')} 16 | /> 17 | 21 |
22 |
23 | setUserType('teacher')} 30 | /> 31 | 35 |
36 |
37 | 38 | ); 39 | } 40 | 41 | export default Radiobtn; 42 | -------------------------------------------------------------------------------- /backend/src/routes/course.routes.js: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | import { addClass, addCourseStudent, addCourseTeacher, canStudentEnroll, enrolledcourseSTD, enrolledcourseTeacher, getCourse, getcourseTeacher, stdEnrolledCoursesClasses, teacherEnrolledCoursesClasses } from "../controllers/course.controller.js"; 3 | import { authSTD } from "../middlewares/stdAuth.middleware.js"; 4 | import { authTeacher } from "../middlewares/teacherAuth.middleware.js"; 5 | 6 | 7 | const router = Router() 8 | 9 | 10 | router.route("/all").get(getCourse) 11 | 12 | router.route("/:coursename").get(getcourseTeacher) 13 | 14 | router.route("/:coursename/create/:id").post(authTeacher, addCourseTeacher) 15 | 16 | router.route("/:coursename/:courseID/add/student/:id").post(authSTD, addCourseStudent) 17 | 18 | router.route("/:coursename/:courseID/verify/student/:id").post(authSTD, canStudentEnroll) 19 | 20 | router.route("/student/:id/enrolled").get(authSTD, enrolledcourseSTD) 21 | 22 | router.route("/teacher/:id/enrolled").get(authTeacher, enrolledcourseTeacher) 23 | 24 | router.route("/:courseId/teacher/:teacherId/add-class").post(authTeacher, addClass) 25 | 26 | router.route("/classes/student/:studentId").get(authSTD, stdEnrolledCoursesClasses) 27 | 28 | router.route("/classes/teacher/:teacherId").get(authTeacher, teacherEnrolledCoursesClasses) 29 | 30 | export default router; -------------------------------------------------------------------------------- /backend/src/routes/admin.routes.js: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | import { adminLogin, adminLogout, adminSignUp, approveStudent, approveTeacher, checkStudentDocuments, checkTeacherDocuments, forApproval, sendmessage, allmessages, readMessage, toapproveCourse, approveCourse } from "../controllers/admin.controller.js"; 3 | import { authAdmin } from "../middlewares/adminAuth.middleware.js"; 4 | 5 | const router = Router() 6 | 7 | router.route("/signup").post(adminSignUp) 8 | 9 | router.route("/login").post(adminLogin) 10 | 11 | router.route("/:adminID/approve").post(authAdmin, forApproval) 12 | 13 | router.route("/:adminID/approve/student/:studentID").post(authAdmin, approveStudent) 14 | 15 | router.route("/:adminID/approve/teacher/:teacherID").post(authAdmin,approveTeacher) 16 | 17 | router.route("/:adminID/documents/student/:studentID").get(authAdmin, checkStudentDocuments) 18 | 19 | router.route("/:adminID/documents/teacher/:teacherID").get(authAdmin, checkTeacherDocuments) 20 | 21 | router.route("/logout").post(authAdmin, adminLogout) 22 | 23 | router.route("/contact-us").post(sendmessage) 24 | 25 | router.route("/messages/all").get(authAdmin, allmessages) 26 | 27 | router.route("/message/read").patch(authAdmin, readMessage) 28 | 29 | router.route("/:adminID/approve/course").get(authAdmin, toapproveCourse) 30 | 31 | router.route("/:adminID/approve/course/:courseID").post(authAdmin, approveCourse) 32 | 33 | export default router; 34 | 35 | //testing -------------------------------------------------------------------------------- /backend/src/models/admin.model.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose" 2 | import jwt from "jsonwebtoken" 3 | import bcrypt from "bcrypt" 4 | 5 | 6 | const adminSchema = new mongoose.Schema({ 7 | 8 | username:{ 9 | type:String, 10 | required:true, 11 | trim:true, 12 | lowercase:true 13 | }, 14 | 15 | password:{ 16 | type:String, 17 | required: true, 18 | }, 19 | 20 | Refreshtoken:{ 21 | type:String, 22 | }, 23 | 24 | }) 25 | 26 | 27 | adminSchema.pre("save", async function (next) { 28 | if(!this.isModified("password")) return next(); 29 | this.password = await bcrypt.hash(this.password, 10) 30 | next() 31 | }) 32 | 33 | adminSchema.methods.isPasswordCorrect = async function (password){ 34 | return await bcrypt.compare(password, this.password) 35 | } 36 | 37 | adminSchema.methods.generateAccessToken = function(){ 38 | return jwt.sign({ 39 | _id:this._id, 40 | Email:this.Email, 41 | }, 42 | process.env.ACCESS_TOKEN_SECRET,{ 43 | expiresIn:process.env.ACCESS_TOKEN_EXPIRY 44 | }) 45 | } 46 | 47 | adminSchema.methods.generateRefreshToken = function(){ 48 | return jwt.sign({ 49 | _id:this._id, 50 | Email:this.Email, 51 | }, 52 | process.env.REFRESH_TOKEN_SECRET,{ 53 | expiresIn:process.env.REFRESH_TOKEN_EXPIRY 54 | }) 55 | } 56 | 57 | const admin = mongoose.model("admin",adminSchema); 58 | 59 | export {admin} -------------------------------------------------------------------------------- /frontend/src/Pages/Components/RadioBtn/Radiobtn.css: -------------------------------------------------------------------------------- 1 | .radio-buttons-container { 2 | display: flex; 3 | align-items: center; 4 | gap: 24px; 5 | } 6 | 7 | .radio-button { 8 | display: inline-block; 9 | position: relative; 10 | cursor: pointer; 11 | } 12 | 13 | .radio-button__input { 14 | position: absolute; 15 | opacity: 0; 16 | width: 0; 17 | height: 0; 18 | } 19 | 20 | .radio-button__label { 21 | display: inline-block; 22 | padding-left: 30px; 23 | margin-bottom: 10px; 24 | position: relative; 25 | font-size: 16px; 26 | color: #fff; 27 | cursor: pointer; 28 | transition: all 0.3s cubic-bezier(0.23, 1, 0.320, 1); 29 | } 30 | 31 | .radio-button__custom { 32 | position: absolute; 33 | top: 50%; 34 | left: 0; 35 | transform: translateY(-50%); 36 | width: 20px; 37 | height: 20px; 38 | border-radius: 50%; 39 | border: 2px solid #555; 40 | transition: all 0.3s cubic-bezier(0.23, 1, 0.320, 1); 41 | } 42 | 43 | .radio-button__input:checked + .radio-button__label .radio-button__custom { 44 | transform: translateY(-50%) scale(0.9); 45 | border: 5px solid #4c8bf5; 46 | color: #4c8bf5; 47 | } 48 | 49 | .radio-button__input:checked + .radio-button__label { 50 | color: #4c8bf5; 51 | } 52 | 53 | .radio-button__label:hover .radio-button__custom { 54 | transform: translateY(-50%) scale(1.2); 55 | border-color: #4c8bf5; 56 | box-shadow: 0 0 10px #4c8bf580; 57 | } 58 | 59 | -------------------------------------------------------------------------------- /frontend/src/Pages/Home/Header/Header.jsx: -------------------------------------------------------------------------------- 1 | import './Header.css' 2 | import { NavLink } from 'react-router-dom' 3 | import Logo from '../../Images/logo.svg' 4 | 5 | function Header() { 6 | return ( 7 | <> 8 |
9 | 10 |
11 | logo 12 |

Shiksharthee

13 |
14 |
15 |
16 |
    17 |
  • isActive ? "active" : "deactive" }> Home
  • 18 |
  • isActive ? "active" : "deactive"}> Courses
  • 19 |
  • isActive ? "active" : "deactive"}> About
  • 20 |
  • isActive ? "active" : "deactive"}> Contact us
  • 21 |
22 |
23 |
24 | isActive ? "deactive" : "deactive"}> 25 | isActive ? "deactive" : "deactive"}> 26 |
27 |
28 |
29 | 30 | ) 31 | } 32 | 33 | export default Header 34 | -------------------------------------------------------------------------------- /frontend/src/Pages/Login/Images/Apple.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /backend/src/routes/teacher.routes.js: -------------------------------------------------------------------------------- 1 | import {Router} from "express"; 2 | import {signup, mailVerified, login, logout, addTeacherDetails, getTeacher, teacherdocuments,ForgetPassword,ResetPassword} from "../controllers/teacher.controller.js"; 3 | import {upload} from "../middlewares/multer.middleware.js" 4 | import { authTeacher } from "../middlewares/teacherAuth.middleware.js"; 5 | import { authSchema } from "../middlewares/joiLogin.middleware.js"; 6 | 7 | 8 | const router = Router() 9 | 10 | router.route("/signup").post( 11 | signup 12 | ) 13 | 14 | router.route("/verify").get( 15 | mailVerified 16 | ) 17 | 18 | router.route("/login").post( 19 | authSchema, login 20 | ) 21 | 22 | router.route("/logout").post( 23 | authTeacher, logout 24 | ) 25 | 26 | router.route("/verification/:id").post(authTeacher, 27 | upload.fields([ 28 | { 29 | name:"Aadhaar", 30 | maxCount:1, 31 | }, 32 | { 33 | name:"Secondary", 34 | maxCount:1, 35 | }, 36 | { 37 | name:"Higher", 38 | maxCount:1 39 | }, 40 | { 41 | name:"UG", 42 | maxCount:1 43 | }, 44 | { 45 | name:"PG", 46 | maxCount:1 47 | } 48 | ]) , 49 | addTeacherDetails) 50 | 51 | router.route("/teacherdocument/:id").get(authTeacher, getTeacher) 52 | 53 | router.route("/teacherdocuments").post(teacherdocuments) 54 | 55 | 56 | router.route('/forgetpassword').post(ForgetPassword) 57 | 58 | router.route('/forgetpassword/:token').post(ResetPassword) 59 | 60 | export default router; 61 | -------------------------------------------------------------------------------- /frontend/src/Pages/Login/Login.css: -------------------------------------------------------------------------------- 1 | .main{ 2 | margin-top: 10vh; 3 | margin-left: 10vh; 4 | color:white; 5 | font-family: sans-serif; 6 | display: flex; 7 | gap: 10rem; 8 | align-items: center; 9 | justify-content: center; 10 | } 11 | 12 | .main::-webkit-scrollbar { 13 | width: 0 !important; 14 | } 15 | 16 | .container{ 17 | min-height: auto; 18 | width:380px; 19 | background-color: #0E3A59; 20 | text-align: center; 21 | border-radius: 15px; 22 | } 23 | 24 | .para1{ 25 | font-size: large; 26 | margin-top: 10px; 27 | } 28 | 29 | .logo{ 30 | padding: 15px; 31 | } 32 | 33 | .para{ 34 | margin-top: 20px; 35 | font-size: 16px; 36 | letter-spacing: 1px; 37 | } 38 | .form{ 39 | margin-top:40px; 40 | } 41 | .input-0{ 42 | border:0; 43 | outline: 0; 44 | background: transparent; 45 | border: 2px solid gray; 46 | width: 70%; 47 | padding-block: 17px ; 48 | border-radius: 15px; 49 | padding-left: 1rem; 50 | color: white; 51 | } 52 | 53 | .input-0::placeholder{ 54 | font-size: 16px; 55 | padding-left: 20px; 56 | } 57 | 58 | .input-2{ 59 | margin-top:20px; 60 | } 61 | 62 | .btns{ 63 | margin-top: 2rem; 64 | display: flex; 65 | justify-content: center; 66 | gap: 80px; 67 | margin-bottom: 1rem; 68 | } 69 | 70 | .btns-1{ 71 | background-color: #157776; 72 | padding: 10px; 73 | width: 200px; 74 | } 75 | 76 | .radio-btn{ 77 | display: flex; 78 | justify-content: center; 79 | margin-top: 2rem; 80 | } 81 | 82 | .signup-link{ 83 | margin-top: 20px; 84 | font-size: small; 85 | } 86 | 87 | .signup-link p{ 88 | color: #fff; 89 | } 90 | 91 | /* .signup-link .link{ 92 | color: green; 93 | font-size: medium; 94 | } */ 95 | -------------------------------------------------------------------------------- /frontend/src/Pages/Dashboard/TeacherDashboard/DateTime.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import DatePicker, { registerLocale } from 'react-datepicker'; 3 | import 'react-datepicker/dist/react-datepicker.css'; 4 | import { setHours, setMinutes, format } from 'date-fns'; 5 | 6 | const DateTime = ({setDate, allowedDays}) => { 7 | const [selectedDate, setSelectedDate] = useState(null); 8 | 9 | const isAllowedDate = (date) => { 10 | // Check if the date's day is in the allowedDays array 11 | return allowedDays.some((allowedDay) => allowedDay.day === date.getDay()); 12 | }; 13 | 14 | const isAllowedTime = (date) => { 15 | const allowedDay = allowedDays.find((day) => day.day === date.getDay()); 16 | if (!allowedDay) return false; 17 | 18 | const minutes = date.getHours() * 60 + date.getMinutes(); 19 | return minutes >= allowedDay.starttime && minutes <= allowedDay.endtime - 60; 20 | }; 21 | 22 | const filterTime = (time) => { 23 | return isAllowedTime(time); 24 | }; 25 | 26 | useEffect(() => { 27 | if (selectedDate) { 28 | const formattedDate = format(selectedDate, "yyyy-MM-dd'T'HH:mm:ssXXX"); 29 | // console.log('Selected Date and Time:', formattedDate.slice(0,19)+'Z'); 30 | setDate(formattedDate.slice(0,19)+'Z'); 31 | } 32 | }, [selectedDate]); 33 | 34 | return ( 35 | <> 36 | setSelectedDate(date)} 39 | filterDate={isAllowedDate} 40 | showTimeSelect 41 | timeIntervals={15} 42 | timeFormat="HH:mm" 43 | minTime={setHours(setMinutes(new Date(), 0), 0)} 44 | maxTime={setHours(setMinutes(new Date(), 0), 23)} 45 | filterTime={filterTime} 46 | dateFormat="MMMM d, yyyy h:mm aa" 47 | placeholderText="Select a date and time" 48 | /> 49 | 50 | ); 51 | }; 52 | 53 | export default DateTime; 54 | -------------------------------------------------------------------------------- /frontend/src/Pages/Home/About/About.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Plant from "../../Images/Plant.svg"; 3 | import Plant2 from "../../Images/Plant2.svg"; 4 | import '../Landing/Landing.css' 5 | import Footer from "../../Footer/Footer.jsx" 6 | import Header from '../Header/Header.jsx'; 7 | 8 | function About({backgroundC}) { 9 | return ( 10 | <> 11 |
12 |
13 |

About Us

14 |
15 |
16 |
17 | 18 |
19 |

20 | At Shiksharthee, we believe in the power of education to transform lives. Our platform is designed to be a gateway to knowledge, offering a diverse range of courses and learning experiences for students. 21 |

Our Story

22 | Shiksharthee was born out of a passion for learning and a desire to make quality education accessible to everyone. We understand the challenges faced by modern learners and strive to provide a solution that is both convenient and effective. 23 |

Our Mission

24 | Our mission is simple yet profound: to empower individuals through education. We aim to create a global learning community where students can discover new passions, enhance their skills, and achieve their academic and professional goals. By leveraging technology and innovative teaching methods, we strive to make learning engaging, interactive, and enjoyable. 25 |

26 |
27 | 28 |
29 |
30 |
31 |