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> </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"> <main class="overflow-hidden">
<div class="w-full"> <div class="w-full">
<div <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)} on:click={() => handleSearch(item?.symbol, item?.type)}
> >
<div class="flex flex-row items-center justify-between w-full"> <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 >{item?.symbol}</span
> >
<span class="ml-3 text-sm text-muted dark:text-white" <span class="ml-3 text-sm text-muted dark:text-white"
@ -443,21 +444,24 @@
/> />
<dialog id="searchBarModal" class="modal modal-bottom"> <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 <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 <label
for="searchBarModal" 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 <svg
class="w-6 h-6 sm:w-8 sm:h-8" class="w-6 h-6 sm:w-8 sm:h-8"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24" viewBox="0 0 24 24"
><path ><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" 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 /></svg
> >
@ -467,7 +471,7 @@
<div class="mt-8"> <div class="mt-8">
<div class="relative"> <div class="relative">
<div <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} {#if isLoading}
<span class="loading loading-spinner loading-sm"></span> <span class="loading loading-spinner loading-sm"></span>
@ -492,7 +496,7 @@
<input <input
id="modal-search" 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" type="search"
placeholder="Company or stock symbol..." placeholder="Company or stock symbol..."
bind:value={inputValue} bind:value={inputValue}
@ -507,7 +511,7 @@
aria-label="Search" aria-label="Search"
> >
<svg <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" viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
><path ><path
@ -525,7 +529,7 @@
<!-- Popular searches --> <!-- Popular searches -->
<div class="mb-3 last:mb-0 mt-3"> <div class="mb-3 last:mb-0 mt-3">
{#if !showSuggestions} {#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"} {searchHistory?.length > 0 ? "Recent" : "Popular"}
</div> </div>
{/if} {/if}
@ -538,22 +542,23 @@
href={`/${item?.type === "ETF" ? "etf" : item?.type === "Index" ? "index" : "stocks"}/${item?.symbol}`} href={`/${item?.type === "ETF" ? "etf" : item?.type === "Index" ? "index" : "stocks"}/${item?.symbol}`}
on:click={() => popularTicker(item?.symbol)} on:click={() => popularTicker(item?.symbol)}
class="mb-2 {item?.symbol === focusedSuggestion class="mb-2 {item?.symbol === focusedSuggestion
? 'cursor-pointer flex justify-start items-center p-2 text-white bg-primary rounded group' ? 'cursor-pointer flex justify-start items-center p-2 bg-white dark: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 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-row items-center w-full">
<div class="flex flex-col"> <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 >{item?.symbol}</span
> >
<span class="text-white" <span class=""
>{item?.name.length > 150 >{item?.name.length > 150
? item?.name?.slice(0, 150) + "..." ? item?.name?.slice(0, 150) + "..."
: item?.name}</span : item?.name}</span
> >
</div> </div>
<div class="text-white ml-auto"> <div class=" ml-auto">
{item?.type} {item?.type}
</div> </div>
</div> </div>
@ -561,9 +566,7 @@
</li> </li>
{/each} {/each}
{:else if showSuggestions && searchBarData?.length > 0} {:else if showSuggestions && searchBarData?.length > 0}
<div class="text-start text-sm font-semibold text-white mb-2"> <div class="text-start text-sm font-semibold mb-2">Suggestions</div>
Suggestions
</div>
{#each searchBarData as item} {#each searchBarData as item}
<li class="border-b border-gray-300 dark:border-gray-600"> <li class="border-b border-gray-300 dark:border-gray-600">
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
@ -572,22 +575,23 @@
href={`/${item?.type === "ETF" ? "etf" : item?.type === "Index" ? "index" : "stocks"}/${item?.symbol}`} href={`/${item?.type === "ETF" ? "etf" : item?.type === "Index" ? "index" : "stocks"}/${item?.symbol}`}
on:click={() => searchBarTicker(item?.symbol)} on:click={() => searchBarTicker(item?.symbol)}
class="mb-2 {item?.symbol === focusedSuggestion class="mb-2 {item?.symbol === focusedSuggestion
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-primary rounded group' ? 'shake-ticker cursor-pointer flex justify-start items-center p-2 bg-whitedark: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'}" : '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-row items-center w-full">
<div class="flex flex-col"> <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 >{item?.symbol}</span
> >
<span class="text-white" <span class=""
>{item?.name?.length > 150 >{item?.name?.length > 150
? item?.name?.slice(0, 150) + "..." ? item?.name?.slice(0, 150) + "..."
: item?.name}</span : item?.name}</span
> >
</div> </div>
<div class="text-white ml-auto"> <div class=" ml-auto">
{item?.type} {item?.type}
</div> </div>
</div> </div>
@ -596,9 +600,7 @@
{/each} {/each}
{:else if showSuggestions && searchBarData?.length === 0} {:else if showSuggestions && searchBarData?.length === 0}
<li> <li>
<label <label class="flex items-center p-2 rounded group">
class="flex items-center p-2 text-white hover:text-white hover:bg-primary rounded group"
>
<svg <svg
class="w-3 h-3 fill-slate-400 shrink-0 mr-3 dark:fill-slate-500" class="w-3 h-3 fill-slate-400 shrink-0 mr-3 dark:fill-slate-500"
width="12" 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} {:else}
<a <a
href="/login" 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 Login
</a> </a>
{/if} {/if}
</div> </div>
</div> </div>

View File

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

View File

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

View File

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