ui fixes
This commit is contained in:
parent
241f2f628a
commit
e416553d2f
@ -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
|
||||||
|
|||||||
@ -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 -->
|
|
||||||
@ -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"
|
||||||
|
|||||||
@ -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}
|
|
||||||
@ -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>
|
|
||||||
@ -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-->
|
|
||||||
@ -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>
|
|
||||||
@ -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>
|
|
||||||
@ -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>
|
|
||||||
@ -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>
|
||||||
|
|||||||
@ -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]'}"
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 -
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user