update dark pool page

This commit is contained in:
MuslemRahimi 2024-12-25 13:34:04 +01:00
parent fa939b926b
commit aa697ccf45
5 changed files with 112 additions and 48 deletions

View File

@ -49,7 +49,10 @@
premium: "none", premium: "none",
assetType: "none", assetType: "none",
volume: "none", volume: "none",
avgVolume: "none",
dailyVolume: "none",
size: "none", size: "none",
sector: "none",
}; };
// Generalized sorting function // Generalized sorting function
@ -84,6 +87,22 @@
? tickerA.localeCompare(tickerB) ? tickerA.localeCompare(tickerB)
: tickerB.localeCompare(tickerA); : tickerB.localeCompare(tickerA);
}, },
sector: (a, b) => {
const sectorA = a.sector || ""; // Default to empty string if undefined
const sectorB = b.sector || ""; // Default to empty string if undefined
// Check if either sector is an empty string and ensure it's placed at the bottom
if (sectorA === "" && sectorB !== "") return 1; // Move empty string to the bottom
if (sectorB === "" && sectorA !== "") return -1; // Move empty string to the bottom
// If both are non-empty, sort normally
const stringA = sectorA.toUpperCase();
const stringB = sectorB.toUpperCase();
return sortOrder === "asc"
? stringA.localeCompare(stringB)
: stringB.localeCompare(stringA);
},
date: (a, b) => { date: (a, b) => {
const timeA = new Date(a.date); const timeA = new Date(a.date);
const timeB = new Date(b.date); const timeB = new Date(b.date);
@ -120,7 +139,7 @@
return sortOrder === "asc" ? volA - volB : volB - volA; return sortOrder === "asc" ? volA - volB : volB - volA;
}, },
assetType: (a, b) => { assetType: (a, b) => {
const typeOrder = { SWEEP: 1, TRADE: 2 }; const typeOrder = { STOCK: 1, ETF: 2 };
const typeA = typeOrder[a.assetType?.toUpperCase()] || 3; const typeA = typeOrder[a.assetType?.toUpperCase()] || 3;
const typeB = typeOrder[b.assetType?.toUpperCase()] || 3; const typeB = typeOrder[b.assetType?.toUpperCase()] || 3;
return sortOrder === "asc" ? typeA - typeB : typeB - typeA; return sortOrder === "asc" ? typeA - typeB : typeB - typeA;
@ -136,7 +155,13 @@
<div class="table"> <div class="table">
<VirtualList <VirtualList
width="100%" width="100%"
height={$screenWidth < 640 ? 550 : 850} height={$screenWidth < 640
? data?.user?.tier === "Pro"
? 550
: 250
: data?.user?.tier === "Pro"
? 850
: 250}
itemCount={displayedData.length} itemCount={displayedData.length}
itemSize={40} itemSize={40}
> >
@ -282,7 +307,7 @@
on:click={() => sortData("dailyVolume")} on:click={() => sortData("dailyVolume")}
class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase" class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase"
> >
% Daily Volume % Size / Vol
<svg <svg
class="flex-shrink-0 w-4 h-4 inline-block {sortOrders[ class="flex-shrink-0 w-4 h-4 inline-block {sortOrders[
'dailyVolume' 'dailyVolume'
@ -306,7 +331,7 @@
on:click={() => sortData("avgVolume")} on:click={() => sortData("avgVolume")}
class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase" class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase"
> >
% 30D Volume % Size / Avg Vol
<svg <svg
class="flex-shrink-0 w-4 h-4 inline-block {sortOrders[ class="flex-shrink-0 w-4 h-4 inline-block {sortOrders[
'avgVolume' 'avgVolume'
@ -350,15 +375,16 @@
</div> </div>
<div <div
on:click={() => sortData("vol")} on:click={() => sortData("assetType")}
class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase" class="td cursor-pointer select-none bg-[#121217] text-slate-300 font-bold text-xs text-start uppercase"
> >
Issue Type Asset Type
<svg <svg
class="flex-shrink-0 w-4 h-4 inline-block {sortOrders['vol'] === class="flex-shrink-0 w-4 h-4 inline-block {sortOrders[
'asc' 'assetType'
] === 'asc'
? 'rotate-180' ? 'rotate-180'
: sortOrders['vol'] === 'desc' : sortOrders['assetType'] === 'desc'
? '' ? ''
: 'hidden'} " : 'hidden'} "
viewBox="0 0 20 20" viewBox="0 0 20 20"
@ -378,7 +404,11 @@
let:index let:index
let:style let:style
{style} {style}
class="tr {index % 2 === 0 ? 'bg-[#19191F]' : 'bg-[#121217]'}" class="tr {index % 2 === 0 ? 'bg-[#19191F]' : 'bg-[#121217]'} {index +
1 ===
rawData?.length && data?.user?.tier !== 'Pro'
? 'opacity-[0.3]'
: ''}"
> >
<!-- Row data --> <!-- Row data -->

View File

@ -1,5 +1,5 @@
export const load = async ({ locals }) => { export const load = async ({ locals }) => {
const { apiURL, apiKey } = locals; const { apiURL, apiKey, user } = locals;
const getFlowData = async () => { const getFlowData = async () => {
// make the POST request to the endpoint // make the POST request to the endpoint
@ -10,7 +10,8 @@ export const load = async ({ locals }) => {
"X-API-KEY": apiKey, "X-API-KEY": apiKey,
}, },
}); });
const output = await response.json(); let output = await response.json();
output = user?.tier !== "Pro" ? output?.slice(0, 6) : output;
return output; return output;
}; };

View File

@ -15,6 +15,7 @@
import * as Popover from "$lib/components/shadcn/popover/index.js"; import * as Popover from "$lib/components/shadcn/popover/index.js";
import { Button } from "$lib/components/shadcn/button/index.js"; import { Button } from "$lib/components/shadcn/button/index.js";
import CalendarIcon from "lucide-svelte/icons/calendar"; import CalendarIcon from "lucide-svelte/icons/calendar";
import UpgradeToPro from "$lib/components/UpgradeToPro.svelte";
import { page } from "$app/stores"; import { page } from "$app/stores";
@ -25,7 +26,6 @@
let shouldLoadWorker = writable(false); let shouldLoadWorker = writable(false);
let ruleOfList = data?.getPredefinedCookieRuleOfList || []; let ruleOfList = data?.getPredefinedCookieRuleOfList || [];
let displayRules = []; let displayRules = [];
let filteredData = []; let filteredData = [];
let filterQuery = $page.url.searchParams.get("query") || ""; let filterQuery = $page.url.searchParams.get("query") || "";
@ -258,8 +258,6 @@
filteredData = event.data?.filteredData ?? []; filteredData = event.data?.filteredData ?? [];
displayedData = filteredData; displayedData = filteredData;
console.log("handle Message"); console.log("handle Message");
//console.log(displayedData)
}; };
async function changeRuleCondition(name: string, state: string) { async function changeRuleCondition(name: string, state: string) {
@ -694,29 +692,29 @@
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" /> <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" />
<title> <title>
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""} Options {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""} Dark
Flow Feed · Stocknear Pool Flow Feed · Stocknear
</title> </title>
<meta <meta
name="description" name="description"
content={`Explore unusual options from big institutional traders and hedge funds.`} content={`Explore unusual dark pool trades from big institutional traders and hedge funds.`}
/> />
<!-- Other meta tags --> <!-- Other meta tags -->
<meta property="og:title" content={`Options Flow Feed · Stocknear`} /> <meta property="og:title" content={`Dark Pool Flow · Stocknear`} />
<meta <meta
property="og:description" property="og:description"
content={`Explore unusual options from big institutional traders and hedge funds.`} content={`Explore unusual dark pool trades from big institutional traders and hedge funds.`}
/> />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<!-- Add more Open Graph meta tags as needed --> <!-- Add more Open Graph meta tags as needed -->
<!-- Twitter specific meta tags --> <!-- Twitter specific meta tags -->
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={`Options Flow Feed · Stocknear`} /> <meta name="twitter:title" content={`Dark Pool Flow · Stocknear`} />
<meta <meta
name="twitter:description" name="twitter:description"
content={`Explore unusual options from big institutional traders and hedge funds.`} content={`Explore unusual dark pool trades from big institutional traders and hedge funds.`}
/> />
<!-- Add more Twitter meta tags as needed --> <!-- Add more Twitter meta tags as needed -->
</svelte:head> </svelte:head>
@ -837,15 +835,35 @@
on:input={debouncedHandleInput} on:input={debouncedHandleInput}
autocomplete="off" autocomplete="off"
/> />
<svg {#if filterQuery?.length > 0}
class="ml-auto h-7 w-7 sm:h-8 sm:w-8 inline-block mr-5" <label
xmlns="http://www.w3.org/2000/svg" class="cursor-pointer"
viewBox="0 0 24 24" on:click={() => {
><path filterQuery = "";
fill="#fff" shouldLoadWorker.set(true);
d="m19.485 20.154l-6.262-6.262q-.75.639-1.725.989t-1.96.35q-2.402 0-4.066-1.663T3.808 9.503T5.47 5.436t4.064-1.667t4.068 1.664T15.268 9.5q0 1.042-.369 2.017t-.97 1.668l6.262 6.261zM9.539 14.23q1.99 0 3.36-1.37t1.37-3.361t-1.37-3.36t-3.36-1.37t-3.361 1.37t-1.37 3.36t1.37 3.36t3.36 1.37" }}
/></svg >
> <svg
class="ml-auto h-6 w-6 inline-block mr-3"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="white"
d="m6.4 18.308l-.708-.708l5.6-5.6l-5.6-5.6l.708-.708l5.6 5.6l5.6-5.6l.708.708l-5.6 5.6l5.6 5.6l-.708.708l-5.6-5.6z"
/></svg
>
</label>
{:else}
<svg
class="ml-auto h-7 w-7 sm:h-8 sm:w-8 inline-block mr-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="#fff"
d="m19.485 20.154l-6.262-6.262q-.75.639-1.725.989t-1.96.35q-2.402 0-4.066-1.663T3.808 9.503T5.47 5.436t4.064-1.667t4.068 1.664T15.268 9.5q0 1.042-.369 2.017t-.97 1.668l6.262 6.261zM9.539 14.23q1.99 0 3.36-1.37t1.37-3.361t-1.37-3.36t-3.36-1.37t-3.361 1.37t-1.37 3.36t1.37 3.36t3.36 1.37"
/></svg
>
{/if}
</label> </label>
{#if notFound === true} {#if notFound === true}
<span <span
@ -1304,6 +1322,7 @@
{#if displayedData?.length !== 0} {#if displayedData?.length !== 0}
<div class="mt-3 w-full overflow-x-auto h-[850px] overflow-hidden"> <div class="mt-3 w-full overflow-x-auto h-[850px] overflow-hidden">
<DarkPoolTable {data} {displayedData} {filteredData} {rawData} /> <DarkPoolTable {data} {displayedData} {filteredData} {rawData} />
<UpgradeToPro {data} />
</div> </div>
{:else} {:else}
<div <div
@ -1322,12 +1341,6 @@
</div> </div>
{/if} {/if}
</div> </div>
<!--
<div class="relative bottom-[400px] w-fit m-auto flex justify-center items-center">
<UpgradeToPro data={data} title="Get the recent Options Flow Data from Hedge Funds and major institutional traders to never miss out"/>
</div>
-->
{:else} {:else}
<div class="flex justify-center items-center h-80"> <div class="flex justify-center items-center h-80">
<div class="relative"> <div class="relative">

View File

@ -367,7 +367,7 @@ onmessage = async (event: MessageEvent) => {
let filteredData = await filterRawData(rawData, ruleOfList, filterQuery); let filteredData = await filterRawData(rawData, ruleOfList, filterQuery);
filteredData = Array.from( filteredData = Array.from(
new Map(filteredData?.map((item) => [item?.id, item]))?.values() new Map(filteredData?.map((item) => [item?.trackingID, item]))?.values()
); );
postMessage({ message: "success", filteredData }); postMessage({ message: "success", filteredData });

View File

@ -970,20 +970,40 @@
id="modal-search" id="modal-search"
type="search" type="search"
class="text-white sm:ml-2 text-[1rem] placeholder-gray-300 border-transparent focus:border-transparent focus:ring-0 flex items-center justify-center w-full px-0 py-1.5 bg-inherit" class="text-white sm:ml-2 text-[1rem] placeholder-gray-300 border-transparent focus:border-transparent focus:ring-0 flex items-center justify-center w-full px-0 py-1.5 bg-inherit"
placeholder="Search AAPL, SPY,..." placeholder="Stock or ETF symbol..."
bind:value={filterQuery} bind:value={filterQuery}
on:input={debouncedHandleInput} on:input={debouncedHandleInput}
autocomplete="off" autocomplete="off"
/> />
<svg {#if filterQuery?.length > 0}
class="ml-auto h-7 w-7 sm:h-8 sm:w-8 inline-block mr-5" <label
xmlns="http://www.w3.org/2000/svg" class="cursor-pointer"
viewBox="0 0 24 24" on:click={() => {
><path filterQuery = "";
fill="#fff" shouldLoadWorker.set(true);
d="m19.485 20.154l-6.262-6.262q-.75.639-1.725.989t-1.96.35q-2.402 0-4.066-1.663T3.808 9.503T5.47 5.436t4.064-1.667t4.068 1.664T15.268 9.5q0 1.042-.369 2.017t-.97 1.668l6.262 6.261zM9.539 14.23q1.99 0 3.36-1.37t1.37-3.361t-1.37-3.36t-3.36-1.37t-3.361 1.37t-1.37 3.36t1.37 3.36t3.36 1.37" }}
/></svg >
> <svg
class="ml-auto h-6 w-6 inline-block mr-3"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="white"
d="m6.4 18.308l-.708-.708l5.6-5.6l-5.6-5.6l.708-.708l5.6 5.6l5.6-5.6l.708.708l-5.6 5.6l5.6 5.6l-.708.708l-5.6-5.6z"
/></svg
>
</label>
{:else}
<svg
class="ml-auto h-7 w-7 sm:h-8 sm:w-8 inline-block mr-5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="#fff"
d="m19.485 20.154l-6.262-6.262q-.75.639-1.725.989t-1.96.35q-2.402 0-4.066-1.663T3.808 9.503T5.47 5.436t4.064-1.667t4.068 1.664T15.268 9.5q0 1.042-.369 2.017t-.97 1.668l6.262 6.261zM9.539 14.23q1.99 0 3.36-1.37t1.37-3.361t-1.37-3.36t-3.36-1.37t-3.361 1.37t-1.37 3.36t1.37 3.36t3.36 1.37"
/></svg
>
{/if}
</label> </label>
{#if notFound === true} {#if notFound === true}
<span <span