diff --git a/src/routes/list/+layout.svelte b/src/routes/list/+layout.svelte index 2fcbef53..ffbdb47d 100644 --- a/src/routes/list/+layout.svelte +++ b/src/routes/list/+layout.svelte @@ -149,10 +149,7 @@ title: "Consumer Defensive Sector Stocks", link: "/list/sector/consumer-defensive", }, - { - title: "Delisted Companies", - link: "/list/delisted-stocks", - }, + { title: "Bitcoin ETFs", link: "/list/bitcoin-etfs", diff --git a/src/routes/list/+page.svelte b/src/routes/list/+page.svelte index 7872c08c..480b100a 100644 --- a/src/routes/list/+page.svelte +++ b/src/routes/list/+page.svelte @@ -541,14 +541,6 @@ All REITs -
  • - - Delisted Companies - -
  • @@ -563,14 +555,7 @@ All REITs -
  • - - Delisted Companies - -
  • + diff --git a/src/routes/list/delisted-stocks/+page.server.ts b/src/routes/list/delisted-stocks/+page.server.ts deleted file mode 100644 index 607b1636..00000000 --- a/src/routes/list/delisted-stocks/+page.server.ts +++ /dev/null @@ -1,22 +0,0 @@ -export const load = async ({ locals }) => { - const getDelistedStocks = async () => { - const { apiKey, apiURL } = locals; - - const response = await fetch(apiURL + "/delisted-companies", { - method: "GET", - headers: { - "Content-Type": "application/json", - "X-API-KEY": apiKey, - }, - }); - - const output = await response.json(); - - return output; - }; - - // Make sure to return a promise - return { - getDelistedStocks: await getDelistedStocks(), - }; -}; diff --git a/src/routes/list/delisted-stocks/+page.svelte b/src/routes/list/delisted-stocks/+page.svelte deleted file mode 100644 index 4763d87e..00000000 --- a/src/routes/list/delisted-stocks/+page.svelte +++ /dev/null @@ -1,150 +0,0 @@ - - -
    -
    - - - A list of companies delisted from the exchange and no longer publicly - traded. -
    - -
    -
    -
    - Total Stocks -
    -
    - {rawData?.length} -
    -
    - -
    -
    - Total Market Cap -
    -
    ---
    -
    - -
    -
    - Total Revenue -
    -
    ---
    -
    -
    - - -
    - -
    - - - - - - - - - - - - {#each marketCapList as item, index} - - - - - - - - - - - - - {/each} - -
    SymbolCompanyIPOExchangeDelisted
    - {item?.symbol} - - {item?.companyName?.length > charNumber - ? item?.companyName?.slice(0, charNumber) + "..." - : item?.companyName} - - {new Date(item?.ipoDate).toLocaleDateString("en-US", { - month: "short", - day: "numeric", - year: "numeric", - })} - - {item?.exchange} - - {new Date(item?.delistedDate).toLocaleDateString("en-US", { - month: "short", - day: "numeric", - year: "numeric", - })} -
    -
    -
    -
    diff --git a/src/routes/list/reit-stocks/+page.server.ts b/src/routes/list/reit-stocks/+page.server.ts index 57ffa7cd..904d671b 100644 --- a/src/routes/list/reit-stocks/+page.server.ts +++ b/src/routes/list/reit-stocks/+page.server.ts @@ -1,9 +1,10 @@ export const load = async ({ locals }) => { - const getAllREITs = async () => { - const { apiKey, apiURL } = locals; - const postData = { filterList: "reit" }; - const response = await fetch(apiURL + "/filter-stock-list", { + const getAllREITS = async () => { + const { apiKey, apiURL } = locals; + const postData = { filterList: 'reits' }; + + const response = await fetch(apiURL + "/list-category", { method: "POST", headers: { "Content-Type": "application/json", @@ -19,6 +20,6 @@ export const load = async ({ locals }) => { // Make sure to return a promise return { - getAllREITs: await getAllREITs(), + getAllREITS: await getAllREITS(), }; }; diff --git a/src/routes/list/reit-stocks/+page.svelte b/src/routes/list/reit-stocks/+page.svelte index 7cc00420..5c423575 100644 --- a/src/routes/list/reit-stocks/+page.svelte +++ b/src/routes/list/reit-stocks/+page.svelte @@ -2,9 +2,12 @@ import { screenWidth } from "$lib/store"; import { onMount } from "svelte"; import { abbreviateNumber } from "$lib/utils"; + import TableHeader from "$lib/components/Table/TableHeader.svelte"; + import HoverStockChart from "$lib/components/HoverStockChart.svelte"; + import DownloadData from "$lib/components/DownloadData.svelte"; export let data; - let rawData = data?.getAllREITs; + let rawData = data?.getAllREITS; let stockList = rawData?.slice(0, 50); async function handleScroll() { @@ -24,6 +27,84 @@ }; }); + let columns = [ + { key: "rank", label: "Rank", align: "center" }, + { key: "symbol", label: "Symbol", align: "left" }, + { key: "name", label: "Name", align: "left" }, + { key: "price", label: "Price", align: "right" }, + { key: "changesPercentage", label: "% Change", align: "right" }, + { key: "dividendYield", label: "Div. Yield", align: "right" }, + { key: "marketCap", label: "Market Cap", align: "right" }, + ]; + + let sortOrders = { + rank: { order: "none", type: "number" }, + symbol: { order: "none", type: "string" }, + name: { order: "none", type: "string" }, + price: { order: "none", type: "number" }, + changesPercentage: { order: "none", type: "number" }, + dividendYield: { order: "none", type: "number" }, + marketCap: { order: "none", type: "number" }, + }; + + const sortData = (key) => { + // Reset all other keys to 'none' except the current key + for (const k in sortOrders) { + if (k !== key) { + sortOrders[k].order = "none"; + } + } + + // Cycle through 'none', 'asc', 'desc' for the clicked key + const orderCycle = ["none", "asc", "desc"]; + + let originalData = rawData; + + const currentOrderIndex = orderCycle.indexOf(sortOrders[key].order); + sortOrders[key].order = + orderCycle[(currentOrderIndex + 1) % orderCycle.length]; + const sortOrder = sortOrders[key].order; + + // Reset to original data when 'none' and stop further sorting + if (sortOrder === "none") { + stockList = [...originalData]?.slice(0, 50); // Reset to original data (spread to avoid mutation) + return; + } + + // Define a generic comparison function + const compareValues = (a, b) => { + const { type } = sortOrders[key]; + let valueA, valueB; + + switch (type) { + case "date": + valueA = new Date(a[key]); + valueB = new Date(b[key]); + break; + case "string": + valueA = a[key].toUpperCase(); + valueB = b[key].toUpperCase(); + return sortOrder === "asc" + ? valueA.localeCompare(valueB) + : valueB.localeCompare(valueA); + case "number": + default: + valueA = parseFloat(a[key]); + valueB = parseFloat(b[key]); + break; + } + + if (sortOrder === "asc") { + return valueA < valueB ? -1 : valueA > valueB ? 1 : 0; + } else { + return valueA > valueB ? -1 : valueA < valueB ? 1 : 0; + } + }; + + // Sort using the generic comparison function + stockList = [...originalData].sort(compareValues)?.slice(0, 50); + }; + $: charNumber = $screenWidth < 640 ? 20 : 30; @@ -45,28 +126,17 @@ the US stock market. +
    + +
    +
    - - - - - - - - + {#each stockList as item} @@ -75,13 +145,17 @@ class="sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] odd:bg-[#27272A] border-b-[#09090B]" > + +
    SymbolCompanyStock Price% ChangeDiv. YieldMarket Cap
    - {item?.symbol} + {item?.rank} + + {item?.name?.length > charNumber ? item?.name?.slice(0, charNumber) + "..." @@ -89,23 +163,29 @@ {item?.price} - {item?.changesPercentage?.toFixed(2)}% + {#if item?.changesPercentage >= 0} + +{item.changesPercentage?.toFixed(2)}% + {:else} + {item.changesPercentage?.toFixed(2)}% + + {/if} - {item?.dividendYield?.toFixed(2)}% + {item?.dividendYield}%