update watchlist page to add more indicators efficiently

This commit is contained in:
MuslemRahimi 2024-10-14 21:55:09 +02:00
parent 2ce87f8187
commit e3dc2347fe
4 changed files with 59 additions and 22 deletions

View File

@ -4,7 +4,7 @@ export const POST: RequestHandler = async ({ request, locals }) => {
const data = await request.json();
const { apiURL, apiKey } = locals;
const postData = { watchListId: data?.watchListId };
const postData = { watchListId: data?.watchListId, ruleOfList: data?.ruleOfList };
const response = await fetch(apiURL + "/get-watchlist", {
method: "POST",
headers: {

View File

@ -0,0 +1,20 @@
import type { RequestHandler } from "./$types";
export const POST: RequestHandler = async ({ request, locals }) => {
const data = await request.json();
const { apiURL, apiKey } = locals;
const postData = { tickerList: data?.tickerList, ruleOfList: data?.ruleOfList };
const response = await fetch(apiURL + "/indicator-data", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
body: JSON.stringify(postData),
});
const output = await response.json();
return new Response(JSON.stringify(output));
};

View File

@ -30,7 +30,15 @@ let allRows = [
{ name: 'AI Score', rule: 'score' },
{ name: 'Revenue', rule: 'revenue'},
{ name: 'Net Income', rule: 'netIncome'},
{ name: 'Free Cash Flow', rule: 'freeCashFlow'}
{ name: 'Free Cash Flow', rule: 'freeCashFlow'},
{ name: 'Industry', rule: 'industry'},
{ name: 'Sector', rule: 'sector'},
{ name: 'Price Change 1W', rule: 'change1W' },
{ name: 'Price Change 1M', rule: 'change1M' },
{ name: 'Price Change 3M', rule: 'change3M' },
{ name: 'Price Change 6M', rule: 'change6M' },
{ name: 'Price Change 1Y', rule: 'change1Y' },
];
let ruleOfList = [
@ -40,14 +48,20 @@ let ruleOfList = [
{ name: 'Change', rule: 'changesPercentage' },
];
const excludedRules = new Set(['volume', 'price', 'changesPercentage', 'eps']);
const proOnlyItems = new Set(
allRows
?.filter(item => !excludedRules?.has(item?.rule)) // Exclude the items based on the rule
?.map(item => item?.name) // Map the remaining items to their names
);
let isLoaded = false;
let searchDataLoaded = false; // Flag to track data loading
//let downloadWorker: Worker | undefined;
let downloadWorker: Worker | undefined;
let displayWatchList;
let allList = data?.getAllWatchlist;
/*
const handleDownloadMessage = (event) => {
isLoaded = false;
watchList = event?.data?.watchlistData ?? [];
@ -57,7 +71,7 @@ const handleDownloadMessage = (event) => {
const updateStockScreenerData = async () => {
downloadWorker.postMessage({ ruleOfList: ruleOfList, tickerList: watchList?.map(item => item?.symbol)});
};
*/
async function loadSearchData() {
@ -80,9 +94,8 @@ async function loadSearchData() {
async function getWatchlistData()
{
const postData = {'watchListId': displayWatchList?.id}
const postData = {'watchListId': displayWatchList?.id, 'ruleOfList': ruleOfList?.map(item => item?.rule)}
const response = await fetch('/api/get-watchlist', {
method: 'POST',
headers: {
@ -358,9 +371,14 @@ onMount(async () => {
const savedRules = localStorage?.getItem('watchlist-ruleOfList');
if (savedRules) {
ruleOfList = JSON.parse(savedRules);
if (data?.user?.tier !== 'Pro') {
//Check if user was Pro Member and has past checks of previous paywalled features. If so remove them from the ruleOfList
ruleOfList = ruleOfList.filter(item => excludedRules.has(item?.rule)); // Use Set to filter
console.log(ruleOfList)
}
}
} catch(e) {
console.log(ey)
console.log(e)
}
checkedItems = new Set(ruleOfList.map(item => item.name))
@ -374,13 +392,14 @@ if(allList?.length !== 0)
displayWatchList = '';
}
await getWatchlistData();
/*
if (!downloadWorker) {
const DownloadWorker = await import('./workers/downloadWorker?worker');
downloadWorker = new DownloadWorker.default();
downloadWorker.onmessage = handleDownloadMessage;
}
*/
isLoaded = true;
});
@ -420,19 +439,18 @@ function isChecked(item) {
}
function sortIndicatorCheckMarks(allRows) {
const priorityItems = new Set(['AI Score', 'Revenue', 'Net Income', 'Free Cash Flow']);
return allRows.sort((a, b) => {
const isAChecked = checkedItems.has(a.name);
const isBChecked = checkedItems.has(b.name);
const isAChecked = checkedItems.has(a?.name);
const isBChecked = checkedItems.has(b?.name);
// Sort checked items first
if (isAChecked !== isBChecked) return isAChecked ? -1 : 1;
// Check if the user is not Pro
if (data?.user?.tier !== 'Pro') {
const isAPriority = priorityItems.has(a.name);
const isBPriority = priorityItems.has(b.name);
const isAPriority = proOnlyItems.has(a?.name);
const isBPriority = proOnlyItems.has(b?.name);
// If both are priority items or both are not, sort alphabetically
if (isAPriority === isBPriority) return a.name.localeCompare(b.name);
@ -459,9 +477,8 @@ async function handleChangeValue(value) {
allRows = [...allRows];
ruleOfList = [...ruleOfList];
allRows = sortIndicatorCheckMarks(allRows)
await updateStockScreenerData()
allRows = sortIndicatorCheckMarks(allRows)
saveRules()
}
@ -712,7 +729,7 @@ function search() {
{#each (searchQuery?.length !== 0 ? testList : allRows) as item}
<DropdownMenu.Item class="sm:hover:bg-[#27272A]" >
<div class="flex items-center">
{#if (data?.user?.tier === 'Pro') || (item.rule !== 'revenue' && item.rule !== 'netIncome' && item.rule !== 'freeCashFlow' && item.rule !== 'score')}
{#if (data?.user?.tier === 'Pro') || excludedRules?.has(item?.rule)}
<label on:click|capture={(event) => { event.preventDefault(); handleChangeValue(item?.name) }} class="cursor-pointer text-white" for={item?.name}>
<input type="checkbox" class="rounded" checked={isChecked(item?.name)}>
<span class="ml-2">{item?.name}</span>
@ -810,9 +827,11 @@ function search() {
{#if item?.[row?.rule] !== undefined && item?.[row?.rule] !== null}
{#if ['marketCap', 'volume','revenue','netIncome','freeCashFlow'].includes(row?.rule)}
{abbreviateNumber(item[row?.rule])}
{:else if ['industry','sector'].includes(row?.rule)}
{item[row?.rule] !== null ? item[row?.rule] : '-'}
{:else if ['eps', 'pe', 'price','freeCashFlow'].includes(row?.rule)}
{item[row?.rule] !== null ? item[row?.rule]?.toFixed(2) : '-'}
{:else if ['changesPercentage'].includes(row?.rule)}
{:else if ['changesPercentage','change1W','change1M','change3M','change6M','change1Y','change3Y'].includes(row?.rule)}
{#if item[row?.rule] >= 0}
<span class="text-[#37C97D]">+{item[row?.rule]?.toFixed(2)}%</span>
{:else}

View File

@ -6,7 +6,6 @@ const getWatchlistData = async (rules, tickerList) => {
// Extract the rule names
let getRuleOfList = rules?.map((rule) => rule.rule) || [];
// Convert the rule set into a string key for the cache
const ruleKey = JSON.stringify(getRuleOfList);
@ -27,7 +26,6 @@ const getWatchlistData = async (rules, tickerList) => {
});
const output = await response.json();
console.log(output);
// Store the new data in the cache
cache.set(ruleKey, output);