Skip to content

Commit

Permalink
Merge pull request #41 from javidangarcia/prices
Browse files Browse the repository at this point in the history
Added Real Time Price To Stock Pages
  • Loading branch information
javidangarcia authored Aug 7, 2023
2 parents b647daf + 077f475 commit 8ee7584
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 33 deletions.
4 changes: 4 additions & 0 deletions backend/ranking.js
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,10 @@ export async function GetRanking(user, page) {

const response = await RankingAlgorithmV4(user);

if (response.status === 422) {
return { status: 422, error: response.error };
}

if (response.status === 500) {
return { status: 500, error: response.error };
}
Expand Down
32 changes: 26 additions & 6 deletions frontend/src/components/Ranking/Ranking.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import "./Ranking.css";
import { useState, useEffect } from "react";
import axios from "axios";
import { Link } from "react-router-dom";
import { Link, useNavigate } from "react-router-dom";
import Card from "react-bootstrap/Card";
import Button from "react-bootstrap/Button";
import { useSelector, useDispatch } from "react-redux";
import { setLoading } from "../../redux/loading";
import { NetworkError, ServerError, ResponseError } from "../../utils";
import Swal from "sweetalert2";

const DEFAULT_RANKING_PAGE = 1;
const MAX_PAGE_SIZE = 10;
Expand All @@ -17,6 +18,8 @@ export default function Ranking() {
const [showLoadMore, setShowLoadMore] = useState(true);
const dispatch = useDispatch();
const loading = useSelector((state) => state.loading);
const [hasRendered, setHasRendered] = useState(false);
const navigate = useNavigate();

useEffect(() => {
const fetchRanking = async () => {
Expand All @@ -42,7 +45,19 @@ export default function Ranking() {
}
}

if (response.status === 422 || response.status === 401) {
if (response.status === 422) {
Swal.fire({
icon: "info",
title: "Get Started with Ranking",
text: "Explore at least 10 stocks to get started."
}).then((result) => {
if (result.isConfirmed) {
navigate("/search");
}
});
}

if (response.status === 401) {
ResponseError(response.data.error);
}

Expand All @@ -56,10 +71,15 @@ export default function Ranking() {
NetworkError(error);
}
};
fetchRanking();
}, [page]);

return (
if (hasRendered) {
fetchRanking();
} else {
setHasRendered(true);
}
}, [page, hasRendered]);

return stocksRanking.length > 0 ? (
<div className="d-flex flex-column align-items-center justify-content-center">
<h1 className="mt-4">Popular Stocks</h1>
<p className="mb-4">
Expand Down Expand Up @@ -103,5 +123,5 @@ export default function Ranking() {
</Button>
) : null}
</div>
);
) : null;
}
11 changes: 9 additions & 2 deletions frontend/src/components/StockCarousel/StockCarousel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default function StockCarousel() {
const [stocks, setStocks] = useState([]);
const [stocksNotFound, setStocksNotFound] = useState(false);
const dispatch = useDispatch();
const [hasRendered, setHasRendered] = useState(false);

useEffect(() => {
const fetchStocks = async () => {
Expand Down Expand Up @@ -38,8 +39,14 @@ export default function StockCarousel() {
NetworkError(error);
}
};
fetchStocks();
}, []);


if (hasRendered) {
fetchStocks();
} else {
setHasRendered(true);
}
}, [hasRendered]);

return (
<>
Expand Down
54 changes: 31 additions & 23 deletions frontend/src/components/StockData/StockData.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,33 @@ export default function StockData() {
const [category, setCategory] = useState("chart");
const [stockInDatabase, setStockInDatabase] = useState(false);
const navigate = useNavigate();
const [stockPrice, setStockPrice] = useState(null);

useEffect(() => {
const fetchStockData = async () => {
try {
dispatch(setLoading(true));

const stockPriceResponse = await axios.get(
getStockPriceUrl(ticker)
);

if (stockPriceResponse.data.c === 0) {
dispatch(setLoading(false));
Swal.fire({
icon: "error",
title: "Stock Not Found",
text: "The stock ticker you entered does not correspond to any existing company."
}).then((result) => {
if (result.isConfirmed) {
navigate("/search");
}
});
return;
}

setStockPrice(stockPriceResponse.data.c);

const databaseResponse = await axios.get(
`${import.meta.env.VITE_HOST}/stock/${ticker}`,
{ withCredentials: true, validateStatus: () => true }
Expand All @@ -52,48 +74,34 @@ export default function StockData() {
}

const stockOverviewUrl = getStockOverviewUrl(ticker);
const stockPriceUrl = getStockPriceUrl(ticker);
const stockLogoUrl = getStockLogoUrl(ticker);

const [overviewResponse, priceResponse, logoResponse] =
await Promise.all([
axios.get(stockOverviewUrl),
axios.get(stockPriceUrl),
axios.get(stockLogoUrl)
]);
const [overviewResponse, logoResponse] = await Promise.all([
axios.get(stockOverviewUrl),
axios.get(stockLogoUrl)
]);

const overviewData = overviewResponse.data;
const priceData = priceResponse.data;
const logoData = logoResponse.data;

if (Object.keys(overviewData).length === 0) {
if (overviewData.Note != null) {
dispatch(setLoading(false));
Swal.fire({
icon: "error",
title: "Stock Not Found",
text: "The stock ticker you entered does not correspond to any existing company."
}).then((result) => {
if (result.isConfirmed) {
navigate("/search");
}
title: "API Limit Reached",
text: `${overviewData.Note}`
});
return;
}

if (overviewData.Note != null) {
dispatch(setLoading(false));
ResponseError(overviewData.Note);
return;
}

const stockSector = capitalize(overviewData.Sector);

const combinedStockData = {
ticker: overviewData.Symbol.toUpperCase(),
name: overviewData.Name,
description: overviewData.Description,
sector: stockSector,
price: priceData.c,
price: stockPriceResponse.data.c,
logo: logoData.logo
};

Expand Down Expand Up @@ -142,7 +150,7 @@ export default function StockData() {
</p>
<div className="d-flex align-items-center ms-5 mb-2">
<p className="h2 text-primary me-2 mb-0">
${stockData.price?.toFixed(2)}
${stockPrice?.toFixed(2)}
</p>
<Follow
ticker={ticker}
Expand Down
10 changes: 8 additions & 2 deletions frontend/src/components/StockNews/StockNews.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export default function StockNews({ stocks }) {
const [currentStock, setCurrentStock] = useState(null);
const [articlesToShow, setArticlesToShow] = useState(ARTICLES_TO_SHOW);
const dispatch = useDispatch();
const [hasRendered, setHasRendered] = useState(false);

useEffect(() => {
const fetchStockNews = async () => {
Expand Down Expand Up @@ -63,8 +64,13 @@ export default function StockNews({ stocks }) {
NetworkError();
}
};
fetchStockNews();
}, [currentStock]);

if (hasRendered) {
fetchStockNews();
} else {
setHasRendered(true);
}
}, [currentStock, hasRendered]);

return (
<div className="stock-news">
Expand Down

0 comments on commit 8ee7584

Please sign in to comment.