Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Ansh Mishra/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env
node_modules/
62 changes: 62 additions & 0 deletions Ansh Mishra/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# 🧠 Neuro Mentor

**Neuro Mentor** is a full-stack web application designed to streamline interaction between mentors and their students. It provides authentication, student management, and secure access control—making it ideal for educational or mentoring platforms.

---

## 🚀 Features

- 🔐 **User Authentication**: Secure login and signup using session-based authentication.
- 📋 **Student Index Page**: View all students with quick access to individual student profiles.
- ➕ **Add New Student**: Logged-in users can create new student records through a form.
- ✏️ **Edit/Delete Access Control**: Only the user who added a student can edit or delete their profile.
- 🖼️ **Cloud-based Image Upload**: Images are uploaded and stored using Cloudinary.

---

## 🛠️ Tech Stack

- **Frontend**: HTML, CSS, JavaScript
- **Backend**: Node.js, Express.js
- **Database**: MongoDB with Mongoose
- **Authentication**: express-session
- **Image Hosting**: Cloudinary
- **Deployment**: Render
- **Architecture**: MVC (Model-View-Controller)

---


---

## 🌐 Live Demo

🔗 https://neuro-mentor.onrender.com/listings

---

## 📸 Video demo :
https://www.linkedin.com/feed/update/urn:li:activity:7356280463709143041/

---

## ⚙️ Setup Instructions

1. **Clone the repository**
git clone https://github.com/Ansh3721/NEURO_MENTOR.git
cd NEURO_MENTOR

2.**Install dependencies**
npm install

3.**Create a .env file in the root folder and add your secrets**
4.**Run the application**
node app.js

## 👨‍💻 Author
**Ansh Mishra**
📧 Email: anshmishra3721@gmail.com
🔗 GitHub: @Ansh3721



121 changes: 121 additions & 0 deletions Ansh Mishra/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
if(process.env.NODE_ENV != 'production'){
require('dotenv').config();
}

const express = require("express");
const app = express();
const mongoose = require("mongoose");
const path = require("path");
const methodOverride = require("method-override");
const ejsMate = require("ejs-mate");
const ExpressError = require("./utils/ExpressError.js");
const session = require("express-session");
const MongoStore = require("connect-mongo");
const flash = require ("connect-flash");
const passport = require ("passport");
const LocalStrategy = require("passport-local");
const User = require("./models/user.js");


const listingRouter = require("./routs/listing.js");
const reviewRouter = require("./routs/review.js");
const userRouter = require("./routs/user.js");

let MONGO_URL = "mongodb://127.0.0.1:27017/stu_info";
// let dbUrl = process.env.ATLASDB_URL ;

main()
.then( () => {
console.log("connected to DB");
})
.catch( (err) => {
console.log(err);
});

async function main() {
await mongoose.connect(MONGO_URL);
}

app.set("view engine","ejs");
app.set("views",path.join(__dirname,"views"));
app.use(express.urlencoded({extended:true}));
app.use(methodOverride("_method"));
app.engine("ejs",ejsMate);
app.use(express.static(path.join(__dirname,"/public")));

const store = MongoStore.create({
mongoUrl : MONGO_URL,
crypto:{
secret: process.env.SECRET
},
touchAfter : 24 * 60 ,
});

store.on("error",()=>{
console.log("Error in MONGO SESSION STORE" , err);
})

const sessionOptions = {
store,
secret: process.env.SECRET,
resave: false ,
saveUninitialized: true ,
cookie : {
expires : Date.now() + 7 * 24 * 60 * 60 * 1000 ,
maxAge : 7 * 24 * 60 * 60 * 1000 ,
httpOnly : true,
},
};


app.use(session(sessionOptions));
app.use(flash());

app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());


app.get("/registeruser", async(req,res) =>{
let fakeUser = new User ({
email: "ansh@gmail.com",
username :"ansh",
});
let newUser = await User.register(fakeUser ,"ansh283");
res.send(newUser);
})


app.use((req,res,next)=>{
res.locals.success = req.flash("success");
res.locals.error = req.flash("error");
res.locals.currUser = req.user ;
next();
});


app.get("/", (req,res)=> {
res.render("./home.ejs");
});


app.use ("/listings" , listingRouter);
app.use ("/listings/:id/stu_problem",reviewRouter);
app.use("/",userRouter);

app.use((req, res, next) => {
next(new ExpressError(404, "page not found!"));
});

app.use((err,req,res,next)=>{
let{statusCode = 500 , message = "something went wrong!!"} = err ;
res.status(statusCode).render("error.ejs" , {message});
// res.status(statusCode).send(message);
});


app.listen(8080, () => {
console.log("server is listening on port 8080");
});
21 changes: 21 additions & 0 deletions Ansh Mishra/cloudconfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');

cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.CLOUD_API_KEY,
api_secret: process.env.CLOUD_API_SECRET
})

const storage = new CloudinaryStorage({
cloudinary: cloudinary,
params: {
folder: 'STU_INFO_DEV',
allowedFormat: ["png" , "jpeg" , "jpg"],
},
});

module.exports = {
cloudinary,
storage
} ;
69 changes: 69 additions & 0 deletions Ansh Mishra/controllers/listing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const Listing = require("../models/listing.js");

//index
module.exports.index = async (req,res) => {
const allListings = await Listing.find();
res.render("listings/index.ejs",{allListings})
};

//new
module.exports.new = (req,res)=>{
res.render("listings/new.ejs");
};

//create
module.exports.create = async (req, res, next) => { // Then wrapAsync the handler
const listing = new Listing(req.body.listing);
if(typeof req.file !== "undefined"){
let url = req.file.path ;
let filename = req.file.filename ;
listing.image = {url,filename};
await listing.save();
}
listing.owner = req.user._id;
await listing.save();
req.flash("success","New student Added!!");
res.redirect("/listings");
};


//show
module.exports.show = async (req,res) =>{
const id = req.params.id;
const listing = await Listing.findById(id).populate("stu_problems").populate("owner");
if(! listing){
req.flash("error","student does not exist!!");
return res.redirect("/listings");
}
res.render("listings/show.ejs",{listing});
};

//edit
module.exports.edit = async(req,res)=>{
const id = req.params.id;
const listing = await Listing.findById(id);
res.render("listings/edit.ejs",{listing});
};

//update
module.exports.update = async (req,res)=>{
console.log(req.body.listing);
const {id} = req.params;
let listing = await Listing.findByIdAndUpdate(id,{...req.body.listing});
if(typeof req.file !== "undefined"){
let url = req.file.path ;
let filename = req.file.filename ;
listing.image = {url,filename};
await listing.save();
}
req.flash("success","student updated!!");
res.redirect(`/listings/${id}`);
};

//delete
module.exports.delete = async (req,res) =>{
const id = req.params.id;
await Listing.findByIdAndDelete(id);
req.flash("success","student Deleted!!");
res.redirect("/listings");
};
25 changes: 25 additions & 0 deletions Ansh Mishra/controllers/stu_problem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const stu_problem = require("../models/stu_problem.js");
const Listing = require("../models/listing.js");

//post
module.exports.post = async (req, res)=>{
let listing =await Listing.findById(req.params.id);
let newStu_problem = new stu_problem(req.body.stu_problem);
newStu_problem.author = req.user._id;
listing.stu_problems.push(newStu_problem);
console.log(newStu_problem);
await newStu_problem.save();
await listing.save();

res.redirect(`/listings/${listing._id}`);
};


//delete
module.exports.delete = async (req, res)=>{
let {id , stu_problem_id} = req.params;
await Listing.findByIdAndUpdate(id,{$pull : {stu_problems:stu_problem_id}});
await stu_problem.findByIdAndDelete(stu_problem_id);

res.redirect(`/listings/${id}`);
};
52 changes: 52 additions & 0 deletions Ansh Mishra/controllers/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const User = require("../models/user.js");

//getsingup
module.exports.getSignUp = (req,res)=>{
res.render("users/signup.ejs");
};


//post signup
module.exports.postSignUp = async (req,res)=>{
try {
let { username , email , password} = req.body;
const newUser = new User ({email,username});
let registerUser = await User.register(newUser ,password);
// console.log(registerUser);
req.login(registerUser,(err)=>{
if(err){
return next(err);
}
req.flash("success","Welcome to NUERO_MENTOR");
res.redirect("/listings");
});
} catch(e){
req.flash("error", e.message);
res.redirect("/signup");
}
};


//getlogin
module.exports.getlogin = (req,res)=>{
res.render("users/login.ejs")
};


//postlogin
module.exports.postlogin = async (req,res)=>{
req.flash("success","Welcome back to NUERO_MENTOR");
let redirectUrl = res.locals.redirectUrl || "/listings";
res.redirect(redirectUrl );
};

//logout
module.exports.logout = (req,res,next)=>{
req.logout((err)=>{
if(err){
return next(err);
}
req.flash("success","you are successfully logged out!!");
res.redirect("/listings");
})
};
Loading