optimize for seo

This commit is contained in:
MuslemRahimi 2025-01-11 11:31:23 +01:00
parent da8a443ee5
commit cbefa701ce
16 changed files with 877 additions and 1561 deletions

View File

@ -6,7 +6,7 @@
// Use the correct reactive declaration
$: {
if ($stockTicker && typeof window !== "undefined") {
if ($stockTicker) {
// Correctly check if score is neither undefined nor null
$scoreComponent = score !== undefined && score !== null && score !== 0;
}

View File

@ -1,170 +0,0 @@
<script lang="ts">
import { stockTicker, displayCompanyName } from "$lib/store";
import InfoModal from "$lib/components/InfoModal.svelte";
import { formatDate } from "$lib/utils";
export let data;
let rawData = {};
function latestInfoDate(inputDate) {
// Convert the input date string to milliseconds since epoch
const inputDateMs = new Date(inputDate);
// Get today's date in milliseconds since epoch
const todayMs = Date?.now();
// Calculate the difference in milliseconds
const differenceInMs = todayMs - inputDateMs;
// Convert milliseconds to days
const differenceInDays = Math?.floor(
differenceInMs / (1000 * 60 * 60 * 24),
);
// Return the difference in days
return differenceInDays <= 1;
}
function handleMode(i) {
activeIdx = i;
}
const tabs = [
{
title: "Bull Case",
},
{
title: "Bear Case",
},
];
let activeIdx = 0;
$: {
if ($stockTicker && typeof window !== "undefined") {
rawData = data?.getBullBearSay;
activeIdx = 0;
}
}
</script>
{#if Object?.keys(rawData)?.length !== 0}
<div class="space-y-3 overflow-hidden">
<!--Start Content-->
<div class="w-auto lg:w-full p-1 flex flex-col m-auto">
<div class="flex flex-col items-center w-full mb-1">
<div class="flex flex-row justify-start mr-auto items-center">
<!--<img class="h-10 inline-block mr-2" src={copilotIcon} />-->
<div class="flex flex-row items-center">
<label
for="bullBearCase"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-2xl font-bold"
>
Bull Case vs Bear Case
</label>
<InfoModal
title={"Bull Case vs Bear Case"}
content={`Before investing, examine both perspectives. We offer brief analyst report summaries, highlighting both positive ("Bulls Say") and negative ("Bears Say") viewpoints on ${$displayCompanyName}`}
id={"bullBearCase"}
/>
</div>
</div>
</div>
<!--Start Header-->
<div
class="inline-flex justify-center sm:justify-start w-full rounded-md sm:w-auto"
>
<div
class="bg-secondary w-full min-w-24 sm:w-fit relative flex flex-wrap items-center justify-center rounded-md p-1 mt-4"
>
{#each tabs as item, i}
<button
on:click={() => handleMode(i)}
class="group relative z-[1] rounded-full w-1/2 min-w-24 md:w-auto px-5 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 font-semibold {activeIdx === i
? 'text-black'
: 'text-white'}"
>
{item.title}
</span>
</button>
{/each}
</div>
</div>
<!--End Header-->
<span class="text-white text-sm italic mt-6 ml-auto">
<label
class="{latestInfoDate(rawData?.date)
? ''
: 'hidden'} text-black bg-[#fff] mr-2 font-semibold not-italic text-xs rounded px-2 py-0.5"
>New</label
>
Updated {formatDate(rawData?.date)}
</span>
<div class="flex mt-5 h-auto">
<div
class="{activeIdx === 0
? 'bg-[#00FC50]'
: 'bg-[#FF2F1F]'} w-full max-w-[3px] rounded-l-xl"
/>
<span class="text-gray-100 ml-3 text-[1rem] w-full">
{#if activeIdx === 0 && data?.user?.tier === "Pro"}
<p class="pr-1">{rawData?.bullSays}</p>
{:else if activeIdx === 1 && data?.user?.tier === "Pro"}
<p class="pr-1">{rawData?.bearSays}</p>
{:else if activeIdx === 0 && data?.user?.tier !== "Pro"}
<p>
{rawData?.bullSays?.slice(0, 150) + "..."}
<span class="mt-3">
Unlock content with
<a
class="inline-block ml-0.5 text-blue-400 sm:hover:text-white"
href="/pricing"
>Pro Subscription <svg
class="w-4 h-4 mb-1 inline-block text[#A3A3A3] sm:hover:text-white"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/></svg
></a
>
</span>
</p>
{:else if activeIdx === 1 && data?.user?.tier !== "Pro"}
<p>
{rawData?.bearSays?.slice(0, 150) + "..."}
<span class="mt-3">
Unlock content with
<a
class="inline-block ml-0.5 text-blue-400 sm:hover:text-white"
href="/pricing"
>Pro Subscription <svg
class="w-4 h-4 mb-1 inline-block text[#A3A3A3] sm:hover:text-white"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/></svg
></a
>
</span>
</p>
{/if}
</span>
</div>
</div>
</div>
{/if}

View File

@ -1,366 +0,0 @@
<script lang 'ts'></script>
<section class="overflow-hidden text-white h-full pb-8">
<main class="overflow-hidden">
<div class="flex flex-row items-center">
<label
for="clinicalTrialInfo"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
>
Clinical Trials
</label>
<InfoModal
title={"Clinical Trial"}
content={"Info description coming soon! But first a word of our sponsor skillshare... just kidding"}
id={"clinicalTrialInfo"}
/>
</div>
{#if data?.user?.tier === "Pro"}
{#if isLoaded}
{#if rawData?.length >= 5}
<div class="w-full flex flex-col items-start">
<div class="text-white text-sm sm:text-[1rem] mt-2 mb-2 w-full">
The Biotech company {$displayCompanyName} has conducted a total of
{abbreviateNumber(rawData?.length)} clinical trials. Out of these,
{numOfActive === 0 ? "none" : numOfActive} are currently active,
{numOfCompleted} have been completed, {numOfTerminated} were terminated
and {numOfResults} trials have produced results.
</div>
</div>
<div class="pb-2 rounded-md bg-default">
<div class="app w-full h-[300px] mt-5">
<Chart {init} options={optionsData} class="chart" />
</div>
</div>
<!--
<h2 class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3">
Latest Information
</h2>
<div class="rounded-md sm:min-h-[330px]">
<div class="w-full m-auto h-auto max-h-[500px] overflow-x-scroll sm:overflow-hidden sm:overflow-y-scroll scroller ">
<table class="table table-sm table-compact table-pin-rows table-pin-cols w-full">
<thead>
<tr>
<th class="text-white shadow-md font-semibold text-sm text-start bg-default">Drug</th>
<th class="text-white shadow-md font-semibold text-sm text-start bg-default">Stage</th>
<th class="text-white shadow-md font-semibold text-sm text-center bg-default">Phase Status</th>
<th class="text-white shadow-md font-semibold text-sm text-end bg-default">Result</th>
</tr>
</thead>
<tbody>
{#each displayList as item,index}
<tr on:click={() => handleViewData(item)} class="border-y border-gray-800 odd:bg-odd sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-default border-b-[#09090B] cursor-pointer">
<td class="text-white font-medium whitespace-nowrap">
{item["Interventions"]?.length === 0 ? '-' : item["Interventions"]?.length > charNumber ? formatString(item["Interventions"]?.slice(0,charNumber)) + "..." : formatString(item["Interventions"])}
</td>
<td class="text-white font-medium w-full text-start">
{item['Start Date'] === null ? 'n/a' : new Date(item["Start Date"])?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })}
</td>
<td class="text-white text-start font-medium">
{formatString(item['Study Status'])}
</td>
<td class="text-white text-center font-medium">
{item['Phases'] !== 'NA' ? formatString(item["Phases"])?.replace('Phase','') : '-'}
</td>
<td class="text-white text-end font-medium ">
{formatString(item["Study Results"])}
</td>
</tr>
{/each}
</tbody>
</table>
</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}
{:else}
<div
class="shadow-lg shadow-bg-[#000] bg-[#111112] sm:bg-opacity-[0.5] text-sm sm:text-[1rem] rounded-md w-full p-4 min-h-24 mt-4 text-white m-auto flex justify-center items-center text-center font-semibold"
>
<svg
class="mr-1.5 w-5 h-5 inline-block"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="#A3A3A3"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/></svg
>
Unlock content with
<a
class="inline-block ml-2 text-blue-400 hover:sm:text-white"
href="/pricing">Pro Subscription</a
>
</div>
{/if}
</main>
</section>
<!-- Put this part before </body> tag -->
<input type="checkbox" id="clinicalDesktopModal" class="modal-toggle" />
<label
for="clinicalDesktopModal"
class="hidden lg:modal modal-bottom sm:modal-middle cursor-pointer"
>
<label for="clinicalDesktopModal" class="cursor-pointer modal-backdrop"
></label>
<!-- svelte-ignore a11y-label-has-associated-control -->
<label
class="modal-box w-full relative bg-primary h-auto max-h-[900px] overflow-y-scroll"
>
<label
for="clinicalDesktopModal"
class="cursor-pointer absolute right-5 top-2 bg-primary text-2xl text-white"
>
</label>
<h3 class="text-xl font-semibold text-white mt-10">
Title: {trialTitle}
</h3>
<p class="py-4 text-gray-200 bg-primary w-full">
<span class="font-semibold text-white">Brief Summary:</span>
{trialSummary}
</p>
<table
class="table table-sm table-compact bg-primary w-full mt-5 mb-10 text-white"
>
<tbody>
<!-- row 1 -->
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">NCT Number</td>
<td class="bg-primary">{trialId}</td>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Start Date</td>
<td class="bg-primary">{trialStart}</td>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">End Date</td>
<td class="bg-primary">{trialEnd}</td>
</tr>
<!-- row 2 -->
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Study Status</td>
<td class="bg-primary">{trialStage}</td>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Phase Status</td>
<td class="bg-primary">{trialPhase}</td>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Study Results</td>
<td class="bg-primary">{trialResult}</td>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Sex</td>
<td class="bg-primary">{formatString(trialSex)}</td>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Age</td>
<td class="bg-primary"
>{formatString(trialAge)?.replace("Older_adult", "Older Adult")}</td
>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Sponsor</td>
<td class="bg-primary">{trialSponsor}</td>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Enrollment</td>
<td class="bg-primary">{trialEnrollment}</td>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Study Type</td>
<td class="bg-primary">{trialStudyType}</td>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Funder Type</td>
<td class="bg-primary">{trialFunderType}</td>
</tr>
<tr class="border-b border-slate-700">
<td class="bg-primary font-semibold">Website</td>
<td class="bg-primary"
><a
class="text-blue-400 sm:hover:text-white"
href={trialLink}
rel="noopener noreferrer"
target="_blank">{trialLink}</a
></td
>
</tr>
</tbody>
</table>
</label>
</label>
<!--Start ETF Modal-->
<div class="lg:hidden drawer drawer-end z-40 overflow-hidden w-screen">
<input id="clinicalMobileModal" type="checkbox" class="drawer-toggle" />
<div class="drawer-side overflow-hidden">
<div class="bg-default min-h-screen w-screen pb-20 overflow-hidden">
<label for="clinicalMobileModal" class="absolute left-6 top-6">
<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 class="w-full overflow-hidden overflow-y-scroll p-2">
<h3 class="text-xl font-semibold text-white mt-14 p-3">
Title: {trialTitle}
</h3>
<p class="py-4 text-gray-200 w-full p-3">
<span class="font-semibold text-white">Brief Summary:</span>
{trialSummary}
</p>
<table
class="table table-sm table-compact w-full mt-5 mb-10 text-white"
>
<tbody>
<!-- row 1 -->
<tr class="border-b border-slate-700 odd:bg-odd">
<td class="font-semibold w-full">NCT Number</td>
<td class="">{trialId}</td>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Start Date</td>
<td class="">{trialStart}</td>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">End Date</td>
<td class="">{trialEnd}</td>
</tr>
<!-- row 2 -->
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Study Status</td>
<td class="">{trialStage}</td>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Phase Status</td>
<td class="">{trialPhase}</td>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Study Results</td>
<td class="">{trialResult}</td>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Sex</td>
<td class="">{formatString(trialSex)}</td>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Age</td>
<td class=""
>{formatString(trialAge)?.replace(
"Older_adult",
"Older Adult",
)}</td
>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Sponsor</td>
<td class="">{trialSponsor}</td>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Enrollment</td>
<td class="">{trialEnrollment}</td>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Study Type</td>
<td class="">{trialStudyType}</td>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Funder Type</td>
<td class="">{trialFunderType}</td>
</tr>
<tr
class="border-b border-slate-700 odd:bg-odd even:bg-default"
>
<td class="font-semibold">Website</td>
<td class=""
><a
class="text-blue-400 sm:hover:text-white"
href={trialLink}
rel="noopener noreferrer"
target="_blank">{trialLink}</a
></td
>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!--End ETF Modal-->
<style>
.app {
height: 300px;
max-width: 100%; /* Ensure chart width doesn't exceed the container */
}
@media (max-width: 640px) {
.app {
height: 210px;
}
}
.chart {
width: 100%;
}
</style>

View File

@ -1,90 +0,0 @@
<script lang 'ts'></script>
<section class="overflow-hidden text-white h-full">
<main class="overflow-hidden">
<div class="flex flex-row items-center">
<label
for="lobbyingInfo"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
>
Corporate Lobbying
</label>
<InfoModal
title={"Corporate Lobbying"}
content={"Lobbying the Senate involves special interest groups hiring professional advocates to influence lawmakers and government policies. It is a constitutionally protected activity, but critics argue it can undermine democratic representation by giving disproportionate influence to wealthy and well-organized groups."}
id={"lobbyingInfo"}
/>
</div>
{#if isLoaded}
{#if rawData?.length !== 0}
<div class="mt-2 pb-8 sm:pb-2 rounded-md bg-default sm:bg-default">
<div class="w-full flex flex-col items-start">
<div class="text-white text-[1rem] mt-1 sm:mt-3 mb-1 w-full">
Explore {$displayCompanyName}'s lobbying strategy by analyzing
their annual spending to influence lawmakers towards favorable
regulation and legislation alignment.
</div>
</div>
<div class="app w-full h-[300px]">
<Chart {init} options={optionsData} class="chart" />
</div>
<div class="w-full text-white text-[1rem] mt-6">
The company allocated an average of {abbreviateNumber(
avgAmount,
true,
)} annually towards lobbying efforts, reaching its peak at {abbreviateNumber(
displayMaxLobbying,
true,
)} in {displayYear}.
</div>
</div>
{:else}
<h2
class="mt-10 mb-5 flex justify-center items-center text-3xl font-bold text-slate-700 m-auto"
>
No data available
<svg
class="w-10 sm:w-12 inline-block"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="#334155"
d="M18.68 12.32a4.49 4.49 0 0 0-6.36.01a4.49 4.49 0 0 0 0 6.36a4.508 4.508 0 0 0 5.57.63L21 22.39L22.39 21l-3.09-3.11c1.13-1.77.87-4.09-.62-5.57m-1.41 4.95c-.98.98-2.56.97-3.54 0c-.97-.98-.97-2.56.01-3.54c.97-.97 2.55-.97 3.53 0c.97.98.97 2.56 0 3.54M10.9 20.1a6.527 6.527 0 0 1-1.48-2.32C6.27 17.25 4 15.76 4 14v3c0 2.21 3.58 4 8 4c-.4-.26-.77-.56-1.1-.9M4 9v3c0 1.68 2.07 3.12 5 3.7v-.2c0-.93.2-1.85.58-2.69C6.34 12.3 4 10.79 4 9m8-6C7.58 3 4 4.79 4 7c0 2 3 3.68 6.85 4h.05c1.2-1.26 2.86-2 4.6-2c.91 0 1.81.19 2.64.56A3.215 3.215 0 0 0 20 7c0-2.21-3.58-4-8-4Z"
/></svg
>
</h2>
{/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: 230px;
}
}
.chart {
width: 100%;
}
</style>

View File

@ -6,7 +6,6 @@
abbreviateNumber,
sectorNavigation,
} from "$lib/utils";
import defaultLogo from "$lib/images/stocks/logo/default_logo.png";
import { goto } from "$app/navigation";
@ -39,7 +38,7 @@
}
$: {
if ($etfTicker && typeof window !== "undefined") {
if ($etfTicker) {
info = data?.getETFProfile?.at(0);
topHoldingList = data?.getETFHoldings?.holdings || [];
topSectorList = data?.getETFSectorWeighting || [];
@ -215,21 +214,9 @@
>
<td class="">
<div class="flex flex-row items-center">
<div
class="rounded-full w-10 h-10 relative flex items-center justify-center"
>
<img
style="clip-path: circle(50%);"
class="w-6 h-6 rounded-full"
src={item?.symbol?.length !== 0
? `https://financialmodelingprep.com/image-stock/${item?.symbol}.png`
: defaultLogo}
loading="lazy"
/>
</div>
<div class="flex flex-col ml-3 w-full">
<div class="flex flex-col w-full">
<span class="text-sm font-medium"
>{item?.symbol ?? "-"}</span
>{item?.symbol ?? "n/a"}</span
>
<span class="text-white text-sm">
{#if typeof item?.name !== "undefined"}

View File

@ -6,14 +6,12 @@
export let data;
let rawData = [];
let rawDataPressRelease;
let rawDataPressRelease = [];
let newsList = [];
let displaySection = "all";
let isLoaded = true;
async function getPressRelease() {
isLoaded = false;
displaySection = "press-releases";
const cachedData = getCache($stockTicker, "getPressRelease");
if (cachedData) {
@ -31,7 +29,6 @@
rawDataPressRelease = await response?.json();
setCache($stockTicker, rawDataPressRelease, "getPressRelease");
}
isLoaded = true;
}
function checkIfYoutubeVideo(link: string): string | null {
@ -67,9 +64,8 @@
: newsList;
$: {
if (($stockTicker || $etfTicker) && typeof window !== "undefined") {
isLoaded = true;
rawData = data?.getNews;
if ($stockTicker || $etfTicker) {
rawData = data?.getNews || [];
rawDataPressRelease = [];
newsList = rawData?.slice(0, 20) ?? [];
displaySection = "all";
@ -143,41 +139,76 @@
</div>
{#if rawData?.length > 0}
{#if isLoaded}
{#if filteredNewsList?.length > 0}
<div class="grid grid-cols-1 gap-2 pb-5 pt-5">
{#each filteredNewsList as item, index}
<div class="w-full flex flex-col bg-default rounded-md m-auto">
{#if checkIfYoutubeVideo(item.url)}
{#if showVideo[index]}
<!-- Show the YouTube iframe when the user clicks play -->
<div class="w-full aspect-video mb-4">
<iframe
class="w-full h-full rounded-md border border-gray-800"
src={`https://www.youtube.com/embed/${checkIfYoutubeVideo(item.url)}`}
frameborder="0"
allow="clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
{:else}
<!-- Show the image placeholder with a play button -->
<div class="w-full aspect-video">
<div class="mb-3 sm:order-3 lg:pr-2">
{#if filteredNewsList?.length > 0}
<div class="grid grid-cols-1 gap-2 pb-5 pt-5">
{#each filteredNewsList as item, index}
<div class="w-full flex flex-col bg-default rounded-md m-auto">
{#if checkIfYoutubeVideo(item.url)}
{#if showVideo[index]}
<!-- Show the YouTube iframe when the user clicks play -->
<div class="w-full aspect-video mb-4">
<iframe
class="w-full h-full rounded-md border border-gray-800"
src={`https://www.youtube.com/embed/${checkIfYoutubeVideo(item.url)}`}
frameborder="0"
allow="clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
{:else}
<!-- Show the image placeholder with a play button -->
<div class="w-full aspect-video">
<div class="mb-3 sm:order-3 lg:pr-2">
<div
class="group relative block cursor-pointer bg-black bg-cover bg-[center_50%] object-contain after:block after:pb-[56.25%] after:content-[''] rounded-sm focus:outline-none focus:ring-2 focus:ring-blue-brand_light focus:ring-offset-2"
style="background-image: url({item?.image});"
tabindex="0"
on:click={() => handlePlayClick(index)}
>
<div
class="group relative block cursor-pointer bg-black bg-cover bg-[center_50%] object-contain after:block after:pb-[56.25%] after:content-[''] rounded-sm focus:outline-none focus:ring-2 focus:ring-blue-brand_light focus:ring-offset-2"
style="background-image: url({item?.image});"
tabindex="0"
on:click={() => handlePlayClick(index)}
>
<div
class="absolute left-[50%] top-[50%] z-10 h-[46px] w-[70px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-[#212121] opacity-80 transition-all before:absolute before:left-[50%] before:top-[50%] before:-translate-x-1/2 before:-translate-y-1/2 before:border-y-[11px] before:border-l-[19px] before:border-r-0 before:border-transparent before:border-l-white before:content-[''] group-hover:bg-[#ff0000] group-hover:opacity-100"
></div>
</div>
class="absolute left-[50%] top-[50%] z-10 h-[46px] w-[70px] -translate-x-1/2 -translate-y-1/2 rounded-lg bg-[#212121] opacity-80 transition-all before:absolute before:left-[50%] before:top-[50%] before:-translate-x-1/2 before:-translate-y-1/2 before:border-y-[11px] before:border-l-[19px] before:border-r-0 before:border-transparent before:border-l-white before:content-[''] group-hover:bg-[#ff0000] group-hover:opacity-100"
></div>
</div>
</div>
{/if}
<div class="mt-3 w-full">
</div>
{/if}
<div class="mt-3 w-full">
<h3 class="text-sm text-white/80 truncate mb-2">
{formatDate(item?.publishedDate)} &#183; {item?.site}
</h3>
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="text-lg sm:text-xl font-bold text-white"
>
{item?.title}
<p class="text-white text-sm mt-2 font-normal">
{item?.text?.length > 200
? item?.text?.slice(0, 200) + "..."
: item?.text}
</p>
</a>
</div>
{:else}
<!-- Default news article display -->
<div class="w-full flex flex-col sm:flex-row">
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="w-full sm:max-w-56 h-fit max-h-96 sm:mr-3 border border-gray-800 rounded-md"
>
<div class="flex-shrink-0 m-auto">
<img
src={item?.image}
class="h-auto w-full rounded-md"
alt="news image"
loading="lazy"
/>
</div>
</a>
<div class="mt-3 sm:mt-0 w-full">
<h3 class="text-sm text-white/80 truncate mb-2">
{formatDate(item?.publishedDate)} &#183; {item?.site}
</h3>
@ -195,96 +226,48 @@
</p>
</a>
</div>
{:else}
<!-- Default news article display -->
<div class="w-full flex flex-col sm:flex-row">
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="w-full sm:max-w-56 h-fit max-h-96 sm:mr-3 border border-gray-800 rounded-md"
>
<div class="flex-shrink-0 m-auto">
<img
src={item?.image}
class="h-auto w-full rounded-md"
alt="news image"
loading="lazy"
/>
</div>
</a>
<div class="mt-3 sm:mt-0 w-full">
<h3 class="text-sm text-white/80 truncate mb-2">
{formatDate(item?.publishedDate)} &#183; {item?.site}
</h3>
<a
href={item?.url}
rel="noopener noreferrer"
target="_blank"
class="text-lg sm:text-xl font-bold text-white"
>
{item?.title}
<p class="text-white text-sm mt-2 font-normal">
{item?.text?.length > 200
? item?.text?.slice(0, 200) + "..."
: item?.text}
</p>
</a>
</div>
</div>
{/if}
</div>
<hr class="border-gray-600 w-full m-auto mt-5 mb-5" />
{/each}
</div>
{:else}
<div class="mt-5 mt-4 px-3 xs:px-4 sm:px-0">
<div class="border-l-4 border-white p-4 text-white">
<div class="flex flex-row items-center">
<svg
class="h-6 w-6"
viewBox="0 0 20 20"
fill="currentColor"
style="max-width:40px"
aria-hidden="true"
><path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clip-rule="evenodd"
></path></svg
>
<div class="ml-3 w-full sm:ml-4">
<div class="flex w-full flex-row justify-between">
<div>
No {displaySection === "videos" ? "videos" : "articles"} found
for this stock.
</div>
</div>
{/if}
</div>
<hr class="border-gray-600 w-full m-auto mt-5 mb-5" />
{/each}
</div>
{:else}
<div class="mt-5 mt-4 px-3 xs:px-4 sm:px-0">
<div class="border-l-4 border-white p-4 text-white">
<div class="flex flex-row items-center">
<svg
class="h-6 w-6"
viewBox="0 0 20 20"
fill="currentColor"
style="max-width:40px"
aria-hidden="true"
><path
fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clip-rule="evenodd"
></path></svg
>
<div class="ml-3 w-full sm:ml-4">
<div class="flex w-full flex-row justify-between">
<div>
No {displaySection === "videos" ? "videos" : "articles"} found
for this stock.
</div>
</div>
</div>
</div>
</div>
{/if}
{#if newsList?.length !== rawData?.length && filteredNewsList?.length > 0 && displaySection === "all"}
<label
on:click={loadMoreData}
class="shadow-lg rounded-md cursor-pointer w-5/6 sm:w-full flex justify-center items-center py-3 h-full text-sm sm:text-[1rem] text-center font-semibold text-black m-auto sm:hover:bg-gray-300 bg-[#fff]"
>
Load More News
</label>
{/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}
{#if newsList?.length !== rawData?.length && filteredNewsList?.length > 0 && displaySection === "all"}
<label
on:click={loadMoreData}
class="shadow-lg rounded-md cursor-pointer w-5/6 sm:w-full flex justify-center items-center py-3 h-full text-sm sm:text-[1rem] text-center font-semibold text-black m-auto sm:hover:bg-gray-300 bg-[#fff]"
>
Load More News
</label>
{/if}
{:else}
<span class="text-white"> No News article available yet </span>
{/if}

View File

@ -20,7 +20,7 @@
}
$: {
if ($stockTicker && typeof window !== "undefined") {
if ($stockTicker) {
rawData = data?.getNextEarnings?.next;
epsRatio =
rawData?.epsPrior !== 0

View File

@ -5,8 +5,6 @@
export let userTier;
export let rawData;
let isLoaded = false;
let xData = [];
let tableRevenue = [];
@ -65,10 +63,8 @@
}
$: {
if ($stockTicker && typeof window !== "undefined") {
isLoaded = false;
if ($stockTicker) {
prepareDataset();
isLoaded = true;
}
}
</script>
@ -76,182 +72,163 @@
<section class="overflow-hidden text-white h-full pb-8 sm:pb-2">
<main class="overflow-hidden">
<div class="w-full m-auto">
{#if isLoaded}
{#if rawData?.length !== 0}
<span class="">
The average price volatility over this 3-day period is
{#if userTier !== "Pro"}
... Unlock content with
<a
class="inline-block ml-0.5 text-blue-400 sm:hover:text-white"
href="/pricing"
>Pro Subscription <svg
class="w-4 h-4 mb-1 inline-block text[#A3A3A3] sm:hover:text-white"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/></svg
></a
>
{:else}
<span class="font-bold">±{averageVolatility?.toFixed(2)}%</span>.
During this period, the reported revenue exceeded expectations
<span class="font-bold">{positiveRevenueSurprisePercentage}%</span
>
of the time & the reported EPS surpassed analyst estimates
<span class="font-bold">{positiveEpsSurprisePercentage}%</span> of
the time.
{/if}
</span>
<div
class="no-scrollbar flex justify-start items-center w-screen sm:w-full mt-3 m-auto overflow-x-scroll pr-5 sm:pr-0"
{#if rawData?.length !== 0}
<span class="">
The average price volatility over this 3-day period is
{#if userTier !== "Pro"}
... Unlock content with
<a
class="inline-block ml-0.5 text-blue-400 sm:hover:text-white"
href="/pricing"
>Pro Subscription <svg
class="w-4 h-4 mb-1 inline-block text[#A3A3A3] sm:hover:text-white"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/></svg
></a
>
{:else}
<span class="font-bold">±{averageVolatility?.toFixed(2)}%</span>.
During this period, the reported revenue exceeded expectations
<span class="font-bold">{positiveRevenueSurprisePercentage}%</span>
of the time & the reported EPS surpassed analyst estimates
<span class="font-bold">{positiveEpsSurprisePercentage}%</span> of the
time.
{/if}
</span>
<div
class="no-scrollbar flex justify-start items-center w-screen sm:w-full mt-3 m-auto overflow-x-scroll pr-5 sm:pr-0"
>
<table
class="table table-sm table-pin-cols table-compact rounded-none sm:rounded-md w-full bg-table border border-gray-800"
>
<table
class="table table-sm table-pin-cols table-compact rounded-none sm:rounded-md w-full bg-table border border-gray-800"
>
<thead class="">
<tr class="">
<th
class="bg-primary border-b border-[#000] text-white font-semibold text-sm text-start"
>Date</th
<thead class="">
<tr class="">
<th
class="bg-primary border-b border-[#000] text-white font-semibold text-sm text-start"
>Date</th
>
{#each xData as item}
<td
class="z-20 bg-primary border-b border-[#000] text-white font-semibold text-sm text-end bg-default"
>{item}</td
>
{#each xData as item}
<td
class="z-20 bg-primary border-b border-[#000] text-white font-semibold text-sm text-end bg-default"
>{item}</td
>
{/each}
</tr>
</thead>
<tbody class="shadow-md">
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
{/each}
</tr>
</thead>
<tbody class="shadow-md">
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
>
Reported Revenue
</th>
{#each tableRevenue as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
>
Reported Revenue
</th>
{#each tableRevenue as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
>
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap"
href="/pricing"
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap"
href="/pricing"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span
>{@html abbreviateNumber(item, false, true)}</span
>
{:else}
n/a
{/if}
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span>{@html abbreviateNumber(item, false, true)}</span>
{:else}
{@html abbreviateNumber(item, false, true)}
n/a
{/if}
</td>
{/each}
</tr>
{:else}
{@html abbreviateNumber(item, false, true)}
{/if}
</td>
{/each}
</tr>
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
>
Est. Revenue
</th>
{#each tableRevenueEst as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
>
Est. Revenue
</th>
{#each tableRevenueEst as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
>
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap"
href="/pricing"
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap"
href="/pricing"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span
>{@html abbreviateNumber(item, false, true)}</span
>
{:else}
n/a
{/if}
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span>{@html abbreviateNumber(item, false, true)}</span>
{:else}
{@html abbreviateNumber(item, false, true)}
n/a
{/if}
</td>
{/each}
</tr>
{:else}
{@html abbreviateNumber(item, false, true)}
{/if}
</td>
{/each}
</tr>
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
>
Revenue Surprise
</th>
{#each tableRevenueSurprise as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-semibold bg-default"
>
Revenue Surprise
</th>
{#each tableRevenueSurprise as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-semibold bg-default"
>
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap font-normal"
href="/pricing"
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap font-normal"
href="/pricing"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span
class={item > 0
? "text-[#00FC50] before:content-['+']"
: item < 0
? "text-[#FF2F1F]"
: ""}
>
{abbreviateNumber(item)}%
</span>
{:else}
n/a
{/if}
{:else}
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span
class={item > 0
? "text-[#00FC50] before:content-['+']"
@ -261,133 +238,133 @@
>
{abbreviateNumber(item)}%
</span>
{/if}
</td>
{/each}
</tr>
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
>
Reported EPS
</th>
{#each tableEPS as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
>
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap"
href="/pricing"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span>{abbreviateNumber(item)}</span>
{:else}
n/a
{/if}
{:else}
{abbreviateNumber(item)}
n/a
{/if}
</td>
{/each}
</tr>
{:else}
<span
class={item > 0
? "text-[#00FC50] before:content-['+']"
: item < 0
? "text-[#FF2F1F]"
: ""}
>
{abbreviateNumber(item)}%
</span>
{/if}
</td>
{/each}
</tr>
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
>
Reported EPS
</th>
{#each tableEPS as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
>
Est. EPS
</th>
{#each tableEPSEst as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
>
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap"
href="/pricing"
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap"
href="/pricing"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span>{abbreviateNumber(item)}</span>
{:else}
n/a
{/if}
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span>{abbreviateNumber(item)}</span>
{:else}
{abbreviateNumber(item)}
n/a
{/if}
</td>
{/each}
</tr>
{:else}
{abbreviateNumber(item)}
{/if}
</td>
{/each}
</tr>
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
>
Est. EPS
</th>
{#each tableEPSEst as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-medium bg-default"
>
EPS Surprise
</th>
{#each tableEPSSurprise as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-semibold bg-default"
>
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap font-normal"
href="/pricing"
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap"
href="/pricing"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span
class={item > 0
? "text-[#00FC50] before:content-['+']"
: item < 0
? "text-[#FF2F1F]"
: ""}
>
{abbreviateNumber(item)}%
</span>
{:else}
n/a
{/if}
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span>{abbreviateNumber(item)}</span>
{:else}
n/a
{/if}
{:else}
{abbreviateNumber(item)}
{/if}
</td>
{/each}
</tr>
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
>
EPS Surprise
</th>
{#each tableEPSSurprise as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-semibold bg-default"
>
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap font-normal"
href="/pricing"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
<span
class={item > 0
? "text-[#00FC50] before:content-['+']"
@ -397,64 +374,65 @@
>
{abbreviateNumber(item)}%
</span>
{/if}
</td>
{/each}
</tr>
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
>
Volatility
</th>
{#each tableVolatility as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-semibold bg-default"
>
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap font-normal"
href="/pricing"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
±{abbreviateNumber(item)}%
{:else}
n/a
{/if}
{:else}
n/a
{/if}
{:else}
<span
class={item > 0
? "text-[#00FC50] before:content-['+']"
: item < 0
? "text-[#FF2F1F]"
: ""}
>
{abbreviateNumber(item)}%
</span>
{/if}
</td>
{/each}
</tr>
<tr class="bg-primary border-b-[#27272A]">
<th
class="bg-primary whitespace-nowrap text-sm sm:text-[1rem] text-white text-start font-medium border-b border-[#27272A]"
>
Volatility
</th>
{#each tableVolatility as item, index}
<td
class="text-white text-sm sm:text-[1rem] text-end font-semibold bg-default"
>
{#if index !== 0}
{#if userTier !== "Pro"}
<a
class="inline-block ml-0.5 text-white whitespace-nowrap font-normal"
href="/pricing"
>
Pro
<svg
class="w-4 h-4 ml-0.5 mb-1 inline-block text-[#A3A3A3]"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/>
</svg>
</a>
{:else if item !== undefined && item !== null}
±{abbreviateNumber(item)}%
{:else}
n/a
{/if}
</td>
{/each}
</tr>
</tbody>
</table>
</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>
{:else}
±{abbreviateNumber(item)}%
{/if}
</td>
{/each}
</tr>
</tbody>
</table>
</div>
{/if}
</div>

View File

@ -34,7 +34,7 @@
}
$: {
if ($stockTicker && typeof window !== "undefined") {
if ($stockTicker) {
info = data?.getStockDeck;
ipoDate =
info?.ipoDate !== null && info?.ipoDate?.length > 0

View File

@ -6,8 +6,7 @@
export let data;
let isLoaded = false;
let wiim;
let wiim = [];
let showFullHistory = false;
function latestInfoDate(inputDate) {
@ -36,11 +35,9 @@
}
$: {
if ((get(stockTicker) || get(etfTicker)) && typeof window !== "undefined") {
isLoaded = false;
if (get(stockTicker) || get(etfTicker)) {
showFullHistory = false;
wiim = data?.getWhyPriceMoved || [];
isLoaded = true;
}
}
</script>
@ -61,185 +58,172 @@
/>
</div>
{#if isLoaded}
{#if wiim?.length !== 0}
<div class="mt-5">
{#each showFullHistory ? wiim : wiim?.slice(0, 2) as item, index}
<div
class="w-full {index === 1 && !showFullHistory && wiim?.length > 2
? 'opacity-[0.5]'
: ''} "
>
<div class="relative">
<div class="">
<div class="flex justify-center">
<!--Start Item-->
<div class="flex flex-row items-center w-full mb-8">
<!-- Vertical Line -->
<div
class="w-1 h-full mr-4 rounded-lg {item?.changesPercentage ===
'-'
? 'bg-white'
: item?.changesPercentage >= 0
? 'bg-[#00FC50]'
: 'bg-[#FF2F1F]'}"
></div>
<!-- Item Content -->
{#if wiim?.length !== 0}
<div class="mt-5">
{#each showFullHistory ? wiim : wiim?.slice(0, 2) as item, index}
<div
class="w-full {index === 1 && !showFullHistory && wiim?.length > 2
? 'opacity-[0.5]'
: ''} "
>
<div class="relative">
<div class="">
<div class="flex justify-center">
<!--Start Item-->
<div class="flex flex-row items-center w-full mb-8">
<!-- Vertical Line -->
<div
class="w-1 h-full mr-4 rounded-lg {item?.changesPercentage ===
'-'
? 'bg-white'
: item?.changesPercentage >= 0
? 'bg-[#00FC50]'
: 'bg-[#FF2F1F]'}"
></div>
<!-- Item Content -->
<div class="w-full h-full">
<div class="flex flex-col items-start">
<div class="flex flex-row items-start w-full">
<span class="text-white text-sm"
>{formatDate(item?.date)} &#183;
<a
href={item?.url}
class="inline-block text-sm text-white sm:hover:underline sm:hover:underline-offset-4"
>
Source
</a></span
<div class="w-full h-full">
<div class="flex flex-col items-start">
<div class="flex flex-row items-start w-full">
<span class="text-white text-sm"
>{formatDate(item?.date)} &#183;
<a
href={item?.url}
class="inline-block text-sm text-white sm:hover:underline sm:hover:underline-offset-4"
>
{#if latestInfoDate(item?.date)}
<label
class="bg-[#fff] rounded text-black font-semibold text-xs px-2 py-0.5 ml-3"
>New</label
>
{/if}
<div
class="text-white text-sm sm:text-[1rem] ml-auto font-medium"
Source
</a></span
>
{#if latestInfoDate(item?.date)}
<label
class="bg-[#fff] rounded text-black font-semibold text-xs px-2 py-0.5 ml-3"
>New</label
>
{#if item?.changesPercentage >= 0}
<span class="text-[#00FC50] inline-block"
>+{item?.changesPercentage}%</span
>
<svg
class="w-5 h-5 hidden sm:inline-block"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
transform="rotate(180)matrix(-1, 0, 0, 1, 0, 0)"
><g id="SVGRepo_bgCarrier" stroke-width="0"
></g><g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g><g id="SVGRepo_iconCarrier">
<g clip-path="url(#clip0_1076_36065)">
<path
d="M1.70711 5.29289C1.31658 4.90237 0.683417 4.90237 0.292893 5.29289C-0.0976311 5.68342 -0.0976311 6.31658 0.292893 6.70711L7.79289 14.2071C8.18342 14.5976 8.81658 14.5976 9.20711 14.2071L13.5 9.91421L20.5858 17H17C16.4477 17 16 17.4477 16 18C16 18.5523 16.4477 19 17 19H22.9993L23.003 19C23.1375 18.9996 23.2657 18.9727 23.3828 18.9241C23.5007 18.8753 23.6112 18.803 23.7071 18.7071C23.8902 18.524 23.9874 18.2877 23.9989 18.048C23.9996 18.032 24 18.016 24 18V12C24 11.4477 23.5523 11 23 11C22.4477 11 22 11.4477 22 12V15.5858L14.2071 7.79289C13.8166 7.40237 13.1834 7.40237 12.7929 7.79289L8.5 12.0858L1.70711 5.29289Z"
{/if}
<div
class="text-white text-sm sm:text-[1rem] ml-auto font-medium"
>
{#if item?.changesPercentage >= 0}
<span class="text-[#00FC50] inline-block"
>+{item?.changesPercentage}%</span
>
<svg
class="w-5 h-5 hidden sm:inline-block"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
transform="rotate(180)matrix(-1, 0, 0, 1, 0, 0)"
><g id="SVGRepo_bgCarrier" stroke-width="0"
></g><g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g><g id="SVGRepo_iconCarrier">
<g clip-path="url(#clip0_1076_36065)">
<path
d="M1.70711 5.29289C1.31658 4.90237 0.683417 4.90237 0.292893 5.29289C-0.0976311 5.68342 -0.0976311 6.31658 0.292893 6.70711L7.79289 14.2071C8.18342 14.5976 8.81658 14.5976 9.20711 14.2071L13.5 9.91421L20.5858 17H17C16.4477 17 16 17.4477 16 18C16 18.5523 16.4477 19 17 19H22.9993L23.003 19C23.1375 18.9996 23.2657 18.9727 23.3828 18.9241C23.5007 18.8753 23.6112 18.803 23.7071 18.7071C23.8902 18.524 23.9874 18.2877 23.9989 18.048C23.9996 18.032 24 18.016 24 18V12C24 11.4477 23.5523 11 23 11C22.4477 11 22 11.4477 22 12V15.5858L14.2071 7.79289C13.8166 7.40237 13.1834 7.40237 12.7929 7.79289L8.5 12.0858L1.70711 5.29289Z"
fill="#00FC50"
></path>
</g>
<defs>
<clipPath id="clip0_1076_36065">
<rect
width="24"
height="24"
fill="#00FC50"
></path>
</g>
<defs>
<clipPath id="clip0_1076_36065">
<rect
width="24"
height="24"
fill="#00FC50"
></rect>
</clipPath>
</defs>
</g></svg
>
{:else if item?.changesPercentage < 0}
<span class="text-[#FF2F1F] inline-block"
>{item?.changesPercentage}%
</span>
<svg
class="w-5 h-5 hidden sm:inline-block"
viewBox="0 0 24 24"
fill="#FF2F1F"
xmlns="http://www.w3.org/2000/svg"
><g id="SVGRepo_bgCarrier" stroke-width="0"
></g><g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g><g id="SVGRepo_iconCarrier">
<g clip-path="url(#clip0_1076_36065)">
<path
d="M1.70711 5.29289C1.31658 4.90237 0.683417 4.90237 0.292893 5.29289C-0.0976311 5.68342 -0.0976311 6.31658 0.292893 6.70711L7.79289 14.2071C8.18342 14.5976 8.81658 14.5976 9.20711 14.2071L13.5 9.91421L20.5858 17H17C16.4477 17 16 17.4477 16 18C16 18.5523 16.4477 19 17 19H22.9993L23.003 19C23.1375 18.9996 23.2657 18.9727 23.3828 18.9241C23.5007 18.8753 23.6112 18.803 23.7071 18.7071C23.8902 18.524 23.9874 18.2877 23.9989 18.048C23.9996 18.032 24 18.016 24 18V12C24 11.4477 23.5523 11 23 11C22.4477 11 22 11.4477 22 12V15.5858L14.2071 7.79289C13.8166 7.40237 13.1834 7.40237 12.7929 7.79289L8.5 12.0858L1.70711 5.29289Z"
></rect>
</clipPath>
</defs>
</g></svg
>
{:else if item?.changesPercentage < 0}
<span class="text-[#FF2F1F] inline-block"
>{item?.changesPercentage}%
</span>
<svg
class="w-5 h-5 hidden sm:inline-block"
viewBox="0 0 24 24"
fill="#FF2F1F"
xmlns="http://www.w3.org/2000/svg"
><g id="SVGRepo_bgCarrier" stroke-width="0"
></g><g
id="SVGRepo_tracerCarrier"
stroke-linecap="round"
stroke-linejoin="round"
></g><g id="SVGRepo_iconCarrier">
<g clip-path="url(#clip0_1076_36065)">
<path
d="M1.70711 5.29289C1.31658 4.90237 0.683417 4.90237 0.292893 5.29289C-0.0976311 5.68342 -0.0976311 6.31658 0.292893 6.70711L7.79289 14.2071C8.18342 14.5976 8.81658 14.5976 9.20711 14.2071L13.5 9.91421L20.5858 17H17C16.4477 17 16 17.4477 16 18C16 18.5523 16.4477 19 17 19H22.9993L23.003 19C23.1375 18.9996 23.2657 18.9727 23.3828 18.9241C23.5007 18.8753 23.6112 18.803 23.7071 18.7071C23.8902 18.524 23.9874 18.2877 23.9989 18.048C23.9996 18.032 24 18.016 24 18V12C24 11.4477 23.5523 11 23 11C22.4477 11 22 11.4477 22 12V15.5858L14.2071 7.79289C13.8166 7.40237 13.1834 7.40237 12.7929 7.79289L8.5 12.0858L1.70711 5.29289Z"
fill="#FF2F1F"
></path>
</g>
<defs>
<clipPath id="clip0_1076_36065">
<rect
width="24"
height="24"
fill="#FF2F1F"
></path>
</g>
<defs>
<clipPath id="clip0_1076_36065">
<rect
width="24"
height="24"
fill="#FF2F1F"
></rect>
</clipPath>
</defs>
</g></svg
>
{/if}
</div>
</div>
<div class="flex flex-col w-full pt-2">
{#if index === 0 && data?.user?.tier !== "Pro"}
<span class="mt-3">
{item?.text?.slice(0, 50) + "..."}
Unlock content with
<a
class="inline-block ml-0.5 text-blue-400 sm:hover:text-white"
href="/pricing"
>Pro Subscription <svg
class="w-4 h-4 mb-1 inline-block text[#A3A3A3] sm:hover:text-white"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/></svg
></a
>
</span>
{:else}
<span class="text-white text-[1rem]">
{item?.text}
</span>
></rect>
</clipPath>
</defs>
</g></svg
>
{/if}
</div>
</div>
<div class="flex flex-col w-full pt-2">
{#if index === 0 && data?.user?.tier !== "Pro"}
<span class="mt-3">
{item?.text?.slice(0, 50) + "..."}
Unlock content with
<a
class="inline-block ml-0.5 text-blue-400 sm:hover:text-white"
href="/pricing"
>Pro Subscription <svg
class="w-4 h-4 mb-1 inline-block text[#A3A3A3] sm:hover:text-white"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="currentColor"
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
/></svg
></a
>
</span>
{:else}
<span class="text-white text-[1rem]">
{item?.text}
</span>
{/if}
</div>
</div>
</div>
<!--End Item-->
</div>
<!--End Item-->
</div>
</div>
</div>
{/each}
</div>
{#if wiim?.length > 2}
<label
on:click={() => (showFullHistory = !showFullHistory)}
class="cursor-pointer flex justify-center items-center mt-5"
>
<svg
class="w-10 h-10 transform {showFullHistory ? 'rotate-180' : ''} "
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="#2A323C"
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2zm0 13.5L7.5 11l1.42-1.41L12 12.67l3.08-3.08L16.5 11L12 15.5z"
/></svg
>
</label>
{/if}
{/if}
{:else}
<div class="flex justify-center items-center h-80">
<div class="relative">
<label
class="bg-default 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>
{/each}
</div>
{#if wiim?.length > 2}
<label
on:click={() => (showFullHistory = !showFullHistory)}
class="cursor-pointer flex justify-center items-center mt-5"
>
<svg
class="w-10 h-10 transform {showFullHistory ? 'rotate-180' : ''} "
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
><path
fill="#2A323C"
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2zm0 13.5L7.5 11l1.42-1.41L12 12.67l3.08-3.08L16.5 11L12 15.5z"
/></svg
>
</label>
{/if}
{/if}
</main>
</section>

View File

@ -44,15 +44,15 @@ const fetchWatchlist = async (pb, userId) => {
export const load = async ({ params, locals }) => {
const { apiURL, apiKey, pb, user } = locals;
const { tickerID } = params;
const endpoints = [
"/etf-profile",
"/etf-profile",
"/etf-holdings",
"/etf-sector-weighting",
"/stock-dividend",
"/stock-quote",
"/pre-post-quote",
"/wiim",
"/one-day-price",
"/stock-news",
@ -66,23 +66,27 @@ export const load = async ({ params, locals }) => {
];
const [
getETFProfile,
getETFProfile,
getETFHoldings,
getETFSectorWeighting,
getStockDividend,
getStockQuote,
getPrePostQuote,
getWhyPriceMoved,
getOneDayPrice,
getNews,
getUserWatchlist,
] = await Promise.all(promises);
return {
getETFProfile,
getETFProfile,
getETFHoldings,
getETFSectorWeighting,
getStockDividend,
getStockQuote,
getPrePostQuote,
getWhyPriceMoved,
getOneDayPrice,
getNews,
@ -90,4 +94,4 @@ export const load = async ({ params, locals }) => {
companyName: cleanString(getETFProfile?.at(0)?.name),
getParams: params.tickerID,
};
};
};

View File

@ -22,16 +22,21 @@
import { onMount, onDestroy, afterUpdate } from "svelte";
import { page } from "$app/stores";
import toast from "svelte-french-toast";
import Markethour from "$lib/components/Markethour.svelte";
import { convertTimestamp } from "$lib/utils";
import PriceAlert from "$lib/components/PriceAlert.svelte";
export let data;
let prePostData = data?.getPrePostQuote || {};
$: $realtimePrice = data?.getStockQuote?.price?.toFixed(2);
let oneDayPrice = [];
let previousRealtimePrice = null;
let previousTicker;
let socket;
$etfTicker = data?.getParams;
$assetType = "stock";
$displayCompanyName = data?.companyName;
let isScrolled = false;
let y;
@ -42,16 +47,17 @@
//let availableCash = 0;
let displaySection = "";
let displayLegend = {};
function shareContent(url) {
if (navigator.share) {
navigator
.share({
?.share({
title: document.title,
url,
})
.then(() => console.log("Content shared successfully."))
.catch((error) => console.log("Error sharing content:", error));
?.then(() => console.log("Content shared successfully."))
?.catch((error) => console.log("Error sharing content:", error));
} else {
toast.error("Sharing is not supported by your device", {
style: "background: #2A2E39; color: #fff;",
@ -65,7 +71,12 @@
options: "/options",
"dark-pool": "/dark-pool",
dividends: "/dividends",
statistics: "/statistics",
metrics: "metrics",
forecast: "/forecast",
financials: "/financials",
history: "/history",
profile: "/profile",
};
if (state !== "overview" && sectionMap[state]) {
@ -241,14 +252,74 @@
});
$: {
if (
$etfTicker &&
$etfTicker?.length !== 0 &&
typeof window !== "undefined"
) {
if ($etfTicker && $etfTicker?.length !== 0) {
// add a check to see if running on client-side
$etfTicker = data?.getParams;
$assetType = "stock";
$displayCompanyName = data?.companyName;
$currentPortfolioPrice = data?.getStockQuote?.price;
prePostData = data?.getPrePostQuote || {};
const output = [...data?.getOneDayPrice] ?? [];
oneDayPrice = output?.map((item) => ({
time: Date?.parse(item?.time + "Z") / 1000,
open: item?.open !== null ? item?.open : NaN,
high: item?.high !== null ? item?.high : NaN,
low: item?.low !== null ? item?.low : NaN,
close: item?.close !== null ? item?.close : NaN,
}));
let change;
let currentDataRowOneDay;
let baseClose =
data?.getStockQuote?.previousClose || oneDayPrice?.at(0)?.open;
const length = oneDayPrice?.length;
for (let i = length - 1; i >= 0; i--) {
if (!isNaN(oneDayPrice[i]?.close)) {
currentDataRowOneDay = oneDayPrice[i];
break;
}
}
// Calculate percentage change if baseClose and currentDataRow are valid
const closeValue =
$realtimePrice !== null && $realtimePrice !== undefined
? $realtimePrice
: currentDataRowOneDay?.close || currentDataRowOneDay?.value;
if (closeValue && baseClose) {
change = ((closeValue / baseClose - 1) * 100)?.toFixed(2);
}
// Format date
const date = new Date(currentDataRowOneDay?.time * 1000);
const options = {
day: "2-digit",
month: "short",
year: "numeric",
hour: "numeric",
minute: "2-digit",
timeZone: "UTC",
};
const formattedDate = date?.toLocaleString("en-US", options);
const safeFormattedDate =
formattedDate === "Invalid Date"
? convertTimestamp(data?.getStockQuote?.timestamp)
: formattedDate;
// Set display legend
displayLegend = {
close:
$realtimePrice !== null && $realtimePrice !== undefined
? $realtimePrice
: currentDataRowOneDay?.close?.toFixed(2) ||
data?.getStockQuote?.price?.toFixed(2),
date: safeFormattedDate,
change,
};
}
}
@ -256,24 +327,21 @@
(item) => item.user === data?.user?.id && item.ticker?.includes($etfTicker),
);
$: charNumber = $screenWidth < 640 ? 15 : 25;
$: charNumber = $screenWidth < 640 ? 25 : 40;
$: {
if (
$etfTicker &&
typeof window !== "undefined" &&
$page.url.pathname === `/etf/${$etfTicker}`
) {
if ($etfTicker && $page.url.pathname === `/etf/${$etfTicker}`) {
displaySection = "overview";
}
}
$: {
if ($page?.url?.pathname && typeof window !== "undefined") {
if ($page?.url?.pathname) {
const parts = $page?.url?.pathname?.split("/");
const sectionMap = {
holdings: "holdings",
options: "options",
options: "options",
"dark-pool": "dark-pool",
insider: "insider",
dividends: "dividends",
@ -292,10 +360,10 @@
<svelte:window bind:scrollY={y} />
<body
class="bg-default w-full max-w-screen sm:max-w-7xl min-h-screen sm:max-w-[1400px] overflow-hidden"
class="bg-default w-full max-w-screen sm:max-w-[1400px] min-h-screen overflow-hidden"
>
<!-- Page wrapper -->
<div class="flex flex-col w-full mt-5 relative w-full">
<div class="mt-5 flex flex-col w-full relative w-full">
<main class="grow w-full">
<section class="w-full">
<div class="w-full">
@ -330,9 +398,7 @@
? "hidden"
: "flex flex-col items-center ml-6 transition-transform ease-in"}
>
<span
class="text-white text-[0.70rem] font-medium text-opacity-[0.6]"
>
<span class="text-white text-xs font-semibold">
{$etfTicker}
</span>
<span class="text-white font-medium text-sm">
@ -497,23 +563,19 @@
</div>
<!--End Mobile Navbar-->
<div class="pt-14 sm:pt-0 w-full px-3 sm:px-0">
<div class="pt-14 sm:pt-0 w-full px-3 sm:px-0 lg:pr-3">
<div
class="md:flex md:justify-between md:divide-x md:divide-slate-800"
>
<!-- Main content -->
<div class="pb-12 md:pb-20 w-full">
<div class="md:pr-6 lg:pr-10">
<div class="">
<!-----Start-Header-CandleChart-Indicators------>
<div
class="m-auto pl-0 sm:pl-4 overflow-hidden mb-3 md:mt-10 xl:pr-7"
>
<div class="m-auto pl-0 sm:pl-4 overflow-hidden mb-3">
<div
class="hidden sm:flex flex-row w-full justify-between items-center"
>
<Markethour />
<!--Start Watchlist-->
{#if data?.user}
@ -640,22 +702,135 @@
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-label-has-associated-control -->
<div class="flex items-center w-full mt-3">
<div class="flex items-center w-full mt-5">
<div
class="flex flex-row justify-start w-full items-center"
>
<div class="flex flex-col items-start ml-2 sm:ml-3">
<span class="text-md sm:text-lg text-blue-400">
{$etfTicker?.toUpperCase()}
</span>
<span
class="text-xl sm:text-2xl font-semibold sm:font-bold text-white"
<div class="flex flex-col items-start w-full">
<div
class="flex flex-row justify-between items-center w-full sm:-mt-[50px] mb-5 sm:mb-10"
>
{$displayCompanyName?.length > charNumber
? $displayCompanyName?.slice(0, charNumber) +
"..."
: $displayCompanyName}
</span>
<div
class="text-2xl lg:text-3xl font-bold text-white"
>
{$displayCompanyName?.length > charNumber
? $displayCompanyName?.slice(0, charNumber) +
"..."
: $displayCompanyName}
<span class="hidden sm:inline-block"
>({$etfTicker?.toUpperCase()})</span
>
</div>
</div>
<div
class="-mt-5 sm:-mt-8 mb-5 flex flex-row items-end space-x-2 xs:space-x-3 sm:space-x-5 text-white"
>
<div class="w-full max-w-[50%] whitespace-nowrap">
<div
class="text-3xl sm:text-4xl font-bold {Object?.keys(
prePostData,
)?.length === 0
? 'inline'
: 'block sm:inline'}"
>
{displayLegend?.close}
</div>
<div
class="font-semibold {Object?.keys(
prePostData,
)?.length === 0
? 'inline'
: 'block sm:inline'} text-lg xs:text-xl sm:text-2xl {displayLegend?.change >=
0
? "before:content-['+'] text-[#00FC50]"
: 'text-[#FF2F1F]'}"
>
{displayLegend?.change}%
</div>
<div class="mt-0.5 text-xs sm:text-sm">
{#if !$isOpen}
<span
class="block font-semibold sm:inline mb-0.5 sm:mb-0"
>At close:</span
>
{/if}
{displayLegend?.date}
{#if $isOpen}
<span
class="{Object?.keys(prePostData)
?.length !== 0
? 'block sm:inline'
: 'inline'} mb-0.5 sm:mb-0"
>- Market open</span
>
{/if}
</div>
</div>
{#if Object?.keys(prePostData)?.length !== 0 && !$isOpen}
<div
class="border-l border-default pl-3 bp:pl-5"
>
<div
class="block text-2xl sm:text-[1.7rem] font-semibold leading-5 text-faded sm:inline"
>
{prePostData?.price?.toFixed(2)}
</div>
<div
class="mt-1.5 block text-sm xs:text-base sm:mt-0 sm:inline sm:text-lg {prePostData?.changesPercentage >=
0
? "before:content-['+'] text-[#00FC50]"
: 'text-[#FF2F1F]'}"
>
{prePostData?.changesPercentage?.toFixed(
2,
)}%
</div>
<div class="mt-1 text-xs sm:text-sm sm:flex">
<span class="flex items-center">
{#if prePostData?.time?.includes("AM")}
<svg
class="h-4 w-4 inline text-yellow-500"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
style="max-width:40px"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"
></path></svg
>
{:else}
<svg
class="h-4 w-4 inline text-blue-400"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
style="max-width:40px"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"
></path></svg
>
{/if}
<span
class="ml-0.5 whitespace-nowrap font-semibold md:ml-1 mb-0.5 sm:mb-0"
>{prePostData?.time?.includes("AM")
? "Pre-market"
: "After-hours"}</span
></span
>
<span class="sm:ml-1 whitespace-nowrap"
>{prePostData?.time}</span
>
</div>
</div>
{/if}
</div>
</div>
</div>
</div>
@ -664,7 +839,6 @@
<!--Start Ticker Section-->
<!--<div class="w-full max-w-3xl sm:max-w-2xl m-auto pt-2 pb-5 sm:pl-3 sticky z-20 bg-default" style="top: {$screenWidth < 520 && $isScrollingUp ? '4rem' : '0rem'};">-->
<nav
class="sm:ml-4 border-b-[2px] overflow-x-scroll md:overflow-hidden whitespace-nowrap"
>
@ -676,28 +850,28 @@
on:click={() => changeSection("overview")}
class="p-2 px-5 cursor-pointer {displaySection ===
'overview'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95]'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95] font-semibold'
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
>
Overview
</a>
<a
href={`/etf/${$etfTicker}/holdings`}
on:click={() => changeSection("holdings")}
class="p-2 px-5 cursor-pointer {displaySection ===
'holdings'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95]'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95] font-semibold'
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
>
Holdings
</a>
<a
href={`/etf/${$etfTicker}/options`}
on:click={() => changeSection("options")}
class="p-2 px-5 cursor-pointer {displaySection ===
'options'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95]'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95] font-semibold'
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
>
Options
@ -707,7 +881,7 @@
on:click={() => changeSection("dark-pool")}
class="p-2 px-5 cursor-pointer {displaySection ===
'dark-pool'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95]'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95] font-semibold'
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
>
Dark Pool
@ -717,7 +891,7 @@
on:click={() => changeSection("insider")}
class="p-2 px-5 cursor-pointer {displaySection ===
'insider'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95]'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95] font-semibold'
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
>
Insider
@ -727,7 +901,7 @@
on:click={() => changeSection("dividends")}
class="p-2 px-5 cursor-pointer {displaySection ===
'dividends'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95]'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95] font-semibold'
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
>
Dividends
@ -737,7 +911,7 @@
on:click={() => changeSection("history")}
class="p-2 px-5 cursor-pointer {displaySection ===
'history'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95]'
? 'text-white bg-secondary sm:hover:bg-opacity-[0.95] font-semibold'
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
>
History
@ -746,6 +920,7 @@
</nav>
<!--Start-Main Content-->
<slot />
<!--End Main Content-->
</div>
@ -767,6 +942,7 @@
<!--Start SellTrade Modal-->
<PriceAlert {data} ticker={$etfTicker} assetType={$assetType} />
<!--Start Add Watchlist Modal-->
<input type="checkbox" id="addWatchListModal" class="modal-toggle" />
@ -798,7 +974,7 @@
class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
>
<div
class="flex flex-row items-center w-full p-3 border rounded-md {item?.ticker?.includes(
class="flex flex-row items-center w-full border p-3 rounded-md {item?.ticker?.includes(
$etfTicker,
)
? 'border border-gray-400'
@ -814,7 +990,9 @@
</span>
</div>
<div class="rounded-full w-8 h-8 relative border border-gray-600">
<div
class="rounded-full w-8 h-8 relative border border-[#737373]"
>
{#if item?.ticker?.includes($etfTicker)}
<svg
class="w-full h-full rounded-full"

View File

@ -1,12 +0,0 @@
import {
etfTicker,
displayCompanyName,
assetType,
} from "$lib/store";
export const load = async ({ data }) => {
etfTicker.set(data?.getParams?.toUpperCase());
assetType.set("etf");
displayCompanyName.set(data?.companyName);
};

View File

@ -6,22 +6,18 @@
setCache,
numberOfUnreadNotification,
globalForm,
isCrosshairMoveActive,
realtimePrice,
priceIncrease,
wsBidPrice,
wsAskPrice,
currentPortfolioPrice,
etfTicker,
displayCompanyName,
isOpen,
isBeforeMarketOpen,
isWeekend,
shouldUpdatePriceChart,
priceChartData,
} from "$lib/store";
import { onDestroy, onMount } from "svelte";
import WIIM from "$lib/components/WIIM.svelte";
import News from "$lib/components/News.svelte";
import ETFSidecard from "$lib/components/ETFSidecard.svelte";
@ -30,8 +26,8 @@
export let data;
export let form;
let prePostData = {};
let stockDeck = {};
$: previousClose = data?.getStockQuote?.previousClose;
//============================================//
const intervals = ["1D", "1W", "1M", "6M", "1Y", "MAX"];
@ -51,62 +47,71 @@
$: {
if (output !== null) {
let change;
let graphChange;
let currentDataRow;
let baseClose;
let currentDataRowOneDay;
let baseClose = previousClose;
let graphBaseClose;
const length = oneDayPrice?.length;
for (let i = length - 1; i >= 0; i--) {
if (!isNaN(oneDayPrice[i]?.close)) {
currentDataRowOneDay = oneDayPrice[i];
break;
}
}
// Determine current data row and base close price based on displayData
switch (displayData) {
case "1D":
const length = oneDayPrice?.length;
for (let i = length - 1; i >= 0; i--) {
if (!isNaN(oneDayPrice[i]?.close)) {
currentDataRow = oneDayPrice[i];
break;
}
}
baseClose = previousClose;
break;
case "1W":
currentDataRow = oneWeekPrice?.at(-1); // Latest entry for 1 week
baseClose = oneWeekPrice?.[0]?.close;
graphBaseClose = oneWeekPrice?.at(0)?.close;
break;
case "1M":
currentDataRow = oneMonthPrice?.at(-1); // Latest entry for 1 month
baseClose = oneMonthPrice?.[0]?.close;
graphBaseClose = oneMonthPrice?.at(0)?.close;
break;
case "6M":
currentDataRow = sixMonthPrice?.at(-1); // Latest entry for 6 months
baseClose = sixMonthPrice?.[0]?.close;
graphBaseClose = sixMonthPrice?.at(0)?.close;
break;
case "1Y":
currentDataRow = oneYearPrice?.at(-1); // Latest entry for 1 year
baseClose = oneYearPrice?.[0]?.close;
graphBaseClose = oneYearPrice?.at(0)?.close;
break;
case "MAX":
currentDataRow = maxPrice?.at(-1); // Latest entry for MAX range
baseClose = maxPrice?.[0]?.close;
graphBaseClose = maxPrice?.at(0)?.close;
break;
}
// Calculate percentage change if baseClose and currentDataRow are valid
const closeValue =
displayData === "1D" &&
!$isCrosshairMoveActive &&
$realtimePrice !== null
$realtimePrice !== null && $realtimePrice !== undefined
? $realtimePrice
: (currentDataRowOneDay?.close ?? currentDataRowOneDay?.value);
const graphCloseValue =
$realtimePrice !== null && $realtimePrice !== undefined
? $realtimePrice
: (currentDataRow?.close ?? currentDataRow?.value);
if (closeValue && baseClose) {
change = ((closeValue / baseClose - 1) * 100).toFixed(2);
change = ((closeValue / baseClose - 1) * 100)?.toFixed(2);
}
if (graphCloseValue && graphBaseClose) {
graphChange = ((graphCloseValue / graphBaseClose - 1) * 100)?.toFixed(
2,
);
}
// Format date
const date = new Date(currentDataRow?.time * 1000);
const date = new Date(currentDataRowOneDay?.time * 1000);
const options = {
day: "2-digit",
@ -117,15 +122,7 @@
timeZone: "UTC",
};
//const formattedDate = (displayData === '1D' || displayData === '1W' || displayData === '1M') ? date.toLocaleString('en-GB', options).replace(/\//g, '.') : date.toLocaleDateString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric' }).replace(/\//g, '.');
const formattedDate =
displayData === "1D" || displayData === "1W" || displayData === "1M"
? date.toLocaleString("en-US", options)
: new Date(currentDataRow?.time)?.toLocaleDateString("en-US", {
day: "2-digit",
month: "short",
year: "numeric",
});
const formattedDate = date?.toLocaleString("en-US", options);
const safeFormattedDate =
formattedDate === "Invalid Date"
@ -135,11 +132,11 @@
// Set display legend
displayLegend = {
close:
currentDataRow?.value ??
currentDataRow?.close ??
data?.getStockQuote?.price,
currentDataRowOneDay?.close?.toFixed(2) ??
data?.getStockQuote?.price?.toFixed(2),
date: safeFormattedDate,
change,
graphChange: displayData === "1D" ? change : graphChange,
};
}
}
@ -413,34 +410,8 @@
}
}
async function getPrePostQuote() {
if (!$isOpen) {
const postData = { ticker: $etfTicker, path: "pre-post-quote" };
const response = await fetch("/api/ticker-data", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(postData),
});
prePostData = await response.json();
}
}
let currentDataRow = { value: "-", date: "-" };
let lineLegend = null;
let displayLegend = { close: "-", date: "-" };
function handleSeriesReference(ref) {
try {
lineLegend = ref;
} catch (error) {
console.log(error);
}
}
let displayLastLogicalRangeValue;
const fitContentChart = async () => {
@ -686,19 +657,11 @@
oneMonthPrice = [];
oneYearPrice = [];
maxPrice = [];
prePostData = {};
output = null;
stockDeck = data?.getETFProfile?.at(0); // Essential otherwise chart will not be updated since we wait until #layout.server.ts server response is finished
const asyncFunctions = [getPrePostQuote()];
Promise.all(asyncFunctions)
.then((results) => {
initializePrice();
})
.catch((error) => {
console.error("An error occurred:", error);
});
initializePrice();
}
}
</script>
@ -708,21 +671,21 @@
<meta name="viewport" content="width=device-width" />
<title>
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
{$displayCompanyName} ({$etfTicker}) Stock Price, Quote & News · Stocknear
{data?.companyName} ({$etfTicker}) Stock Price, Quote & News · Stocknear
</title>
<meta
name="description"
content={`Get a real-time ${$displayCompanyName} (${$etfTicker}) stock chart, price quote with breaking news, financials, statistics, charts and more.`}
content={`Get a real-time ${data?.companyName} (${$etfTicker}) stock chart, price quote with breaking news, financials, statistics, charts and more.`}
/>
<!-- Other meta tags -->
<meta
property="og:title"
content={`${$displayCompanyName} (${$etfTicker}) Stock Price, Quote & News · Stocknear`}
content={`${data?.companyName} (${$etfTicker}) Stock Price, Quote & News · Stocknear`}
/>
<meta
property="og:description"
content={`Get a real-time ${$displayCompanyName} (${$etfTicker}) stock chart, price quote with breaking news, financials, statistics, charts and more.`}
content={`Get a real-time ${data?.companyName} (${$etfTicker}) stock chart, price quote with breaking news, financials, statistics, charts and more.`}
/>
<!--<meta property="og:image" content="https://stocknear-pocketbase.s3.amazonaws.com/logo/meta_logo.jpg"/>-->
<meta property="og:type" content="website" />
@ -732,11 +695,11 @@
<meta name="twitter:card" content="summary_large_image" />
<meta
name="twitter:title"
content={`${$displayCompanyName} (${$etfTicker}) Stock Price, Quote & News · Stocknear`}
content={`${data?.companyName} (${$etfTicker}) Stock Price, Quote & News · Stocknear`}
/>
<meta
name="twitter:description"
content={`Get a real-time ${$displayCompanyName} (${$etfTicker}) stock chart, price quote with breaking news, financials, statistics, charts and more.`}
content={`Get a real-time ${data?.companyName} (${$etfTicker}) stock chart, price quote with breaking news, financials, statistics, charts and more.`}
/>
<!--<meta name="twitter:image" content="https://stocknear-pocketbase.s3.amazonaws.com/logo/meta_logo.jpg"/>-->
<!-- Add more Twitter meta tags as needed -->
@ -749,100 +712,7 @@
>
<!-- Main content -->
<div class="pb-12 md:pb-20 w-full sm:pr-6 xl:pr-0">
<div class="xl:pr-10">
<!-- svelte-ignore a11y-click-events-have-key-events -->
<!-- svelte-ignore a11y-label-has-associated-control -->
<div class="flex flex-row items-start w-full sm:pl-6 mt-4">
<div class="flex flex-col items-start justify-start w-full">
<div
class="text-2xl md:text-3xl font-bold text-white flex flex-row items-center w-full"
>
{$realtimePrice ?? displayLegend?.close}
{#if $priceIncrease === true}
<div
style="background-color: green;"
class="inline-block pulse rounded-full w-3 h-3 ml-2"
></div>
{:else if $priceIncrease === false}
<div
style="background-color: red;"
class="inline-block pulse rounded-full w-3 h-3 ml-2"
></div>
{/if}
</div>
<div class="flex flex-row items-center w-full">
<span
class="items-center justify-start {displayLegend?.change > 0
? "before:content-['+'] text-[#00FC50]"
: 'text-[#FF2F1F]'} font-medium text-xs sm:text-sm"
>{displayLegend?.change ?? "-"}%</span
>
<span class="ml-3 text-white text-xs sm:text-sm"
>{displayLegend?.date}</span
>
</div>
</div>
<div class="ml-auto">
{#if Object?.keys(prePostData)?.length !== 0 && prePostData?.price !== 0}
<div class="flex flex-col justify-end items-end">
<div class="flex flex-row items-center justify-end">
<span class="text-white text-lg sm:text-2xl font-bold">
{prePostData?.price}
</span>
{#if prePostData?.changesPercentage >= 0}
<span
class="ml-1 items-center justify-start text-[#00FC50] font-medium text-xs sm:text-sm"
>({prePostData?.changesPercentage}%)</span
>
{:else if prePostData?.changesPercentage < 0}
<span
class="ml-1 items-center justify-start text-[#FF2F1F] font-medium text-xs sm:text-sm"
>({prePostData?.changesPercentage}%)</span
>
{/if}
</div>
{#if $isBeforeMarketOpen && !$isOpen && !$isWeekend}
<div
class="flex flex-row items-center justify-end text-white text-xs sm:text-sm font-normal text-end w-24"
>
<span>Pre-market:</span>
<svg
class="ml-1 w-4 h-4 inline-block"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 256 256"
><path
fill="#EA9703"
d="M120 40V16a8 8 0 0 1 16 0v24a8 8 0 0 1-16 0m72 88a64 64 0 1 1-64-64a64.07 64.07 0 0 1 64 64m-16 0a48 48 0 1 0-48 48a48.05 48.05 0 0 0 48-48M58.34 69.66a8 8 0 0 0 11.32-11.32l-16-16a8 8 0 0 0-11.32 11.32Zm0 116.68l-16 16a8 8 0 0 0 11.32 11.32l16-16a8 8 0 0 0-11.32-11.32M192 72a8 8 0 0 0 5.66-2.34l16-16a8 8 0 0 0-11.32-11.32l-16 16A8 8 0 0 0 192 72m5.66 114.34a8 8 0 0 0-11.32 11.32l16 16a8 8 0 0 0 11.32-11.32ZM48 128a8 8 0 0 0-8-8H16a8 8 0 0 0 0 16h24a8 8 0 0 0 8-8m80 80a8 8 0 0 0-8 8v24a8 8 0 0 0 16 0v-24a8 8 0 0 0-8-8m112-88h-24a8 8 0 0 0 0 16h24a8 8 0 0 0 0-16"
/></svg
>
</div>
{:else}
<div
class="flex flex-row items-center justify-end text-white text-xs sm:text-sm font-normal text-end w-28"
>
<span>After-hours:</span>
<svg
class="ml-1 w-4 h-4 inline-block"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 256 256"
><path
fill="#70A1EF"
d="M232.13 143.64a6 6 0 0 0-6-1.49a90.07 90.07 0 0 1-112.27-112.3a6 6 0 0 0-7.49-7.48a102.88 102.88 0 0 0-51.89 36.31a102 102 0 0 0 142.84 142.84a102.88 102.88 0 0 0 36.31-51.89a6 6 0 0 0-1.5-5.99m-42 48.29a90 90 0 0 1-126-126a90.9 90.9 0 0 1 35.52-28.27a102.06 102.06 0 0 0 118.69 118.69a90.9 90.9 0 0 1-28.24 35.58Z"
/></svg
>
</div>
{/if}
</div>
{/if}
</div>
</div>
<!-----End-Header-CandleChart-Indicators------>
<div class="mt-2">
<!--End Ticker Section-->
<!-- Start Graph -->
@ -877,20 +747,6 @@
{/each}
</ul>
</div>
<div
class="flex shrink flex-row space-x-1 pr-1 text-sm sm:text-[1rem]"
>
<span
class={displayLegend?.change >= 0
? "before:content-['+'] text-[#00FC50]"
: "text-[#FF2F1F]"}
>
{displayLegend?.change ?? "-"}%
</span>
<span class="hidden text-gray-200 sm:block"
>({displayData})</span
>
</div>
</div>
<div class="h-[250px] sm:h-[350px]">
<div
@ -938,11 +794,11 @@
class="flex shrink flex-row space-x-1 pr-1 text-sm sm:text-[1rem]"
>
<span
class={displayLegend?.change >= 0
class={displayLegend?.graphChange >= 0
? "before:content-['+'] text-[#00FC50]"
: "text-[#FF2F1F]"}
>
{displayLegend?.change}%
{displayLegend?.graphChange}%
</span>
<span class="hidden text-gray-200 sm:block"
>({displayData})</span
@ -968,7 +824,6 @@
lineColor={colorChange}
topColor={topColorChange}
bottomColor={bottomColorChange}
ref={handleSeriesReference}
priceLineVisible={false}
>
<PriceLine
@ -988,7 +843,6 @@
lineColor={colorChange}
topColor={topColorChange}
bottomColor={bottomColorChange}
ref={handleSeriesReference}
priceLineVisible={false}
>
<PriceLine
@ -1008,7 +862,6 @@
lineColor={colorChange}
topColor={topColorChange}
bottomColor={bottomColorChange}
ref={handleSeriesReference}
priceLineVisible={false}
>
<PriceLine
@ -1028,7 +881,6 @@
lineColor={colorChange}
topColor={topColorChange}
bottomColor={bottomColorChange}
ref={handleSeriesReference}
priceLineVisible={false}
>
<PriceLine
@ -1048,7 +900,6 @@
lineColor={colorChange}
topColor={topColorChange}
bottomColor={bottomColorChange}
ref={handleSeriesReference}
priceLineVisible={false}
>
<PriceLine
@ -1068,7 +919,6 @@
lineColor={colorChange}
topColor={topColorChange}
bottomColor={bottomColorChange}
ref={handleSeriesReference}
priceLineVisible={false}
>
<PriceLine
@ -1101,7 +951,7 @@
class="mt-10 lg:mt-0 order-5 lg:order-1 flex flex-row space-x-2 sm:space-x-3 xs:space-x-4"
>
<table
class="w-[50%] text-sm text-white tiny:text-small lg:w-full lg:min-w-[210px]"
class="w-[50%] text-sm text-white sm:text-[1rem] lg:min-w-[250px] 2xl:min-w-[300px]"
>
<tbody
><tr
@ -1221,8 +1071,7 @@
</tbody>
</table>
<table
class="w-[48%] text-sm text-white tiny:text-small lg:w-auto lg:min-w-[210px]"
data-test="overview-quote"
class="w-[50%] text-sm text-white lg:min-w-[250px] 2xl:min-w-[300px]"
>
<tbody
><tr
@ -1332,16 +1181,15 @@
<!--End Graph-->
<div
class="mt-6 flex flex-col lg:flex-row gap-x-14 items-start w-full"
class="mt-6 flex flex-col lg:flex-row gap-x-14 items-start w-full justify-between"
>
<div
class="lg:space-y-6 lg:order-2 lg:pt-1 sm:pl-7 lg:pl-0 w-full lg:w-[45%] sm:ml-auto"
class="lg:space-y-6 lg:order-2 lg:pt-1 sm:pl-7 lg:pl-0 w-full lg:w-[45%] sm:ml-auto lg:max-w-[400px]"
>
<ETFSidecard {data} />
<div class="lg:sticky lg:top-20"></div>
</div>
<div class="w-full">
<div class="w-full lg:w-[65%] 2xl:w-[70%]">
<div
class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 {data
?.getWhyPriceMoved?.length !== 0
@ -1351,7 +1199,7 @@
<WIIM {data} />
</div>
<div class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 sm:pt-6">
<div class="w-full mt-5 sm:mt-0 m-auto sm:pl-6 sm:pb-6">
<News {data} />
</div>
</div>

View File

@ -254,11 +254,7 @@
});
$: {
if (
$stockTicker &&
$stockTicker?.length !== 0 &&
typeof window !== "undefined"
) {
if ($stockTicker && $stockTicker?.length !== 0) {
// add a check to see if running on client-side
$stockTicker = data?.getParams;
$assetType = "stock";
@ -337,17 +333,13 @@
$: charNumber = $screenWidth < 640 ? 25 : 40;
$: {
if (
$stockTicker &&
typeof window !== "undefined" &&
$page.url.pathname === `/stocks/${$stockTicker}`
) {
if ($stockTicker && $page.url.pathname === `/stocks/${$stockTicker}`) {
displaySection = "overview";
}
}
$: {
if ($page?.url?.pathname && typeof window !== "undefined") {
if ($page?.url?.pathname) {
const parts = $page?.url?.pathname?.split("/");
const sectionMap = {
statistics: "statistics",

View File

@ -1230,7 +1230,7 @@
<WIIM {data} />
</div>
<div class="w-full mt-5 sm:mt-0 m-auto sm:pl-6 sm:pb-6 sm:pt-6">
<div class="w-full mt-5 sm:mt-0 m-auto sm:pl-6 sm:pb-6">
<News {data} />
</div>
</div>