This commit is contained in:
MuslemRahimi 2025-03-10 20:24:16 +01:00
parent 241f2f628a
commit e416553d2f
14 changed files with 216 additions and 1791 deletions

View File

@ -13,7 +13,9 @@
}
</script>
<section class="overflow-hidden text-muted dark:text-white">
<section
class="overflow-hidden bg-white dark:bg-default text-muted dark:text-white"
>
<main class="overflow-hidden">
<div class="w-full">
<div

View File

@ -1,197 +0,0 @@
<script lang="ts">
import { executiveClicked, stockTicker, clientSideCache } from "$lib/store";
import { afterUpdate } from "svelte";
//export let executiveList;
let executiveList = [];
let isLoaded = false;
const currentYear = new Date().getFullYear();
let numberOfFemales = 0;
let numberOfMales = 0;
async function fetchData() {
if ($clientSideCache[$stockTicker]?.getExecutives) {
executiveList = $clientSideCache[$stockTicker]?.getExecutives;
} else {
const postData = { ticker: $stockTicker, path: "get-executives" };
const response = await fetch("/api/ticker-data", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(postData),
});
executiveList = await response.json();
$clientSideCache[$stockTicker].getExecutives = executiveList;
}
}
afterUpdate(async () => {
if (
$stockTicker &&
typeof window !== "undefined" &&
$executiveClicked === true
) {
$executiveClicked = false;
await fetchData();
for (const executive of executiveList) {
switch (executive?.gender) {
case "female":
numberOfFemales++;
break;
case "male":
numberOfMales++;
break;
// Handle other gender cases if needed
}
}
isLoaded = true;
}
});
</script>
<div class="space-y-3 sm:pt-5">
<div class="bg-[#000] h-auto w-screen">
<!--Start Header-->
<div class="w-full p-1 flex flex-col items-center pb-5 h-auto">
<h2 class="text-center m-auto text-[1.1rem] text-white mt-5">
Executives
</h2>
<div
class="{!isLoaded
? 'hidden'
: ''} flex flex-col items-center mt-10 w-full"
>
<span class="text-white text-[1rem]"> Female/Total Ratio </span>
<div class="flex flex-row justify-center items-center w-full mt-5">
<div class="flex flex-row items-center ml-5">
<div
class="h-full bg-gray-800 transform -translate-x-1/2"
aria-hidden="true"
></div>
<div
class="w-3 h-3 bg-[#0FC008] border-4 box-content border-gray-900 rounded-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<span class="text-white text-sm inline-block">
Female <span class=" text-[0.95rem]">({numberOfFemales})</span>
</span>
</div>
<span class="text-white text-3xl m-auto">
{numberOfFemales === 0
? 0
: (
(numberOfFemales / (numberOfFemales + numberOfMales)) *
100
)?.toFixed(2)}%
</span>
<div class="flex flex-row items-center mr-5">
<div
class="h-full bg-gray-800 transform -translate-x-1/2"
aria-hidden="true"
></div>
<div
class="w-3 h-3 bg-[#FF2F1F] border-4 box-content border-gray-900 rounded-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<span class="text-white text-sm inline-block">
Male <span class=" text-[0.95rem]">({numberOfMales})</span>
</span>
</div>
</div>
</div>
</div>
<!--End Header-->
{#if isLoaded}
{#if executiveList?.length !== 0}
<div class="mt-5 w-full">
{#each executiveList as item}
<!--Start Item-->
<div class="flex flex-row items-center pl-4 pr-4 w-full mb-3">
<div class="w-full rounded-md bg-primary h-auto pb-3 pl-3 pt-3">
<div class="flex flex-row items-center relative">
<div class="flex flex-col">
<div
class="flex flex-row items-center mr-auto mb-2 text-white text-sm w-56"
>
<span>
{item?.name}
{#if item?.yearBorn !== null}
, {currentYear - item.yearBorn}
{/if}
</span>
</div>
<span class="text-gray-300 text-sm w-48">
{item?.title}
</span>
</div>
{#if item?.gender === "male"}
<div
class="flex flex-row items-center ml-auto absolute right-3 top-0"
>
<div
class="h-full bg-primary transform -translate-x-1/2"
aria-hidden="true"
></div>
<div
class="w-2 h-2 bg-[#FF2F1F] box-content rounded-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<span class="text-white text-[0.85rem] inline-block">
Male
</span>
</div>
{:else if item?.gender === "female"}
<div
class="flex flex-row items-center ml-auto absolute right-3 top-0"
>
<div
class="h-full bg-primary transform -translate-x-1/2"
aria-hidden="true"
></div>
<div
class="w-2 h-2 bg-[#0FC008] box-content rounded-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<span class="text-white text-[0.85rem] inline-block">
Female
</span>
</div>
{/if}
</div>
</div>
</div>
<!--End Item-->
{/each}
</div>
{:else}
<div
class=" mt-20 flex justify-center items-center text-2xl font-bold text-slate-700 mb-20 m-auto"
>
No data available
</div>
{/if}
{:else}
<div class="flex justify-center items-center h-80">
<div class="relative">
<label
class="bg-secondary rounded-md h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
>
<span class="loading loading-spinner loading-md text-gray-400"
></span>
</label>
</div>
</div>
{/if}
</div>
</div>
<!--End Similar Stocks Card -->

View File

@ -378,7 +378,8 @@
on:click={() => handleSearch(item?.symbol, item?.type)}
>
<div class="flex flex-row items-center justify-between w-full">
<span class="text-sm text-blue-500 dark:text-blue-400"
<span
class="text-sm text-muted font-semibold dark:font-normal dark:text-blue-400"
>{item?.symbol}</span
>
<span class="ml-3 text-sm text-muted dark:text-white"
@ -443,21 +444,24 @@
/>
<dialog id="searchBarModal" class="modal modal-bottom">
<label for="searchBarModal" class="cursor-pointer modal-backdrop"></label>
<label
for="searchBarModal"
class="cursor-pointer modal-backdrop bg-[#000] bg-[#000]/30"
></label>
<div
class="z-999 modal-box overflow-hidden rounded-md bg-secondary border border-gray-300 dark:border-gray-600 sm:my-8 sm:m-auto sm:h-auto w-full sm:w-3/4 lg:w-1/2 2xl:w-1/3"
class="z-999 modal-box overflow-hidden rounded-md shadow bg-white dark:bg-secondary border border-gray-300 dark:border-gray-600 sm:my-8 sm:m-auto sm:h-auto w-full sm:w-3/4 lg:w-1/2 2xl:w-1/3"
>
<label
for="searchBarModal"
class="inline-block cursor-pointer absolute right-3 top-3 text-[1.3rem] sm:text-[1.8rem] text-white"
class="inline-block cursor-pointer absolute right-3 top-3 text-[1.3rem] sm:text-[1.8rem]"
>
<svg
class="w-6 h-6 sm:w-8 sm:h-8"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="white"
fill="currentColor"
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
>
@ -467,7 +471,7 @@
<div class="mt-8">
<div class="relative">
<div
class="inline-block cursor-pointer absolute right-5 top-1.5 text-[1.3rem] sm:text-[1.5rem] text-white"
class="inline-block cursor-pointer absolute right-5 top-1.5 text-[1.3rem] sm:text-[1.5rem]"
>
{#if isLoading}
<span class="loading loading-spinner loading-sm"></span>
@ -492,7 +496,7 @@
<input
id="modal-search"
class="rounded-md w-full text-white bg-gray-300 dark:bg-secondary border border-gray-300 dark:border-gray-600 focus:ring-transparent placeholder-gray-200 py-3 pl-10 pr-4"
class="rounded-md w-full bg-gray-300 dark:bg-secondary border border-gray-300 dark:border-gray-600 focus:ring-transparent placeholder-gray-600 dark:placeholder-gray-200 py-3 pl-10 pr-4"
type="search"
placeholder="Company or stock symbol..."
bind:value={inputValue}
@ -507,7 +511,7 @@
aria-label="Search"
>
<svg
class="w-4 h-4 shrink-0 fill-current text-white ml-4 mr-2 text-slate-400"
class="w-4 h-4 shrink-0 fill-current ml-4 mr-2 dark:text-slate-400"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
><path
@ -525,7 +529,7 @@
<!-- Popular searches -->
<div class="mb-3 last:mb-0 mt-3">
{#if !showSuggestions}
<div class="text-start text-sm font-semibold text-white mb-2">
<div class="text-start text-sm font-semibold mb-2">
{searchHistory?.length > 0 ? "Recent" : "Popular"}
</div>
{/if}
@ -538,22 +542,23 @@
href={`/${item?.type === "ETF" ? "etf" : item?.type === "Index" ? "index" : "stocks"}/${item?.symbol}`}
on:click={() => popularTicker(item?.symbol)}
class="mb-2 {item?.symbol === focusedSuggestion
? 'cursor-pointer flex justify-start items-center p-2 text-white bg-primary rounded group'
: 'cursor-pointer bg-secondary sm:hover:bg-gray-300 dark:sm:hover:bg-primary rounded-md flex justify-start items-center p-2 text-white group'} w-full"
? 'cursor-pointer flex justify-start items-center p-2 bg-white dark:bg-primary rounded group'
: 'cursor-pointer bg-white dark:bg-secondary sm:hover:bg-gray-300 dark:sm:hover:bg-primary rounded-md flex justify-start items-center p-2 group'} w-full"
>
<div class="flex flex-row items-center w-full">
<div class="flex flex-col">
<span class="text-blue-500 dark:text-blue-400"
<span
class="font-semibold dark:font-normal text-muted dark:text-blue-400"
>{item?.symbol}</span
>
<span class="text-white"
<span class=""
>{item?.name.length > 150
? item?.name?.slice(0, 150) + "..."
: item?.name}</span
>
</div>
<div class="text-white ml-auto">
<div class=" ml-auto">
{item?.type}
</div>
</div>
@ -561,9 +566,7 @@
</li>
{/each}
{:else if showSuggestions && searchBarData?.length > 0}
<div class="text-start text-sm font-semibold text-white mb-2">
Suggestions
</div>
<div class="text-start text-sm font-semibold mb-2">Suggestions</div>
{#each searchBarData as item}
<li class="border-b border-gray-300 dark:border-gray-600">
<!-- svelte-ignore a11y-click-events-have-key-events -->
@ -572,22 +575,23 @@
href={`/${item?.type === "ETF" ? "etf" : item?.type === "Index" ? "index" : "stocks"}/${item?.symbol}`}
on:click={() => searchBarTicker(item?.symbol)}
class="mb-2 {item?.symbol === focusedSuggestion
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-primary rounded group'
: 'cursor-pointer mb-2 bg-secondary sm:hover:bg-primary rounded-md flex justify-start items-center p-2 text-white group'}"
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 bg-whitedark:bg-primary rounded group'
: 'cursor-pointer mb-2 bg-white dark:bg-secondary sm:hover:bg-primary rounded-md flex justify-start items-center p-2 group'}"
>
<div class="flex flex-row items-center w-full">
<div class="flex flex-col">
<span class="text-blue-500 dark:text-blue-400"
<span
class="font-semibold dark:font-normal text-muted dark:text-blue-400"
>{item?.symbol}</span
>
<span class="text-white"
<span class=""
>{item?.name?.length > 150
? item?.name?.slice(0, 150) + "..."
: item?.name}</span
>
</div>
<div class="text-white ml-auto">
<div class=" ml-auto">
{item?.type}
</div>
</div>
@ -596,9 +600,7 @@
{/each}
{:else if showSuggestions && searchBarData?.length === 0}
<li>
<label
class="flex items-center p-2 text-white hover:text-white hover:bg-primary rounded group"
>
<label class="flex items-center p-2 rounded group">
<svg
class="w-3 h-3 fill-slate-400 shrink-0 mr-3 dark:fill-slate-500"
width="12"

View File

@ -1,68 +0,0 @@
<script lang = 'ts'>
export let signal;
</script>
{#if signal === 'Strong Buy'}
<div class="relative h-full w-full mt-5">
<div class="absolute bottom-0 right-0 flex flex-row items-end">
<div class="bg-[#00FC50] mr-0.5 h-2.5 w-1.5"></div>
<div class="bg-[#00FC50] mr-0.5 h-3 w-1.5"></div>
<div class="bg-[#00FC50] mr-0.5 h-3.5 w-1.5"></div>
<div class="bg-[#00FC50] mr-0.5 h-4 w-1.5"></div>
<div class="bg-[#00FC50] mr-0.5 h-[18px] w-1.5"></div>
</div>
</div>
{:else if signal === 'Buy'}
<div class="relative h-full w-full mt-5">
<div class="absolute bottom-0 right-0 flex flex-row items-end">
<div class="bg-[#00FC50] mr-0.5 h-2.5 w-1.5"></div>
<div class="bg-[#00FC50] mr-0.5 h-3 w-1.5"></div>
<div class="bg-[#00FC50] mr-0.5 h-3.5 w-1.5"></div>
<div class="bg-[#00FC50] mr-0.5 h-4 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-[18px] w-1.5"></div>
</div>
</div>
{:else if signal === 'Neutral'}
<div class="relative h-full w-full mt-5">
<div class="absolute bottom-0 right-0 flex flex-row items-end">
<div class="bg-[#F8901E] mr-0.5 h-2.5 w-1.5"></div>
<div class="bg-[#F8901E] mr-0.5 h-3 w-1.5"></div>
<div class="bg-[#F8901E] mr-0.5 h-3.5 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-4 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-[18px] w-1.5"></div>
</div>
</div>
{:else if signal === 'Sell'}
<div class="relative h-full w-full mt-5">
<div class="absolute bottom-0 right-0 flex flex-row items-end">
<div class="bg-[#FF2F1F] mr-0.5 h-2.5 w-1.5"></div>
<div class="bg-[#FF2F1F] mr-0.5 h-3 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-3.5 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-4 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-[18px] w-1.5"></div>
</div>
</div>
{:else if signal === 'Strong Sell'}
<div class="relative h-full w-full mt-5">
<div class="absolute bottom-0 right-0 flex flex-row items-end">
<div class="bg-[#FF2F1F] mr-0.5 h-2.5 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-3 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-3.5 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-4 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-[18px] w-1.5"></div>
</div>
</div>
{:else}
<div class="relative h-full w-full mt-5">
<div class="absolute bottom-0 right-0 flex flex-row items-end">
<div class="bg-[#707070] mr-0.5 h-2.5 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-3 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-3.5 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-4 w-1.5"></div>
<div class="bg-[#707070] mr-0.5 h-[18px] w-1.5"></div>
</div>
</div>
{/if}

View File

@ -1,318 +0,0 @@
<script lang="ts">
import { abbreviateNumber } from "$lib/utils";
import {
swapComponent,
stockTicker,
screenWidth,
getCache,
setCache,
} from "$lib/store";
import InfoModal from "$lib/components/InfoModal.svelte";
import { Chart } from "svelte-echarts";
import { init, use } from "echarts/core";
import { ScatterChart } from "echarts/charts";
import { GridComponent, TooltipComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";
export let data: any; // Add type for `data` if possible
use([ScatterChart, GridComponent, TooltipComponent, CanvasRenderer]);
let isLoaded = false;
const tabs = [{ title: "Effective Date" }, { title: "Expiration Date" }];
let activeIdx = 0;
function changeTab(index: number) {
activeIdx = index;
optionsData = getPlotOptions(
activeIdx === 0 ? "effectiveDate" : "expirationDate",
);
}
let rawData: any[] = [];
let optionsData: any;
let avgNotionalAmount: number | undefined;
let avgNotionalQuantity: number | undefined;
function getPlotOptions(state: "effectiveDate" | "expirationDate") {
const combinedData = rawData?.map((item) => ({
date:
state === "effectiveDate"
? item["Effective Date"]
: item["Expiration Date"],
notionalAmount: item["Notional amount-Leg 1"],
notionalQuantity: item["Total notional quantity-Leg 1"],
}));
// Group data by date and sum the values
const groupedData = combinedData.reduce(
(acc, curr) => {
const { date, notionalAmount, notionalQuantity } = curr;
if (acc[date]) {
acc[date].notionalAmount += notionalAmount;
acc[date].notionalQuantity += notionalQuantity;
} else {
acc[date] = {
date,
notionalAmount,
notionalQuantity,
};
}
return acc;
},
{} as Record<string, any>,
);
const result = Object.values(groupedData);
result?.sort(
(a, b) => new Date(a?.date).getTime() - new Date(b?.date).getTime(),
);
const dates = result?.map((item) => item?.date);
const notionalAmount = result?.map((item) => item?.notionalAmount);
const notionalQuantity = result?.map((item) => item?.notionalQuantity);
const totalNotionalAmount = notionalAmount?.reduce(
(acc, item) => acc + item,
0,
);
avgNotionalAmount = totalNotionalAmount / notionalAmount?.length;
const totalNotionalQuantity = notionalQuantity?.reduce(
(acc, item) => acc + item,
0,
);
avgNotionalQuantity = totalNotionalQuantity / notionalQuantity?.length;
const option = {
silent: true,
tooltip: {
trigger: "axis",
hideDelay: 100,
},
animation: false,
grid: {
left: "3%",
right: "3%",
bottom: "0%",
top: "10%",
containLabel: true,
},
xAxis: {
type: "category",
boundaryGap: false,
data: dates,
axisLabel: {
color: "#fff",
},
},
yAxis: [
{
type: "value",
splitLine: {
show: false,
},
axisLabel: {
show: false,
},
},
{
type: "value",
splitLine: {
show: false,
},
position: "right",
axisLabel: {
show: false,
},
},
],
series: [
{
name: "Notional Amount",
type: "scatter",
data: dates?.map((date, index) => [date, notionalAmount[index]]),
itemStyle: {
color: "#8F54F4",
},
},
{
name: "Notional Quantity",
type: "scatter",
data: dates?.map((date, index) => [date, notionalQuantity[index]]),
yAxisIndex: 1,
itemStyle: {
color: "#fff",
},
},
],
};
return option;
}
async function getSwapData(ticker: string) {
const cachedData = getCache(ticker, "getSwapData");
if (cachedData) {
rawData = cachedData;
} else {
try {
const postData = { ticker, path: "swap-ticker" };
const response = await fetch("/api/ticker-data", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(postData),
});
if (!response.ok) throw new Error("API request failed");
rawData = await response.json();
setCache(ticker, rawData, "getSwapData");
} catch (error) {
console.error("Failed to fetch swap data:", error);
rawData = [];
}
}
$swapComponent = rawData?.length !== 0; // Correct the use of `$`
}
$: if ($stockTicker && typeof window !== "undefined") {
isLoaded = false;
activeIdx = 0;
getSwapData($stockTicker).then(() => {
optionsData = getPlotOptions("effectiveDate");
isLoaded = true;
});
}
$: charNumber = $screenWidth < 640 ? 20 : 40;
</script>
<section class="overflow-hidden text-white h-full pb-8">
<main class="overflow-hidden">
<div class="flex flex-row items-center">
<label
for="swapInfo"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
>
Swap Data
</label>
<InfoModal
title={"Swap Data"}
content={"Swaps in the stock market are derivative contracts to exchange cash flows or assets, used for risk management, speculation, and enhancing market liquidity."}
id={"swapInfo"}
/>
</div>
{#if isLoaded}
{#if rawData?.length !== 0}
<div class="w-full flex flex-col items-start">
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
The swap data from the past 100 days shows an average notional
amount of {abbreviateNumber(avgNotionalAmount, true)} and an average
notional quantity of {abbreviateNumber(avgNotionalQuantity)}.
</div>
</div>
<div class="pb-2 rounded-md bg-default">
<div
class="bg-secondary w-fit relative flex flex-wrap items-center justify-center rounded-md p-1 mt-4"
>
{#each tabs as item, i}
<button
on:click={() => changeTab(i)}
class="group relative z-1 rounded-full px-3 py-1 {activeIdx ===
i
? 'z-0'
: ''} "
>
{#if activeIdx === i}
<div class="absolute inset-0 rounded-md bg-[#fff]"></div>
{/if}
<span class="relative text-sm block duration-200 text-white">
{item.title}
</span>
</button>
{/each}
</div>
<div class="app w-full h-[300px] mt-5">
<Chart {init} options={optionsData} class="chart" />
</div>
</div>
<div
class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12"
>
<div
class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
>
<div
class="h-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<div
class="w-3 h-3 bg-[#8F54F4] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
aria-hidden="true"
></div>
<span
class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block"
>
Notional Amount
</span>
</div>
<div
class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
>
<div
class="h-full transform -translate-x-1/2"
aria-hidden="true"
></div>
<div
class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
aria-hidden="true"
></div>
<span
class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm: inline-block"
>
Notional Quantity
</span>
</div>
</div>
{/if}
{:else}
<div class="flex justify-center items-center h-80">
<div class="relative">
<label
class="bg-secondary rounded-md h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
>
<span class="loading loading-spinner loading-md text-gray-400"
></span>
</label>
</div>
</div>
{/if}
</main>
</section>
<style>
.app {
height: 300px;
max-width: 100%; /* Ensure chart width doesn't exceed the container */
}
@media (max-width: 640px) {
.app {
height: 210px;
}
}
.chart {
width: 100%;
}
</style>

View File

@ -1,655 +0,0 @@
<script lang="ts">
import {
searchBarData,
stockTicker,
etfTicker,
screenWidth,
} from "$lib/store";
let apiURL = import.meta.env.VITE_USEAST_API_URL;
let apiKey = import.meta.env.VITE_STOCKNEAR_API_KEY;
let assetType = "";
let showSuggestions = false;
let notFoundTicker = false;
let searchQuery = "";
let searchOpen = false;
let searchBarModalChecked = false; // Initialize it to false
let inputElement;
async function loadSearchData() {
if ($searchBarData?.length !== 0) {
return;
} else {
// make the GET request to the endpoint
const response = await fetch(apiURL + "/searchbar-data", {
method: "GET",
headers: {
"Content-Type": "application/json",
"X-API-KEY": apiKey,
},
});
$searchBarData = await response.json();
}
}
function popularTicker(state) {
searchOpen = false;
stockTicker.update((value) => state.toUpperCase());
const closePopup = document.getElementById("tagSearchBarModal");
closePopup?.dispatchEvent(new MouseEvent("click"));
}
function searchBarTicker(state, assetType) {
showSuggestions = false;
if (
state !== "" &&
$searchBarData.find((item) => item?.symbol === state.toUpperCase())
) {
stockTicker.update((value) => state?.toUpperCase());
//In this case we dont care if stockTicker or etfTicker
searchOpen = false;
notFoundTicker = false;
//searchQuery = state.toUpperCase();
const closePopup = document.getElementById("tagSearchBarModal");
closePopup?.dispatchEvent(new MouseEvent("click"));
} else {
notFoundTicker = true;
//searchQuery ="";
}
searchQuery = "";
}
let searchResults = [];
async function search() {
const normalizedSearchQuery = searchQuery?.toLowerCase();
// Define names for which symbols without dots should be prioritized
const prioritizeWithoutDotsForNames = [
"apple" /* Add more names as needed */,
];
const filteredList = $searchBarData
?.map((item) => ({
...item,
nameLower: item?.name?.toLowerCase(),
symbolLower: item?.symbol?.toLowerCase(),
}))
?.filter(
({ nameLower, symbolLower }) =>
nameLower?.includes(normalizedSearchQuery) ||
symbolLower?.includes(normalizedSearchQuery),
);
filteredList?.sort((a, b) => {
const aSymbolLower = a?.symbolLower;
const bSymbolLower = b?.symbolLower;
const aNameLower = a?.nameLower;
const bNameLower = b?.nameLower;
// Check for exact symbol matches
const isExactMatchA = aSymbolLower === normalizedSearchQuery;
const isExactMatchB = bSymbolLower === normalizedSearchQuery;
if (isExactMatchA && !isExactMatchB) {
return -1; // Prioritize exact symbol match for A
} else if (!isExactMatchA && isExactMatchB) {
return 1; // Prioritize exact symbol match for B
}
const aSymbolIndex = aSymbolLower?.indexOf(normalizedSearchQuery);
const bSymbolIndex = bSymbolLower?.indexOf(normalizedSearchQuery);
const aNameIndex = aNameLower?.indexOf(normalizedSearchQuery);
const bNameIndex = bNameLower?.indexOf(normalizedSearchQuery);
// If no exact symbol match, prioritize based on the combined position in name and symbol
const positionComparison =
aSymbolIndex + aNameIndex - (bSymbolIndex + bNameIndex);
// Additional condition for prioritizing symbols without dots for specific names
if (prioritizeWithoutDotsForNames.includes(normalizedSearchQuery)) {
const aHasDot = aSymbolLower?.includes(".") || false;
const bHasDot = bSymbolLower?.includes(".") || false;
// Prioritize results without dots for the specified names
return aHasDot - bHasDot || positionComparison;
}
return positionComparison;
});
searchResults = filteredList?.slice(0, 5);
showSuggestions = normalizedSearchQuery !== "";
}
const onKeyPress = (e) => {
if (e.charCode === 13) {
searchBarTicker(searchQuery, assetType);
focusedSuggestion = "";
}
};
let focusedSuggestion = null;
function handleKeyDown(event) {
if (event.key === "ArrowDown" && showSuggestions) {
// Move down in the suggestions
event.preventDefault(); // Prevent scrolling
const currentIndex = searchResults.findIndex(
(item) => item.symbol === searchQuery,
);
if (currentIndex < searchResults.length - 1) {
searchQuery = searchResults[currentIndex + 1].symbol;
assetType = searchResults[currentIndex + 1].type;
focusedSuggestion = searchQuery; // Update the focused suggestion
}
} else if (event.key === "ArrowUp" && showSuggestions) {
// Move up in the suggestions
event.preventDefault(); // Prevent scrolling
const currentIndex = searchResults.findIndex(
(item) => item.symbol === searchQuery,
);
if (currentIndex > 0) {
searchQuery = searchResults[currentIndex - 1].symbol;
assetType = searchResults[currentIndex - 1].type;
focusedSuggestion = searchQuery; // Update the focused suggestion
}
} else if (event.key === "ArrowDown" && !showSuggestions) {
// Move down in the suggestions
event.preventDefault(); // Prevent scrolling
const currentIndex = popularList.findIndex(
(item) => item.symbol === searchQuery,
);
if (currentIndex < popularList.length - 1) {
searchQuery = popularList[currentIndex + 1].symbol;
assetType = popularList[currentIndex + 1].type;
focusedSuggestion = searchQuery; // Update the focused suggestion
}
} else if (event.key === "ArrowUp" && !showSuggestions) {
// Move up in the suggestions
event.preventDefault(); // Prevent scrolling
const currentIndex = popularList.findIndex(
(item) => item.symbol === searchQuery,
);
if (currentIndex > 0) {
searchQuery = popularList[currentIndex - 1].symbol;
assetType = popularList[currentIndex - 1].type;
focusedSuggestion = searchQuery; // Update the focused suggestion
}
}
}
let charNumber = 20;
$: {
if ($screenWidth < 640) {
charNumber = 20;
} else {
charNumber = 20;
}
}
let popularList = [];
const popularSymbols = [
"ADBE",
"SHOP",
"CRM",
"UBER",
"RDHL",
"TSM",
"INTC",
"NIO",
"DBX",
"HOOD",
"AMZN",
"TSLA",
"AMD",
"MCD",
"NVDA",
"PYPL",
"AAPL",
"BYND",
"KO",
];
$: {
if ($searchBarData && popularList?.length === 0) {
popularList = $searchBarData.filter(({ symbol }) =>
popularSymbols?.includes(symbol),
);
// Fisher-Yates (Knuth) Shuffle Algorithm
for (let i = popularList.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[popularList[i], popularList[j]] = [popularList[j], popularList[i]];
}
popularList = popularList?.slice(0, 5);
}
}
$: {
if (searchBarModalChecked === true && typeof window !== "undefined") {
if ($screenWidth > 640) {
inputElement.focus();
}
//Page is not scrollable now
document.body.classList.add("overflow-hidden");
}
}
$: {
if (searchBarModalChecked === false && typeof window !== "undefined") {
showSuggestions = searchQuery = "";
document.body.classList.remove("overflow-hidden");
}
}
$: {
if (searchQuery?.length !== 0) {
notFoundTicker = false;
}
}
</script>
<label
on:click={loadSearchData}
for="tagSearchBarModal"
class="border border-slate-500 mb-2 flex flex-wrap pl-4 pr-4 py-2 m-1 mr-3 justify-between items-center text-sm rounded-xl cursor-pointer text-gray-200 hover:text-gray-100"
>
<svg
class="w-4 h-4 mr-2"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<path
class="fill-current text-white"
d="M7 14c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7zM7 2C4.243 2 2 4.243 2 7s2.243 5 5 5 5-2.243 5-5-2.243-5-5-5z"
/>
<path
class="fill-current text-white"
d="M15.707 14.293L13.314 11.9a8.019 8.019 0 01-1.414 1.414l2.393 2.393a.997.997 0 001.414 0 .999.999 0 000-1.414z"
/>
</svg>
<span class="text-gray-300">Search a ticker...</span>
</label>
<!--Start Searchbar Modal-->
{#if $screenWidth > 640}
<input
type="checkbox"
id="tagSearchBarModal"
class="modal-toggle"
bind:checked={searchBarModalChecked}
/>
<dialog id="tagSearchBarModal" class="modal modal-top">
<label for="tagSearchBarModal" class="cursor-pointer modal-backdrop"
></label>
<div
class="modal-box overflow-hidden rounded-xl bg-default sm:my-8 sm:m-auto sm:h-auto w-full sm:w-1/2 2xl:w-1/3"
>
<!-- Search layout -->
<div class="mt-5 sm:mt-0">
<div class="relative">
<label for="modal-search" class="sr-only">Search</label>
<input
id="modal-search"
class="rounded-md w-full text-white bg-default border border-gray-600 focus:ring-transparent placeholder-gray-200 py-3 pl-10 pr-4"
type="search"
placeholder="Search Anything…"
bind:value={searchQuery}
bind:this={inputElement}
on:input={search}
on:keydown={handleKeyDown}
on:keypress={onKeyPress}
autocomplete="off"
/>
<button
on:click={() => searchBarTicker(searchQuery, assetType)}
class="absolute inset-0 right-auto group"
type="submit"
aria-label="Search"
>
<svg
class="w-4 h-4 shrink-0 fill-current text-white ml-4 mr-2 text-slate-400"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
><path
d="M7 14c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7zM7 2C4.243 2 2 4.243 2 7s2.243 5 5 5 5-2.243 5-5-2.243-5-5-5z"
/>
<path
d="M15.707 14.293L13.314 11.9a8.019 8.019 0 01-1.414 1.414l2.393 2.393a.997.997 0 001.414 0 .999.999 0 000-1.414z"
/>
</svg>
</button>
</div>
</div>
{#if $searchBarData?.length !== 0}
<div class="py-4">
<!-- Popular searches -->
<div class="mb-3 last:mb-0 mt-3">
{#if notFoundTicker}
<p class="text-xs font-semibold text-[#FB6A67] px-2 mb-4">
Oh snapp, ticker does not exist in our database
</p>
{/if}
{#if !showSuggestions}
<div class="text-start text-sm font-semibold text-white mb-2">
Popular
</div>
{/if}
<ul class="text-sm">
{#if !showSuggestions}
{#each popularList as item}
<li class="border-b border-gray-800">
<a
data-sveltekit-preload-data="false"
on:click={() => popularTicker(item?.symbol)}
class="mb-2 {item?.symbol === focusedSuggestion
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#404040] bg-opacity-[0.25] rounded group'
: 'shake-ticker cursor-pointer bg-default sm:hover:bg-[#17171A] rounded-md flex justify-start items-center p-2 text-white group'} w-full"
>
<div class="flex flex-row items-center w-full">
<div
class="rounded-full w-10 h-10 relative bg-[#000] flex items-center justify-center"
>
<img
style="clip-path: circle(50%);"
class="w-6 h-6"
src={`https://financialmodelingprep.com/image-stock/${item?.symbol}.png`}
loading="lazy"
/>
</div>
<div class="flex flex-col ml-2">
<span class="text-blue-400">{item?.symbol}</span>
<span class="text-white"
>{item?.name.length > 150
? item?.name?.slice(0, 150) + "..."
: item?.name}</span
>
</div>
<div class="text-white ml-auto">
{item?.type}
</div>
</div>
</a>
</li>
{/each}
{:else if showSuggestions && searchResults?.length > 0}
<div class="text-start text-sm font-semibold text-white mb-2">
Suggestions
</div>
{#each searchResults as item}
<li class="border-b border-gray-800">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-label-has-associated-control -->
<label
data-sveltekit-preload-data="false"
on:click={() => searchBarTicker(item?.symbol, item?.type)}
class="mb-2 {item?.symbol === focusedSuggestion
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#404040] bg-opacity-[0.25] rounded group'
: 'cursor-pointer mb-2 bg-default sm:hover:bg-[#17171A] rounded-md flex justify-start items-center p-2 text-white group'}"
>
<div class="flex flex-row items-center w-full">
<div class="flex flex-col">
<span class="text-blue-400">{item?.symbol}</span>
<span class="text-white"
>{item?.name?.length > 150
? item?.name?.slice(0, 150) + "..."
: item?.name}</span
>
</div>
<div class="text-white ml-auto">
{item?.type}
</div>
</div>
</label>
</li>
{/each}
{:else if showSuggestions && searchResults?.length === 0}
<li>
<label
class="flex items-center p-2 text-white hover:text-white hover:bg-[#404040] bg-opacity-[0.25] rounded group"
>
<svg
class="w-3 h-3 fill-slate-400 shrink-0 mr-3 dark:fill-slate-500"
width="12"
height="12"
viewBox="0 0 12 12"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11.953 4.29a.5.5 0 0 0-.454-.292H6.14L6.984.62A.5.5 0 0 0 6.12.173l-6 7a.5.5 0 0 0 .379.825h5.359l-.844 3.38a.5.5 0 0 0 .864.445l6-7a.5.5 0 0 0 .075-.534Z"
/>
</svg>
<span>No results found</span>
</label>
</li>
{/if}
</ul>
</div>
</div>
{:else}
<div class="flex justify-center items-center m-auto mt-4 py-20">
<span class="loading loading-lg loading-spinner text-success"></span>
</div>
{/if}
<label for="searchBarModal" class="absolute left-6 top-4 sm:hidden">
<svg
class="w-6 h-6 inline-block mb-0.5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="#fff"
d="M9.125 21.1L.7 12.7q-.15-.15-.213-.325T.425 12q0-.2.063-.375T.7 11.3l8.425-8.425q.35-.35.875-.35t.9.375q.375.375.375.875t-.375.875L3.55 12l7.35 7.35q.35.35.35.863t-.375.887q-.375.375-.875.375t-.875-.375Z"
/></svg
>
<span class="text-white text-md"> Return </span>
</label>
</div>
</dialog>
{:else}
<!--Start Drawer Sidewise for mobile-->
<div class="drawer drawer-end overflow-hidden" style="z-index: 9999">
<input
id="tagSearchBarModal"
type="checkbox"
class="drawer-toggle"
bind:checked={searchBarModalChecked}
/>
<div class="drawer-side overflow-hidden">
<div
class="modal-box overflow-hidden rounded-xl bg-default min-h-screen w-screen pt-10"
>
<!-- Search layout -->
<div class="mt-5 sm:mt-0">
<div class="relative">
<label for="modal-search" class="sr-only">Search</label>
<input
id="modal-search"
class="rounded-md w-full text-white bg-default border border-gray-600 focus:ring-transparent placeholder-gray-200 py-3 pl-10 pr-4"
type="search"
placeholder="Search Anything…"
bind:value={searchQuery}
bind:this={inputElement}
on:input={search}
on:keydown={handleKeyDown}
on:keypress={onKeyPress}
autocomplete="off"
/>
<button
on:click={() => searchBarTicker(searchQuery, assetType)}
class="absolute inset-0 right-auto group"
type="submit"
aria-label="Search"
>
<svg
class="w-4 h-4 shrink-0 fill-current text-white ml-4 mr-2 text-slate-400"
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M7 14c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7zM7 2C4.243 2 2 4.243 2 7s2.243 5 5 5 5-2.243 5-5-2.243-5-5-5z"
/>
<path
d="M15.707 14.293L13.314 11.9a8.019 8.019 0 01-1.414 1.414l2.393 2.393a.997.997 0 001.414 0 .999.999 0 000-1.414z"
/>
</svg>
</button>
</div>
</div>
{#if $searchBarData?.length !== 0}
<div class="py-4">
<!-- Popular searches -->
<div class="mb-3 last:mb-0 mt-3">
{#if notFoundTicker}
<p class="text-xs font-semibold text-[#FB6A67] px-2 mb-4">
Oh snapp, ticker does not exist in our database
</p>
{/if}
{#if !showSuggestions}
<div
class="text-start text-sm font-semibold text-slate-400 mb-2"
>
Popular
</div>
{/if}
<ul class="text-sm">
{#if !showSuggestions}
{#each popularList as item}
<li>
<a
data-sveltekit-preload-data="false"
on:click={() => popularTicker(item?.symbol, item?.type)}
class="mb-2 {item?.symbol === focusedSuggestion
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#404040] bg-opacity-[0.25] rounded group'
: 'cursor-pointer bg-default rounded-md flex justify-start items-center p-2 text-white group'} w-full"
>
<div class="flex flex-row items-center w-full">
<div
class="rounded-full w-10 h-10 relative bg-[#000] flex items-center justify-center"
>
<img
style="clip-path: circle(50%);"
class="w-6 h-6"
src={`https://financialmodelingprep.com/image-stock/${item?.symbol}.png`}
loading="lazy"
/>
</div>
<div class="flex flex-col ml-2">
<span class="text-blue-400">{item?.symbol}</span>
<span class="text-white"
>{item?.name.length > charNumber
? item?.name.slice(0, charNumber) + "..."
: item?.name}</span
>
</div>
<div class="text-white ml-auto mr-2">
{item?.type}
</div>
</div>
</a>
</li>
{/each}
{:else if showSuggestions && searchResults?.length > 0}
<div
class="text-start text-sm font-semibold text-slate-400 mb-2"
>
Suggestions
</div>
{#each searchResults as item}
<li>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-label-has-associated-control -->
<label
data-sveltekit-preload-data="false"
on:click={() =>
searchBarTicker(item?.symbol, item?.type)}
class="mb-2 {item?.symbol === focusedSuggestion
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#404040] bg-opacity-[0.25] rounded group'
: 'cursor-pointer mb-2 bg-default rounded-md flex justify-start items-center p-2 text-white group'}"
>
<div class="flex flex-row items-center w-full">
<div class="flex flex-col ml-1">
<span class="text-blue-400">{item?.symbol}</span>
<span class="text-white"
>{item?.name?.length > charNumber
? item?.name?.slice(0, charNumber) + "..."
: item?.name}</span
>
</div>
<div class="text-white ml-auto mr-2">
{item?.type}
</div>
</div>
</label>
</li>
{/each}
{:else if showSuggestions && searchResults?.length === 0}
<li>
<label
class="flex items-center p-2 text-white hover:text-white hover:bg-[#404040] bg-opacity-[0.25] rounded group"
>
<svg
class="w-3 h-3 fill-slate-400 shrink-0 mr-3 dark:fill-slate-500"
width="12"
height="12"
viewBox="0 0 12 12"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11.953 4.29a.5.5 0 0 0-.454-.292H6.14L6.984.62A.5.5 0 0 0 6.12.173l-6 7a.5.5 0 0 0 .379.825h5.359l-.844 3.38a.5.5 0 0 0 .864.445l6-7a.5.5 0 0 0 .075-.534Z"
/>
</svg>
<span>No results found</span>
</label>
</li>
{/if}
</ul>
</div>
</div>
{:else}
<div class="flex justify-center items-center m-auto mt-4 py-20">
<span class="loading loading-lg loading-spinner text-success"
></span>
</div>
{/if}
<label for="tagSearchBarModal" class="absolute left-6 top-4 sm:hidden">
<svg
class="w-6 h-6 inline-block mb-0.5"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="#fff"
d="M9.125 21.1L.7 12.7q-.15-.15-.213-.325T.425 12q0-.2.063-.375T.7 11.3l8.425-8.425q.35-.35.875-.35t.9.375q.375.375.375.875t-.375.875L3.55 12l7.35 7.35q.35.35.35.863t-.375.887q-.375.375-.875.375t-.875-.375Z"
/></svg
>
</label>
</div>
</div>
</div>
<!--End Drawer Sidewise for mobile-->
{/if}
<!--End Searchbar Modal-->

View File

@ -1,36 +0,0 @@
<script>
export let lines
let open = true
const toggle = () => open = !open
</script>
<div class="" class:open class:lines on:click={toggle}>
<!-- if it's a "lines" style -->
{#if lines}
{open ? '' : '↕️'}
{:else}
{open ? '[-]' : '[+] comments collapsed'}
{/if}
</div>
<div style:display={open ? 'block' : 'none'}>
<slot />
</div>
<style>
.toggle{
cursor: pointer;
}
.toggle.lines {
width: 0.5px;
background: #334155;
height: 100%;
display: block;
position: absolute;
left: 0;
top: 0;
}
.toggle.lines:hover {
background: #ddd;
}
</style>

View File

@ -1,234 +0,0 @@
<script lang 'ts'></script>
<section class="overflow-hidden text-white h-full pb-8 sm:pb-2">
<main class="overflow-hidden">
<div class="flex flex-row items-center">
<label
for="trendAnalysisInfo"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
>
AI Trend Analysis
</label>
<InfoModal
title={"Trend Analysis"}
content={`We trained our model using historical data of $${$assetType === "stock" ? $stockTicker : $assetType === "etf" ? $etfTicker : $cryptoTicker} and assessed its precision and accuracy with unseen company data to evaluate its performance. The model exhibits varying performance across different time periods.`}
id={"trendAnalysisInfo"}
/>
</div>
{#if isLoaded}
{#if trendList?.length !== 0}
<div class="w-full flex flex-col items-start">
<div class="text-white text-[1rem] mt-1 sm:mt-3 mb-1 w-full">
Our model uses technical indicators to predict the next trend. Here
are the stats of the model for {$displayCompanyName} to ensure transparency
and reliability.
</div>
</div>
<div class="w-full mt-5 mb-5 flex justify-start items-center">
<div
class="w-full grid grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-y-3 gap-x-3"
>
<!--Start Flow Sentiment-->
<div
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-primary shadow-lg rounded-md h-20"
>
<div class="flex flex-col items-start">
<span class=" text-gray-200 text-sm"
>Trend Sentiment</span
>
<span
class="text-start text-[1rem] sm:text-lg font-semibold {flowSentiment ===
'Bullish'
? 'text-[#00FC50]'
: 'text-[#FF2F1F]'}">{flowSentiment}</span
>
</div>
</div>
<!--End Flow Sentiment-->
<!--Start Put/Call-->
<div
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-primary shadow-lg rounded-md h-20"
>
<div class="flex flex-col items-start">
<span class=" text-gray-200 text-sm">Accuracy</span>
<span
class="text-start text-sm sm:text-[1rem] text-white"
>
{accuracy >= 65
? "Good"
: accuracy >= 50
? "Moderate"
: "Bad"}
</span>
</div>
<!-- Circular Progress -->
<div class="relative size-14 ml-auto">
<svg
class="size-full w-14 h-14"
viewBox="0 0 36 36"
xmlns="http://www.w3.org/2000/svg"
>
<!-- Background Circle -->
<circle
cx="18"
cy="18"
r="16"
fill="none"
class="stroke-current text-[#3E3E3E]"
stroke-width="3"
></circle>
<!-- Progress Circle inside a group with rotation -->
<g class="origin-center -rotate-90 transform">
<circle
cx="18"
cy="18"
r="16"
fill="none"
class="stroke-current {accuracy >= 65
? 'text-[#00FC50]'
: accuracy >= 50
? 'text-[#F8901E]'
: 'text-[#FF2F1F]'}"
stroke-width="3"
stroke-dasharray="100"
stroke-dashoffset={100 - accuracy}
></circle>
</g>
</svg>
<!-- Percentage Text -->
<div
class="absolute top-1/2 start-1/2 transform -translate-y-1/2 -translate-x-1/2"
>
<span class="text-center text-white text-sm">{accuracy}%</span
>
</div>
</div>
<!-- End Circular Progress -->
</div>
<!--End Put/Call-->
<!--Start Precision-->
<div
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-primary shadow-lg rounded-md h-20"
>
<div class="flex flex-col items-start">
<span class=" text-gray-200 text-sm">Precision</span>
<span
class="text-start text-sm sm:text-[1rem] text-white"
>
{precision >= 65
? "Good"
: precision >= 50
? "Moderate"
: "Bad"}
</span>
</div>
<!-- Circular Progress -->
<div class="relative size-14 ml-auto">
<svg
class="size-full w-14 h-14"
viewBox="0 0 36 36"
xmlns="http://www.w3.org/2000/svg"
>
<!-- Background Circle -->
<circle
cx="18"
cy="18"
r="16"
fill="none"
class="stroke-current text-[#3E3E3E]"
stroke-width="3"
></circle>
<!-- Progress Circle inside a group with rotation -->
<g class="origin-center -rotate-90 transform">
<circle
cx="18"
cy="18"
r="16"
fill="none"
class="stroke-current {precision >= 65
? 'text-[#00FC50]'
: precision >= 50
? 'text-[#F8901E]'
: 'text-[#FF2F1F]'}"
stroke-width="3"
stroke-dasharray="100"
stroke-dashoffset={100 - precision}
></circle>
</g>
</svg>
<!-- Percentage Text -->
<div
class="absolute top-1/2 start-1/2 transform -translate-y-1/2 -translate-x-1/2"
>
<span class="text-center text-white text-sm"
>{precision}%</span
>
</div>
</div>
<!-- End Circular Progress -->
</div>
<!--End Precision-->
</div>
</div>
<select
class="mt-1 sm:mt-3 ml-1 w-36 select select-bordered select-sm p-0 pl-5 overflow-y-auto bg-secondary"
on:change={changeStatement}
>
<option disabled>Choose Time Period</option>
<option disabled={deactivateContent} value="oneWeek">
{!deactivateContent ? "Predict 1W" : "1W (Pro Only)"}
</option>
<option disabled={deactivateContent} value="oneMonth">
{!deactivateContent ? "Predict 1M" : "1M (Pro Only)"}
</option>
<option value="threeMonth" selected>Predict 3M</option>
</select>
<div class="text-white text-[1rem] mt-4 sm:mt-7 ml-1">
Over the next {displayData === "threeMonth"
? "3 months"
: displayData === "oneMonth"
? "1 month"
: "1 week"}, the model forecasts a
<span
class="font-semibold {flowSentiment === 'Bullish'
? 'text-[#00FC50]'
: 'text-[#FF2F1F]'}">{flowSentiment}</span
>
trend, indicating that the future price is expected to {flowSentiment ===
"Bullish"
? "exceed"
: "to be less than"} the previous price of
<span class="">${lastPrice ?? "n/a"}</span>.
</div>
{:else}
<div class="flex justify-center items-center h-80">
<div class="relative">
<label
class="bg-secondary rounded-md h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
>
<span class="loading loading-spinner loading-md text-gray-400"
></span>
</label>
</div>
</div>
{/if}
{:else}
<div class="flex justify-center items-center h-80">
<div class="relative">
<label
class="bg-secondary rounded-md h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
>
<span class="loading loading-spinner loading-md text-gray-400"
></span>
</label>
</div>
</div>
{/if}
</main>
</section>

View File

@ -1,44 +0,0 @@
<script lang="ts">
export let state;
let color = state === "active" ? "#0076FE" : "#A6ADBB";
/*
async function clickEvent()
{ if(state === 'active')
{
state = 'deactive';
}
else {
state = 'active';
}
}
*/
</script>
<div
class="flex justify-center items-center {state === 'active'
? 'text-[#0076FE] bg-[#31304D] lg:bg-inherit'
: 'text-[#A6ADBB]'} rounded-md w-8 h-8 relative"
>
<svg
class="lg:hidden inline-block rotate-180 w-4 h-4"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512.171 512.171"
xml:space="preserve"
><path
fill="currentColor"
d="M479.046,283.925c-1.664-3.989-5.547-6.592-9.856-6.592H352.305V10.667C352.305,4.779,347.526,0,341.638,0H170.971 c-5.888,0-10.667,4.779-10.667,10.667v266.667H42.971c-4.309,0-8.192,2.603-9.856,6.571c-1.643,3.989-0.747,8.576,2.304,11.627 l212.8,213.504c2.005,2.005,4.715,3.136,7.552,3.136s5.547-1.131,7.552-3.115l213.419-213.504 C479.793,292.501,480.71,287.915,479.046,283.925z"
></path></svg
>
<svg
class="hidden lg:block cursor-pointer rotate-180 inline-block w-9 h-9 hover:text-[#fff] text-[#5C5C5C]"
fill={state === "active" ? color : "currentColor"}
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
><path
d="M17.9188 8.17969H11.6888H6.07877C5.11877 8.17969 4.63877 9.33969 5.31877 10.0197L10.4988 15.1997C11.3288 16.0297 12.6788 16.0297 13.5088 15.1997L15.4788 13.2297L18.6888 10.0197C19.3588 9.33969 18.8788 8.17969 17.9188 8.17969Z"
/></svg
>
</div>

View File

@ -901,10 +901,12 @@
{:else}
<a
href="/login"
class="inline-flex items-center justify-center rounded bg-[#3B82F6] dark:bg-[#fff] dark:text-black px-4 py-2 text-sm font-semibold shadow-xs transition-all duration-150 sm:hover:bg-blue-600 dark:sm:hover:bg-gray-300 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-purple-600"
class="inline-flex items-center justify-center rounded bg-[#3B82F6] dark:bg-[#fff] text-white dark:text-black px-4 py-2 text-sm font-semibold shadow-xs transition-all duration-150 sm:hover:bg-blue-600 dark:sm:hover:bg-gray-300 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-purple-600"
>
Login
</a>
{/if}
</div>
</div>

View File

@ -721,7 +721,7 @@
<!--End Price Alert -->
<div
class="hidden sm:flex items-end justify-end absolute right-1.5 top-12 {$scoreComponent ===
class="hidden sm:flex items-end justify-end absolute right-1.5 top-0 {$scoreComponent ===
false
? 'invisible'
: ''}"
@ -825,12 +825,12 @@
class="border-l border-default pl-3 bp:pl-5"
>
<div
class="block text-2xl sm:text-[1.7rem] font-semibold leading-5 text-faded sm:inline"
class="block text-2xl sm:text-[1.7rem] font-semibold leading-5 sm:inline"
>
{prePostData?.price?.toFixed(2)}
</div>
<div
class="mt-1.5 block text-sm xs:text-base sm:mt-0 sm:inline sm:text-lg {prePostData?.changesPercentage >=
class="mt-1.5 block text-sm sm:mt-0 sm:inline sm:text-lg {prePostData?.changesPercentage >=
0
? "before:content-['+'] text-green-600 dark:text-[#00FC50]"
: 'text-red-600 dark:text-[#FF2F1F]'}"

View File

@ -70,9 +70,7 @@
description={`Analyze the historical price reaction of ${$displayCompanyName} (${$stockTicker}) following earnings releases to understand market trends and investor sentiment.`}
/>
<section
class="bg-default w-full overflow-hidden min-h-screen text-white h-full"
>
<section class=" w-full overflow-hidden min-h-screen h-full">
<div class="w-full flex justify-center w-full sm-auto h-full overflow-hidden">
<div
class="w-full relative flex justify-center items-center overflow-hidden"
@ -80,7 +78,7 @@
<main class="w-full">
<div class="sm:pl-7 sm:pt-7 sm:pb-7 m-auto mt-2 sm:mt-0">
<div class="mb-3">
<h1 class="text-xl sm:text-2xl text-white font-bold">
<h1 class="text-xl sm:text-2xl font-bold">
Price Reaction to Earnings Reports
</h1>
</div>
@ -90,18 +88,17 @@
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 mb-6"
>
<div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors"
class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
>
<div class="text-[#c3c6d0] text-sm mb-2 flex items-center">
<div class=" text-sm mb-2 flex items-center">
<span>EPS Beats Estimate</span>
<span class="ml-1 text-violet-400"></span>
</div>
<div class="flex items-baseline">
<span class="text-2xl font-bold text-white"
<span class="text-2xl font-bold"
>{earningsData.positiveEpsPercent}%</span
>
<div class="flex flex-col ml-2">
<span class="text-sm text-[#c3c6d0]"
<span class="text-sm"
>{`${earningsData?.positiveEpsSurprises}/${earningsData?.totalReports}`}
quarters</span
>
@ -116,22 +113,21 @@
</div>
<div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors"
class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
>
<div class="text-[#c3c6d0] text-sm mb-2 flex items-center">
<div class=" text-sm mb-2 flex items-center">
<span>Revenue Beats Estimate</span>
<span class="ml-1 text-red-400"></span>
</div>
<div class="flex items-baseline">
<span class="text-2xl font-bold text-white"
<span class="text-2xl font-bold"
>{earningsData.positiveRevenuePercent}%</span
>
<div class="flex flex-col ml-2">
<span class="text-sm text-[#c3c6d0]"
<span class="text-sm"
>{`${earningsData?.positiveRevenueSurprises}/${earningsData?.totalReports}`}
quarters</span
>
<span class="text-xs text-red-400">
<span class="text-xs text-red-600 dark:text-red-400">
{earningsData?.positiveRevenueSurprises >
earningsData?.totalReports / 2
? "Above Average"
@ -142,24 +138,19 @@
</div>
<div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors"
class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
>
<div class="text-[#c3c6d0] text-sm mb-2 flex items-center">
<div class=" text-sm mb-2 flex items-center">
<span>Avg. Price Impact</span>
<span
class="ml-1 text-{metrics.avgPriceImpact >= 0
? 'green'
: 'red'}-400">●</span
>
</div>
<div class="flex items-baseline">
<span class="text-2xl font-bold text-white"
<span class="text-2xl font-bold"
>{metrics.avgPriceImpact >= 0
? "+"
: ""}{metrics.avgPriceImpact}%</span
>
<div class="flex flex-col ml-2">
<span class="text-sm text-[#c3c6d0]">Next Day</span>
<span class="text-sm">Next Day</span>
<span
class="text-xs text-{metrics.avgPriceImpact >= 0
? 'green'
@ -172,19 +163,18 @@
</div>
<div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors"
class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
>
<div class="text-[#c3c6d0] text-sm mb-2 flex items-center">
<div class=" text-sm mb-2 flex items-center">
<span>Volatility Impact</span>
<span class="ml-1 text-yellow-400"></span>
</div>
<div class="flex items-baseline">
<span class="text-2xl font-bold text-white"
<span class="text-2xl font-bold"
{metrics.volatilityImpact}%</span
>
<div class="flex flex-col ml-2">
<span class="text-sm text-[#c3c6d0]">Range</span>
<span class="text-xs text-yellow-400">
<span class="text-sm">Range</span>
<span class="text-xs text-yellow-700 dark:text-yellow-400">
{Number(metrics.volatilityImpact) > 3 ? "High" : "Normal"}
Impact
</span>
@ -201,10 +191,10 @@
<div class="w-full overflow-x-auto no-scrollbar">
<table
class="table-fixed leading-3 border-separate border-spacing-0 font-sans tabular-nums text-white w-full"
class="table-fixed leading-3 border-separate border-spacing-0 font-sans tabular-nums w-full"
>
<thead
><tr class="bg-inherit text-[#c3c6d0] text-sm sm:text-[1rem]"
><tr class=" text-sm sm:text-[1rem]"
><th
class="w-44 whitespace-nowrap font-normal h-5 text-left px-1"
>Report Date</th
@ -219,16 +209,16 @@
>-1 Day</th
><th class="px-0 w-1 whitespace-nowrap font-normal h-5 p-0"
></th><th
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-600 dark:text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
>Open</th
><th
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-600 dark:text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
>High</th
><th
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-600 dark:text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
>Low</th
><th
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
class="px-4 last:pr-11 w-20 last:w-24.5 text-violet-600 dark:text-violet-300 font-semibold whitespace-nowrap font-normal h-5 text-right p-0"
>Close</th
><th class="px-0 w-1 whitespace-nowrap font-normal h-5 p-0"
></th><th
@ -253,10 +243,8 @@
<tbody class="">
<tr class="group"
><td
class="whitespace-nowrap border-l border-t border-primary py-0.5 rounded-tl-md px-1"
><div
class="flex flex-col items-start text-white w-full"
>
class="whitespace-nowrap border-l border-t border-gray-300 dark:border-primary py-0.5 rounded-tl-md px-1"
><div class="flex flex-col items-start w-full">
<div
class="pr-0.5 mt-2 flex flex-row items-center w-full text-sm"
>
@ -279,93 +267,93 @@
</div>
</div>
<div class="text-[#c3c6d0] text-xs -mt-2 invisible">
<div class=" text-xs -mt-2 invisible">
{item?.quarter}
{item?.year}
</div>
</div></td
><td
class="border-primary px-3.5 py-0.5 border-t border-l px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t border-l px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class=" text-sm sm:text-[1rem]"
>{item?.backward_2_days_close?.toFixed(2)}</span
></td
><td
class="border-primary px-3.5 py-0.5 border-t px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class=" text-sm sm:text-[1rem]"
>{item?.backward_1_days_close?.toFixed(2)}</span
></td
><td
class="border-primary px-3.5 py-0.5 border-t border-r rounded-tr-md px-4 last:pr-11 w-17 last:w-24.5 border-r px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t border-r rounded-tr-md px-4 last:pr-11 w-17 last:w-24.5 border-r px-1 text-right"
><span class=" text-sm sm:text-[1rem]"
>{item?.forward_0_days_close?.toFixed(2)}</span
></td
><td
class="border-primary px-3.5 py-0.5 px-4 last:pr-11 w-17 last:w-24.5 px-1"
class="border-gray-300 dark:border-primary px-3.5 py-0.5 px-4 last:pr-11 w-17 last:w-24.5 px-1"
></td><td
class="border-primary px-3.5 py-0.5 border-t border-l {index ===
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t border-l {index ===
0
? 'rounded-tl-md border-t-violet-500'
: ''} px-4 last:pr-11 w-17 last:w-24.5 border-l border-l-violet-500 px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
? 'rounded-tl-md border-t-violet-800 dark:border-t-violet-500'
: ''} px-4 last:pr-11 w-17 last:w-24.5 border-l border-l-violet-800 dark:border-l-violet-500 px-1 text-right"
><span class=" text-sm sm:text-[1rem]"
>{item?.open?.toFixed(2)}</span
></td
><td
class="border-primary px-3.5 py-0.5 border-t {index ===
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t {index ===
0
? 'border-t-violet-500'
? 'border-t-violet-800 dark:border-t-violet-500'
: ''} px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
><span class=" text-sm sm:text-[1rem]"
>{item?.high?.toFixed(2)}</span
></td
><td
class="border-primary px-3.5 py-0.5 border-t {index ===
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t {index ===
0
? 'border-t-violet-500'
? 'border-t-violet-800 dark:border-t-violet-500'
: ''} px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
><span class=" text-sm sm:text-[1rem]"
>{item?.low?.toFixed(2)}</span
></td
><td
class="border-primary px-3.5 py-0.5 border-t {index ===
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t {index ===
0
? 'rounded-tr-md border-t-violet-500'
? 'rounded-tr-md border-t-violet-800 dark:border-t-violet-500'
: ''} border-r border-r-violet-500 px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
><span class=" text-sm sm:text-[1rem]"
>{item?.close?.toFixed(2)}</span
></td
><td
class="border-primary px-3.5 py-0.5 px-4 last:pr-11 w-17 last:w-24.5 px-1"
class="border-gray-300 dark:border-primary px-3.5 py-0.5 px-4 last:pr-11 w-17 last:w-24.5 px-1"
></td><td
class="border-primary px-3.5 py-0.5 border-t border-l rounded-tl-md px-4 last:pr-11 w-17 last:w-24.5 border-l px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t border-l rounded-tl-md px-4 last:pr-11 w-17 last:w-24.5 border-l px-1 text-right"
><span class=" text-sm sm:text-[1rem]"
>{item?.forward_2_days_close !== undefined
? item?.forward_2_days_close?.toFixed(2)
: "n/a"}</span
></td
><td
class="border-primary px-3.5 py-0.5 border-t px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class=" text-sm sm:text-[1rem]"
>{item?.forward_3_days_close !== undefined
? item?.forward_3_days_close?.toFixed(2)
: "n/a"}</span
></td
><td
class="border-primary px-3.5 py-0.5 border-t px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class=" text-sm sm:text-[1rem]"
>{item?.forward_4_days_close !== undefined
? item?.forward_4_days_close?.toFixed(2)
: "n/a"}</span
></td
><td
class="border-primary px-3.5 py-0.5 border-t border-l px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t border-l px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class=" text-sm sm:text-[1rem]"
>{item?.forward_6_days_close !== undefined
? item?.forward_6_days_close?.toFixed(2)
: "n/a"}</span
></td
><td
class="border-primary px-3.5 py-0.5 border-t border-r px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class="text-white text-sm sm:text-[1rem]"
class="border-gray-300 dark:border-primary px-3.5 py-0.5 border-t border-r px-4 last:pr-11 w-17 last:w-24.5 px-1 text-right"
><span class=" text-sm sm:text-[1rem]"
>{item?.backward_4_days_close
? item?.backward_4_days_close?.toFixed(2)
: "n/a"}</span
@ -378,21 +366,29 @@
? 'opacity-[0.1]'
: ''}"
><td
class="border-l border-primary pl-1 text-gray-200 text-sm px-1"
class="border-l border-gray-300 dark:border-primary pl-1 text-muted dark:text-gray-200 text-sm px-1"
><div class="flex w-full justify-between">
<div class="flex items-center">
<div class="mr-1 text-purple-400">IV:</div>
<div
class="leading-3 w-full whitespace-nowrap text-purple-400 text-white"
class="mr-1 text-purple-700 dark:text-purple-400"
>
IV:
</div>
<div
class="leading-3 w-full whitespace-nowrap text-purple-700 dark:text-purple-400"
>
{item?.iv ?? "-"}
</div>
</div>
<div class="flex items-center">
<div class="mr-1 text-purple-400">RSI:</div>
<div
class="leading-3 w-full whitespace-nowrap text-purple-400 text-white"
class="mr-1 text-purple-700 dark:text-purple-400"
>
RSI:
</div>
<div
class="leading-3 w-full whitespace-nowrap text-purple-700 dark:text-purple-400"
>
{item?.rsi ?? "n/a"}
</div>
@ -401,44 +397,44 @@
<div>{$stockTicker} %</div>
</div></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 border-l px-1 text-right"
><span
class="w-full text-sm sm:text-[1rem] items-baseline justify-end whitespace-nowrap {item?.backward_2_days_change_percent >=
0
? "text-positive before:content-['+']"
: 'text-negative'}"
? "text-green-600 dark:text-positive before:content-['+']"
: 'text-red-600 dark:text-negative'}"
>{item?.backward_2_days_change_percent}%<span
class="w-0 text-center"
></span></span
></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 border-l px-1 text-right"
><span
class="w-full text-sm sm:text-[1rem] items-baseline justify-end whitespace-nowrap {item?.backward_1_days_change_percent >=
0
? "text-positive before:content-['+']"
: 'text-negative'}"
? "text-green-600 dark:text-positive before:content-['+']"
: 'text-red-600 dark:text-negative'}"
>{item?.backward_1_days_change_percent?.toFixed(
2,
)}%<span class="w-0 text-center"></span></span
></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 border-l px-1 text-right"
><span
class="w-full text-sm sm:text-[1rem] items-baseline justify-end whitespace-nowrap {item?.backward_1_days_change_percent >=
0
? "text-positive before:content-['+']"
: 'text-negative'}"
? "text-green-600 dark:text-positive before:content-['+']"
: 'text-red-600 dark:text-negative'}"
>{item?.backward_1_days_change_percent?.toFixed(
2,
)}%<span class="w-0 text-center"></span></span
></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 px-1 text-right"
></td><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l border-l-violet-500 px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 border-l border-l-violet-800 dark:border-l-violet-500 px-1 text-right"
><div
class="w-full whitespace-nowrap rounded border-gray-800 badge-lg text-white text-sm sm:text-[1rem] {item?.open_change_percent >=
class="w-full whitespace-nowrap rounded border-gray-800 badge-lg text-sm sm:text-[1rem] {item?.open_change_percent >=
0
? "bg-positive/60 before:content-['+'] "
: 'bg-negative/70'}"
@ -446,9 +442,9 @@
{item?.open_change_percent?.toFixed(2)}%
</div></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 px-1 text-right"
><div
class="w-full whitespace-nowrap rounded border-gray-800 badge-lg text-white text-sm sm:text-[1rem] {item?.high_change_percent >=
class="w-full whitespace-nowrap rounded border-gray-800 badge-lg text-sm sm:text-[1rem] {item?.high_change_percent >=
0
? "bg-positive/60 before:content-['+'] "
: 'bg-negative/70'}"
@ -456,9 +452,9 @@
{item?.high_change_percent?.toFixed(2)}%
</div></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 px-1 text-right"
><div
class="w-full whitespace-nowrap rounded border-gray-800 badge-lg text-white text-sm sm:text-[1rem] {item?.low_change_percent >=
class="w-full whitespace-nowrap rounded border-gray-800 badge-lg text-sm sm:text-[1rem] {item?.low_change_percent >=
0
? "bg-positive/60 before:content-['+'] "
: 'bg-negative/70'}"
@ -466,9 +462,9 @@
{item?.low_change_percent?.toFixed(2)}%
</div></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-r border-r-violet-500 px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 border-r border-r-violet-500 px-1 text-right"
><div
class="w-full whitespace-nowrap rounded border-gray-800 badge-lg text-white text-sm sm:text-[1rem] {item?.close_change_percent >=
class="w-full whitespace-nowrap rounded border-gray-800 badge-lg text-sm sm:text-[1rem] {item?.close_change_percent >=
0
? "bg-positive/60 before:content-['+'] "
: 'bg-negative/70'}"
@ -476,66 +472,66 @@
{item?.close_change_percent?.toFixed(2)}%
</div></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 px-1 text-right"
></td><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 border-l px-1 text-right"
><span
class="w-full text-sm sm:text-[1rem] items-baseline justify-end whitespace-nowrap {item?.forward_2_days_change_percent >=
0
? "text-positive before:content-['+']"
? "text-green-600 dark:text-positive before:content-['+']"
: item?.forward_2_days_change_percent < 0
? 'text-negative'
: 'text-white'}"
? 'text-red-600 dark:text-negative'
: ''}"
>{item?.forward_2_days_change_percent !== undefined
? item?.forward_2_days_change_percent + "%"
: "n/a"}<span class="w-0 text-center"></span></span
></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 px-1 text-right"
><span
class="w-full text-sm sm:text-[1rem] items-baseline justify-end whitespace-nowrap {item?.forward_3_days_change_percent >=
0
? "text-positive before:content-['+']"
? "text-green-600 dark:text-positive before:content-['+']"
: item?.forward_3_days_change_percent < 0
? 'text-negative'
: 'text-white'}"
? 'text-red-600 dark:text-negative'
: ''}"
>{item?.forward_3_days_change_percent !== undefined
? item?.forward_3_days_change_percent + "%"
: "n/a"}<span class="w-0 text-center"></span></span
></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 px-1 text-right"
><span
class="w-full text-sm sm:text-[1rem] items-baseline justify-end whitespace-nowrap {item?.forward_4_days_change_percent >=
0
? "text-positive before:content-['+']"
? "text-green-600 dark:text-positive before:content-['+']"
: item?.forward_4_days_change_percent < 0
? 'text-negative'
: 'text-white'}"
? 'text-red-600 dark:text-negative'
: ''}"
>{item?.forward_4_days_change_percent !== undefined
? item?.forward_4_days_change_percent + "%"
: "n/a"}<span class="w-0 text-center"></span></span
></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-l px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 border-l px-1 text-right"
><span
class="w-full text-sm sm:text-[1rem] items-baseline justify-end whitespace-nowrap {item?.forward_6_days_change_percent >=
0
? "text-positive before:content-['+']"
? "text-green-600 dark:text-positive before:content-['+']"
: item?.forward_6_days_change_percent < 0
? 'text-negative'
: 'text-white'}"
? 'text-red-600 dark:text-negative'
: ''}"
>{item?.forward_6_days_change_percent !== undefined
? item?.forward_6_days_change_percent + "%"
: "n/a"}<span class="w-0 text-center"></span></span
></td
><td
class="px-4 last:pr-11 w-17 last:w-24.5 border-primary px-3.5 py-0.5 border-r px-1 text-right"
class="px-4 last:pr-11 w-17 last:w-24.5 border-gray-300 dark:border-primary px-3.5 py-0.5 border-r px-1 text-right"
><span
class="w-full text-sm sm:text-[1rem] items-baseline justify-end whitespace-nowrap {item?.backward_4_days_change_percent >=
0
? "text-positive before:content-['+']"
: 'text-negative'}"
? "text-green-600 dark:text-positive before:content-['+']"
: 'text-red-600 dark:text-negative'}"
>{item?.backward_4_days_change_percent?.toFixed(
2,
)}%<span class="w-0 text-center"></span></span
@ -546,9 +542,7 @@
{/each}
<tfoot
><tr
><td
colspan="15"
class="pt-3 text-[#c3c6d0] px-1 leading-tight text-sm"
><td colspan="15" class="pt-3 px-1 leading-tight text-sm"
>Daily change and RSI 14 are based on the report date for
BMO releases and the following day for AMC releases.</td
></tr

View File

@ -49,20 +49,18 @@
<aside class="inline-block relative w-full lg:w-1/4 mt-3">
{#if !["Pro", "Plus"]?.includes(data?.user?.tier) || data?.user?.freeTrial}
<div
class="w-full text-white border border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer bg-inherit sm:hover:bg-secondary transition ease-out duration-100"
class="w-full border border-gray-300 dark:border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer sm:hover:bg-secondary transition ease-out duration-100"
>
<a
href="/pricing"
class="w-auto lg:w-full p-1 flex flex-col m-auto px-2 sm:px-0"
>
<div class="w-full flex justify-between items-center p-3 mt-3">
<h2
class="text-start text-xl font-semibold text-white sm:ml-3"
>
<h2 class="text-start text-xl font-semibold sm:ml-3">
Pro Subscription
</h2>
</div>
<span class="text-white p-3 sm:ml-3 sm:mr-3 -mt-4">
<span class=" p-3 sm:ml-3 sm:mr-3 -mt-4">
Upgrade now for unlimited access to all data and tools.
</span>
</a>
@ -70,10 +68,10 @@
{/if}
<div
class="w-full p-2 text-white border border-gray-600 bg-inherit rounded-md h-fit pb-4 mt-4"
class="w-full p-2 border border-gray-300 dark:border-gray-600 rounded-md h-fit pb-4 mt-4"
>
<h3 class="p-2 pt-4 text-xl font-semibold">Revenue Definition</h3>
<div class="text-white p-2">
<div class=" p-2">
Revenue, also called sales, is the amount of money a company
receives from its business activities, such as sales of products
or services. Revenue does not take any expenses into account and
@ -82,7 +80,7 @@
<div class="px-2">
<a
href="/blog/article/revenue"
class="flex justify-center items-center rounded cursor-pointer w-full py-2 mt-3 text-[1rem] text-center font-semibold text-black m-auto sm:hover:bg-gray-300 bg-[#fff] transition duration-100"
class="flex justify-center items-center rounded cursor-pointer w-full py-2 mt-3 text-[1rem] text-center font-semibold text-white dark:text-black m-auto sm:hover:bg-blue-600 dark:sm:hover:bg-gray-300 bg-[#3B82F6] dark:bg-[#fff] transition duration-100"
>
Full Definition
</a>
@ -91,18 +89,18 @@
{#if similarStocks?.length > 0}
<div
class="w-full p-2 text-white border border-gray-600 bg-inherit rounded-md h-fit pb-4 mt-4"
class="w-full p-2 border border-gray-300 dark:border-gray-600 rounded-md h-fit pb-4 mt-4"
>
<h3 class="p-2 pt-4 text-xl font-semibold">Related Stocks</h3>
<table class="table table-sm table-compact w-full text-white">
<thead class="text-white"
<table class="table table-sm table-compact w-full">
<thead class="text-muted dark:text-white"
><tr
><th
class="whitespace-nowrap border-b border-gray-600 font-semibold text-[1rem] text-left px-2"
class="whitespace-nowrap border-b border-gray-300 dark:border-gray-600 font-semibold text-[1rem] text-left px-2"
>Company</th
>
<th
class="whitespace-nowrap border-b border-gray-600 font-semibold text-[1rem] text-right px-2"
class="whitespace-nowrap border-b border-gray-300 dark:border-gray-600 font-semibold text-[1rem] text-right px-2"
>Revenue</th
></tr
></thead
@ -111,14 +109,14 @@
{#each similarStocks?.slice(0, 8) as item, index}
{#if item?.revenue > 0}
<tr
class="border-gray-800 text-[1rem] {index !==
class="border-gray-300 dark:border-gray-800 text-[1rem] {index !==
similarStocks?.slice(0, 8).length - 1
? 'border-b'
: ''}"
><td class="text-left text-[1rem] px-2"
><a
href={`/stocks/${item?.symbol}/statistics/revenue`}
class="sm:hover:text-white text-blue-400"
class="text-blue-500 sm:hover:text-muted dark:sm:hover:text-white dark:text-blue-400"
>{item?.name}</a
></td
>
@ -133,7 +131,7 @@
<div class="px-2">
<a
href="/list/highest-revenue"
class="flex justify-center items-center rounded cursor-pointer w-full py-2 mt-3 text-[1rem] text-center font-semibold text-black m-auto sm:hover:bg-gray-300 bg-[#fff] transition duration-100"
class="flex justify-center items-center rounded cursor-pointer w-full py-2 mt-3 text-[1rem] text-center font-semibold text-white dark:text-black m-auto sm:hover:bg-blue-600 dark:sm:hover:bg-gray-300 bg-[#3B82F6] dark:bg-[#fff] transition duration-100"
>
Revenue Rankings
</a>
@ -143,18 +141,18 @@
{#if newsList?.length !== 0}
<div
class="w-full sm:hover:text-white text-white border border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer bg-inherit"
class="w-full sm:hover: border border-gray-300 dark:border-gray-600 rounded-md h-fit pb-4 mt-4 cursor-pointer"
>
<div class="p-4 text-sm">
<h3 class="text-xl text-white font-semibold mb-3">
<h3 class="text-xl font-semibold mb-3">
{$stockTicker} News
</h3>
<ul class="text-white">
<ul class="">
{#each newsList?.slice(0, 10) as item}
<li class="mb-3 last:mb-1">
{formatDate(item?.publishedDate)} ago -
<a
class="sm:hover:text-white text-blue-400"
class="text-blue-500 sm:hover:text-muted dark:sm:hover:text-white dark:text-blue-400"
href={item?.url}
target="_blank"
rel="noopener noreferrer nofollow">{item?.title}</a

View File

@ -2,6 +2,7 @@
import { displayCompanyName, stockTicker } from "$lib/store";
import { abbreviateNumber, removeCompanyStrings } from "$lib/utils";
import SEO from "$lib/components/SEO.svelte";
import { mode } from "mode-watcher";
import { goto } from "$app/navigation";
import highcharts from "$lib/highcharts.ts";
@ -92,8 +93,8 @@
},
chart: {
type: "column",
backgroundColor: "#09090B",
plotBackgroundColor: "#09090B",
backgroundColor: $mode === "light" ? "#fff" : "#09090B",
plotBackgroundColor: $mode === "light" ? "#fff" : "#09090B",
height: 360, // Set the maximum height for the chart
animation: false,
},
@ -103,7 +104,7 @@
? `<h3 class="mt-3 mb-1">${removeCompanyStrings($displayCompanyName)} Revenue - Annual</h3>`
: `<h3 class="mt-3 mb-1">${removeCompanyStrings($displayCompanyName)} Revenue - Quarterly</h3>`,
style: {
color: "white",
color: $mode === "light" ? "black" : "white",
// Using inline CSS for margin-top and margin-bottom
},
useHTML: true, // Enable HTML to apply custom class styling
@ -113,7 +114,7 @@
categories: dates,
gridLineWidth: 0,
labels: {
style: { color: "white" },
style: { color: $mode === "light" ? "black" : "white" },
formatter: function () {
return timeIdx === 0 ? this?.value?.substring(0, 4) : this?.value;
},
@ -121,9 +122,9 @@
},
yAxis: {
gridLineWidth: 1,
gridLineColor: "#111827",
gridLineColor: $mode === "light" ? "#d1d5dc" : "#111827",
labels: {
style: { color: "white" },
style: { color: $mode === "light" ? "black" : "white" },
},
title: { text: null },
opposite: true,
@ -142,7 +143,7 @@
borderRadius: 4,
formatter: function () {
// Format the x value to display time in hh:mm format
let tooltipContent = `<span class="text-white m-auto text-black text-[1rem] font-[501]">${new Date(
let tooltipContent = `<span class=" m-auto text-[1rem] font-[501]">${new Date(
this?.x,
).toLocaleDateString("en-US", {
year: "numeric",
@ -152,8 +153,8 @@
// Loop through each point in the shared tooltip
this.points.forEach((point) => {
tooltipContent += `<span class="text-white font-semibold text-sm">${point.series.name}:</span>
<span class="text-white font-normal text-sm" style="color:${point.color}">${abbreviateNumber(
tooltipContent += `<span class=" font-semibold text-sm">${point.series.name}:</span>
<span class=" font-normal text-sm">${abbreviateNumber(
point.y,
)}</span><br>`;
});
@ -164,11 +165,11 @@
plotOptions: {
series: {
color: "white",
color: $mode === "light" ? "black" : "white",
animation: false,
dataLabels: {
enabled: timeIdx === 0 ? true : false,
color: "white",
color: $mode === "light" ? "black" : "white",
style: {
fontSize: "13px",
fontWeight: "bold",
@ -186,7 +187,7 @@
{
name: "Revenue",
data: valueList,
color: "white",
color: $mode === "light" ? "#2C6288" : "white",
},
],
};
@ -207,7 +208,7 @@
description={`Explore the historical revenue, sales performance, and growth trends of ${$displayCompanyName} (${$stockTicker}). Get in-depth financial insights.`}
/>
<section class="bg-default w-full overflow-hidden text-white h-full">
<section class="w-full overflow-hidden h-full">
<div class="w-full flex justify-center w-full sm-auto h-full overflow-hidden">
<div
class="w-full relative flex justify-center items-center overflow-hidden"
@ -215,7 +216,7 @@
<main class="w-full">
<div class="sm:pl-7 sm:pb-7 sm:pt-7 m-auto mt-2 sm:mt-0">
<div class="">
<h1 class="text-xl sm:text-2xl text-white font-bold">
<h1 class="text-xl sm:text-2xl font-bold">
{removeCompanyStrings($displayCompanyName)} Revenue
</h1>
</div>
@ -230,60 +231,52 @@
class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 mb-4 mt-3"
>
<div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors"
class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
>
<div
class="text-[#c3c6d0] text-sm sm:text-[1rem] mb-2 flex items-center"
>
<div class="text-sm sm:text-[1rem] mb-2 flex items-center">
<span>Revenue (ttm)</span>
</div>
<div class="flex items-baseline">
<span class="text-xl font-bold text-white">
<span class="text-xl font-bold">
{abbreviateNumber(rawData?.revenue, true)}</span
>
</div>
</div>
<div
class="bg-gray-800/30 rounded-lg p-4 sm:hover:bg-gray-800/40 transition-colors"
class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
>
<div
class="text-[#c3c6d0] text-sm sm:text-[1rem] mb-2 flex items-center"
>
<div class="text-sm sm:text-[1rem] mb-2 flex items-center">
<span>Revenue Growth</span>
</div>
<div class="flex items-baseline">
<span class="text-xl font-bold text-white"
<span class="text-xl font-bold"
>{rawData?.growthRevenue}%</span
>
</div>
</div>
<div
class="bg-gray-800/30 rounded p-4 sm:hover:bg-gray-800/40 transition-colors"
class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
>
<div
class="text-[#c3c6d0] text-sm sm:text-[1rem] mb-2 flex items-center"
>
<div class="text-sm sm:text-[1rem] mb-2 flex items-center">
<span>Price / Sales Ratio</span>
</div>
<div class="flex items-baseline">
<span class="text-xl font-bold text-white"
<span class="text-xl font-bold"
>{rawData?.priceToSalesRatio}</span
>
</div>
</div>
<div
class="bg-gray-800/30 rounded p-4 sm:hover:bg-gray-800/40 transition-colors"
class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
>
<div
class="text-[#c3c6d0] text-sm sm:text-[1rem] mb-2 flex items-center"
>
<div class="text-sm sm:text-[1rem] mb-2 flex items-center">
<span>Revenue / Employee </span>
</div>
<div class="flex items-baseline">
<span class="text-xl font-bold text-white"
<span class="text-xl font-bold"
>{abbreviateNumber(
rawData?.revenuePerEmployee,
true,
@ -293,29 +286,25 @@
</div>
<div
class="bg-gray-800/30 rounded p-4 sm:hover:bg-gray-800/40 transition-colors"
class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
>
<div
class="text-[#c3c6d0] text-sm sm:text-[1rem] mb-2 flex items-center"
>
<div class="text-sm sm:text-[1rem] mb-2 flex items-center">
<span>Employees </span>
</div>
<div class="flex items-baseline">
<span class="text-xl font-bold text-white"
<span class="text-xl font-bold"
>{rawData?.employees?.toLocaleString("en-US")}</span
>
</div>
</div>
<div
class="bg-gray-800/30 rounded p-4 sm:hover:bg-gray-800/40 transition-colors"
class="shadow-md bg-gray-100 dark:bg-gray-800/30 rounded-lg p-4 transition-colors"
>
<div
class="text-[#c3c6d0] text-sm sm:text-[1rem] mb-2 flex items-center"
>
<div class="text-sm sm:text-[1rem] mb-2 flex items-center">
<span>Market Cap </span>
</div>
<div class="flex items-baseline">
<span class="text-xl font-bold text-white"
<span class="text-xl font-bold"
>{abbreviateNumber(data?.getStockQuote?.marketCap)}</span
>
</div>
@ -325,15 +314,13 @@
<div
class=" flex flex-col sm:flex-row items-start sm:items-center w-full justify-between"
>
<h2 class="text-xl sm:text-2xl text-white font-bold">
Revenue Chart
</h2>
<h2 class="text-xl sm:text-2xl font-bold">Revenue Chart</h2>
<div
class="inline-flex justify-center w-full rounded-md sm:w-auto sm:ml-auto"
>
<div
class="bg-secondary w-full min-w-24 sm:w-fit relative flex flex-wrap items-center justify-center rounded-md p-1 mt-4"
class="bg-gray-300 dark:bg-secondary w-full min-w-24 sm:w-fit relative flex flex-wrap items-center justify-center rounded-md p-1 mt-4"
>
{#each plotTabs as item, i}
<button
@ -352,7 +339,7 @@
class="relative text-sm block font-semibold {timeIdx ===
i
? 'text-black'
: 'text-white'}"
: ''}"
>
{item.title}
</span>
@ -370,9 +357,7 @@
<div
class="mt-5 flex flex-col sm:flex-row items-start sm:items-center w-full justify-between sm:border-y border-gray-800 sm:pt-2 sm:pb-2"
>
<h3
class="text-xl sm:text-2xl text-white font-bold mb-2 sm:mb-0"
>
<h3 class="text-xl sm:text-2xl font-bold mb-2 sm:mb-0">
Revenue History
</h3>
@ -380,7 +365,7 @@
class="inline-flex justify-center w-full rounded-md sm:w-auto sm:ml-auto"
>
<div
class="bg-secondary w-full min-w-24 sm:w-fit relative flex flex-wrap items-center justify-center rounded-md p-1"
class="bg-gray-300 dark:bg-secondary w-full min-w-24 sm:w-fit relative flex flex-wrap items-center justify-center rounded-md p-1"
>
{#each tabs as item, i}
{#if !["Pro", "Plus"]?.includes(data?.user?.tier) && i > 0}
@ -418,7 +403,7 @@
class="relative text-sm block font-semibold whitespace-nowrap {activeIdx ===
i
? 'text-black'
: 'text-white'}"
: ''}"
>
{item.title}
</span>
@ -431,32 +416,26 @@
<div class="w-full overflow-x-auto">
<table
class="table table-sm table-compact bg-table border border-gray-800 rounded-none sm:rounded-md w-full m-auto mt-4"
class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md w-full bg-white dark:bg-table border border-gray-300 dark:border-gray-800 m-auto mt-4"
>
<thead class="bg-default">
<thead class="text-muted dark:text-white">
<tr>
<th class="text-white font-semibold text-start text-sm"
<th class=" font-semibold text-start text-sm"
>{activeIdx === 0
? "Fiscal Year End"
: "Quarter Ended"}</th
>
<th class="text-white font-semibold text-end text-sm"
>Revenue</th
>
<th class="text-white font-semibold text-end text-sm"
>% Change</th
>
<th class=" font-semibold text-end text-sm">Revenue</th>
<th class=" font-semibold text-end text-sm">% Change</th>
</tr>
</thead>
<tbody>
{#each tableList as item, index}
<!-- row -->
<tr
class="sm:hover:bg-[#245073]/10 odd:bg-odd border-b border-gray-800"
class="dark:sm:hover:bg-[#245073]/10 odd:bg-[#F6F7F8] dark:odd:bg-odd"
>
<td
class="text-white text-sm sm:text-[1rem] whitespace-nowrap"
>
<td class=" text-sm sm:text-[1rem] whitespace-nowrap">
{new Date(item?.date)?.toLocaleDateString("en-US", {
day: "2-digit", // Include day number
month: "short", // Display short month name
@ -465,18 +444,18 @@
</td>
<td
class="text-white text-sm sm:text-[1rem] text-right whitespace-nowrap"
class=" text-sm sm:text-[1rem] text-right whitespace-nowrap"
>
{abbreviateNumber(item?.revenue)}
</td>
<td
class="text-white text-sm sm:text-[1rem] whitespace-nowrap text-end"
class=" text-sm sm:text-[1rem] whitespace-nowrap text-end"
>
{#if index === tableList?.length - 1}
n/a
{:else if item?.revenue > tableList[index + 1]?.revenue}
<span class="text-[#00FC50]">
<span class="text-green-600 dark:text-[#00FC50]">
+{(
((item?.revenue -
tableList[index + 1]?.revenue) /
@ -485,7 +464,7 @@
)?.toFixed(2)}%
</span>
{:else if item?.revenue < tableList[index + 1]?.revenue}
<span class="text-[#FF2F1F]">
<span class="text-red-600 dark:text-[#FF2F1F]">
-{(
Math.abs(
(item?.revenue -