├── .gitignore ├── routes ├── user.js ├── rating.js └── event.js ├── models ├── Rating.js ├── Participant.js ├── User.js └── Event.js ├── package.json ├── server.js ├── Controller ├── rating.controller.js ├── event.controller.js └── user.controller.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | node_modules -------------------------------------------------------------------------------- /routes/user.js: -------------------------------------------------------------------------------- 1 | import {Router} from "express" ; 2 | 3 | import { signup, login } from "../Controller/user.controller.js" 4 | const router = new Router(); 5 | 6 | // CRUD OPERATIONS 7 | //GET Method: READ 8 | // Post Method: Create 9 | // creating signup 10 | // posting signup 11 | router.post("/signup", signup); 12 | // posting Login 13 | router.post("/login", login); 14 | router.get("/login",login) 15 | 16 | 17 | 18 | export default router; -------------------------------------------------------------------------------- /models/Rating.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | import validator from 'validator' // this is used for the library to validate the files and install the package using npm install validator 4 | 5 | // creating RatingSchema 6 | const ratingSchema = new mongoose.Schema({ 7 | eventname:{ 8 | type:String, 9 | required: true 10 | }, 11 | 12 | Date: 13 | { 14 | type:String, 15 | required:true 16 | }, 17 | location:{ 18 | type:String, 19 | required:true 20 | }, 21 | 22 | }, {timestamps: true}); 23 | 24 | export const Rating = mongoose.model("Rating", ratingSchema) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "type": "module", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "description": "", 13 | "dependencies": { 14 | "bcrypt": "^5.1.1", 15 | "bcryptjs": "^2.4.3", 16 | "cors": "^2.8.5", 17 | "dotenv": "^16.4.5", 18 | "express": "^4.21.1", 19 | "mongodb": "^6.10.0", 20 | "mongoose": "^8.7.2", 21 | "morgan": "^1.10.0", 22 | "validator": "^13.12.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /routes/rating.js: -------------------------------------------------------------------------------- 1 | import {Router} from "express" ; 2 | import {Rating} from "../models/Rating.js"; 3 | 4 | // import { rating } from "../Controller/rating.controller.js" 5 | const router = new Router(); 6 | 7 | 8 | /** 9 | * GET /api/projects/ 10 | * @description fetches all projects 11 | */ 12 | router.get("/", async (req, res, next) => { 13 | try { 14 | const projects = await Project.find(); 15 | 16 | if (projects) { 17 | res.json({ projects }); 18 | } else { 19 | res.json({ message: "No projects found" }); 20 | } 21 | } catch (error) { 22 | next(error); 23 | } 24 | }); 25 | 26 | 27 | 28 | 29 | export default router; -------------------------------------------------------------------------------- /models/Participant.js: -------------------------------------------------------------------------------- 1 | import mongoose from 'mongoose'; 2 | 3 | // creating the Participant schema 4 | const participantSchema = new mongoose.Schema({ 5 | fullname: { 6 | type: String, 7 | required: true 8 | }, 9 | email: { 10 | type: String, 11 | required: true 12 | }, 13 | status: { 14 | type: String, 15 | enum: ['invited', 'attending', 'declined'], 16 | default: 'invited' 17 | }, 18 | event: { 19 | type: mongoose.Schema.Types.ObjectId, 20 | ref: 'Event' // Reference to the Event model 21 | } 22 | }, { timestamps: true }); 23 | 24 | const Participant = mongoose.model('Participant', participantSchema); 25 | 26 | export default Participant; -------------------------------------------------------------------------------- /models/User.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | import validator from 'validator' // this is used for the library to validate the files and install the package using npm install validator 4 | 5 | // creating UserSchema 6 | const userSchema = new mongoose.Schema({ 7 | username:{ 8 | type:String, 9 | required: true, 10 | minlength: [3, "Name must contain at least 3 characters!"], 11 | maxlength: 30, 12 | }, 13 | email:{ 14 | type:String, 15 | required:true, 16 | unique: true, 17 | validate: [validator.isEmail, "Please provide valid email!"] // this is validate if it is email or not , also need to install the package for validator npm i validator 18 | }, 19 | password: 20 | { 21 | type:String, 22 | required:true, 23 | unique: true, 24 | minlength: 3 25 | } 26 | 27 | }, {timestamps: true}); 28 | 29 | export const User = mongoose.model("Users", userSchema) -------------------------------------------------------------------------------- /models/Event.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | import participant from "./Participant.js"; 3 | 4 | // creating event Schema 5 | const eventSchema = new mongoose.Schema({ 6 | eventname:{ 7 | type:String, 8 | required: true, 9 | }, 10 | date:{ 11 | type:String, 12 | required:true, 13 | }, 14 | 15 | location:{ 16 | type:String, 17 | required:true, 18 | }, 19 | // participants: [{ type: mongoose.Schema.Types.ObjectId,ref:participant}], // Array of participants using the participant schema 20 | // updatedAt: { 21 | // type:Date, 22 | // default: Date.now 23 | // } 24 | 25 | }); 26 | 27 | // Middleware to update the updatedAt field before saving 28 | // This is used to save the information and update with date 29 | eventSchema.pre('save', function (next) { 30 | this.updatedAt = Date.now(); 31 | next(); 32 | }); 33 | 34 | const Event = mongoose.model("Events", eventSchema) 35 | export default Event; 36 | 37 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | import express from "express" 2 | import morgan from "morgan" 3 | import mongoose from "mongoose" 4 | import dotenv from "dotenv" 5 | import cors from "cors" 6 | import userRouter from "./routes/user.js" 7 | import eventRouter from "./routes/event.js" 8 | import ratingRouter from "./routes/rating.js" 9 | 10 | //======== setting environment variables========= 11 | dotenv.config(); 12 | const app = express() 13 | const PORT = process.env.PORT; 14 | 15 | //======== connecting to DB ======== 16 | try{ 17 | await mongoose.connect(process.env.MONGODB_URI); 18 | console.log(`connected to mongodb`); 19 | } 20 | catch(error){ 21 | console.log(error); 22 | } 23 | 24 | //========== Middleware ======= 25 | app.use(morgan('dev')); // used for monitoring 26 | app.use(express.json()); // parse data to the body 27 | app.use(express.urlencoded({extended: true})); // for url 28 | app.use(cors()); 29 | 30 | //=========== ROUTES ================== 31 | app.use("/user",userRouter); 32 | app.use("/events", eventRouter); 33 | app.use("/rating", ratingRouter) 34 | app.get('/', (req,res)=> 35 | { 36 | res.send("Welcome to the API") 37 | }); 38 | // ========== ERROR Middlewares======= 39 | app.use((e, req, res,next)=>{ 40 | console.error(e); 41 | res.status(500).json({message:e.message, error:e}) 42 | }); 43 | 44 | 45 | // =========Listening to the PORT========= 46 | app.listen(PORT,()=> console.log(`Server running on the port: ${PORT}`)) -------------------------------------------------------------------------------- /Controller/rating.controller.js: -------------------------------------------------------------------------------- 1 | import {Rating} from "../models/Rating.js"; 2 | // Rating 3 | export const rating = async(req, res) => { 4 | try { 5 | // Extract fullname, email, and password from the request body 6 | const { username, email, stars,location, eventname } = req.body; 7 | console.log(username,email,stars,location, eventname) 8 | // Check if a user with the given email already exists in the database 9 | const rating = await Rating.findOne({ email }); 10 | console.log(rating) 11 | if (rating) { 12 | // If user already exists, return a 400 Bad Request response with an error message 13 | return res.status(400).json({ message: "Rating already exists" }); 14 | } 15 | 16 | const createdUserRating = new Rating({ 17 | username: username, 18 | email: email, 19 | stars: stars, 20 | location: location, 21 | eventname: eventname 22 | }); 23 | console.log(createdUserRating) 24 | // save for the user database 25 | await createdUserRating.save(); 26 | res.status(201).json({ 27 | message: "Rating created successfully", 28 | rating: { 29 | _id: createdUserRating._id, 30 | email: createdUserRating.email, 31 | stars:createdUserRating.stars, 32 | location: createdUserRating.location, 33 | eventname: createdUserRating.eventname 34 | }, 35 | }); 36 | } catch (error) { 37 | console.log("Error: " + error.message + "coming here 1"); 38 | res.status(500).json({ message: error.message + "coming here"}); 39 | } 40 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eRate Backend 2 | 3 | # Project Title: 4 | eRate 5 | 6 | ## Description 7 | This is a web application which is used to send invitation cards by just one click. By just one click we can send the invitation cards for desired events with the specified date and location 8 | 9 | ## Table of Contents 10 | - [Roadmap](#Roadmap)- 11 | - [WireFrame](#Wireframe)- 12 | - [Technologies Used](#technologies-used) 13 | - [Installation](#installation) 14 | - [Configuration](#configuration) 15 | - [API Documentation](#api-documentation) 16 | - [Testing](#testing) 17 | - [Deployment](#deployment) 18 | - [License](#license) 19 | - [Contact Information](#contact-information) 20 | - [Future Enhacements](#Future-Enhacements) 21 | 22 | ## Roadmap 23 | Used Trello App for project management 24 | 25 | ## WireFrame 26 | pen and paper 27 | 28 | ## Technologies Used 29 | This is a full stack application which is built with using MERN technologies.Backend is built using Mongodb, Express, Nodejs and using REST API 30 | 31 | ## Installation 32 | This is an example of how to list things you need to use the software and how to install them. 33 | * npm 34 | ```sh 35 | npm i express mongodb dotenv cors 36 | 37 | ### Prerequisites 38 | ``` 39 | ### Steps to Install 40 | ```bash 41 | git clone 42 | cd 43 | cd server 44 | npm install 45 | npm init -y 46 | to run the server 47 | nodemon index.js 48 | 49 | #### Configuration 50 | ``` 51 | configure the environment variables before using this code in .env file 52 | ### API Documentation 53 | REST API wit CURD operations 54 | 55 | ### Testing 56 | Tested the integration tests using POSTMAN 57 | 58 | ### Deployment 59 | Netlify is used for the deployment 60 | 61 | ### License 62 | All the copy rights of this application belongs to priya :-) 63 | 64 | ### Contact 65 | https://www.linkedin.com/in/priyavemulamada/ 66 | 67 | ## Future Enhancements 68 | * Upcoming Feature 1: 69 | need to build user's event schema 70 | * Upcoming Feature 2 : 71 | need to build particpant schema 72 | -------------------------------------------------------------------------------- /routes/event.js: -------------------------------------------------------------------------------- 1 | import {Router} from "express" ; 2 | import Event from "../models/Event.js" 3 | 4 | // import {createEvent, addParticipatoEvent, updateParticipant} from "../Controller/event.controller.js" 5 | 6 | const router = new Router(); 7 | // get events 8 | router.get("/", async (req, res, next) => { 9 | try { 10 | const events = await Event.find(); 11 | 12 | if (events) { 13 | res.json({ events }); 14 | } else { 15 | res.json({ message: "No events found" }); 16 | } 17 | } catch (error) { 18 | next(error); 19 | } 20 | }); 21 | 22 | // get events by id 23 | 24 | router.get("/:id", async (req, res, next) => { 25 | try { 26 | const events = await Event.findById(req.params.id); 27 | 28 | if (events) { 29 | res.json({ events }); 30 | } else { 31 | res.json({ message: `No events found with id: ${req.params.id}` }); 32 | } 33 | } catch (error) { 34 | next(error); 35 | } 36 | }); 37 | // ========== post =========== // 38 | router.post("/", async (req, res, next) => { 39 | try { 40 | console.log(req.body); 41 | 42 | const events = await Event.create(req.body); 43 | console.log(events) 44 | if (events) { 45 | res.status(201).json({events }); 46 | } else { 47 | res.status(400).json({ message: "Error creating new Event" }); 48 | } 49 | } catch (error) { 50 | next(error); 51 | } 52 | }); 53 | 54 | //================ put ====================// 55 | router.put("/:id", async (req, res, next) => { 56 | try { 57 | const { id } = req.params; 58 | const { body } = req; 59 | const updatedEvents = await Event.findByIdAndUpdate(id, body, { 60 | new: true, 61 | }); 62 | if (updatedEvents) { 63 | res.json({ updatedEvents }); 64 | } else { 65 | res.json({ message: `Error updating event: ${req.params.id}` }); 66 | } 67 | } catch (error) { 68 | next(error); 69 | } 70 | }); 71 | /** 72 | * DELETE /api/projects/:id 73 | */ 74 | router.delete("/:id", async (req, res, next) => { 75 | try { 76 | const deletedevent = await Project.findByIdAndDelete(req.params.id); 77 | 78 | if (deletedevent) { 79 | res.json({ 80 | message: `deletedevent: ${req.params.id}`, 81 | deletedProject, 82 | }); 83 | } else { 84 | res.json({ message: `Error deleting event: ${req.params.id}` }); 85 | } 86 | } catch (error) { 87 | next(error); 88 | } 89 | }) 90 | 91 | 92 | 93 | export default router; -------------------------------------------------------------------------------- /Controller/event.controller.js: -------------------------------------------------------------------------------- 1 | import Event from "../models/Event.js" 2 | import participant from "../models/Participant.js" 3 | // for creating an event 4 | export const createEvent = async (req,res) => { 5 | try{ 6 | const{ eventname,date,location} = req.body; 7 | const newEvent = new Event({ 8 | eventname,date,location 9 | }); 10 | // Saving the events 11 | const savedEvent = await newEvent.save(); 12 | res.status(201).json({ 13 | message: "Event created successfully", 14 | event: savedEvent 15 | }); 16 | } 17 | 18 | catch (error) { 19 | console.error("Error creating event:", error.message); 20 | res.status(500).json({ message: "Internal server error" }); 21 | } 22 | } 23 | //===================================== Adding the participant =============================== 24 | 25 | export const addParticipatoEvent = async(req, res) => { 26 | try { 27 | const { fullname, email, status } = req.body; 28 | const { eventId } = req.params; 29 | 30 | // Find the event by ID 31 | const event = await Event.findById(eventId); 32 | 33 | if (!event) { 34 | return res.status(404).json({ message: "Event not found" }); 35 | } 36 | 37 | // Create a new participant 38 | const participant = new participant({ 39 | fullname, 40 | email, 41 | status, 42 | event: eventId 43 | 44 | }); 45 | // Save the participant to the database 46 | const savedParticipant = await participant.save(); 47 | 48 | // Add the participant to the event's participants array 49 | event.participants.push(savedParticipant._id); 50 | await event.save(); 51 | 52 | res.status(201).json({ 53 | message: "Participant added to event successfully", 54 | participant: savedParticipant 55 | }); 56 | 57 | } 58 | 59 | 60 | // Error Message 61 | catch (error) { 62 | console.error("Error adding participant to event:", error.message); 63 | res.status(500).json({ message: "Internal server error" }); 64 | } 65 | } 66 | // ================================Updating the participants=============================== 67 | 68 | export const updateParticipant = async(req,res)=>{ 69 | try{ 70 | const {eventId} = req.params; // URL parameters 71 | const { participants} = req.body; // client request participants from request body 72 | 73 | const event = await Event.findById(eventId); 74 | if(!event){ 75 | return res.status(404).json({ message: "Event not found" }); 76 | } 77 | // Update participants (overwrite existing participants or append new ones) 78 | event.participants = participants; 79 | 80 | // Save the updated event 81 | await event.save(); 82 | 83 | res.status(200).json({ message: "Participants updated successfully", event }); 84 | } catch (error) { 85 | console.error("Error updating participants:", error.message); 86 | res.status(500).json({ message: "Internal server error" }); 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /Controller/user.controller.js: -------------------------------------------------------------------------------- 1 | import {User} from "../models/User.js"; 2 | import bcryptjs from "bcryptjs"; // Import bcryptjs library for password hashing and comparison 3 | // SignUp 4 | export const signup = async(req, res) => { 5 | try { 6 | // Extract fullname, email, and password from the request body 7 | const { username, email, password } = req.body; 8 | console.log(username,email,password) 9 | // Check if a user with the given email already exists in the database 10 | const user = await User.findOne({ email }); 11 | console.log(user) 12 | if (user) { 13 | // If user already exists, return a 400 Bad Request response with an error message 14 | return res.status(400).json({ message: "User already exists" }); 15 | } 16 | // Hash the user's password before saving it to the database 17 | // const hashPassword = await bcryptjs.hash(password, 5); 18 | // create the password 19 | const createdUser = new User({ 20 | username: username, 21 | email: email, 22 | password: password, 23 | }); 24 | console.log(createdUser) 25 | // save for the user database 26 | await createdUser.save(); 27 | res.status(201).json({ 28 | message: "User created successfully", 29 | user: { 30 | _id: createdUser._id, 31 | fullname: createdUser.fullname, 32 | email: createdUser.email, 33 | }, 34 | }); 35 | } catch (error) { 36 | console.log("Error: " + error.message); 37 | res.status(500).json({ message: error.message }); 38 | } 39 | }; 40 | 41 | // Login controller function for authenticating a user 42 | export const login = async(req, res) => { 43 | try { 44 | // Extract email and password from the request body 45 | const { email, password } = req.body; 46 | // Find the user by email in the database 47 | // const sample = await User.findOne({ 48 | // username 49 | // }); 50 | 51 | // if (!sample) { 52 | // return res.status(400).json({ message: "Invalid email or password" }); 53 | // } 54 | // saving the User details in user attribute 55 | const user = await User.findOne({ email }); 56 | console.log(user) 57 | if (!user) { 58 | return res.status(400).json({ message: "Invalid email or password" }); 59 | } 60 | 61 | const isMatch = (password == user.password); 62 | if (!user || !isMatch) { 63 | return res.status(400).json({ message: "Invalid username or password" }); 64 | } else { 65 | res.status(200).json({ 66 | message: "Login successful", 67 | user: { 68 | _id: user._id, 69 | email: user.email, 70 | username: user.username 71 | }, 72 | }); 73 | } 74 | } 75 | // Log the error to the server console and return a 500 Internal Server Error response 76 | catch (error) { 77 | console.log("Error: " + error.message); 78 | res.status(500).json({ message: "Internal server error" }); 79 | } 80 | }; --------------------------------------------------------------------------------