diff --git a/financial-tracker/api-gateway/app/app.py b/financial-tracker/api-gateway/app/app.py
index a98550772383027c587b9eb45c45d37e75212103..67d640d46436493486b5925f70776080adfc7d61 100644
--- a/financial-tracker/api-gateway/app/app.py
+++ b/financial-tracker/api-gateway/app/app.py
@@ -14,6 +14,7 @@ CORS(app, resources={r"/*": {"origins": "http://localhost:3000"}})
 # Configuration
 USER_SERVICE_URL = os.getenv('USER_SERVICE_URL', 'http://user-service:5001')
 TRANSACTION_SERVICE_URL = os.getenv("TRANSACTION_SERVICE_URL", "http://transaction-service:5002")
+BUDGET_SERVICE_URL = os.getenv('BUDGET_SERVICE_URL', 'http://budget-service:5003')
 app.config["JWT_SECRET_KEY"] = os.getenv(
     "JWT_SECRET_KEY", "3b5e41af18179f530c5881a5191e15f0ab35eed2fefdc068fda254eed3fb1ecb"
 )
@@ -187,6 +188,21 @@ def delete_expense(expense_id):
     except requests.exceptions.RequestException as e:
         app.logger.error(f"Error contacting transaction-service: {e}")
         return jsonify({"error": "Transaction service unavailable"}), 503
+ 
+
+@app.route('/expenses/monthly', methods=['GET'])
+@jwt_required()
+def get_monthly_expenses():
+    """Forward request to the monthly expenses endpoint."""
+    token = request.headers.get("Authorization")
+    if not token:
+        return jsonify({"error": "Missing authorization token"}), 401
+
+    # Forward the request to the actual expense service
+    response = requests.get(f"{TRANSACTION_SERVICE_URL}/expenses/monthly", headers={"Authorization": token})
+
+    # Return the response back to the client
+    return jsonify(response.json()), response.status_code
 
 
 @app.route('/categories', methods=['GET'])
@@ -214,5 +230,104 @@ def fetch_categories():
         return jsonify({"error": "Transaction service unavailable"}), 503
 
 
+@app.route('/budgets', methods=['POST'])
+@jwt_required()
+def add_budget():
+    """Forward request to budget-service to add a budget."""
+    token = request.headers.get("Authorization")  # Get token from headers
+
+    if not token:
+        app.logger.error("Authorization token is missing.")
+        return jsonify({"error": "Authorization token is missing"}), 400
+
+    try:
+        headers = {"Authorization": token, "Content-Type": "application/json"}
+        data = request.get_json()
+        app.logger.info(f"Forwarding budget addition request: {data}")
+
+        response = requests.post(f"{BUDGET_SERVICE_URL}/budgets", headers=headers, json=data)
+        return jsonify(response.json()), response.status_code
+
+    except requests.exceptions.RequestException as e:
+        app.logger.error(f"Error contacting budget-service: {e}")
+        return jsonify({"error": "Budget service unavailable"}), 503
+    
+
+@app.route('/budgets/<int:budget_id>', methods=['PUT'])
+@jwt_required()
+def edit_budget(budget_id):
+    """Forward request to budget-service to edit a budget."""
+    token = request.headers.get("Authorization")  # Get token from headers
+
+    if not token:
+        app.logger.error("Authorization token is missing.")
+        return jsonify({"error": "Authorization token is missing."}), 400
+
+    try:
+        headers = {"Authorization": token, "Content-Type": "application/json"}
+        data = request.get_json()
+        
+        app.logger.info(f"Forwarding budget update request for ID {budget_id}: {data}")
+
+        response = requests.put(f"{BUDGET_SERVICE_URL}/budgets/{budget_id}", headers=headers, json=data)
+        return jsonify(response.json()), response.status_code
+
+    except requests.exceptions.RequestException as e:
+        app.logger.error(f"Error contacting budget-service: {e}")
+        return jsonify({"error": "Budget service unavailable."}), 503
+    
+
+@app.route('/budgets/<int:budget_id>', methods=['DELETE'])
+@jwt_required()
+def delete_budget(budget_id):
+    """Forward request to budget-service to delete a budget."""
+    token = request.headers.get("Authorization")  # Get token from headers
+
+    if not token:
+        app.logger.error("Authorization token is missing.")
+        return jsonify({"error": "Authorization token is missing."}), 400
+
+    try:
+        headers = {"Authorization": token}  # Forward token
+        response = requests.delete(f"{BUDGET_SERVICE_URL}/budgets/{budget_id}", headers=headers)
+
+        if response.status_code == 200:
+            app.logger.info(f"Budget with ID {budget_id} deleted successfully.")
+            return jsonify({"message": "Budget deleted successfully."}), 200
+        else:
+            app.logger.error(f"Failed to delete budget with ID {budget_id}.")
+            return jsonify({"error": "Failed to delete budget."}), response.status_code
+
+    except requests.exceptions.RequestException as e:
+        app.logger.error(f"Error contacting budget-service: {e}")
+        return jsonify({"error": "Budget service unavailable."}), 503
+    
+
+@app.route('/budgets', methods=['GET'])
+@jwt_required()
+def fetch_budgets():
+    """Forward request to budget-service to fetch budgets for the logged-in user."""
+    token = request.headers.get("Authorization")  # Get token from headers
+
+    if not token:
+        app.logger.error("Authorization token is missing.")
+        return jsonify({"error": "Authorization token is missing."}), 400
+
+    try:
+        headers = {"Authorization": token}  # Forward token
+        response = requests.get(f"{BUDGET_SERVICE_URL}/budgets", headers=headers)
+
+        if response.status_code == 200:
+            app.logger.info("Successfully fetched budgets.")
+            return jsonify(response.json()), response.status_code
+        else:
+            app.logger.error(f"Failed to fetch budgets: {response.status_code}")
+            return jsonify({"error": "Failed to fetch budgets"}), response.status_code
+
+    except requests.exceptions.RequestException as e:
+        app.logger.error(f"Error contacting budget-service: {e}")
+        return jsonify({"error": "Budget service unavailable"}), 503
+    
+
 if __name__ == '__main__':
     app.run(host='0.0.0.0', port=8000, debug=True)
diff --git a/financial-tracker/budget-service/app/app.py b/financial-tracker/budget-service/app/app.py
index 94dd4d9890fdafbaecea6a295c0ab7cf5a9a6f8d..7b6122766d3fb2e896eceb2f8b4e28368a8b88c0 100644
--- a/financial-tracker/budget-service/app/app.py
+++ b/financial-tracker/budget-service/app/app.py
@@ -1,10 +1,221 @@
+from datetime import datetime, timedelta
 from flask import Flask, jsonify, request
+from flask_cors import CORS
+from flask_jwt_extended import (
+    jwt_required, get_jwt_identity, JWTManager
+)
+from flask_sqlalchemy import SQLAlchemy
+import logging
+import os
 
+# Initialise Flask app
 app = Flask(__name__)
+app.debug = True
+CORS(app)
 
+# Configure logging
+logging.basicConfig(level=logging.INFO)
+app.logger.setLevel(logging.INFO)
+
+# Configuration
+app.config["SQLALCHEMY_DATABASE_URI"] = os.getenv(
+    "DATABASE_URL", "postgresql://user:password@budget-db:5432/budget_db"
+)
+app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
+app.config["JWT_SECRET_KEY"] = os.getenv(
+    "JWT_SECRET_KEY", "3b5e41af18179f530c5881a5191e15f0ab35eed2fefdc068fda254eed3fb1ecb"
+)
+app.config["JWT_ACCESS_TOKEN_EXPIRES"] = timedelta(hours=1)
+app.config["JWT_TOKEN_LOCATION"] = ["headers"]
+app.config["JWT_HEADER_NAME"] = "Authorization"  # Default header for JWT
+app.config["JWT_HEADER_TYPE"] = "Bearer" 
+
+# Initialise Flask-JWT-Extended & SQLAlchemy
+jwt = JWTManager(app)
+db = SQLAlchemy(app)
+
+# DATABASE MODELS
+class Budget(db.Model):
+    id = db.Column(db.Integer, primary_key=True)
+    user_id = db.Column(db.Integer, nullable=False)
+    category = db.Column(db.String(100), nullable=False)
+    budget_limit = db.Column(db.Float, nullable=False)
+    spent = db.Column(db.Float, default=0.0)
+
+    def to_dict(self):
+        return {
+            "id": self.id,
+            "user_id": self.user_id,
+            "category": self.category,
+            "budget_limit": self.budget_limit,
+            "spent": self.spent
+        }
+
+
+# BUDGET ROUTES
 @app.route('/budgets', methods=['GET'])
+@jwt_required()
 def get_budgets():
-    return jsonify({"message": "Budget service active"}), 200
+    """Retrieve all budgets for the logged-in user"""
+    try:
+        user_id = get_jwt_identity()  # Extract user_id from JWT token
+        user_id = int(user_id)
+        app.logger.info(f"Retrieved user_id from JWT: {user_id}")  # Log user_id
+
+        if not user_id:
+            app.logger.error("User ID is None or invalid.")
+            return jsonify({"error": "Invalid user authentication"}), 401
+
+        budgets = Budget.query.filter_by(user_id=user_id).all()
+        app.logger.info(f"Found {len(budgets)} budgets for user_id {user_id}")
+
+        budgets_list = [budget.to_dict() for budget in budgets]
+        return jsonify({"budgets": budgets_list}), 200
+
+    except Exception as e:
+        app.logger.error(f"Error retrieving budgets: {e}", exc_info=True)
+        return jsonify({"error": "An error occurred while fetching budgets"}), 500
+
+
+@app.route('/budgets', methods=['POST'])
+@jwt_required()
+def add_budget():
+    """Add a new budget for the logged-in user"""
+    data = request.get_json()
+    app.logger.info(f"Received data: {data}")
+
+    # Required fields check
+    required_fields = ["category", "budget_limit"]
+    missing_fields = [field for field in required_fields if field not in data]
+
+    if missing_fields:
+        app.logger.error(f"Missing required fields: {missing_fields}")
+        return jsonify({"error": f"Missing required fields: {', '.join(missing_fields)}"}), 400
+
+    # Validate budget limit
+    try:
+        budget_limit = float(data["budget_limit"])
+        if budget_limit <= 0:
+            app.logger.error("Budget limit must be greater than 0.")
+            return jsonify({"error": "Budget limit must be a positive number."}), 400
+    except (ValueError, TypeError):
+        app.logger.error("Invalid budget limit value.")
+        return jsonify({"error": "Invalid budget limit value."}), 400
+
+    try:
+        user_id = get_jwt_identity()
+        user_id = int(user_id)
+        app.logger.info(f"User ID: {user_id}")
+
+        if not user_id:
+            app.logger.error("User ID is missing or invalid.")
+            return jsonify({"error": "User authentication failed."}), 401
+
+        # Create a new budget object
+        new_budget = Budget(
+            user_id=user_id,
+            category=data["category"],
+            budget_limit=budget_limit
+        )
+
+        # Add budget to the database
+        db.session.add(new_budget)
+        db.session.commit()
+
+        app.logger.info(f"Budget added: {new_budget.to_dict()}")
+        return jsonify({"message": "Budget added", "budget": new_budget.to_dict()}), 201
+
+    except Exception as e:
+        app.logger.error(f"Error while adding budget: {str(e)}", exc_info=True)
+        return jsonify({"error": "An error occurred while adding the budget."}), 500
+
+
+@app.route('/budgets/<int:budget_id>', methods=['PUT'])
+@jwt_required()
+def edit_budget(budget_id):
+    """Edit a budget by ID for the logged-in user"""
+    try:
+        user_id = get_jwt_identity()
+        user_id = int(user_id)
+        app.logger.info(f"User ID: {user_id}")
+
+        if not user_id:
+            app.logger.error("User ID is missing or invalid.")
+            return jsonify({"error": "User authentication failed"}), 401
+
+        budget = Budget.query.filter_by(id=budget_id, user_id=user_id).first()
+
+        if not budget:
+            app.logger.error(f"Budget not found for ID {budget_id} and User ID {user_id}")
+            return jsonify({"error": "Budget not found"}), 404
+
+        data = request.json
+        app.logger.info(f"Received data: {data}")
+
+        # Update fields
+        budget.category = data.get("category", budget.category)  # update category
+        try:
+            new_budget_limit = float(data["budget_limit"])  # Ensure budget limit is a float
+            if new_budget_limit <= 0:
+                app.logger.error("Budget limit must be greater than 0.")
+                return jsonify({"error": "Budget limit must be a positive number."}), 400
+            budget.budget_limit = new_budget_limit  # Update budget limit
+        except (ValueError, TypeError):
+            app.logger.error("Invalid budget limit value.")
+            return jsonify({"error": "Invalid budget limit value."}), 400
+
+        db.session.commit()
+
+        app.logger.info(f"Budget updated: {budget.to_dict()}")
+        return jsonify({"message": "Budget updated successfully", "budget": budget.to_dict()}), 200
+
+    except Exception as e:
+        app.logger.error(f"Error updating budget: {str(e)}", exc_info=True)
+        return jsonify({"error": "An error occurred while updating the budget"}), 500
+
+
+@app.route('/budgets/<int:budget_id>', methods=['DELETE'])
+@jwt_required()
+def delete_budget(budget_id):
+    """Delete a budget by ID for the logged-in user"""
+    try:
+        user_id = get_jwt_identity()
+        user_id = int(user_id)
+        app.logger.info(f"User ID: {user_id}")
+
+        if not user_id:
+            app.logger.error("User ID is missing or invalid.")
+            return jsonify({"error": "User authentication failed"}), 401
+
+        budget = Budget.query.filter_by(id=budget_id, user_id=user_id).first()
+
+        if not budget:
+            app.logger.error(f"Budget not found for ID {budget_id} and User ID {user_id}")
+            return jsonify({"error": "Budget not found"}), 404
+
+        db.session.delete(budget)
+        db.session.commit()
+
+        app.logger.info(f"Budget deleted: {budget.to_dict()}")
+        return jsonify({"message": "Budget deleted successfully"}), 200
+
+    except Exception as e:
+        app.logger.error(f"Error deleting budget: {str(e)}", exc_info=True)
+        return jsonify({"error": "An error occurred while deleting the budget"}), 500
+    
+
+# HEALTH CHECK ROUTE
+@app.route('/health')
+def health():
+    """Health check endpoint to verify service is running."""
+    app.logger.info("Health check requested")
+    return jsonify({"status": "Budget service is running"}), 200
+
 
+# INITIALIZATION & RUNNING APP
 if __name__ == '__main__':
+    # Create all tables in the database (if they don't exist)
+    with app.app_context():
+        db.create_all()  # Creates the tables for all models
+    app.logger.info("Starting Budget Service...")
     app.run(host='0.0.0.0', port=5003)
diff --git a/financial-tracker/docker-compose.yml b/financial-tracker/docker-compose.yml
index 130d285ac21641f15e5d5bb625cbec6b3a850247..04833088ae3ec4398cbd74ee74285a133f37efb6 100644
--- a/financial-tracker/docker-compose.yml
+++ b/financial-tracker/docker-compose.yml
@@ -65,6 +65,10 @@ services:
       - budget-db
     networks:
       - app-network
+    healthcheck:
+      test: ["CMD", "curl", "-f", "http://localhost:5003/health"]
+      interval: 30s
+      retries: 3
 
   analytics-service:
     build:
diff --git a/financial-tracker/frontend/package-lock.json b/financial-tracker/frontend/package-lock.json
index d109621253c524b888e4c90e15211c45de14c131..dee52157b450d06e5b5d8f23863adb289323aa3d 100644
--- a/financial-tracker/frontend/package-lock.json
+++ b/financial-tracker/frontend/package-lock.json
@@ -22,6 +22,7 @@
         "react-paginate": "^8.3.0",
         "react-router-dom": "^7.4.0",
         "react-scripts": "5.0.1",
+        "recharts": "^2.15.2",
         "web-vitals": "^2.1.4",
         "yup": "^1.6.1"
       }
@@ -3671,6 +3672,69 @@
       "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
       "license": "MIT"
     },
+    "node_modules/@types/d3-array": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
+      "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==",
+      "license": "MIT"
+    },
+    "node_modules/@types/d3-color": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
+      "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
+      "license": "MIT"
+    },
+    "node_modules/@types/d3-ease": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
+      "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
+      "license": "MIT"
+    },
+    "node_modules/@types/d3-interpolate": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
+      "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/d3-color": "*"
+      }
+    },
+    "node_modules/@types/d3-path": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
+      "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
+      "license": "MIT"
+    },
+    "node_modules/@types/d3-scale": {
+      "version": "4.0.9",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
+      "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/d3-time": "*"
+      }
+    },
+    "node_modules/@types/d3-shape": {
+      "version": "3.1.7",
+      "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz",
+      "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/d3-path": "*"
+      }
+    },
+    "node_modules/@types/d3-time": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",
+      "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
+      "license": "MIT"
+    },
+    "node_modules/@types/d3-timer": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
+      "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
+      "license": "MIT"
+    },
     "node_modules/@types/eslint": {
       "version": "8.56.12",
       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.12.tgz",
@@ -5710,6 +5774,15 @@
         "wrap-ansi": "^7.0.0"
       }
     },
+    "node_modules/clsx": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+      "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/co": {
       "version": "4.6.0",
       "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@@ -6446,6 +6519,127 @@
       "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
       "license": "MIT"
     },
+    "node_modules/d3-array": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+      "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+      "license": "ISC",
+      "dependencies": {
+        "internmap": "1 - 2"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-color": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+      "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-ease": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+      "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-format": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+      "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-interpolate": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+      "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+      "license": "ISC",
+      "dependencies": {
+        "d3-color": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-path": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+      "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-scale": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+      "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+      "license": "ISC",
+      "dependencies": {
+        "d3-array": "2.10.0 - 3",
+        "d3-format": "1 - 3",
+        "d3-interpolate": "1.2.0 - 3",
+        "d3-time": "2.1.1 - 3",
+        "d3-time-format": "2 - 4"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-shape": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+      "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
+      "license": "ISC",
+      "dependencies": {
+        "d3-path": "^3.1.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-time": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
+      "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
+      "license": "ISC",
+      "dependencies": {
+        "d3-array": "2 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-time-format": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+      "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+      "license": "ISC",
+      "dependencies": {
+        "d3-time": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-timer": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+      "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/damerau-levenshtein": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -6540,6 +6734,12 @@
       "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==",
       "license": "MIT"
     },
+    "node_modules/decimal.js-light": {
+      "version": "2.5.1",
+      "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
+      "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
+      "license": "MIT"
+    },
     "node_modules/dedent": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
@@ -6772,6 +6972,16 @@
         "utila": "~0.4"
       }
     },
+    "node_modules/dom-helpers": {
+      "version": "5.2.1",
+      "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
+      "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.8.7",
+        "csstype": "^3.0.2"
+      }
+    },
     "node_modules/dom-serializer": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
@@ -8003,6 +8213,15 @@
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
       "license": "MIT"
     },
+    "node_modules/fast-equals": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.2.2.tgz",
+      "integrity": "sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
     "node_modules/fast-glob": {
       "version": "3.3.3",
       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
@@ -9399,6 +9618,15 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/internmap": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+      "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+      "license": "ISC",
+      "engines": {
+        "node": ">=12"
+      }
+    },
     "node_modules/ipaddr.js": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz",
@@ -14232,6 +14460,37 @@
         }
       }
     },
+    "node_modules/react-smooth": {
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz",
+      "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==",
+      "license": "MIT",
+      "dependencies": {
+        "fast-equals": "^5.0.1",
+        "prop-types": "^15.8.1",
+        "react-transition-group": "^4.4.5"
+      },
+      "peerDependencies": {
+        "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+        "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+      }
+    },
+    "node_modules/react-transition-group": {
+      "version": "4.4.5",
+      "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
+      "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "@babel/runtime": "^7.5.5",
+        "dom-helpers": "^5.0.1",
+        "loose-envify": "^1.4.0",
+        "prop-types": "^15.6.2"
+      },
+      "peerDependencies": {
+        "react": ">=16.6.0",
+        "react-dom": ">=16.6.0"
+      }
+    },
     "node_modules/read-cache": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -14267,6 +14526,44 @@
         "node": ">=8.10.0"
       }
     },
+    "node_modules/recharts": {
+      "version": "2.15.2",
+      "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.2.tgz",
+      "integrity": "sha512-xv9lVztv3ingk7V3Jf05wfAZbM9Q2umJzu5t/cfnAK7LUslNrGT7LPBr74G+ok8kSCeFMaePmWMg0rcYOnczTw==",
+      "license": "MIT",
+      "dependencies": {
+        "clsx": "^2.0.0",
+        "eventemitter3": "^4.0.1",
+        "lodash": "^4.17.21",
+        "react-is": "^18.3.1",
+        "react-smooth": "^4.0.4",
+        "recharts-scale": "^0.4.4",
+        "tiny-invariant": "^1.3.1",
+        "victory-vendor": "^36.6.8"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "peerDependencies": {
+        "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+        "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+      }
+    },
+    "node_modules/recharts-scale": {
+      "version": "0.4.5",
+      "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz",
+      "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==",
+      "license": "MIT",
+      "dependencies": {
+        "decimal.js-light": "^2.4.1"
+      }
+    },
+    "node_modules/recharts/node_modules/react-is": {
+      "version": "18.3.1",
+      "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+      "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+      "license": "MIT"
+    },
     "node_modules/recursive-readdir": {
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz",
@@ -16329,6 +16626,12 @@
       "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
       "license": "MIT"
     },
+    "node_modules/tiny-invariant": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
+      "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
+      "license": "MIT"
+    },
     "node_modules/tiny-warning": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
@@ -16864,6 +17167,28 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/victory-vendor": {
+      "version": "36.9.2",
+      "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz",
+      "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==",
+      "license": "MIT AND ISC",
+      "dependencies": {
+        "@types/d3-array": "^3.0.3",
+        "@types/d3-ease": "^3.0.0",
+        "@types/d3-interpolate": "^3.0.1",
+        "@types/d3-scale": "^4.0.2",
+        "@types/d3-shape": "^3.1.0",
+        "@types/d3-time": "^3.0.0",
+        "@types/d3-timer": "^3.0.0",
+        "d3-array": "^3.1.6",
+        "d3-ease": "^3.0.1",
+        "d3-interpolate": "^3.0.1",
+        "d3-scale": "^4.0.2",
+        "d3-shape": "^3.1.0",
+        "d3-time": "^3.0.0",
+        "d3-timer": "^3.0.1"
+      }
+    },
     "node_modules/w3c-hr-time": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
diff --git a/financial-tracker/frontend/package.json b/financial-tracker/frontend/package.json
index bf17e4b0261820c73a6d4e022a3e06dffcd2bcdc..d81507da563b72f58c878bd7636a9b6be837ace0 100644
--- a/financial-tracker/frontend/package.json
+++ b/financial-tracker/frontend/package.json
@@ -17,6 +17,7 @@
     "react-paginate": "^8.3.0",
     "react-router-dom": "^7.4.0",
     "react-scripts": "5.0.1",
+    "recharts": "^2.15.2",
     "web-vitals": "^2.1.4",
     "yup": "^1.6.1"
   },
diff --git a/financial-tracker/frontend/src/App.js b/financial-tracker/frontend/src/App.js
index 15b508747874982d406ddce4337af6b06f4de5cd..2cf786b0ff5012f5aa99feb4facdf6bdafcf9859 100644
--- a/financial-tracker/frontend/src/App.js
+++ b/financial-tracker/frontend/src/App.js
@@ -6,6 +6,7 @@ import Register from "./pages/Register";
 import Login from "./pages/Login";
 import Dashboard from "./pages/Dashboard";
 import Expenses from "./pages/Expenses";
+import Budget from "./pages/Budget";
 
 function App() {
   const [token, setToken] = useState(localStorage.getItem("token"));
@@ -34,6 +35,7 @@ function App() {
               <>
                 <li><Link to="/dashboard">Dashboard</Link></li>
                 <li><Link to="/expenses">Expenses</Link></li>
+                <li><Link to="/budget">Budget</Link></li> 
                 <li>
                   <Link to="/" onClick={() => { localStorage.removeItem("token"); setToken(null); }}>
                     Logout
@@ -55,6 +57,7 @@ function App() {
           <Route path="/login" element={<Login setToken={setToken} />} />
           <Route path="/dashboard" element={<Dashboard setToken={setToken} />} />
           <Route path="/expenses" element={<Expenses />} />
+          <Route path="/budget" element={<Budget />} /> 
         </Routes>
       </div>
     </Router>
diff --git a/financial-tracker/frontend/src/pages/Budget.js b/financial-tracker/frontend/src/pages/Budget.js
new file mode 100644
index 0000000000000000000000000000000000000000..090693c83f9d661f27a250c27bc406042418d6f3
--- /dev/null
+++ b/financial-tracker/frontend/src/pages/Budget.js
@@ -0,0 +1,620 @@
+import React, { useState, useEffect } from "react";
+import axios from "axios";
+import { jwtDecode } from 'jwt-decode';
+import ReactPaginate from 'react-paginate';
+import BudgetChart from "./BudgetChart";
+import "../styles/Budget.css";
+
+const Budget = () => {
+  const [budgets, setBudgets] = useState([]);
+  const [isSessionValid, setIsSessionValid] = useState(true);
+  const [filteredBudgets, setFilteredBudgets] = useState([]);
+  const [sortConfig, setSortConfig] = useState({ key: null, direction: "asc" });
+  const budgetsPerPage = 5;
+  const [currentPage, setCurrentPage] = useState(0);
+  const offset = currentPage * budgetsPerPage;
+  const currentBudgets = filteredBudgets.slice(offset, offset + budgetsPerPage);
+  const [newBudget, setNewBudget] = useState({ category: "", budget_limit: "" });
+  const [successMessage, setSuccessMessage] = useState("");
+  const [deleteMessage, setDeleteMessage] = useState("");
+  const [categories, setCategories] = useState([]);
+  const [totalSpent, setTotalSpent] = useState(0);
+  const [totalBudget, setTotalBudget] = useState(0);
+  const [remainingBudget, setRemainingBudget] = useState(0);
+  const [isModalOpen, setIsModalOpen] = useState(false);
+  const [editBudget, setEditBudget] = useState({
+    id: null,
+    category: "",
+    budget_limit: 0.0
+  });
+  const [showFilters, setShowFilters] = useState(false);
+  const [filters, setFilters] = useState({
+    status: "",
+  });
+  const [budgetStatusCounts, setBudgetStatusCounts] = useState({ good: 0, warning: 0, overBudget: 0 });
+  const percentageSpent = ((totalSpent / totalBudget) * 100).toFixed(2);
+
+  const openModal = () => {
+    setIsModalOpen(true);
+  };
+  
+  const closeModal = () => {
+    setIsModalOpen(false);
+  };
+
+  // Check if token exists in localStorage to determine if session is valid
+  useEffect(() => {
+    const token = localStorage.getItem("token");
+
+    if (token) {
+        // Validate the token's expiration date or refresh it if necessary
+        const decoded = jwtDecode(token);
+        const now = new Date();
+        const expirationDate = new Date(decoded.exp * 1000);
+        if (now > expirationDate) {
+            // Token has expired; refresh it or redirect to login page
+            alert("Your session has expired. Please log in again.");
+            window.location.href = "/login";
+        } else {
+            setIsSessionValid(true);
+        }
+    } else {
+        setIsSessionValid(false);
+    }
+  }, []);
+
+  useEffect(() => {
+    const totalBudgetAmount = budgets.reduce((acc, item) => acc + Number(item.budget_limit), 0);
+    const totalSpentAmount = budgets.reduce((acc, item) => acc + Number(item.spent), 0);
+  
+    setTotalBudget(totalBudgetAmount);
+    setTotalSpent(totalSpentAmount);
+    setRemainingBudget(totalBudgetAmount - totalSpentAmount);
+  
+    console.log("Total Budget:", totalBudgetAmount);
+    console.log("Total Spent:", totalSpentAmount);
+    console.log("Remaining Budget:", totalBudgetAmount - totalSpentAmount);
+
+    if (budgets.length > 0) {
+      const statusCounts = calculateBudgetStatus(budgets);
+      setBudgetStatusCounts(statusCounts);
+    }
+  }, [budgets]);  
+
+
+  const fetchBudgets = async () => {
+    try {
+      const token = localStorage.getItem("token");
+  
+      if (!token) {
+        console.error("No token found, user might not be logged in.");
+        return;
+      }
+  
+      const decoded = jwtDecode(token);
+      console.log("Decoded JWT:", decoded);
+
+      // Use 'sub' as user_id
+      const user_id = decoded.sub;
+      if (!user_id) {
+        console.error("User ID is undefined. Check JWT structure.");
+        return;
+      }
+  
+      const response = await axios.get("http://localhost:8000/budgets", {
+        headers: { Authorization: `Bearer ${token}` },
+      });
+  
+      if (Array.isArray(response.data.budgets)) {
+        console.log("Budgets fetched:", response.data.budgets);
+        setBudgets(response.data.budgets);
+        setFilteredBudgets(response.data.budgets);
+        await fetchCurrentMonthExpenses();
+      } else {
+        console.error("Expected an array but got:", response.data);
+        setBudgets([]);
+        setFilteredBudgets([]);
+      }
+    } catch (error) {
+      console.error("Error fetching budgets:", error);
+      setBudgets([]);
+      setFilteredBudgets([]);
+    }
+  };
+
+  const fetchCurrentMonthExpenses = async () => {
+    try {
+      const token = localStorage.getItem("token");
+  
+      if (!token) {
+        console.error("No token found, user might not be logged in.");
+        return;
+      }
+  
+      const response = await axios.get("http://localhost:8000/expenses/monthly", {
+        headers: { Authorization: `Bearer ${token}` },
+      });
+  
+      if (response.status === 200) {
+        console.log("Fetched monthly aggregated expenses:", response.data);
+  
+        const spentMapping = {};
+        let totalSpent = 0;
+  
+        response.data.expenses.forEach((item) => {
+
+          if (!spentMapping[item.category]) {
+              spentMapping[item.category] = 0;
+          }
+          spentMapping[item.category] += item.amount; 
+          totalSpent += item.amount;
+        });
+
+        console.log("Spent mapping after accumulation:", spentMapping);
+  
+
+        setBudgets((prevBudgets) =>
+          prevBudgets.map((budget) => ({
+            ...budget,
+            spent: spentMapping[budget.category] || 0,
+          }))
+        );
+  
+        setFilteredBudgets((prevFiltered) =>
+          prevFiltered.map((budget) => ({
+            ...budget,
+            spent: spentMapping[budget.category] || 0,
+          }))
+        );
+  
+        // Calculate total budget
+        const totalBudget = budgets.reduce((sum, budget) => sum + budget.amount, 0);
+  
+        // Calculate remaining budget
+        const remainingBudget = totalBudget - totalSpent;
+  
+
+        setTotalSpent(totalSpent);
+        setTotalBudget(totalBudget);
+        setRemainingBudget(remainingBudget);
+  
+        console.log("Total Budget:", totalBudget);
+        console.log("Total Spent:", totalSpent);
+        console.log("Remaining Budget:", remainingBudget);
+      }
+    } catch (error) {
+      console.error("Error fetching monthly expenses:", error);
+    }
+  };
+
+  // Only fetch data if session is valid
+  useEffect(() => {
+    if (isSessionValid) {
+      fetchCategories();
+      fetchBudgets();
+      fetchCurrentMonthExpenses();
+    }
+  }, [isSessionValid]);
+  
+  const addBudget = async () => {
+    try {
+      const token = localStorage.getItem("token");
+      if (!token) return console.error("No token found, user might not be logged in.");
+  
+      // Check if the category already exists
+      const categoryExists = budgets.find(b => b.category === newBudget.category);
+      if (categoryExists) {
+        alert("A budget for this category already exists. Please select a different category.");
+        return; // Prevent the addition of the new budget
+      } else {
+        const response = await axios.post("http://localhost:8000/budgets", newBudget, {
+          headers: { Authorization: `Bearer ${token}` },
+        });   
+        if (response.status === 201) {
+          setSuccessMessage("Budget added successfully. Refreshing budget page...");
+          fetchBudgets(); // Refresh the budget list
+          setNewBudget({ category: "", budget_limit: "" }); // Reset input fields
+        }
+      }
+    } catch (error) {
+      console.error("Error adding budget:", error);
+    }
+  };
+
+  const handleEdit = (budget) => {
+    setEditBudget({
+      id: budget.id,
+      category: budget.category,
+      budget_limit: budget.budget_limit
+    });
+    openModal();
+  };
+  
+  const handleSaveEdit = async (e, id) => {
+    e.preventDefault();
+  
+    try {
+      const updatedBudget = {
+        category: editBudget.category,
+        budget_limit: parseFloat(editBudget.budget_limit),
+      };
+  
+      const token = localStorage.getItem("token");
+  
+      const response = await axios.put(
+        `http://localhost:8000/budgets/${id}`,
+        updatedBudget,
+        {
+          headers: {
+            "Content-Type": "application/json",
+            Authorization: `Bearer ${token}`,
+          },
+        }
+      );
+  
+      if (response.status === 200) {
+        setBudgets((prevBudgets) =>
+          prevBudgets.map((budget) =>
+            budget.id === id ? { ...budget, ...updatedBudget } : budget
+          )
+        );
+
+        setFilteredBudgets((prevFiltered) =>
+          prevFiltered.map((budget) =>
+            budget.id === id ? { ...budget, ...updatedBudget } : budget
+          )
+        );
+
+        closeModal();
+        setSuccessMessage("Budget updated successfully. Refreshing budget page...");
+        // Wait 1.5 seconds before refreshing
+        setTimeout(() => {
+          window.location.reload();
+        }, 1500);
+      }
+    } catch (error) {
+      console.error("Error updating budget:", error);
+      alert(`Error updating budget: ${error.response ? error.response.data.error || error.response.data.message : error.message}`);
+    }
+  };
+  
+  const handleDelete = async (id) => {
+    const confirmDelete = window.confirm("Are you sure you want to delete this budget?");
+    
+    if (confirmDelete) {
+      try {
+        const token = localStorage.getItem("token");
+        const response = await axios.delete(`http://localhost:8000/budgets/${id}`, {
+          headers: { Authorization: `Bearer ${token}` },
+        });
+  
+        if (response.status === 200) {
+          setBudgets((prevBudgets) => prevBudgets.filter(budget => budget.id !== id));
+          setDeleteMessage("Budget deleted successfully. Refreshing budget page...");
+          setTimeout(() => {
+            window.location.reload();
+          }, 1500);
+        }
+      } catch (error) {
+        console.error("Error deleting budget:", error);
+        alert("Error deleting budget. Please try again.");
+      }
+    }
+  };
+
+  const fetchCategories = async () => {
+    try {
+      const token = localStorage.getItem("token");
+
+      if (!token) {
+        console.error("No token found, user might not be logged in.");
+        return;
+      }
+
+      const response = await axios.get("http://localhost:8000/categories", {
+        headers: { Authorization: `Bearer ${token}` },
+      });
+
+      console.log("Categories Response:", response.data);
+
+      if (Array.isArray(response.data.categories)) {
+        setCategories(response.data.categories);
+      } else {
+        console.error("Categories data is not in expected format", response.data);
+      }
+    } catch (error) {
+      console.error("Error fetching categories:", error);
+    }
+  };
+
+  const sortData = (key) => {
+    let direction = "asc";
+    if (sortConfig.key === key && sortConfig.direction === "asc") {
+      direction = "desc";
+    }
+    setSortConfig({ key, direction });
+
+    const sortedBudgets = [...budgets].sort((a, b) => {
+      if (a[key] < b[key]) return direction === "asc" ? -1 : 1;
+      if (a[key] > b[key]) return direction === "asc" ? 1 : -1;
+      return 0;
+    });
+
+    setBudgets(sortedBudgets);
+  };
+
+  const handleBudgetChange = (e) => {
+    setNewBudget({ ...newBudget, [e.target.name]: e.target.value });
+  };
+
+  const getStatus = (budget) => {
+    const remaining = budget.budget_limit - budget.spent;
+    if (remaining < 0) return "🔴 Over budget";
+    if (remaining < budget.budget_limit * 0.2) return "🟡 Warning (near limit)";
+    return "🟢 Good";
+  };
+
+  const applyFilters = () => {
+    console.log("Applying filters with current filters:", filters);
+    let filtered = budgets.filter(budget => {
+      const status = getStatus(budget);  
+      return (
+        (!filters.status || status === filters.status)
+      );
+    });
+  
+    setFilteredBudgets(filtered);
+    console.log("Filtered Budgets:", filtered); 
+  };
+  
+  const calculateBudgetStatus = (budgets) => {
+    if (!budgets || budgets.length === 0) {
+      return {
+        good: 0,
+        warning: 0,
+        overBudget: 0,
+      };
+    }
+  
+    const statusCounts = { good: 0, warning: 0, overBudget: 0 };
+  
+    budgets.forEach(budget => {
+      const remaining = budget.budget_limit - budget.spent;
+      if (remaining < 0) {
+        statusCounts.overBudget += 1;
+      } else if (remaining < budget.budget_limit * 0.2) {
+        statusCounts.warning += 1;
+      } else {
+        statusCounts.good += 1;
+      }
+    });
+  
+    return statusCounts;
+  };
+ 
+  return (
+    <div className="budget-container">
+      <h1>Budget</h1>
+
+      {/* Delete Message */}
+      {deleteMessage && <div className="delete-message">{deleteMessage}</div>}
+
+      {/* Success Message */}
+      {successMessage && <div className="success-message">{successMessage}</div>}
+
+      {/* Add/Set Budget Form */}
+      <form onSubmit={addBudget} className="budget-form">
+        <div className="budget-inputs">
+          <div className="input-group">
+            <label htmlFor="category">Category</label>
+            <select
+              name="category"
+              value={newBudget.category}
+              onChange={handleBudgetChange}
+              required
+            >
+              <option value="" disabled>Select a category</option>
+              {categories.map((cat) => (
+                <option key={cat} value={cat}>{cat}</option>
+              ))}
+            </select>
+          </div>
+          <div className="input-group">
+            <label htmlFor="budget_limit">Budget Limit (£)</label>
+            <input
+              type="number"
+              name="budget_limit"
+              placeholder="Budget Limit (£)"
+              value={newBudget.budget_limit}
+              onChange={handleBudgetChange}
+              step="0.01"
+              required
+            />
+          </div>
+        </div>
+        <button type="submit" className="add-budget-btn">Add Budget</button>
+      </form>
+
+    {/* Filter Toggle */}
+    <div className="filter-toggle">
+        <button onClick={() => setShowFilters((prev) => !prev)}>
+          {showFilters ? "Hide Filters" : "Show Filters"}
+        </button>
+      </div>
+
+      {showFilters && (
+        <div className="filter-dropdown">
+          <div className="filter-column">
+            <label htmlFor="status">Budget Status</label>
+            <select
+              id="status"
+              value={filters.status}
+              onChange={(e) => setFilters({ ...filters, status: e.target.value })}
+            >
+              <option value="">All Statuses</option>
+              <option value="🔴 Over budget">🔴 Over budget</option>
+              <option value="🟡 Warning (near limit)">🟡 Warning (near limit)</option>
+              <option value="🟢 Good">🟢 Good</option>
+            </select>
+          </div>
+          <div className="apply-filters-container">
+            <button className="apply-filters-btn" onClick={applyFilters}>
+              Apply Filters
+            </button>
+          </div>
+        </div>
+      )}
+
+
+    {/* Modal Content */}
+    <div className={`modal-overlay ${isModalOpen ? "show" : ""}`}>
+      <div className="modal-content">
+        <h3>Edit Budget</h3>
+        <form onSubmit={(e) => handleSaveEdit(e, editBudget.id)} className="budget-form">
+          <div className="budget-inputs">
+            <div className="input-group">
+              <label htmlFor="category">Category</label>
+              <input
+                type="text"
+                id="category"
+                value={editBudget.category}
+                className="disabled-input"
+                disabled
+              />
+            </div>
+            <div className="input-group">
+              <label htmlFor="budget_limit">Budget Limit (£)</label>
+              <input
+                type="number"
+                id="budget_limit"
+                value={editBudget.budget_limit || ""}
+                onChange={(e) => setEditBudget({ ...editBudget, budget_limit: e.target.value })}
+                step="0.01"
+                required
+              />
+            </div>
+          </div>
+          <button type="submit" className="add-budget-btn">Save Changes</button>
+          <button type="button" className="close-modal-btn" onClick={closeModal}>Cancel</button>
+        </form>
+      </div>
+    </div>
+
+
+    {/* Budget Table once required */}
+    <table className="budget-table">
+      <thead>
+        <tr>
+          <th>Category</th>
+          <th onClick={() => sortData("budget_limit")} className="sortable">
+            Budget (£) {sortConfig.key === "budget_limit" && (sortConfig.direction === "asc" ? "↑" : "↓")}
+          </th>
+          <th onClick={() => sortData("spent")} className="sortable">
+            Spent (£) {sortConfig.key === "spent" && (sortConfig.direction === "asc" ? "↑" : "↓")}
+          </th>
+          <th>Remaining (£)</th>
+          <th>Status</th>
+          <th>Actions</th>
+        </tr>
+      </thead>
+      <tbody>
+      {currentBudgets.length > 0 ? (
+        currentBudgets.map((budget) => {
+          const remaining = (budget.budget_limit - budget.spent).toFixed(2);
+          return (
+            <tr key={budget.id}>
+              <td>{budget.category}</td>
+              <td>£{budget.budget_limit.toFixed(2)}</td>
+              <td>£{budget.spent.toFixed(2)}</td>
+              <td>£{remaining}</td>
+              <td>{getStatus(budget)}</td>
+              <td>
+                <button onClick={() => handleEdit(budget)} className="edit-budget-btn">Edit</button>
+                <button onClick={() => handleDelete(budget.id)}>Delete</button>
+              </td>
+            </tr>
+          );
+        })
+      ) : (
+        <tr>
+          <td colSpan="6" style={{ textAlign: "center" }}>No budgets found.</td>
+        </tr>
+      )}
+    </tbody>
+    </table>
+
+      {/* Pagination */}
+      {budgets.length > 0 && (
+        <ReactPaginate
+          previousLabel={"<< Previous"}
+          nextLabel={"Next >>"}
+          breakLabel={"..."}
+          pageCount={Math.max(1, Math.ceil(budgets.length / budgetsPerPage))}
+          marginPagesDisplayed={2}
+          pageRangeDisplayed={5}
+          onPageChange={(data) => setCurrentPage(data.selected)}
+          containerClassName={"pagination"}
+          activeClassName={"active"}
+        />
+      )}
+
+      {/* Budget Overview Section */}
+      <div className="budget-overview">
+        <h2>Budget Overview</h2>
+        
+        <div className="overview-stats">
+          <div className="stat">
+            <p><strong>Total Budget:</strong> <span className="amount">£{totalBudget.toFixed(2)}</span></p>
+            <small className="description">This is the total amount allocated for your budgeted categories.</small>
+          </div>
+          
+          <div className="stat">
+            <p><strong>Total Spent:</strong> <span className="amount">£{totalSpent.toFixed(2)}</span></p>
+            <small className="description">This reflects the total amount spent across all budget categories.</small>
+          </div>
+          
+          <div className="stat">
+            <p><strong>Remaining Budget:</strong> <span className="amount">£{remainingBudget.toFixed(2)}</span></p>
+            <small className="description">The remaining amount available in your budget.</small>
+          </div>
+
+          <div className="stat">
+            <p><strong>Number of Budget Categories:</strong> <span className="amount">{budgets.length}</span></p>
+            <small className="description">Total number of budget categories currently set.</small>
+          </div>
+
+          <div className="stat">
+            <p><strong>Percentage of Budget Used:</strong> <span className="amount">{percentageSpent}%</span></p>
+            <small className="description">The percentage of the budget that has been spent.</small>
+          </div>
+        </div>
+
+        {/* Budget Status Summary */}
+        <div className="budget-status-summary">
+          <h3>Budget Status Summary</h3>
+          <div className="status-item good">
+            <p><strong>Good Budgets:</strong> <span className="amount">{budgetStatusCounts.good}</span></p>
+            <small className="description">Budgets that are currently under their limit.</small>
+          </div>
+          
+          <div className="status-item warning">
+            <p><strong>Warning Budgets:</strong> <span className="amount">{budgetStatusCounts.warning}</span></p>
+            <small className="description">Budgets that are near their limit (within 20%).</small>
+          </div>
+          
+          <div className="status-item over-budget">
+            <p><strong>Over Budget:</strong> <span className="amount">{budgetStatusCounts.overBudget}</span></p>
+            <small className="description">Budgets that have exceeded their allocated limit.</small>
+          </div>
+        </div>
+      </div>
+      
+      <div className="chart-item">
+        <BudgetChart budgets={budgets} />
+      </div>
+    </div>
+  );
+};
+
+
+export default Budget;
\ No newline at end of file
diff --git a/financial-tracker/frontend/src/pages/BudgetChart.js b/financial-tracker/frontend/src/pages/BudgetChart.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae4a6109c6f541b5772c09b90a8ad1b7eb42c336
--- /dev/null
+++ b/financial-tracker/frontend/src/pages/BudgetChart.js
@@ -0,0 +1,79 @@
+import React from 'react';
+import { Bar } from 'react-chartjs-2';
+import { Chart as ChartJS, CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend } from 'chart.js';
+
+// Register necessary components
+ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend);
+
+const BudgetChart = ({ budgets }) => {
+  // Ensure budgets is provided and is an array
+  if (!budgets || !Array.isArray(budgets) || budgets.length === 0) {
+    console.error("Invalid budgets data provided to BudgetChart:", budgets);
+    return <div>No data available for chart.</div>;
+  }
+
+  // Prepare the data for Chart.js
+  const chartData = {
+    labels: budgets.map(item => item.category), 
+    datasets: [
+      {
+        label: 'Spent',
+        data: budgets.map(item => item.spent || 0), 
+        backgroundColor: '#FF6B6B',
+      },
+      {
+        label: 'Budget',
+        data: budgets.map(item => item.budget_limit || 0),
+        backgroundColor: '#4ECDC4',
+      },
+    ],
+  };
+
+  const options = {
+    responsive: true,
+    plugins: {
+      legend: {
+        position: 'right',
+      },
+      title: {
+        display: true,
+      },
+    },
+    scales: {
+      x: {
+        title: {
+          display: true,
+          text: 'Categories',
+        },
+      },
+      y: {
+        title: {
+          display: true,
+          text: 'Amount Spent', 
+        },
+        beginAtZero: true,
+      },
+    },
+  };
+
+  return (
+    <div className="budget-chart-container">
+      <div className="chart-section">
+        <div className="text-container">
+          <h4>Bar Chart: Budget vs. Spending</h4>
+          <p>
+            This bar chart compares your budgeted amounts against your actual spending.
+            Each pair of bars represents a category, with one bar denoting the budget
+            limit and the other showing the amount spent. This visualisation helps you
+            quickly assess where you're over or under budget.
+          </p>
+        </div>
+        <div className="chart">
+          <Bar data={chartData} options={options} />
+        </div>
+      </div>
+    </div>
+  );
+};
+
+export default BudgetChart;
\ No newline at end of file
diff --git a/financial-tracker/frontend/src/styles/Budget.css b/financial-tracker/frontend/src/styles/Budget.css
new file mode 100644
index 0000000000000000000000000000000000000000..5d4c629a20b99990955625989a367c88fd24cbbf
--- /dev/null
+++ b/financial-tracker/frontend/src/styles/Budget.css
@@ -0,0 +1,378 @@
+/* Budget Container */
+.budget-container {
+  max-width: 900px;
+  margin: 0 auto;
+}
+
+.budget-overview h2 {
+  font-size: 2em;
+  margin-top: 15px;
+  font-weight: bold;
+  text-align: center;
+}
+
+.budget-overview p {
+  font-size: 1.3em;
+  margin-top: 10px;
+  line-height: 1.5;
+  text-align: center;
+}
+
+.budget-overview {
+  padding: 20px;
+  background-color: #f1f1f1;
+  border-radius: 8px;
+  margin-top: 20px;
+}
+
+.overview-stats {
+  display: flex;
+  justify-content: space-between;
+  flex-wrap: wrap;
+  margin-bottom: 15px;
+}
+
+.stat {
+  flex: 1;
+  margin: 10px;
+  padding: 15px;
+  background-color: #ffffff;
+  border: 1px solid #e0e0e0;
+  border-radius: 8px;
+  text-align: center;
+}
+
+.amount {
+  font-size: 1.5em; 
+  color: #4ECDC4; 
+}
+
+.description {
+  color: #666666;
+  font-size: 0.9em;
+}
+
+/* Budget Status Summary */
+.budget-status-summary h3 {
+  font-size: 1.5em;
+  margin-top: 15px;
+  font-weight: bold;
+  text-align: center;
+}
+
+.status-item {
+  margin: 10px 0;
+  padding: 10px;
+  background-color: #ffffff;
+  border: 1px solid #e0e0e0;
+  border-radius: 5px;
+}
+
+.good {
+  border-left: 5px solid #4CAF50; 
+}
+
+.warning {
+  border-left: 5px solid #FFA500; 
+}
+
+.over-budget {
+  border-left: 5px solid #FF6B6B; 
+}
+
+/* Budget Form */
+.budget-form {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 10px;
+  margin-bottom: 20px;
+  padding: 20px;
+  border-radius: 10px;
+  background-color: #f9f9f9;
+  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+}
+
+.budget-inputs {
+  display: flex;
+  justify-content: space-between;
+  gap: 10px;
+  width: 100%;
+}
+
+.input-group {
+  flex: 1;
+  min-width: calc(50% - 5px);
+}
+
+.budget-inputs input,
+.budget-inputs select {
+  padding: 8px;
+  font-size: 14px;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  width: calc(50% - 5px);
+  box-sizing: border-box;
+}
+
+.budget-inputs label {
+  font-weight: bold;
+}
+
+.modal-content .disabled-input {
+  cursor: not-allowed;
+  background-color: #f0f0f0; 
+  pointer-events: none; 
+}
+
+/* Add / Submit Button */
+.add-budget-btn {
+  padding: 10px 15px;
+  font-size: 14px;
+  background-color: #007bff;
+  color: white;
+  border: none;
+  border-radius: 5px;
+  cursor: pointer;
+  margin-top: 20px;
+}
+
+.add-budget-btn:hover {
+  background-color: #0056b3;
+}
+
+/* Input and select styling for filter section */
+.filter-column label {
+  font-size: 14px;
+  font-weight: bold;
+  margin-bottom: 5px;
+}
+
+.filter-column select,
+.filter-column input {
+  width: 100%;
+  padding: 8px;
+  font-size: 14px;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  box-sizing: border-box;
+  background-color: #f8f8f8;
+}
+
+/* Styling the dropdown with a pointer cursor */
+.filter-column select {
+  cursor: pointer;
+}
+
+/* Apply Filters Button Container */
+.apply-filters-container {
+  width: 100%;
+  display: flex;
+  justify-content: center;
+}
+
+/* Styling the Apply Filters Button */
+.apply-filters-btn {
+  width: 100%;
+  max-width: 600px; 
+  padding: 12px 20px;
+  background-color: #28a745;
+  color: white;
+  border: none;
+  border-radius: 5px;
+  cursor: pointer;
+  font-size: 14px;
+  margin-top: 15px;
+  transition: background-color 0.3s;
+}
+
+.apply-filters-btn:hover {
+  background-color: #218838;
+}
+
+/* Additional styles for toggling filter visibility */
+.filter-toggle {
+  margin-bottom: 15px;
+}
+
+/* Styles for the filter dropdown when shown */
+.filter-dropdown {
+  align-items: flex-start;
+  border: 1px solid #ccc;
+  border-radius: 5px; 
+  background-color: #ffffff;
+  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
+  flex-wrap: wrap;
+  gap: 20px;
+  justify-content: space-between;
+  margin-top: 10px;
+  margin-left: auto;
+  margin-right: auto;
+  padding: 15px; 
+}
+
+/* Adding some spacing to the filter columns */
+.filter-column {
+  margin-bottom: 15px; /* Margin below each filter column */
+}
+
+/* Budget Table */
+.budget-table {
+  width: 100%;
+  border-collapse: collapse;
+  margin: auto;
+  margin-top: 20px;
+}
+
+.budget-table th, .budget-table td {
+  border: 1px solid #ddd;
+  padding: 10px;
+}
+
+.budget-table th {
+  background-color: #f4f4f4;
+}
+
+.budget-table th.sortable {
+  cursor: pointer;
+}
+
+.budget-table th.sortable:hover {
+  background-color: #e0e0e0;
+}
+
+/* Action Buttons */
+.budget-table button {
+  padding: 5px 10px;
+  font-size: 12px;
+  border: none;
+  cursor: pointer;
+  margin: 2px;
+  border-radius: 3px;
+}
+
+.budget-table button:first-child {
+  background-color: #ffc107;
+  color: black;
+}
+
+.budget-table button:last-child {
+  background-color: #dc3545;
+  color: white;
+}
+
+/* Dropdown for Category */
+.budget-form select {
+  padding: 8px;
+}
+
+
+/* Success Message */
+.success-message {
+  padding: 10px;
+  margin-top: 10px;
+  background-color: #4CAF50;
+  color: white;
+  border-radius: 5px;
+}
+
+/* Error Message */
+.error-message {
+  padding: 10px;
+  margin-top: 10px;
+  background-color: #dc3545;
+  color: white;
+}
+
+
+/* Pagination */
+.pagination {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  list-style-type: none;
+  padding: 10px 0;
+  margin-top: 20px;
+}
+
+.pagination li {
+  margin: 0 10px;
+  cursor: pointer;
+  font-size: 14px;
+  padding: 8px 12px;
+  border-radius: 5px;
+  transition: background-color 0.3s ease, color 0.3s ease;
+}
+
+.pagination li:hover {
+  background-color: #007bff;
+  color: white;
+}
+
+.pagination .active {
+  background-color: #007bff;
+  color: white;
+  font-weight: bold;
+  border-radius: 5px;
+  padding: 8px 12px;
+}
+
+.pagination li.disabled {
+  cursor: not-allowed;
+  opacity: 0.5;
+}
+
+.pagination .previous, .pagination .next {
+  font-weight: bold;
+}
+
+/* Adding styles for Previous and Next buttons */
+.pagination .previous,
+.pagination .next {
+  padding: 8px 12px;
+  background-color: #007bff;
+  color: white;
+  border-radius: 5px;
+  font-size: 14px;
+  cursor: pointer;
+  transition: background-color 0.3s ease;
+}
+
+.pagination .previous:hover,
+.pagination .next:hover {
+  background-color: #0056b3;
+}
+
+/* Responsive: Stack on small screens */
+@media (max-width: 600px) {
+  /* Budget Inputs */
+  .budget-inputs {
+    flex-direction: column; 
+    width: 100%;
+  }
+
+  .budget-inputs input,
+  .budget-inputs select {
+    width: 100%; 
+  }
+
+  /* Budget Table */
+  .budget-table {
+    font-size: 12px; 
+  }
+
+  .budget-table th,
+  .budget-table td {
+    padding: 8px;
+  }
+
+  /* Filter Dropdown */
+  .filter-dropdown {
+    flex-direction: column; 
+    align-items: center; 
+  }
+
+  .filter-column {
+    width: 100%; 
+  }
+}
\ No newline at end of file
diff --git a/financial-tracker/requirements.txt b/financial-tracker/requirements.txt
index 272c6bd5bd8b2e078244000e54df9a4bcd41c2c3..b865926eae7539ee6a8aa5e8a4b5604f38cb7bdf 100644
Binary files a/financial-tracker/requirements.txt and b/financial-tracker/requirements.txt differ
diff --git a/financial-tracker/transaction-service/app/app.py b/financial-tracker/transaction-service/app/app.py
index bb654fe16c940a660e8f77b057f9d882596fa774..c78d6bda411483a425d1ed2fa1e0c740cf4a8fea 100644
--- a/financial-tracker/transaction-service/app/app.py
+++ b/financial-tracker/transaction-service/app/app.py
@@ -1,4 +1,5 @@
 from datetime import datetime, timedelta
+from dateutil.relativedelta import relativedelta
 from flask import Flask, request, jsonify
 from flask_cors import CORS
 from flask_jwt_extended import (
@@ -157,7 +158,7 @@ class Expense(db.Model):
             "id": self.id,
             "user_id": self.user_id,
             "amount": self.amount,
-            "currency": self.currency.value,  # Convert Enum to its string value
+            "currency": self.currency.value,
             "category": self.category,
             "date": self.date.strftime('%Y-%m-%d'),
             "description": self.description,
@@ -277,7 +278,6 @@ def add_expense():
         return jsonify({"error": "An error occurred while adding the expense"}), 500
 
 
-
 @app.route('/expenses', methods=['GET'])
 @jwt_required()
 def get_expenses():
@@ -461,6 +461,44 @@ def delete_expense(expense_id):
         return jsonify({"error": "An error occurred while deleting the expense"}), 500
 
 
+
+@app.route('/expenses/monthly', methods=['GET'])
+@jwt_required()
+def get_monthly_expenses():
+    """Retrieve expenses for the logged-in user for the current month"""
+    try:
+        user_id = get_jwt_identity()
+        user_id = int(user_id)
+        app.logger.info(f"Retrieved user_id from JWT: {user_id}")
+
+        if not user_id:
+            app.logger.error("User ID is None or invalid.")
+            return jsonify({"error": "Invalid user authentication"}), 401
+
+        # Get the start and end dates for the current month
+        now = datetime.now()
+        start_date = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
+        end_date = (start_date + relativedelta(months=1)).replace(day=1)
+
+        app.logger.info(f"Fetching expenses from {start_date} to {end_date}")
+
+        # Query expenses for the current month
+        expenses = Expense.query.filter(
+            Expense.user_id == user_id,
+            Expense.date >= start_date,
+            Expense.date < end_date
+        ).all()
+
+        app.logger.info(f"Found {len(expenses)} monthly expenses for user_id {user_id}")
+
+        expenses_list = [expense.to_dict() for expense in expenses]
+        return jsonify({"expenses": expenses_list}), 200
+
+    except Exception as e:
+        app.logger.error(f"Error retrieving monthly expenses: {e}", exc_info=True)
+        return jsonify({"error": "An error occurred while fetching monthly expenses"}), 500
+    
+
 @app.route('/categories', methods=['GET'])
 @jwt_required()
 def get_categories():
@@ -492,7 +530,7 @@ def health():
     return jsonify({"status": "User service is running"}), 200
 
 
-# INITIALIZATION & RUNNING APP
+# INITIALISATION & RUNNING APP
 if __name__ == "__main__":
     # Create all tables in the database (if they don't exist)
     with app.app_context():