optimize for seo
This commit is contained in:
parent
da8a443ee5
commit
cbefa701ce
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
// Use the correct reactive declaration
|
// Use the correct reactive declaration
|
||||||
$: {
|
$: {
|
||||||
if ($stockTicker && typeof window !== "undefined") {
|
if ($stockTicker) {
|
||||||
// Correctly check if score is neither undefined nor null
|
// Correctly check if score is neither undefined nor null
|
||||||
$scoreComponent = score !== undefined && score !== null && score !== 0;
|
$scoreComponent = score !== undefined && score !== null && score !== 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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}
|
|
||||||
@ -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>
|
|
||||||
@ -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>
|
|
||||||
@ -6,7 +6,6 @@
|
|||||||
abbreviateNumber,
|
abbreviateNumber,
|
||||||
sectorNavigation,
|
sectorNavigation,
|
||||||
} from "$lib/utils";
|
} from "$lib/utils";
|
||||||
import defaultLogo from "$lib/images/stocks/logo/default_logo.png";
|
|
||||||
|
|
||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
|
|
||||||
@ -39,7 +38,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ($etfTicker && typeof window !== "undefined") {
|
if ($etfTicker) {
|
||||||
info = data?.getETFProfile?.at(0);
|
info = data?.getETFProfile?.at(0);
|
||||||
topHoldingList = data?.getETFHoldings?.holdings || [];
|
topHoldingList = data?.getETFHoldings?.holdings || [];
|
||||||
topSectorList = data?.getETFSectorWeighting || [];
|
topSectorList = data?.getETFSectorWeighting || [];
|
||||||
@ -215,21 +214,9 @@
|
|||||||
>
|
>
|
||||||
<td class="">
|
<td class="">
|
||||||
<div class="flex flex-row items-center">
|
<div class="flex flex-row items-center">
|
||||||
<div
|
<div class="flex flex-col w-full">
|
||||||
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">
|
|
||||||
<span class="text-sm font-medium"
|
<span class="text-sm font-medium"
|
||||||
>{item?.symbol ?? "-"}</span
|
>{item?.symbol ?? "n/a"}</span
|
||||||
>
|
>
|
||||||
<span class="text-white text-sm">
|
<span class="text-white text-sm">
|
||||||
{#if typeof item?.name !== "undefined"}
|
{#if typeof item?.name !== "undefined"}
|
||||||
|
|||||||
@ -6,14 +6,12 @@
|
|||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
let rawData = [];
|
let rawData = [];
|
||||||
let rawDataPressRelease;
|
let rawDataPressRelease = [];
|
||||||
|
|
||||||
let newsList = [];
|
let newsList = [];
|
||||||
let displaySection = "all";
|
let displaySection = "all";
|
||||||
let isLoaded = true;
|
|
||||||
|
|
||||||
async function getPressRelease() {
|
async function getPressRelease() {
|
||||||
isLoaded = false;
|
|
||||||
displaySection = "press-releases";
|
displaySection = "press-releases";
|
||||||
const cachedData = getCache($stockTicker, "getPressRelease");
|
const cachedData = getCache($stockTicker, "getPressRelease");
|
||||||
if (cachedData) {
|
if (cachedData) {
|
||||||
@ -31,7 +29,6 @@
|
|||||||
rawDataPressRelease = await response?.json();
|
rawDataPressRelease = await response?.json();
|
||||||
setCache($stockTicker, rawDataPressRelease, "getPressRelease");
|
setCache($stockTicker, rawDataPressRelease, "getPressRelease");
|
||||||
}
|
}
|
||||||
isLoaded = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkIfYoutubeVideo(link: string): string | null {
|
function checkIfYoutubeVideo(link: string): string | null {
|
||||||
@ -67,9 +64,8 @@
|
|||||||
: newsList;
|
: newsList;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (($stockTicker || $etfTicker) && typeof window !== "undefined") {
|
if ($stockTicker || $etfTicker) {
|
||||||
isLoaded = true;
|
rawData = data?.getNews || [];
|
||||||
rawData = data?.getNews;
|
|
||||||
rawDataPressRelease = [];
|
rawDataPressRelease = [];
|
||||||
newsList = rawData?.slice(0, 20) ?? [];
|
newsList = rawData?.slice(0, 20) ?? [];
|
||||||
displaySection = "all";
|
displaySection = "all";
|
||||||
@ -143,7 +139,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if rawData?.length > 0}
|
{#if rawData?.length > 0}
|
||||||
{#if isLoaded}
|
|
||||||
{#if filteredNewsList?.length > 0}
|
{#if filteredNewsList?.length > 0}
|
||||||
<div class="grid grid-cols-1 gap-2 pb-5 pt-5">
|
<div class="grid grid-cols-1 gap-2 pb-5 pt-5">
|
||||||
{#each filteredNewsList as item, index}
|
{#each filteredNewsList as item, index}
|
||||||
@ -273,18 +268,6 @@
|
|||||||
Load More News
|
Load More News
|
||||||
</label>
|
</label>
|
||||||
{/if}
|
{/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}
|
{:else}
|
||||||
<span class="text-white"> No News article available yet </span>
|
<span class="text-white"> No News article available yet </span>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ($stockTicker && typeof window !== "undefined") {
|
if ($stockTicker) {
|
||||||
rawData = data?.getNextEarnings?.next;
|
rawData = data?.getNextEarnings?.next;
|
||||||
epsRatio =
|
epsRatio =
|
||||||
rawData?.epsPrior !== 0
|
rawData?.epsPrior !== 0
|
||||||
|
|||||||
@ -5,8 +5,6 @@
|
|||||||
export let userTier;
|
export let userTier;
|
||||||
export let rawData;
|
export let rawData;
|
||||||
|
|
||||||
let isLoaded = false;
|
|
||||||
|
|
||||||
let xData = [];
|
let xData = [];
|
||||||
|
|
||||||
let tableRevenue = [];
|
let tableRevenue = [];
|
||||||
@ -65,10 +63,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ($stockTicker && typeof window !== "undefined") {
|
if ($stockTicker) {
|
||||||
isLoaded = false;
|
|
||||||
prepareDataset();
|
prepareDataset();
|
||||||
isLoaded = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -76,7 +72,6 @@
|
|||||||
<section class="overflow-hidden text-white h-full pb-8 sm:pb-2">
|
<section class="overflow-hidden text-white h-full pb-8 sm:pb-2">
|
||||||
<main class="overflow-hidden">
|
<main class="overflow-hidden">
|
||||||
<div class="w-full m-auto">
|
<div class="w-full m-auto">
|
||||||
{#if isLoaded}
|
|
||||||
{#if rawData?.length !== 0}
|
{#if rawData?.length !== 0}
|
||||||
<span class="">
|
<span class="">
|
||||||
The average price volatility over this 3-day period is
|
The average price volatility over this 3-day period is
|
||||||
@ -98,11 +93,10 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<span class="font-bold">±{averageVolatility?.toFixed(2)}%</span>.
|
<span class="font-bold">±{averageVolatility?.toFixed(2)}%</span>.
|
||||||
During this period, the reported revenue exceeded expectations
|
During this period, the reported revenue exceeded expectations
|
||||||
<span class="font-bold">{positiveRevenueSurprisePercentage}%</span
|
<span class="font-bold">{positiveRevenueSurprisePercentage}%</span>
|
||||||
>
|
|
||||||
of the time & the reported EPS surpassed analyst estimates
|
of the time & the reported EPS surpassed analyst estimates
|
||||||
<span class="font-bold">{positiveEpsSurprisePercentage}%</span> of
|
<span class="font-bold">{positiveEpsSurprisePercentage}%</span> of the
|
||||||
the time.
|
time.
|
||||||
{/if}
|
{/if}
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div
|
||||||
@ -155,9 +149,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
{:else if item !== undefined && item !== null}
|
{:else if item !== undefined && item !== null}
|
||||||
<span
|
<span>{@html abbreviateNumber(item, false, true)}</span>
|
||||||
>{@html abbreviateNumber(item, false, true)}</span
|
|
||||||
>
|
|
||||||
{:else}
|
{:else}
|
||||||
n/a
|
n/a
|
||||||
{/if}
|
{/if}
|
||||||
@ -197,9 +189,7 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
{:else if item !== undefined && item !== null}
|
{:else if item !== undefined && item !== null}
|
||||||
<span
|
<span>{@html abbreviateNumber(item, false, true)}</span>
|
||||||
>{@html abbreviateNumber(item, false, true)}</span
|
|
||||||
>
|
|
||||||
{:else}
|
{:else}
|
||||||
n/a
|
n/a
|
||||||
{/if}
|
{/if}
|
||||||
@ -445,18 +435,6 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/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>
|
||||||
</main>
|
</main>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ($stockTicker && typeof window !== "undefined") {
|
if ($stockTicker) {
|
||||||
info = data?.getStockDeck;
|
info = data?.getStockDeck;
|
||||||
ipoDate =
|
ipoDate =
|
||||||
info?.ipoDate !== null && info?.ipoDate?.length > 0
|
info?.ipoDate !== null && info?.ipoDate?.length > 0
|
||||||
|
|||||||
@ -6,8 +6,7 @@
|
|||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
|
||||||
let isLoaded = false;
|
let wiim = [];
|
||||||
let wiim;
|
|
||||||
let showFullHistory = false;
|
let showFullHistory = false;
|
||||||
|
|
||||||
function latestInfoDate(inputDate) {
|
function latestInfoDate(inputDate) {
|
||||||
@ -36,11 +35,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ((get(stockTicker) || get(etfTicker)) && typeof window !== "undefined") {
|
if (get(stockTicker) || get(etfTicker)) {
|
||||||
isLoaded = false;
|
|
||||||
showFullHistory = false;
|
showFullHistory = false;
|
||||||
wiim = data?.getWhyPriceMoved || [];
|
wiim = data?.getWhyPriceMoved || [];
|
||||||
isLoaded = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -61,7 +58,6 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if isLoaded}
|
|
||||||
{#if wiim?.length !== 0}
|
{#if wiim?.length !== 0}
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
{#each showFullHistory ? wiim : wiim?.slice(0, 2) as item, index}
|
{#each showFullHistory ? wiim : wiim?.slice(0, 2) as item, index}
|
||||||
@ -229,17 +225,5 @@
|
|||||||
</label>
|
</label>
|
||||||
{/if}
|
{/if}
|
||||||
{/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>
|
|
||||||
{/if}
|
|
||||||
</main>
|
</main>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@ -44,7 +44,6 @@ const fetchWatchlist = async (pb, userId) => {
|
|||||||
|
|
||||||
export const load = async ({ params, locals }) => {
|
export const load = async ({ params, locals }) => {
|
||||||
const { apiURL, apiKey, pb, user } = locals;
|
const { apiURL, apiKey, pb, user } = locals;
|
||||||
|
|
||||||
const { tickerID } = params;
|
const { tickerID } = params;
|
||||||
|
|
||||||
const endpoints = [
|
const endpoints = [
|
||||||
@ -53,6 +52,7 @@ export const load = async ({ params, locals }) => {
|
|||||||
"/etf-sector-weighting",
|
"/etf-sector-weighting",
|
||||||
"/stock-dividend",
|
"/stock-dividend",
|
||||||
"/stock-quote",
|
"/stock-quote",
|
||||||
|
"/pre-post-quote",
|
||||||
"/wiim",
|
"/wiim",
|
||||||
"/one-day-price",
|
"/one-day-price",
|
||||||
"/stock-news",
|
"/stock-news",
|
||||||
@ -71,18 +71,22 @@ export const load = async ({ params, locals }) => {
|
|||||||
getETFSectorWeighting,
|
getETFSectorWeighting,
|
||||||
getStockDividend,
|
getStockDividend,
|
||||||
getStockQuote,
|
getStockQuote,
|
||||||
|
getPrePostQuote,
|
||||||
getWhyPriceMoved,
|
getWhyPriceMoved,
|
||||||
getOneDayPrice,
|
getOneDayPrice,
|
||||||
getNews,
|
getNews,
|
||||||
getUserWatchlist,
|
getUserWatchlist,
|
||||||
] = await Promise.all(promises);
|
] = await Promise.all(promises);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getETFProfile,
|
getETFProfile,
|
||||||
getETFHoldings,
|
getETFHoldings,
|
||||||
getETFSectorWeighting,
|
getETFSectorWeighting,
|
||||||
getStockDividend,
|
getStockDividend,
|
||||||
getStockQuote,
|
getStockQuote,
|
||||||
|
getPrePostQuote,
|
||||||
getWhyPriceMoved,
|
getWhyPriceMoved,
|
||||||
getOneDayPrice,
|
getOneDayPrice,
|
||||||
getNews,
|
getNews,
|
||||||
|
|||||||
@ -22,16 +22,21 @@
|
|||||||
import { onMount, onDestroy, afterUpdate } from "svelte";
|
import { onMount, onDestroy, afterUpdate } from "svelte";
|
||||||
import { page } from "$app/stores";
|
import { page } from "$app/stores";
|
||||||
import toast from "svelte-french-toast";
|
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";
|
import PriceAlert from "$lib/components/PriceAlert.svelte";
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
|
let prePostData = data?.getPrePostQuote || {};
|
||||||
$: $realtimePrice = data?.getStockQuote?.price?.toFixed(2);
|
$: $realtimePrice = data?.getStockQuote?.price?.toFixed(2);
|
||||||
|
let oneDayPrice = [];
|
||||||
let previousRealtimePrice = null;
|
let previousRealtimePrice = null;
|
||||||
let previousTicker;
|
let previousTicker;
|
||||||
let socket;
|
let socket;
|
||||||
|
|
||||||
|
$etfTicker = data?.getParams;
|
||||||
|
$assetType = "stock";
|
||||||
|
$displayCompanyName = data?.companyName;
|
||||||
|
|
||||||
let isScrolled = false;
|
let isScrolled = false;
|
||||||
let y;
|
let y;
|
||||||
|
|
||||||
@ -42,16 +47,17 @@
|
|||||||
//let availableCash = 0;
|
//let availableCash = 0;
|
||||||
|
|
||||||
let displaySection = "";
|
let displaySection = "";
|
||||||
|
let displayLegend = {};
|
||||||
|
|
||||||
function shareContent(url) {
|
function shareContent(url) {
|
||||||
if (navigator.share) {
|
if (navigator.share) {
|
||||||
navigator
|
navigator
|
||||||
.share({
|
?.share({
|
||||||
title: document.title,
|
title: document.title,
|
||||||
url,
|
url,
|
||||||
})
|
})
|
||||||
.then(() => console.log("Content shared successfully."))
|
?.then(() => console.log("Content shared successfully."))
|
||||||
.catch((error) => console.log("Error sharing content:", error));
|
?.catch((error) => console.log("Error sharing content:", error));
|
||||||
} else {
|
} else {
|
||||||
toast.error("Sharing is not supported by your device", {
|
toast.error("Sharing is not supported by your device", {
|
||||||
style: "background: #2A2E39; color: #fff;",
|
style: "background: #2A2E39; color: #fff;",
|
||||||
@ -65,7 +71,12 @@
|
|||||||
options: "/options",
|
options: "/options",
|
||||||
"dark-pool": "/dark-pool",
|
"dark-pool": "/dark-pool",
|
||||||
dividends: "/dividends",
|
dividends: "/dividends",
|
||||||
|
statistics: "/statistics",
|
||||||
|
metrics: "metrics",
|
||||||
|
forecast: "/forecast",
|
||||||
|
financials: "/financials",
|
||||||
history: "/history",
|
history: "/history",
|
||||||
|
profile: "/profile",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (state !== "overview" && sectionMap[state]) {
|
if (state !== "overview" && sectionMap[state]) {
|
||||||
@ -241,14 +252,74 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (
|
if ($etfTicker && $etfTicker?.length !== 0) {
|
||||||
$etfTicker &&
|
|
||||||
$etfTicker?.length !== 0 &&
|
|
||||||
typeof window !== "undefined"
|
|
||||||
) {
|
|
||||||
// add a check to see if running on client-side
|
// add a check to see if running on client-side
|
||||||
|
$etfTicker = data?.getParams;
|
||||||
|
$assetType = "stock";
|
||||||
|
$displayCompanyName = data?.companyName;
|
||||||
$currentPortfolioPrice = data?.getStockQuote?.price;
|
$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),
|
(item) => item.user === data?.user?.id && item.ticker?.includes($etfTicker),
|
||||||
);
|
);
|
||||||
|
|
||||||
$: charNumber = $screenWidth < 640 ? 15 : 25;
|
$: charNumber = $screenWidth < 640 ? 25 : 40;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (
|
if ($etfTicker && $page.url.pathname === `/etf/${$etfTicker}`) {
|
||||||
$etfTicker &&
|
|
||||||
typeof window !== "undefined" &&
|
|
||||||
$page.url.pathname === `/etf/${$etfTicker}`
|
|
||||||
) {
|
|
||||||
displaySection = "overview";
|
displaySection = "overview";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ($page?.url?.pathname && typeof window !== "undefined") {
|
if ($page?.url?.pathname) {
|
||||||
const parts = $page?.url?.pathname?.split("/");
|
const parts = $page?.url?.pathname?.split("/");
|
||||||
const sectionMap = {
|
const sectionMap = {
|
||||||
holdings: "holdings",
|
holdings: "holdings",
|
||||||
options: "options",
|
options: "options",
|
||||||
|
options: "options",
|
||||||
"dark-pool": "dark-pool",
|
"dark-pool": "dark-pool",
|
||||||
insider: "insider",
|
insider: "insider",
|
||||||
dividends: "dividends",
|
dividends: "dividends",
|
||||||
@ -292,10 +360,10 @@
|
|||||||
<svelte:window bind:scrollY={y} />
|
<svelte:window bind:scrollY={y} />
|
||||||
|
|
||||||
<body
|
<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 -->
|
<!-- 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">
|
<main class="grow w-full">
|
||||||
<section class="w-full">
|
<section class="w-full">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
@ -330,9 +398,7 @@
|
|||||||
? "hidden"
|
? "hidden"
|
||||||
: "flex flex-col items-center ml-6 transition-transform ease-in"}
|
: "flex flex-col items-center ml-6 transition-transform ease-in"}
|
||||||
>
|
>
|
||||||
<span
|
<span class="text-white text-xs font-semibold">
|
||||||
class="text-white text-[0.70rem] font-medium text-opacity-[0.6]"
|
|
||||||
>
|
|
||||||
{$etfTicker}
|
{$etfTicker}
|
||||||
</span>
|
</span>
|
||||||
<span class="text-white font-medium text-sm">
|
<span class="text-white font-medium text-sm">
|
||||||
@ -497,23 +563,19 @@
|
|||||||
</div>
|
</div>
|
||||||
<!--End Mobile Navbar-->
|
<!--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
|
<div
|
||||||
class="md:flex md:justify-between md:divide-x md:divide-slate-800"
|
class="md:flex md:justify-between md:divide-x md:divide-slate-800"
|
||||||
>
|
>
|
||||||
<!-- Main content -->
|
<!-- Main content -->
|
||||||
<div class="pb-12 md:pb-20 w-full">
|
<div class="pb-12 md:pb-20 w-full">
|
||||||
<div class="md:pr-6 lg:pr-10">
|
<div class="">
|
||||||
<!-----Start-Header-CandleChart-Indicators------>
|
<!-----Start-Header-CandleChart-Indicators------>
|
||||||
|
|
||||||
<div
|
<div class="m-auto pl-0 sm:pl-4 overflow-hidden mb-3">
|
||||||
class="m-auto pl-0 sm:pl-4 overflow-hidden mb-3 md:mt-10 xl:pr-7"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
class="hidden sm:flex flex-row w-full justify-between items-center"
|
class="hidden sm:flex flex-row w-full justify-between items-center"
|
||||||
>
|
>
|
||||||
<Markethour />
|
|
||||||
|
|
||||||
<!--Start Watchlist-->
|
<!--Start Watchlist-->
|
||||||
|
|
||||||
{#if data?.user}
|
{#if data?.user}
|
||||||
@ -640,22 +702,135 @@
|
|||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
<!-- 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
|
<div
|
||||||
class="flex flex-row justify-start w-full items-center"
|
class="flex flex-row justify-start w-full items-center"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col items-start ml-2 sm:ml-3">
|
<div class="flex flex-col items-start w-full">
|
||||||
<span class="text-md sm:text-lg text-blue-400">
|
<div
|
||||||
{$etfTicker?.toUpperCase()}
|
class="flex flex-row justify-between items-center w-full sm:-mt-[50px] mb-5 sm:mb-10"
|
||||||
</span>
|
>
|
||||||
<span
|
<div
|
||||||
class="text-xl sm:text-2xl font-semibold sm:font-bold text-white"
|
class="text-2xl lg:text-3xl font-bold text-white"
|
||||||
>
|
>
|
||||||
{$displayCompanyName?.length > charNumber
|
{$displayCompanyName?.length > charNumber
|
||||||
? $displayCompanyName?.slice(0, charNumber) +
|
? $displayCompanyName?.slice(0, charNumber) +
|
||||||
"..."
|
"..."
|
||||||
: $displayCompanyName}
|
: $displayCompanyName}
|
||||||
</span>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -664,7 +839,6 @@
|
|||||||
|
|
||||||
<!--Start Ticker Section-->
|
<!--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
|
<nav
|
||||||
class="sm:ml-4 border-b-[2px] overflow-x-scroll md:overflow-hidden whitespace-nowrap"
|
class="sm:ml-4 border-b-[2px] overflow-x-scroll md:overflow-hidden whitespace-nowrap"
|
||||||
>
|
>
|
||||||
@ -676,28 +850,28 @@
|
|||||||
on:click={() => changeSection("overview")}
|
on:click={() => changeSection("overview")}
|
||||||
class="p-2 px-5 cursor-pointer {displaySection ===
|
class="p-2 px-5 cursor-pointer {displaySection ===
|
||||||
'overview'
|
'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]'}"
|
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
|
||||||
>
|
>
|
||||||
Overview
|
Overview
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href={`/etf/${$etfTicker}/holdings`}
|
href={`/etf/${$etfTicker}/holdings`}
|
||||||
on:click={() => changeSection("holdings")}
|
on:click={() => changeSection("holdings")}
|
||||||
class="p-2 px-5 cursor-pointer {displaySection ===
|
class="p-2 px-5 cursor-pointer {displaySection ===
|
||||||
'holdings'
|
'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]'}"
|
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
|
||||||
>
|
>
|
||||||
Holdings
|
Holdings
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
<a
|
||||||
href={`/etf/${$etfTicker}/options`}
|
href={`/etf/${$etfTicker}/options`}
|
||||||
on:click={() => changeSection("options")}
|
on:click={() => changeSection("options")}
|
||||||
class="p-2 px-5 cursor-pointer {displaySection ===
|
class="p-2 px-5 cursor-pointer {displaySection ===
|
||||||
'options'
|
'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]'}"
|
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
|
||||||
>
|
>
|
||||||
Options
|
Options
|
||||||
@ -707,7 +881,7 @@
|
|||||||
on:click={() => changeSection("dark-pool")}
|
on:click={() => changeSection("dark-pool")}
|
||||||
class="p-2 px-5 cursor-pointer {displaySection ===
|
class="p-2 px-5 cursor-pointer {displaySection ===
|
||||||
'dark-pool'
|
'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]'}"
|
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
|
||||||
>
|
>
|
||||||
Dark Pool
|
Dark Pool
|
||||||
@ -717,7 +891,7 @@
|
|||||||
on:click={() => changeSection("insider")}
|
on:click={() => changeSection("insider")}
|
||||||
class="p-2 px-5 cursor-pointer {displaySection ===
|
class="p-2 px-5 cursor-pointer {displaySection ===
|
||||||
'insider'
|
'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]'}"
|
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
|
||||||
>
|
>
|
||||||
Insider
|
Insider
|
||||||
@ -727,7 +901,7 @@
|
|||||||
on:click={() => changeSection("dividends")}
|
on:click={() => changeSection("dividends")}
|
||||||
class="p-2 px-5 cursor-pointer {displaySection ===
|
class="p-2 px-5 cursor-pointer {displaySection ===
|
||||||
'dividends'
|
'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]'}"
|
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
|
||||||
>
|
>
|
||||||
Dividends
|
Dividends
|
||||||
@ -737,7 +911,7 @@
|
|||||||
on:click={() => changeSection("history")}
|
on:click={() => changeSection("history")}
|
||||||
class="p-2 px-5 cursor-pointer {displaySection ===
|
class="p-2 px-5 cursor-pointer {displaySection ===
|
||||||
'history'
|
'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]'}"
|
: 'text-gray-400 sm:hover:text-white sm:hover:bg-secondary sm:hover:bg-opacity-[0.95]'}"
|
||||||
>
|
>
|
||||||
History
|
History
|
||||||
@ -746,6 +920,7 @@
|
|||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<!--Start-Main Content-->
|
<!--Start-Main Content-->
|
||||||
|
|
||||||
<slot />
|
<slot />
|
||||||
<!--End Main Content-->
|
<!--End Main Content-->
|
||||||
</div>
|
</div>
|
||||||
@ -767,6 +942,7 @@
|
|||||||
|
|
||||||
<!--Start SellTrade Modal-->
|
<!--Start SellTrade Modal-->
|
||||||
<PriceAlert {data} ticker={$etfTicker} assetType={$assetType} />
|
<PriceAlert {data} ticker={$etfTicker} assetType={$assetType} />
|
||||||
|
|
||||||
<!--Start Add Watchlist Modal-->
|
<!--Start Add Watchlist Modal-->
|
||||||
<input type="checkbox" id="addWatchListModal" class="modal-toggle" />
|
<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"
|
class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
|
||||||
>
|
>
|
||||||
<div
|
<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,
|
$etfTicker,
|
||||||
)
|
)
|
||||||
? 'border border-gray-400'
|
? 'border border-gray-400'
|
||||||
@ -814,7 +990,9 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</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)}
|
{#if item?.ticker?.includes($etfTicker)}
|
||||||
<svg
|
<svg
|
||||||
class="w-full h-full rounded-full"
|
class="w-full h-full rounded-full"
|
||||||
|
|||||||
@ -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);
|
|
||||||
};
|
|
||||||
@ -6,22 +6,18 @@
|
|||||||
setCache,
|
setCache,
|
||||||
numberOfUnreadNotification,
|
numberOfUnreadNotification,
|
||||||
globalForm,
|
globalForm,
|
||||||
isCrosshairMoveActive,
|
|
||||||
realtimePrice,
|
realtimePrice,
|
||||||
priceIncrease,
|
priceIncrease,
|
||||||
wsBidPrice,
|
wsBidPrice,
|
||||||
wsAskPrice,
|
wsAskPrice,
|
||||||
currentPortfolioPrice,
|
currentPortfolioPrice,
|
||||||
etfTicker,
|
etfTicker,
|
||||||
displayCompanyName,
|
|
||||||
isOpen,
|
|
||||||
isBeforeMarketOpen,
|
|
||||||
isWeekend,
|
|
||||||
shouldUpdatePriceChart,
|
shouldUpdatePriceChart,
|
||||||
priceChartData,
|
priceChartData,
|
||||||
} from "$lib/store";
|
} from "$lib/store";
|
||||||
import { onDestroy, onMount } from "svelte";
|
import { onDestroy, onMount } from "svelte";
|
||||||
import WIIM from "$lib/components/WIIM.svelte";
|
import WIIM from "$lib/components/WIIM.svelte";
|
||||||
|
|
||||||
import News from "$lib/components/News.svelte";
|
import News from "$lib/components/News.svelte";
|
||||||
import ETFSidecard from "$lib/components/ETFSidecard.svelte";
|
import ETFSidecard from "$lib/components/ETFSidecard.svelte";
|
||||||
|
|
||||||
@ -30,8 +26,8 @@
|
|||||||
export let data;
|
export let data;
|
||||||
export let form;
|
export let form;
|
||||||
|
|
||||||
let prePostData = {};
|
|
||||||
let stockDeck = {};
|
let stockDeck = {};
|
||||||
|
|
||||||
$: previousClose = data?.getStockQuote?.previousClose;
|
$: previousClose = data?.getStockQuote?.previousClose;
|
||||||
//============================================//
|
//============================================//
|
||||||
const intervals = ["1D", "1W", "1M", "6M", "1Y", "MAX"];
|
const intervals = ["1D", "1W", "1M", "6M", "1Y", "MAX"];
|
||||||
@ -51,62 +47,71 @@
|
|||||||
$: {
|
$: {
|
||||||
if (output !== null) {
|
if (output !== null) {
|
||||||
let change;
|
let change;
|
||||||
|
let graphChange;
|
||||||
let currentDataRow;
|
let currentDataRow;
|
||||||
let baseClose;
|
let currentDataRowOneDay;
|
||||||
|
let baseClose = previousClose;
|
||||||
|
let graphBaseClose;
|
||||||
|
|
||||||
// Determine current data row and base close price based on displayData
|
|
||||||
switch (displayData) {
|
|
||||||
case "1D":
|
|
||||||
const length = oneDayPrice?.length;
|
const length = oneDayPrice?.length;
|
||||||
for (let i = length - 1; i >= 0; i--) {
|
for (let i = length - 1; i >= 0; i--) {
|
||||||
if (!isNaN(oneDayPrice[i]?.close)) {
|
if (!isNaN(oneDayPrice[i]?.close)) {
|
||||||
currentDataRow = oneDayPrice[i];
|
currentDataRowOneDay = oneDayPrice[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
baseClose = previousClose;
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
// Determine current data row and base close price based on displayData
|
||||||
|
switch (displayData) {
|
||||||
case "1W":
|
case "1W":
|
||||||
currentDataRow = oneWeekPrice?.at(-1); // Latest entry for 1 week
|
currentDataRow = oneWeekPrice?.at(-1); // Latest entry for 1 week
|
||||||
baseClose = oneWeekPrice?.[0]?.close;
|
graphBaseClose = oneWeekPrice?.at(0)?.close;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "1M":
|
case "1M":
|
||||||
currentDataRow = oneMonthPrice?.at(-1); // Latest entry for 1 month
|
currentDataRow = oneMonthPrice?.at(-1); // Latest entry for 1 month
|
||||||
baseClose = oneMonthPrice?.[0]?.close;
|
graphBaseClose = oneMonthPrice?.at(0)?.close;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "6M":
|
case "6M":
|
||||||
currentDataRow = sixMonthPrice?.at(-1); // Latest entry for 6 months
|
currentDataRow = sixMonthPrice?.at(-1); // Latest entry for 6 months
|
||||||
baseClose = sixMonthPrice?.[0]?.close;
|
graphBaseClose = sixMonthPrice?.at(0)?.close;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "1Y":
|
case "1Y":
|
||||||
currentDataRow = oneYearPrice?.at(-1); // Latest entry for 1 year
|
currentDataRow = oneYearPrice?.at(-1); // Latest entry for 1 year
|
||||||
baseClose = oneYearPrice?.[0]?.close;
|
graphBaseClose = oneYearPrice?.at(0)?.close;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "MAX":
|
case "MAX":
|
||||||
currentDataRow = maxPrice?.at(-1); // Latest entry for MAX range
|
currentDataRow = maxPrice?.at(-1); // Latest entry for MAX range
|
||||||
baseClose = maxPrice?.[0]?.close;
|
graphBaseClose = maxPrice?.at(0)?.close;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate percentage change if baseClose and currentDataRow are valid
|
// Calculate percentage change if baseClose and currentDataRow are valid
|
||||||
const closeValue =
|
const closeValue =
|
||||||
displayData === "1D" &&
|
$realtimePrice !== null && $realtimePrice !== undefined
|
||||||
!$isCrosshairMoveActive &&
|
? $realtimePrice
|
||||||
$realtimePrice !== null
|
: (currentDataRowOneDay?.close ?? currentDataRowOneDay?.value);
|
||||||
|
|
||||||
|
const graphCloseValue =
|
||||||
|
$realtimePrice !== null && $realtimePrice !== undefined
|
||||||
? $realtimePrice
|
? $realtimePrice
|
||||||
: (currentDataRow?.close ?? currentDataRow?.value);
|
: (currentDataRow?.close ?? currentDataRow?.value);
|
||||||
|
|
||||||
if (closeValue && baseClose) {
|
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
|
// Format date
|
||||||
const date = new Date(currentDataRow?.time * 1000);
|
const date = new Date(currentDataRowOneDay?.time * 1000);
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
day: "2-digit",
|
day: "2-digit",
|
||||||
@ -117,15 +122,7 @@
|
|||||||
timeZone: "UTC",
|
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 = date?.toLocaleString("en-US", options);
|
||||||
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 safeFormattedDate =
|
const safeFormattedDate =
|
||||||
formattedDate === "Invalid Date"
|
formattedDate === "Invalid Date"
|
||||||
@ -135,11 +132,11 @@
|
|||||||
// Set display legend
|
// Set display legend
|
||||||
displayLegend = {
|
displayLegend = {
|
||||||
close:
|
close:
|
||||||
currentDataRow?.value ??
|
currentDataRowOneDay?.close?.toFixed(2) ??
|
||||||
currentDataRow?.close ??
|
data?.getStockQuote?.price?.toFixed(2),
|
||||||
data?.getStockQuote?.price,
|
|
||||||
date: safeFormattedDate,
|
date: safeFormattedDate,
|
||||||
change,
|
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: "-" };
|
let displayLegend = { close: "-", date: "-" };
|
||||||
|
|
||||||
function handleSeriesReference(ref) {
|
|
||||||
try {
|
|
||||||
lineLegend = ref;
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let displayLastLogicalRangeValue;
|
let displayLastLogicalRangeValue;
|
||||||
|
|
||||||
const fitContentChart = async () => {
|
const fitContentChart = async () => {
|
||||||
@ -686,19 +657,11 @@
|
|||||||
oneMonthPrice = [];
|
oneMonthPrice = [];
|
||||||
oneYearPrice = [];
|
oneYearPrice = [];
|
||||||
maxPrice = [];
|
maxPrice = [];
|
||||||
prePostData = {};
|
|
||||||
output = null;
|
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
|
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();
|
initializePrice();
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.error("An error occurred:", error);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -708,21 +671,21 @@
|
|||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
<title>
|
<title>
|
||||||
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
|
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
|
||||||
{$displayCompanyName} ({$etfTicker}) Stock Price, Quote & News · Stocknear
|
{data?.companyName} ({$etfTicker}) Stock Price, Quote & News · Stocknear
|
||||||
</title>
|
</title>
|
||||||
|
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
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 -->
|
<!-- Other meta tags -->
|
||||||
<meta
|
<meta
|
||||||
property="og:title"
|
property="og:title"
|
||||||
content={`${$displayCompanyName} (${$etfTicker}) Stock Price, Quote & News · Stocknear`}
|
content={`${data?.companyName} (${$etfTicker}) Stock Price, Quote & News · Stocknear`}
|
||||||
/>
|
/>
|
||||||
<meta
|
<meta
|
||||||
property="og:description"
|
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:image" content="https://stocknear-pocketbase.s3.amazonaws.com/logo/meta_logo.jpg"/>-->
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
@ -732,11 +695,11 @@
|
|||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
<meta
|
<meta
|
||||||
name="twitter:title"
|
name="twitter:title"
|
||||||
content={`${$displayCompanyName} (${$etfTicker}) Stock Price, Quote & News · Stocknear`}
|
content={`${data?.companyName} (${$etfTicker}) Stock Price, Quote & News · Stocknear`}
|
||||||
/>
|
/>
|
||||||
<meta
|
<meta
|
||||||
name="twitter:description"
|
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"/>-->
|
<!--<meta name="twitter:image" content="https://stocknear-pocketbase.s3.amazonaws.com/logo/meta_logo.jpg"/>-->
|
||||||
<!-- Add more Twitter meta tags as needed -->
|
<!-- Add more Twitter meta tags as needed -->
|
||||||
@ -749,100 +712,7 @@
|
|||||||
>
|
>
|
||||||
<!-- Main content -->
|
<!-- Main content -->
|
||||||
<div class="pb-12 md:pb-20 w-full sm:pr-6 xl:pr-0">
|
<div class="pb-12 md:pb-20 w-full sm:pr-6 xl:pr-0">
|
||||||
<div class="xl:pr-10">
|
<div class="mt-2">
|
||||||
<!-- 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------>
|
|
||||||
|
|
||||||
<!--End Ticker Section-->
|
<!--End Ticker Section-->
|
||||||
<!-- Start Graph -->
|
<!-- Start Graph -->
|
||||||
|
|
||||||
@ -877,20 +747,6 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</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>
|
||||||
<div class="h-[250px] sm:h-[350px]">
|
<div class="h-[250px] sm:h-[350px]">
|
||||||
<div
|
<div
|
||||||
@ -938,11 +794,11 @@
|
|||||||
class="flex shrink flex-row space-x-1 pr-1 text-sm sm:text-[1rem]"
|
class="flex shrink flex-row space-x-1 pr-1 text-sm sm:text-[1rem]"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class={displayLegend?.change >= 0
|
class={displayLegend?.graphChange >= 0
|
||||||
? "before:content-['+'] text-[#00FC50]"
|
? "before:content-['+'] text-[#00FC50]"
|
||||||
: "text-[#FF2F1F]"}
|
: "text-[#FF2F1F]"}
|
||||||
>
|
>
|
||||||
{displayLegend?.change}%
|
{displayLegend?.graphChange}%
|
||||||
</span>
|
</span>
|
||||||
<span class="hidden text-gray-200 sm:block"
|
<span class="hidden text-gray-200 sm:block"
|
||||||
>({displayData})</span
|
>({displayData})</span
|
||||||
@ -968,7 +824,6 @@
|
|||||||
lineColor={colorChange}
|
lineColor={colorChange}
|
||||||
topColor={topColorChange}
|
topColor={topColorChange}
|
||||||
bottomColor={bottomColorChange}
|
bottomColor={bottomColorChange}
|
||||||
ref={handleSeriesReference}
|
|
||||||
priceLineVisible={false}
|
priceLineVisible={false}
|
||||||
>
|
>
|
||||||
<PriceLine
|
<PriceLine
|
||||||
@ -988,7 +843,6 @@
|
|||||||
lineColor={colorChange}
|
lineColor={colorChange}
|
||||||
topColor={topColorChange}
|
topColor={topColorChange}
|
||||||
bottomColor={bottomColorChange}
|
bottomColor={bottomColorChange}
|
||||||
ref={handleSeriesReference}
|
|
||||||
priceLineVisible={false}
|
priceLineVisible={false}
|
||||||
>
|
>
|
||||||
<PriceLine
|
<PriceLine
|
||||||
@ -1008,7 +862,6 @@
|
|||||||
lineColor={colorChange}
|
lineColor={colorChange}
|
||||||
topColor={topColorChange}
|
topColor={topColorChange}
|
||||||
bottomColor={bottomColorChange}
|
bottomColor={bottomColorChange}
|
||||||
ref={handleSeriesReference}
|
|
||||||
priceLineVisible={false}
|
priceLineVisible={false}
|
||||||
>
|
>
|
||||||
<PriceLine
|
<PriceLine
|
||||||
@ -1028,7 +881,6 @@
|
|||||||
lineColor={colorChange}
|
lineColor={colorChange}
|
||||||
topColor={topColorChange}
|
topColor={topColorChange}
|
||||||
bottomColor={bottomColorChange}
|
bottomColor={bottomColorChange}
|
||||||
ref={handleSeriesReference}
|
|
||||||
priceLineVisible={false}
|
priceLineVisible={false}
|
||||||
>
|
>
|
||||||
<PriceLine
|
<PriceLine
|
||||||
@ -1048,7 +900,6 @@
|
|||||||
lineColor={colorChange}
|
lineColor={colorChange}
|
||||||
topColor={topColorChange}
|
topColor={topColorChange}
|
||||||
bottomColor={bottomColorChange}
|
bottomColor={bottomColorChange}
|
||||||
ref={handleSeriesReference}
|
|
||||||
priceLineVisible={false}
|
priceLineVisible={false}
|
||||||
>
|
>
|
||||||
<PriceLine
|
<PriceLine
|
||||||
@ -1068,7 +919,6 @@
|
|||||||
lineColor={colorChange}
|
lineColor={colorChange}
|
||||||
topColor={topColorChange}
|
topColor={topColorChange}
|
||||||
bottomColor={bottomColorChange}
|
bottomColor={bottomColorChange}
|
||||||
ref={handleSeriesReference}
|
|
||||||
priceLineVisible={false}
|
priceLineVisible={false}
|
||||||
>
|
>
|
||||||
<PriceLine
|
<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"
|
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
|
<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
|
<tbody
|
||||||
><tr
|
><tr
|
||||||
@ -1221,8 +1071,7 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<table
|
<table
|
||||||
class="w-[48%] text-sm text-white tiny:text-small lg:w-auto lg:min-w-[210px]"
|
class="w-[50%] text-sm text-white lg:min-w-[250px] 2xl:min-w-[300px]"
|
||||||
data-test="overview-quote"
|
|
||||||
>
|
>
|
||||||
<tbody
|
<tbody
|
||||||
><tr
|
><tr
|
||||||
@ -1332,16 +1181,15 @@
|
|||||||
<!--End Graph-->
|
<!--End Graph-->
|
||||||
|
|
||||||
<div
|
<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
|
<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} />
|
<ETFSidecard {data} />
|
||||||
<div class="lg:sticky lg:top-20"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full">
|
<div class="w-full lg:w-[65%] 2xl:w-[70%]">
|
||||||
<div
|
<div
|
||||||
class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 {data
|
class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 {data
|
||||||
?.getWhyPriceMoved?.length !== 0
|
?.getWhyPriceMoved?.length !== 0
|
||||||
@ -1351,7 +1199,7 @@
|
|||||||
<WIIM {data} />
|
<WIIM {data} />
|
||||||
</div>
|
</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} />
|
<News {data} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -254,11 +254,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (
|
if ($stockTicker && $stockTicker?.length !== 0) {
|
||||||
$stockTicker &&
|
|
||||||
$stockTicker?.length !== 0 &&
|
|
||||||
typeof window !== "undefined"
|
|
||||||
) {
|
|
||||||
// add a check to see if running on client-side
|
// add a check to see if running on client-side
|
||||||
$stockTicker = data?.getParams;
|
$stockTicker = data?.getParams;
|
||||||
$assetType = "stock";
|
$assetType = "stock";
|
||||||
@ -337,17 +333,13 @@
|
|||||||
$: charNumber = $screenWidth < 640 ? 25 : 40;
|
$: charNumber = $screenWidth < 640 ? 25 : 40;
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (
|
if ($stockTicker && $page.url.pathname === `/stocks/${$stockTicker}`) {
|
||||||
$stockTicker &&
|
|
||||||
typeof window !== "undefined" &&
|
|
||||||
$page.url.pathname === `/stocks/${$stockTicker}`
|
|
||||||
) {
|
|
||||||
displaySection = "overview";
|
displaySection = "overview";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if ($page?.url?.pathname && typeof window !== "undefined") {
|
if ($page?.url?.pathname) {
|
||||||
const parts = $page?.url?.pathname?.split("/");
|
const parts = $page?.url?.pathname?.split("/");
|
||||||
const sectionMap = {
|
const sectionMap = {
|
||||||
statistics: "statistics",
|
statistics: "statistics",
|
||||||
|
|||||||
@ -1230,7 +1230,7 @@
|
|||||||
<WIIM {data} />
|
<WIIM {data} />
|
||||||
</div>
|
</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} />
|
<News {data} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user