diff --git a/src/routes/cramer-tracker/+page.svelte b/src/routes/cramer-tracker/+page.svelte index 7ada1a0a..bce0b7a6 100644 --- a/src/routes/cramer-tracker/+page.svelte +++ b/src/routes/cramer-tracker/+page.svelte @@ -3,6 +3,7 @@ import { onMount } from "svelte"; import ArrowLogo from "lucide-svelte/icons/move-up-right"; import HoverStockChart from "$lib/components/HoverStockChart.svelte"; + import TableHeader from "$lib/components/Table/TableHeader.svelte"; export let data; @@ -15,43 +16,43 @@ let path; switch (sector) { case "Financials": - path = "financial-sector"; + path = "financial"; break; case "Healthcare": - path = "healthcare-sector"; + path = "healthcare"; break; case "Information Technology": - path = "technology-sector"; + path = "technology"; break; case "Technology": - path = "technology-sector"; + path = "technology"; break; case "Financial Services": - path = "financial-sector"; + path = "financial"; break; case "Industrials": - path = "industrials-sector"; + path = "industrials"; break; case "Energy": - path = "energy-sector"; + path = "energy"; break; case "Utilities": - path = "utilities-sector"; + path = "utilities"; break; case "Consumer Cyclical": - path = "consumer-cyclical-sector"; + path = "consumer-cyclical"; break; case "Real Estate": - path = "real-estate-sector"; + path = "real-estate"; break; case "Basic Materials": - path = "basic-materials-sector"; + path = "basic-materials"; break; case "Communication Services": - path = "communication-services-sector"; + path = "communication-services"; break; case "Consumer Defensive": - path = "consumer-defensive-sector"; + path = "consumer-defensive"; break; default: // Handle default case if needed @@ -117,6 +118,82 @@ }); $: charNumber = 20; + + let columns = [ + { key: "date", label: "Date", align: "left" }, + { key: "ticker", label: "Symbol", align: "left" }, + { key: "name", label: "Name", align: "left" }, + { key: "sentiment", label: "Sentiment", align: "right" }, + { key: "returnSince", label: "Return Since", align: "right" }, + { key: "sector", label: "Sector", align: "right" }, + ]; + + let sortOrders = { + date: { order: "none", type: "date" }, + ticker: { order: "none", type: "string" }, + name: { order: "none", type: "string" }, + sentiment: { order: "none", type: "string" }, + returnSince: { order: "none", type: "number" }, + sector: { order: "none", type: "string" }, + }; + + 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") { + displayList = [...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 + displayList = [...originalData].sort(compareValues)?.slice(0, 50); + }; @@ -199,98 +276,21 @@ -
+
- - - - - - - + - {#each displayList as item, index} + {#each displayList as item} - - + + + + @@ -331,7 +345,8 @@ class="text-end text-sm sm:text-[1rem] whitespace-nowrap font-medium" > {item?.sector} diff --git a/src/routes/list/industrials-sector/+page.server.ts b/src/routes/list/industrials-sector/+page.server.ts deleted file mode 100644 index 8e3dd167..00000000 --- a/src/routes/list/industrials-sector/+page.server.ts +++ /dev/null @@ -1,43 +0,0 @@ -export const load = async ({ locals }) => { - const { apiKey, apiURL } = locals; - - const getIndustrialsSector = async () => { - const postData = { filterList: "industrials" }; - - const response = await fetch(apiURL + "/filter-stock-list", { - method: "POST", - headers: { - "Content-Type": "application/json", - "X-API-KEY": apiKey, - }, - body: JSON.stringify(postData), - }); - - const output = await response.json(); - - return output; - }; - - const getHistoricalSector = async () => { - const postData = { filterList: "industrials" }; - - const response = await fetch(apiURL + "/historical-sector-price", { - method: "POST", - headers: { - "Content-Type": "application/json", - "X-API-KEY": apiKey, - }, - body: JSON.stringify(postData), - }); - - const output = await response.json(); - - return output; - }; - - // Make sure to return a promise - return { - getIndustrialsSector: await getIndustrialsSector(), - getHistoricalSector: await getHistoricalSector(), - }; -}; diff --git a/src/routes/list/industrials-sector/+page.svelte b/src/routes/list/industrials-sector/+page.svelte deleted file mode 100644 index 2699c58a..00000000 --- a/src/routes/list/industrials-sector/+page.svelte +++ /dev/null @@ -1,410 +0,0 @@ - - -
-
- - A complete list of companies in the Industrials Sector that are publicly traded - on the US stock exchange. -
- -
-
- -
-
- {rawData?.length} -
-
-
- -
- -
-
- {abbreviateNumber(totalMarketCap, true)} -
-
-
- -
- -
-
- {abbreviateNumber(totalRevenue, true)} -
-
-
- -
- -
-
- {abbreviateNumber(totalProfits, true)} -
-
-
- -
- -
-
- {((totalProfits / totalRevenue) * 100)?.toFixed(2)}% -
-
-
- -
- -
-
- {(totalMarketCap / totalProfits)?.toFixed(2)} -
-
-
-
- -

- Historical Performance -

-
- {#if isLoaded} - - {:else} -
-
- -
-
- {/if} -
- - -
- -
-
- Company Name - - Date - - Sentiment - - Return Since - - Sector -
- {#if index >= 5 && data?.user?.tier !== "Pro"} - - - XXXX - - -
- XXXXXXXXXXXXXXXX -
- -
- - - - - - - Upgrade - -
-
- {:else} -
- - - {item?.name?.length > charNumber - ? item?.name?.slice(0, charNumber) + "..." - : item?.name} - -
- {/if} -
@@ -302,6 +302,20 @@ })} + + + {item?.name?.length > charNumber + ? item?.name?.slice(0, charNumber) + "..." + : item?.name} + {item?.sentiment}
- - - - - - - - - - - - {#each marketCapList as item, index} - - goto("/stocks/" + item?.symbol)} - class="sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] odd:bg-[#27272A] border-b-[#09090B] shake-ticker cursor-pointer" - > - - - - - - - - - - - - - {/each} - -
SymbolCompanyMarket CapRevenueProfitsPrice
- {item?.symbol} - - {item?.name?.length > charNumber - ? item?.name?.slice(0, charNumber) + "..." - : item?.name} - - {abbreviateNumber(item?.marketCap, true)} - - {item?.revenue !== null - ? abbreviateNumber(item?.revenue, true) - : "-"} - - {item?.netIncome !== null - ? abbreviateNumber(item?.netIncome, true) - : "-"} - -
-
- ${item.price?.toFixed(2)} -
- {#if item.changesPercentage >= 0} - +{item.changesPercentage?.toFixed(2)}% - {:else} - {item.changesPercentage?.toFixed(2)}% - - {/if} -
-
-
-
-
-
- - -