Skip to content

Update app.js #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 128 additions & 27 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,116 @@
const express = require("express");
const axios = require("axios");
const cheerio = require("cheerio");

const app = express();
const port = process.env.PORT || 3001;

app.get("/", (req, res) => res.type('html').send(html));
// API Endpoint to Fetch Trades from Capitol Trades
const URL = "https://www.capitoltrades.com/trades?txDate=365d";

async function fetchTrades() {
try {
const response = await axios.get(URL, {
headers: {
"User-Agent": "Mozilla/5.0"
}
});

const html = response.data;
const $ = cheerio.load(html);
const trades = [];

$(".trade-item").each((index, element) => {
const legislator = $(element).find(".legislator-name").text().trim();
const ticker = $(element).find(".ticker-symbol").text().trim();
const transaction = $(element).find(".transaction-type").text().trim();
const date = $(element).find(".trade-date").text().trim();
const amount = $(element).find(".amount").text().trim();

if (legislator && ticker && transaction && date && amount) {
trades.push({
legislator,
ticker,
transaction,
date,
amount,
});
}
});

return trades;
} catch (error) {
console.error("Error fetching trade data:", error);
return [];
}
}

// API Route for Trade Data (Searchable)
app.get("/trades", async (req, res) => {
const { legislator, ticker, transaction } = req.query;
let trades = await fetchTrades();

const server = app.listen(port, () => console.log(`Example app listening on port ${port}!`));
// Filter Results Based on Query Params
if (legislator) {
trades = trades.filter(trade => trade.legislator.toLowerCase().includes(legislator.toLowerCase()));
}
if (ticker) {
trades = trades.filter(trade => trade.ticker.toLowerCase() === ticker.toLowerCase());
}
if (transaction) {
trades = trades.filter(trade => trade.transaction.toLowerCase() === transaction.toLowerCase());
}

res.json({ total: trades.length, trades });
});

// Serve Frontend HTML with Search Integration
app.get("/", (req, res) => {
res.type("html").send(html);
});

const server = app.listen(port, () => console.log(`Server running on http://localhost:${port}`));
server.keepAliveTimeout = 120 * 1000;
server.headersTimeout = 120 * 1000;

// Frontend HTML with Search Functionality
const html = `
<!DOCTYPE html>
<html>
<head>
<title>Hello from Render!</title>
<title>Congress Trades Dashboard</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/confetti.browser.min.js"></script>
<script>
function fetchTrades() {
const legislator = document.getElementById("legislator").value;
const ticker = document.getElementById("ticker").value;
const transaction = document.getElementById("transaction").value;

let query = "?";
if (legislator) query += "legislator=" + encodeURIComponent(legislator) + "&";
if (ticker) query += "ticker=" + encodeURIComponent(ticker) + "&";
if (transaction) query += "transaction=" + encodeURIComponent(transaction) + "&";

fetch("/trades" + query)
.then(response => response.json())
.then(data => {
const resultsDiv = document.getElementById("results");
resultsDiv.innerHTML = "";
data.trades.forEach(trade => {
const tradeElement = document.createElement("div");
tradeElement.classList.add("trade-item");
tradeElement.innerHTML = \`
<strong>\${trade.legislator}</strong> -
<span style="color: blue;">\${trade.ticker}</span> -
<em>\${trade.transaction}</em> -
<span>\${trade.date}</span> -
<span style="color: green;">\${trade.amount}</span>
\`;
resultsDiv.appendChild(tradeElement);
});
});
}

setTimeout(() => {
confetti({
particleCount: 100,
Expand All @@ -26,36 +121,42 @@ const html = `
}, 500);
</script>
<style>
@import url("https://p.typekit.net/p.css?s=1&k=vnd5zic&ht=tk&f=39475.39476.39477.39478.39479.39480.39481.39482&a=18673890&app=typekit&e=css");
@font-face {
font-family: "neo-sans";
src: url("https://use.typekit.net/af/00ac0a/00000000000000003b9b2033/27/l?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3") format("woff2"), url("https://use.typekit.net/af/00ac0a/00000000000000003b9b2033/27/d?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3") format("woff"), url("https://use.typekit.net/af/00ac0a/00000000000000003b9b2033/27/a?primer=7cdcb44be4a7db8877ffa5c0007b8dd865b3bbc383831fe2ea177f62257a9191&fvd=n7&v=3") format("opentype");
font-style: normal;
font-weight: 700;
}
html {
font-family: neo-sans;
font-weight: 700;
font-size: calc(62rem / 16);
}
body {
font-family: Arial, sans-serif;
background: white;
text-align: center;
padding: 20px;
}
h1 {
color: #333;
}
section {
border-radius: 1em;
padding: 1em;
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
input, button {
margin: 5px;
padding: 10px;
font-size: 16px;
}
.trade-item {
background: #f8f9fa;
padding: 10px;
margin: 5px;
border-radius: 5px;
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
}
</style>
</head>
<body>
<section>
Hello from Render!
</section>
<h1>Congress Trades Dashboard</h1>

<div>
<input type="text" id="legislator" placeholder="Search by Legislator">
<input type="text" id="ticker" placeholder="Search by Ticker">
<input type="text" id="transaction" placeholder="Buy/Sell">
<button onclick="fetchTrades()">Search</button>
</div>

<div id="results">
<p>Enter a search term and click "Search" to see results.</p>
</div>
</body>
</html>
`
`;