Open In App

Expense Tracker (Budget Management) using MERN

Last Updated : 27 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

An Expense Tracker or Budget Management application using the MERN stack (MongoDB, Express, React, Node) is a powerful and versatile solution for individuals or businesses looking to manage their finances effectively. This stack provides a seamless and efficient way to build a full-fledged web application with a robust backend and a dynamic front end. Here’s a brief introduction to creating an Expense Tracker using the MERN stack.

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

EXPENCE-TRACKER-3

Output Preview

Prerequisites:

Approach and Features:

  • User Authentication:
    • Implement user authentication to allow users to securely create accounts and log in.
    • Use techniques like JWT (JSON Web Tokens) for secure token-based authentication.
  • Dashboard:
    • Create an intuitive dashboard where users can get an overview of their financial status.
    • Display charts and graphs to represent income, expenses, and overall budget trends.
  • Expense Tracking:
    • Enable users to add, edit, and delete expenses.
    • Categorize expenses to provide a detailed breakdown of spending patterns.
    • Implement features for recurring expenses to simplify regular budgeting.
  • Budget Planning:
    • Allow users to set budget goals for different categories.
    • Provide notifications or alerts when users exceed predefined budget limits.
  • Transaction History:
    • Maintain a transaction history that users can review and analyze.
    • Implement filters and search options for easy navigation through transaction records.
  • Reports and Analytics:
    • Generate detailed reports and visual analytics to help users understand their financial habits.
    • Use charts and graphs to represent data trends and patterns.
  • Responsive Design:
    • Ensure that the application is accessible and user-friendly on various devices, including desktops, tablets, and mobile phones.
  • Data Security:
    • Implement secure data storage practices, including encryption and regular backups, to protect users’ financial information.

Development Workflow:

  • Backend Development:
    • Set up a Node.js server using Express.js.
    • Connect the server to a MongoDB database to store user data and financial information.
  • Authentication (JWT):
    • Implement user authentication using JSON Web Tokens to secure user accounts.
  • API Development:
    • Create RESTful APIs for managing user accounts, expenses, budgets, and other relevant functionalities.
  • Frontend Development (React.js):
    • Develop a responsive and dynamic user interface using React.js.
    • Utilize state management libraries like Redux for efficient data handling.
  • Integration:
    • Connect the frontend and backend to enable seamless communication between the user interface and the server.
  • Testing:
    • Conduct thorough testing of both the frontend and backend to ensure the application’s reliability and functionality.
  • Deployment:
    • Deploy the application on hosting platforms like Heroku, AWS, or others.
  • Monitoring and Maintenance:
    • Implement monitoring tools and perform regular maintenance to ensure the application’s ongoing performance and security.

Project Structure:

mernstruc

Project Structure

Steps to Create the Expense Tracker Server:

Step 1: Set up React Project using the Command:

npm init -y

Step 2: Installing Required Dependencies.

npm install express mongoose cors

The updated dependencies in package.json file for backend:

"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.2",
"mongoose": "^7.6.5",
}

Example: Below is the code of the backend server. Write the following code in server.js file.

Javascript




//backend
const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
 
const app = express();
const PORT = process.env.PORT || 5000;
 
app.use(cors());
app.use(express.json());
 
// Connect to MongoDB
mongoose.connect(
    {
        useNewUrlParser: true,
        useUnifiedTopology: true,
    }
);
 
const db = mongoose.connection;
db.on("error", (error) => {
    console.error("MongoDB connection error:", error);
});
db.once("open", () => {
    console.log("Connected to MongoDB");
});
 
// Define Expense schema
const expenseSchema = new mongoose.Schema({
    description: { type: String, required: true },
    amount: { type: Number, required: true },
});
 
const Expense = mongoose.model("Expense", expenseSchema);
 
// API routes
app.get("/expenses", async (req, res) => {
    try {
        const expenses = await Expense.find();
        res.json(expenses);
    } catch (error) {
        console.error("Error fetching expenses:", error);
        res.status(500).json({ message: "Internal Server Error" });
    }
});
 
app.post("/expenses", async (req, res) => {
    const { description, amount } = req.body;
 
    try {
        if (!description || !amount) {
            return res
                .status(400)
                .json({ message: "Description and amount are required." });
        }
 
        const newExpense = new Expense({ description, amount });
        await newExpense.save();
        res.json(newExpense);
    } catch (error) {
        console.error("Error saving expense:", error);
        res.status(500).json({ message: "Internal Server Error" });
    }
});
 
// Start the server
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});


Steps to Create the Expense Tracker Client Side:

Step 1: Set up React Project using the Command:

npx create-react-app expense-tracker

Step 2: Navigate to the Project folder using:

cd expense-tracker

Step 3: Install Axios (for making HTTP requests):

npm install axios

The updated dependencies in package.json file for frontend:

"dependencies": {
"axios": "^1.6.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
}

Example: Below is the code example of the frontend.

Javascript




import React, { useState } from 'react';
 
const ExpenseTracker = () => {
    const [balance, setBalance] = useState(0);
    const [transactions, setTransactions] = useState([]);
    const [description, setDescription] = useState('');
    const [amount, setAmount] = useState('');
 
    const addExpense = () => {
        const parsedAmount = parseFloat(amount);
 
        if (isNaN(parsedAmount) || parsedAmount <= 0) {
            alert('Please enter a valid amount.');
            return;
        }
 
        // Update balance
        setBalance(
            (prevBalance) => prevBalance + parsedAmount);
 
        // Add transaction to the list
        setTransactions((prevTransactions) => [
            ...prevTransactions,
            { description, amount: parsedAmount },
        ]);
 
        // Clear form
        setDescription('');
        setAmount('');
    };
 
    return (
        <div className="container">
            <h1>Expense Tracker</h1>
            <div className="balance">
                <h2>
                    Balance: $
                    <span id="balance">
                        {balance.toFixed(2)}
                    </span>
                </h2>
            </div>
            <div className="transactions">
                <h2>Transactions</h2>
                <ul>
                    {
                        transactions
                            .map(
                                (transaction, index) => (
                                    <li key={index}>
                                        {
                                            `${transaction.description}:
                                            $${transaction.amount.toFixed(2)}`
                                        }
                                    </li>
                                ))
                    }
                </ul>
            </div>
            <div className="add-expense">
                <h2>Add Expense</h2>
                <form>
                    <label htmlFor="description">
                        Description:
                    </label>
                    <input
                        type="text"
                        id="description"
                        value={description}
                        onChange={
                            (e) =>
                                setDescription(e.target.value)
                        }
                        required
                    />
                    <label htmlFor="amount">
                        Amount:
                    </label>
                    <input
                        type="number"
                        id="amount"
                        step="0.01"
                        value={amount}
                        onChange={
                            (e) =>
                                setAmount(e.target.value)
                        }
                        required
                    />
                    <button type="button"
                        onClick={addExpense}>
                        Add Expense
                    </button>
                </form>
            </div>
        </div>
    );
};
 
export default ExpenseTracker;


CSS




/* index.css */
body {
    font-family: 'Arial', sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f4f4f4;
}
 
.container {
    max-width: 600px;
    margin: 50px auto;
    background-color: #fff;
    padding: 20px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
 
h1,
h2 {
    text-align: center;
    color: #333;
}
 
.balance {
    margin-bottom: 20px;
}
 
.balance h2 {
    color: #2ecc71;
}
 
.transactions ul {
    list-style: none;
    padding: 0;
}
 
.transactions li {
    margin-bottom: 10px;
    padding: 10px;
    background-color: #ecf0f1;
    border-radius: 5px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
 
.add-expense label,
.add-expense input,
.add-expense button {
    margin-bottom: 10px;
    display: block;
}
 
.add-expense button {
    background-color: #3498db;
    color: #fff;
    padding: 10px;
    border: none;
    cursor: pointer;
    border-radius: 5px;
}
 
.add-expense button:hover {
    background-color: #2980b9;
}


Steps to start server:

npm start and node sverver

Output: Visit http://localhost:3000 in your browser to see the MERN fundraising app in action.

Expense-Tracker---Google-Chrome-2023-12-20-19-08-34

Output of Data saved in database:

expense

Data saved in the db after submission



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads