Open In App

Volunteer Management System using MERN Stack

Last Updated : 22 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will explore the development of a Volunteer Management System using NodeJS and ExpressJS and MongoDB as a database for storing data and performing operations . This project will involve performing basic and advanced calculations to streamline the volunteer management process.

Output Preview: Let us have a look at how the final output will look like.

Screenshot-2024-03-06-105112

Screenshot-2024-03-06-105053

Prerequisites

Project Structure:

VMS(structure)

Steps to create the project:

Server-Side (Node.js and Express):

Step 1: Install Node.js and npm

Step 2: Set Up the Project

mkdir <<name of project>>
cd <<name of project>>

Step 3: Initialize a Node.js Project

npm init -y

Step 4: Install Required Packages

npm install express body-parser cors

Step 5: The server code uses MongoDB as the database. Make sure you have MongoDB installed and running.

npm install mongoose

Step 6: Create the index.js File and to connect to MongoDB (replace ‘your_database_uri’ with your actual MongoDB URI)

Javascript
// server/index.js
const express = require("express");
const cors = require("cors");
const mongoose = require("mongoose");

const app = express();
const port = 5000;

app.use(cors());
app.use(express.json());

// Connect to MongoDB 
// (replace 'your_database_uri' with your actual MongoDB URI)
mongoose.connect("your_database_uri", {
    useNewUrlParser: true,
    useUnifiedTopology: true,
});

// Define a schema for the volunteer model
const volunteerSchema = new mongoose.Schema({
    id: Number,
    name: String,
    event: String,
    date: String,
    startTime: String,
    endTime: String,
    status: String,
});

// Create a Volunteer model based on the schema
const Volunteer = mongoose.model("Volunteer", volunteerSchema);

// Dummy data insertion function
async function insertDummyData() {
    try {
        const dummyData = [
            {
                id: 1,
                name: "User 1",
                event: "Event 1",
                date: "2024-03-05",
                startTime: "09:00",
                endTime: "12:00",
                status: "request",
            },
            {
                id: 2,
                name: "User 2",
                event: "Event 2",
                date: "2024-03-08",
                startTime: "13:00",
                endTime: "16:00",
                status: "request",
            },
            {
                id: 3,
                name: "User 3",
                event: "Event 3",
                date: "2024-03-10",
                startTime: "10:30",
                endTime: "14:30",
                status: "request",
            },
            {
                id: 4,
                name: "User 4",
                event: "Event 4",
                date: "2024-03-12",
                startTime: "08:00",
                endTime: "11:00",
                status: "request",
            },
            {
                id: 5,
                name: "User 5",
                event: "Event 5",
                date: "2024-03-15",
                startTime: "14:00",
                endTime: "17:00",
                status: "request",
            },
        ];

        await Volunteer.insertMany(dummyData);
        console.log("Dummy data inserted successfully");
    } catch (error) {
        console.error("Error inserting dummy data:", error);
    }
}

// Call the dummy data insertion function
insertDummyData();

// Fetch and load volunteer data from the database
app.get("/vols", async (req, res) => {
    try {
        const volunteerRequests = await Volunteer.find();
        res.json(volunteerRequests);
    } catch (error) {
        res.status(500).json({ message: "Internal Server Error" });
    }
});

// Add a new volunteer
app.post("/addVolunteer", async (req, res) => {
    const newVolunteer = req.body;
    newVolunteer.status = "request";

    try {
        await Volunteer.create(newVolunteer);
        res.json({ message: "Volunteer added successfully" });
    } catch (error) {
        res.status(500).json({ message: "Internal Server Error" });
    }
});

// Approve a volunteer
app.post("/approveVolunteer", async (req, res) => {
    const volunteerId = req.body.id;

    try {
        const result = await Volunteer.updateOne(
            { id: volunteerId },
            { status: "approved" }
        );

        if (result.nModified === 1) {
            res.json({ message: "Volunteer approved successfully" });
        } else {
            res.status(404).json({ message: "Volunteer not found" });
        }
    } catch (error) {
        res.status(500).json({ message: "Internal Server Error" });
    }
});

app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});

Step 6: Open web-browser and type the following URL

http://localhost:5000/vols

Run the Server

node index.js

FRONTEND(REACT based)

Step 1: Create a new React app:

npx create-react-app <<Name_of_project>>
cd <<Name_of_project>>

Step 2:Install Axios to make HTTP requests:

npm install axios

Step 3:

  • Replace the contents of src/App.js with the following:
  • Create a new file src/Navbar.js with the following content:
  • Create index.css and App.css for styling
CSS
/*App.css*/
body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
  }
  
  .App {
    text-align: center;
  }
  
  .navbar {
    background-color: #333;
    color: white;
    padding: 1em;
    text-align: center;
  }
  
  .hero-section {
    display: flex;
  }
  
  .buttons {
    width: 30%;
    background-color: #f0f0f0;
    padding: 1em;
    border-right: 1px solid #ccc;
  }
  
  button {
    display: block;
    width: 100%;
    padding: 0.5em;
    margin-bottom: 1em;
    background-color: #3498db;
    color: white;
    border: none;
    cursor: pointer;
  }
  
  .data-display {
    flex-grow: 1;
    padding: 1em;
  }
  
  form {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  
  form label, form input, form button {
    margin-bottom: 1em;
  }
  
CSS
/*index.css*/

.navbar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px;
    background-color: #3498db;
    color: white;
  }
  
  .volunteer-request-btn {
    background-color: #2ecc71;
    color: white;
    padding: 10px;
    cursor: pointer;
    border: none;
    border-radius: 5px;
  }
  
  /* src/Home.css */
  
  .home {
    margin: 20px;
  }
  
  .volunteer-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 20px;
  }
  
  .volunteer-item {
    background-color: #ecf0f1;
    padding: 15px;
    border-radius: 5px;
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
  }
  
Javascript
// App.js
import React, { useState, useEffect } from "react";
import "./App.css";
import AddVolunteerForm from "./AddVolunteerForm";
import VolunteerRequests from "./VolunteerRequests";

const App = () => {
    const [volunteerData, setVolunteerData] = useState([]);
    const [currentSection, setCurrentSection] = useState("");

    useEffect(() => {
        fetchVolunteerData();
    }, []);

    const fetchVolunteerData = async () => {
        try {
            const response = await fetch("http://localhost:5000/vols", {
                headers: {
                    Authorization: localStorage.getItem("token"),
                },
            });

            if (!response.ok) {
                throw new Error("Failed to fetch volunteer data");
            }

            const data = await response.json();
            setVolunteerData(data);
        } catch (error) {
            console.error("Error:", error);
        }
    };

    const openAddVolunteerForm = () => {
        setCurrentSection("addVolunteer");
    };

    const loadVolunteerRequests = () => {
        setCurrentSection("volunteerRequests");
    };

    const handleApprove = async (volunteerId) => {
        try {
            const approveResponse = await fetch(
                "http://localhost:5000/approveVolunteer",
                {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                        Authorization: localStorage.getItem("token"),
                    },
                    body: JSON.stringify({ id: volunteerId }),
                }
            );

            if (!approveResponse.ok) {
                throw new Error("Failed to approve volunteer");
            }

            await fetchVolunteerData();
        } catch (error) {
            console.error("Error:", error);
        }
    };

    const handleRemoveFromRequests = async (volunteerId) => {
        try {
            const response = await fetch(
                "http://localhost:5000/removeFromRequests",
                {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                        Authorization: localStorage.getItem("token"),
                    },
                    body: JSON.stringify({ id: volunteerId }),
                }
            );

            if (!response.ok) {
                throw new Error(`Failed to remove 
                                 volunteer from requests`);
            }

            await fetchVolunteerData();
        } catch (error) {
            console.error("Error:", error);
        }
    };

    return (
        <div className="App">
            <div className="navbar">
                <h1>Volunteer Management System</h1>
            </div>

            <div className="hero-section">
                <div className="buttons">
                    <button onClick={openAddVolunteerForm}>
                        Add Volunteer
                    </button>
                    <button onClick={loadVolunteerRequests}>
                        Volunteer Requests
                    </button>
                </div>

                <div className="data-display">
                    {currentSection === "addVolunteer" && (
                        <AddVolunteerForm
                            fetchVolunteerData={fetchVolunteerData}
                        />
                    )}
                    {currentSection === "volunteerRequests" && (
                        <VolunteerRequests
                            volunteerData={volunteerData}
                            setVolunteerData={setVolunteerData}
                            handleApprove={handleApprove}
                            handleRemoveFromRequests=
                                    {handleRemoveFromRequests}
                        />
                    )}
                </div>
            </div>
        </div>
    );
};

export default App;
Javascript
//AddVolunteerForm.js
import React, { useState } from "react";

const AddVolunteerForm = ({ fetchVolunteerData }) => {
    const [formData, setFormData] = useState({
        name: "",
        event: "",
        date: "",
    });

    const handleChange = (e) => {
        setFormData({
            ...formData,
            [e.target.name]: e.target.value,
        });
    };

    const handleSubmit = async (e) => {
        e.preventDefault();

        try {
            const response = await fetch(
`http://localhost:5000/addVolunteer`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(formData),
            });

            if (!response.ok) {
                throw new Error("Failed to add volunteer");
            }

            await fetchVolunteerData();

            setFormData({
                name: "",
                event: "",
                date: "",
            });
        } catch (error) {
            console.error("Error:", error);
        }
    };

    return (
        <div>
            <h2>Add Volunteer</h2>
            <form onSubmit={handleSubmit}>
                <label>
                    Name:
                    <input
                        type="text"
                        name="name"
                        value={formData.name}
                        onChange={handleChange}
                    />
                </label>
                <br />
                <label>
                    Event:
                    <input
                        type="text"
                        name="event"
                        value={formData.event}
                        onChange={handleChange}
                    />
                </label>
                <br />
                <label>
                    Date:
                    <input
                        type="text"
                        name="date"
                        value={formData.date}
                        onChange={handleChange}
                    />
                </label>
                <br />
                <button type="submit">Submit</button>
            </form>
        </div>
    );
};

export default AddVolunteerForm;
Javascript
//VolunteerRequests.js

import React, { useEffect } from "react";

const VolunteerRequests = ({ volunteerData, setVolunteerData }) => {
    const handleApprove = async (volunteerId) => {
        try {
            const response = await fetch(
                "http://localhost:5000/approveVolunteer",
                {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/json",
                    },
                    body: JSON.stringify({ id: volunteerId }),
                }
            );

            if (!response.ok) {
                throw new Error("Failed to approve volunteer");
            }

            const updatedVolunteerData = await response.json();
            setVolunteerData(updatedVolunteerData);
        } catch (error) {
            console.error("Error:", error);
        }
    };

    useEffect(() => {
        fetchVolunteerData();
    }, [volunteerData]);

    const fetchVolunteerData = async () => {
        try {
            const response = await fetch("http://localhost:5000/vols");
            if (!response.ok) {
                throw new Error("Failed to fetch volunteer data");
            }
            const data = await response.json();
            setVolunteerData(data);
        } catch (error) {
            console.error("Error:", error);
        }
    };

    return (
        <div>
            <h2>Volunteer Requests</h2>
            <ul>
                {Array.isArray(volunteerData) && volunteerData.length > 0 ? (
                    volunteerData.map((volunteer) => (
                        <li key={volunteer.id}>
                            {volunteer.name} - {volunteer.event} -{" "}
                            {volunteer.date} - Status: {volunteer.status}
                            {volunteer.status === "request" && (
                                <button
                                    onClick={
                                        ()=>handleApprove(volunteer.id)
                                     }
                                >
                                    Approve
                                </button>
                            )}
                        </li>
                    ))
                ) : (
                    <p>No volunteer requests available.</p>
                )}
            </ul>
        </div>
    );
};

export default VolunteerRequests;
Javascript
// src/navbar.js
import React from 'react';

const Navbar = () => {
  return <div className="navbar">Volunteer Management System</div>;
};

export default Navbar;

Output:

vms

Volunteer Management System



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads