Open In App

Stock Market Portfolio App using MERN Stack

Last Updated : 17 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

The Stock Market Portfolio project is a web application that helps to efficiently manage and track stock market investments and portfolios. In this article, we will see a step-wise process of building a Stock Market Portfolio using the power of the MERN stack.

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

imresizer-1705078170237

Prerequisites:

Approach to create Stock Market Portfolio App:

  • In the database there will be a list of stocks data which will be fetched by the server.
  • There will be also option to manually add the data though API request.
  • In the frontend there will be two routes-one will show all the stocks and other will show all the stocks watchlisted.
  • There is an option to add your favorite stocks in the watchlist.
  • If the stocks value is increasing it will show price in green color otherwise show red color.

Steps to Create the Project:

Step 1: Create a folder for the project backend and initialized the Express Application.

mkdir stock-market-portfolio
cd stock-market-portfolio
npm init -y

Step 2: Install Express and other required packages:

npm install express mongoose body-parser cors

Folder Structure:

hk

Dependencies (Backend):

"dependencies": {
"body-parser": "^1.20.2",
"cors": "^2.8.5",
"express": "^4.18.2",
"mongoose": "^8.0.4"
}

Example: Create a file named server.js and add the following code.

Javascript




const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const bodyParser = require("body-parser");
 
const app = express();
const PORT = process.env.PORT || 5000;
 
app.use(cors());
app.use(bodyParser.json());
 
mongoose.connect("Your MongoDB URI link", {
    useNewUrlParser: true,
    useUnifiedTopology: true,
});
 
const stockSchema = new mongoose.Schema({
    company: String,
    description: String,
    initial_price: Number,
    price_2002: Number,
    price_2007: Number,
    symbol: String,
});
 
const Stock = mongoose.model("Stock", stockSchema);
 
app.get("/api/stocks", async (req, res) => {
    try {
        const stocks = await Stock.find();
        res.json(stocks);
    } catch (error) {
        console.error(error);
        res.status(500).json({ error: "Internal Server Error" });
    }
});
 
app.post("/api/watchlist", async (req, res) => {
    try {
        const {
            company,
            description,
            initial_price,
            price_2002,
            price_2007,
            symbol,
        } = req.body;
        const stock = new Stock({
            company,
            description,
            initial_price,
            price_2002,
            price_2007,
            symbol,
        });
        await stock.save();
        res.json({ message: "Stock added to watchlist successfully" });
    } catch (error) {
        console.error(error);
        res.status(500).json({ error: "Internal Server Error" });
    }
});
 
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});


Step 3: Open the MongoDB atlas or compass and insert the following JSON file in the stocks collection.

"https://gist.github.com/stevekinney/f96d5800852e91282f46#file-stocks-json".

Step 4: Create the Frontend (React.js) by running the below command.

npx create-react-app stock-market-frontend
cd stock-market-frontend

Step 5: Install the required dependencies.

npm install axios

Dependencies (Frontend):

"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.15.4",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.21.2",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
}

Example: Write the given code in the respective files.

Javascript




// src/App.js
 
import React, { useState, useEffect } from "react";
import {
    BrowserRouter as Router,
    Routes,
    Route,
    NavLink,
} from "react-router-dom";
import "./App.css";
 
const Stocks = ({ addToWatchlist }) => {
    const [stocks, setStocks] = useState([]);
 
    useEffect(() => {
        // Fetch stock data from the backend
        fetch("http://localhost:5000/api/stocks")
            .then((res) => res.json())
            .then((data) => setStocks(data))
            .catch((error) => console.error("Error fetching stocks:", error));
    }, []);
    console.log(setStocks, "Stocksdata");
 
    const getRandomColor = () => {
        const colors = ["#FF0000", "#00FF00"]; // Red and Green
        return colors[Math.floor(Math.random() * colors.length)];
    };
 
    return (
        <div className="App">
            <h1>Stock Market MERN App</h1>
            <h2>Stocks</h2>
            <ul>
                {stocks.map((stock) => (
                    <li key={stock.symbol}>
                        {stock.company} ({stock.symbol}) -
                        <span style={{ color: getRandomColor() }}>
                            {" "}
                            ${stock.initial_price}
                        </span>
                        <button onClick={() => addToWatchlist(stock)}>
                            Add to My Watchlist
                        </button>
                    </li>
                ))}
            </ul>
        </div>
    );
};
 
const Watchlist = ({ watchlist }) => {
    const getRandomColor = () => {
        const colors = ["#FF0000", "#00FF00"]; // Red and Green
        return colors[Math.floor(Math.random() * colors.length)];
    };
 
    return (
        <div className="App">
            <h1>Stock Market MERN App</h1>
            <h2>My Watchlist</h2>
            <ul>
                {watchlist.map((stock) => (
                    <li key={stock.symbol}>
                        {stock.company} ({stock.symbol}) -
                        <span style={{ color: getRandomColor() }}>
                            {" "}
                            ${stock.initial_price}
                        </span>
                    </li>
                ))}
            </ul>
        </div>
    );
};
 
function App() {
    const [watchlist, setWatchlist] = useState([]);
 
    const addToWatchlist = (stock) => {
        // Add stock to watchlist
        fetch("http://localhost:5000/api/watchlist", {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify(stock),
        })
            .then((res) => res.json())
            .then((data) => {
                // Show an alert with the message received from the server
                alert(data.message);
                setWatchlist([...watchlist, stock]);
            })
            .catch((error) =>
                console.error("Error adding to watchlist:", error)
            );
    };
 
    return (
        <Router>
            <nav>
                <NavLink to="/stocks">Stocks</NavLink>
                <NavLink to="/watchlist">Watchlist</NavLink>
            </nav>
            <Routes>
                <Route
                    path="/stocks"
                    element={<Stocks addToWatchlist={addToWatchlist} />}
                />
                <Route
                    path="/watchlist"
                    element={<Watchlist watchlist={watchlist} />}
                />
            </Routes>
        </Router>
    );
}
 
export default App;


CSS




/* src/App.css */
 
body {
    font-family: 'Arial', sans-serif;
    background-color: #d9d7ca;
    margin: 0;
    padding: 0;
}
 
.App {
    text-align: center;
    padding: 20px;
}
 
h1 {
    color: #1f454d;
}
 
h2 {
    color: #3c8d93;
    margin-top: 30px;
}
 
ul {
    list-style-type: none;
    padding: 0;
}
 
li {
    background-color: #3c8d93;
    color: #d9d7ca;
    padding: 10px;
    margin: 10px 0;
    border-radius: 5px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}
 
button {
    background-color: #1f454d;
    color: #d9d7ca;
    border: none;
    padding: 8px;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s ease;
}
 
button:hover {
    background-color: #3c8d93;
}
 
/* Navigation bar styles */
nav {
    background-color: #1f454d;
    padding: 15px 0;
}
 
nav a {
    color: #d9d7ca;
    text-decoration: none;
    margin: 0 20px;
    font-size: 18px;
    transition: color 0.3s ease;
}
 
nav a:hover {
    color: #3c8d93;
}


To start the frontend run the following command.

npm start

Output:

hknjk_AdobeExpress-ezgifcom-video-to-gif-converter



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

Similar Reads