clean code
This commit is contained in:
parent
5d7ccf6358
commit
fa55ed4634
@ -1,210 +0,0 @@
|
||||
<svelte:options immutable={true} />
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
correlationComponent,
|
||||
stockTicker,
|
||||
etfTicker,
|
||||
assetType,
|
||||
screenWidth,
|
||||
getCache,
|
||||
setCache,
|
||||
} from "$lib/store";
|
||||
import { goto } from "$app/navigation";
|
||||
import InfoModal from "$lib/components/InfoModal.svelte";
|
||||
import Lazy from "svelte-lazy";
|
||||
|
||||
export let data;
|
||||
|
||||
let showFullStats = false;
|
||||
let isLoaded = false;
|
||||
let rawData = [];
|
||||
|
||||
async function stockSelector(symbol) {
|
||||
window?.scroll({ top: 0, left: 0, behavior: "smooth" });
|
||||
|
||||
if ($assetType === "etf") {
|
||||
etfTicker.update((value) => symbol);
|
||||
goto(`/etf/${symbol}`);
|
||||
} else {
|
||||
stockTicker.update((value) => symbol);
|
||||
goto(`/stocks/${symbol}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function getCorrelation(ticker) {
|
||||
const cachedData = getCache(ticker, "getCorrelation");
|
||||
if (cachedData) {
|
||||
rawData = cachedData;
|
||||
} else {
|
||||
try {
|
||||
const response = await fetch("/api/ticker-data", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-API-KEY": data?.apiKey,
|
||||
},
|
||||
body: JSON.stringify({ ticker: ticker, path: "correlation-ticker" }),
|
||||
});
|
||||
rawData = (await response?.json()) || [];
|
||||
+setCache(ticker, rawData, "getCorrelation");
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch swap data:", error);
|
||||
rawData = [];
|
||||
}
|
||||
}
|
||||
if (rawData?.lenght !== 0) {
|
||||
$correlationComponent = true;
|
||||
} else {
|
||||
$correlationComponent = false;
|
||||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
if (
|
||||
($assetType === "stock" ? $stockTicker : $etfTicker) &&
|
||||
typeof window !== "undefined"
|
||||
) {
|
||||
showFullStats = false;
|
||||
isLoaded = false;
|
||||
const ticker = $assetType === "stock" ? $stockTicker : $etfTicker;
|
||||
getCorrelation(ticker).then(() => {
|
||||
isLoaded = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$: charNumber = $screenWidth < 640 ? 10 : 20;
|
||||
</script>
|
||||
|
||||
<section class="overflow-hidden w-full">
|
||||
<main>
|
||||
<div class="flex flex-row items-center">
|
||||
<label
|
||||
for="correlationInfo"
|
||||
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
|
||||
>
|
||||
Most Correlated Stocks
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Most Correlated Stocks"}
|
||||
content={"Correlation between -1 and +1 shows how two stocks move together. +1 means they move in sync, while -1 means they move in opposite directions. Zero means no clear relationship."}
|
||||
id={"correlationInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if data?.user?.tier === "Pro"}
|
||||
{#if isLoaded}
|
||||
{#if rawData?.length !== 0}
|
||||
<Lazy
|
||||
height={300}
|
||||
fadeOption={{ delay: 100, duration: 500 }}
|
||||
keep={true}
|
||||
>
|
||||
{#each showFullStats ? rawData : rawData?.slice(0, 3) as item, index}
|
||||
<div
|
||||
class="shadow-lg bg-primary w-full rounded-md p-4 sm:p-3 mb-5 flex flex-row items-center {index ===
|
||||
0
|
||||
? 'mt-4'
|
||||
: ''} {index === 2 && !showFullStats && rawData?.length > 2
|
||||
? 'opacity-[0.3]'
|
||||
: ''}"
|
||||
>
|
||||
<div
|
||||
on:click={() => stockSelector(item?.symbol)}
|
||||
class="flex-shrink-0 mr-3 rounded-full w-8 h-8 sm:w-10 sm:h-10 relative bg-default"
|
||||
>
|
||||
<img
|
||||
class="avatar rounded-full w-5 h-5 absolute inset-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||
src={`https://financialmodelingprep.com/image-stock/${item?.symbol}.png`}
|
||||
alt=" "
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col -mt-3 sm:-mt-5s w-full">
|
||||
<div class="flex flex-row items-center w-full">
|
||||
<div class="mr-auto mt-2 mb-2 text-sm sm:text-md">
|
||||
<span class="text-blue-400">
|
||||
{item?.symbol}
|
||||
</span>
|
||||
<span class="text-white">
|
||||
· {item?.name?.length > charNumber
|
||||
? item?.name?.slice(0, charNumber) + "..."
|
||||
: item?.name}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
class="text-white text-sm sm:text-md font-medium ml-auto"
|
||||
>
|
||||
{item?.value?.toFixed(2)}
|
||||
</span>
|
||||
</div>
|
||||
{#if item?.value >= 0}
|
||||
<progress
|
||||
class="progress bg-[#3B3D3F] [&::-webkit-progress-value]:bg-[#00FC50] [&::-moz-progress-bar]:bg-[#00FC50]"
|
||||
value={item?.value}
|
||||
max="1"
|
||||
></progress>
|
||||
{:else}
|
||||
<progress
|
||||
class="progress bg-[#3B3D3F] [&::-webkit-progress-value]:bg-[#C7271A] [&::-moz-progress-bar]:bg-[#C7271A]"
|
||||
value={-item?.value}
|
||||
min="1"
|
||||
></progress>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
<label
|
||||
on:click={() => (showFullStats = !showFullStats)}
|
||||
class="{rawData?.length < 4
|
||||
? 'hidden'
|
||||
: ''} cursor-pointer flex justify-center items-center mt-5"
|
||||
>
|
||||
<svg
|
||||
class="w-10 h-10 transform {showFullStats ? '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>
|
||||
</Lazy>
|
||||
{/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>
|
||||
@ -1,52 +0,0 @@
|
||||
<script lang="ts">
|
||||
|
||||
import CryptoProfileCard from '$lib/components/CryptoProfileCard.svelte';
|
||||
|
||||
export let cryptoProfile;
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<section class="mt-4">
|
||||
|
||||
|
||||
<div class="grid grid-cols-3 gap-x-4 gap-y-2">
|
||||
<label for="tickerModal" class="w-auto border border-gray-300 flex px-4 py-2 mb-2 justify-center items-center text-xs font-medium rounded-xl text-gray-200">
|
||||
Details
|
||||
</label>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--Start Crypto Modal-->
|
||||
<div class="drawer drawer-end z-40 overflow-hidden w-screen">
|
||||
<input id="tickerModal" type="checkbox" class="drawer-toggle"/>
|
||||
<div class="drawer-side overflow-hidden">
|
||||
|
||||
|
||||
<div class="bg-[#000] min-h-screen w-screen pb-20 overflow-hidden">
|
||||
|
||||
<label for="tickerModal" 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-screen overflow-y-scroll" >
|
||||
|
||||
<CryptoProfileCard cryptoProfile = {cryptoProfile}/>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Crypto Modal-->
|
||||
|
||||
|
||||
|
||||
@ -1,248 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { cryptoTicker, screenWidth, displayCompanyName } from "$lib/store";
|
||||
|
||||
import { abbreviateNumber } from "$lib/utils";
|
||||
import { fade } from "svelte/transition";
|
||||
import { goto } from "$app/navigation";
|
||||
import defaultImage from "$lib/images/etf/cover/default.jpg";
|
||||
|
||||
export let cryptoProfile;
|
||||
|
||||
let cloudFrontUrl = import.meta.env.VITE_IMAGE_URL; // Set a default API URL
|
||||
|
||||
let info;
|
||||
let imageUrl;
|
||||
let marketCap = "-";
|
||||
let totalVolume = "-";
|
||||
let circulatingSupply = "-";
|
||||
let maxSupply = "-";
|
||||
let description = "";
|
||||
let snippet;
|
||||
let website;
|
||||
let athPrice;
|
||||
let athDate;
|
||||
|
||||
let showFullText = false;
|
||||
|
||||
$: {
|
||||
if (
|
||||
$cryptoTicker &&
|
||||
typeof $cryptoTicker !== "undefined" &&
|
||||
typeof window !== "undefined" &&
|
||||
typeof cryptoProfile !== "undefined" &&
|
||||
Object?.keys(cryptoProfile)?.length !== 0
|
||||
) {
|
||||
marketCap = cryptoProfile?.market_cap;
|
||||
totalVolume = cryptoProfile?.total_volume;
|
||||
description =
|
||||
cryptoProfile?.description ??
|
||||
"A detailed description of the company is not yet available.";
|
||||
snippet = description?.slice(0, 150) + "...";
|
||||
circulatingSupply = cryptoProfile?.circulating_supply;
|
||||
maxSupply = cryptoProfile?.max_supply;
|
||||
website = cryptoProfile?.website;
|
||||
athPrice = cryptoProfile?.ath;
|
||||
athDate = cryptoProfile?.ath_date;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="sm:space-y-3">
|
||||
<div
|
||||
class="lg:rounded-md shadow-lg sm:border sm:border-gray-600 bg-[#000] lg:bg-default h-auto h-auto w-screen pt-16 sm:w-full md:w-[420px] xl:w-[450px] lg:pt-0"
|
||||
>
|
||||
<!--Start Header-->
|
||||
<div
|
||||
class="sm:rounded-t-lg w-full h-[130px] bg-[#000] p-3 flex flex-col bg-cover bg-center bg-no-repeat"
|
||||
style="background-image: url({`${cloudFrontUrl}/stocks/cover/${$cryptoTicker?.toUpperCase()}.jpg`});"
|
||||
>
|
||||
<div class="flex flex-row pt-1 pb-2"></div>
|
||||
<!--
|
||||
<div class="flex flex-row justify-end items-center mt-2 relative z-10 -my-5">
|
||||
<div style={`background-image: url(${sTier}`} class="animate-bounce circle-background mr-5 w-20 h-20 z-10">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-28 h-28" viewBox="0 0 106 34">
|
||||
<g class="sparkles">
|
||||
<path style="--duration: 4s;" d="M2.5740361 5.33344622s1.1875777-6.20179466 2.24320232 0c0 0 5.9378885 1.05562462 0 2.11124925 0 0-1.05562463 6.33374774-2.24320233 0-3.5627331-.6597654-3.29882695-1.31953078 0-2.11124925z" />
|
||||
<path style="--duration: 3.2s;" d="M33.5173993 29.97263826s1.03464615-5.40315215 1.95433162 0c0 0 5.17323078.91968547 0 1.83937095 0 0-.91968547 5.51811283-1.95433162 0-3.10393847-.57480342-2.8740171-1.14960684 0-1.83937095z" />
|
||||
<path style="--duration: 2.5s;" d="M69.03038108 1.71240809s.73779281-3.852918 1.39360864 0c0 0 3.68896404.65581583 0 1.31163166 0 0-.65581583 3.93489497-1.39360864 0-2.21337842-.4098849-2.04942447-.81976979 0-1.31163166z" />
|
||||
</g>
|
||||
</svg>
|
||||
<div class="tier-text italic m-auto text-xl">
|
||||
<span class="text-4xl" style="color: #FFFFFF}">
|
||||
{tierList ?? 'n/a'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<!--End Header-->
|
||||
|
||||
<!--Start Content-->
|
||||
<div class="w-full flex flex-wrap border-t border-gray-600">
|
||||
<h2 class="text-start ml-4 text-2xl font-bold text-white pb-2 mt-3">
|
||||
Crypto Info
|
||||
</h2>
|
||||
<div class="flex items-center w-full">
|
||||
<table class="table table-md table-compact">
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr
|
||||
class="text-white border-b border-[#27272A]"
|
||||
style="font-size: 0.8rem"
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-medium"
|
||||
>Name</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default"
|
||||
>{$displayCompanyName?.length > 30
|
||||
? $displayCompanyName?.slice(0, 30) + "..."
|
||||
: $displayCompanyName}</td
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-medium"
|
||||
>Ticker</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default"
|
||||
>{$cryptoTicker}</td
|
||||
>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr
|
||||
class="text-white border-b border-[#27272A]"
|
||||
style="font-size: 0.8rem"
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-medium"
|
||||
>Mkt Cap</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default whitespace-normal"
|
||||
>{abbreviateNumber(marketCap, true)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-medium"
|
||||
>Total Volume</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default whitespace-normal"
|
||||
>{abbreviateNumber(totalVolume)}</td
|
||||
>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr
|
||||
class="text-white border-b border-[#27272A]"
|
||||
style="font-size: 0.8rem"
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-medium"
|
||||
>Circulating Supply</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default whitespace-normal"
|
||||
>{abbreviateNumber(circulatingSupply)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-medium"
|
||||
>Max Supply</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default whitespace-normal"
|
||||
>{maxSupply !== null
|
||||
? abbreviateNumber(maxSupply)
|
||||
: "Uncapped"}</td
|
||||
>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr
|
||||
class="text-white border-b border-[#27272A]"
|
||||
style="font-size: 0.8rem"
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-medium"
|
||||
>ATH Price</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default whitespace-normal"
|
||||
>${new Intl.NumberFormat("en", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
}).format(athPrice)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-medium"
|
||||
>ATH Date</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default whitespace-normal"
|
||||
>{new Date(athDate).toLocaleString("en-US", {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
daySuffix: "2-digit",
|
||||
})}</td
|
||||
>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2
|
||||
class="text-start ml-2 text-xl font-bold text-white pb-2 pt-6 lg:pt-3"
|
||||
>
|
||||
Description
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-100 ml-2 text-sm whitespace-normal">
|
||||
{#if showFullText}
|
||||
<div transition:fade={{ delay: 0, duration: 80 }} in={showFullText}>
|
||||
{description}
|
||||
</div>
|
||||
{:else if $screenWidth <= 800}
|
||||
{description}
|
||||
{:else}
|
||||
{snippet}
|
||||
{/if}
|
||||
</p>
|
||||
{#if description.length !== 0}
|
||||
<div class="flex flex-row w-full items-center mt-4 pb-2 mb-2">
|
||||
<label
|
||||
on:click={() => (showFullText = !showFullText)}
|
||||
class="hidden lg:block ml-3 w-full text-md mt-1 cursor-pointer font-medium text-white sm:hover:text-blue-400 sm:hover:underline"
|
||||
>
|
||||
{#if showFullText}
|
||||
Show less
|
||||
{:else}
|
||||
Show more
|
||||
{/if}
|
||||
</label>
|
||||
|
||||
<div class="flex justify-end w-full relative bottom-0 right-0 mr-3">
|
||||
<a
|
||||
target="_blank"
|
||||
href={website}
|
||||
class="inline-flex text-sm font-medium text-white sm:hover:text-blue-400 sm:hover:underline"
|
||||
>
|
||||
Go to website
|
||||
<svg
|
||||
class="w-5 h-5 ml-2"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><path
|
||||
d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z"
|
||||
></path><path
|
||||
d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z"
|
||||
></path></svg
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
File diff suppressed because one or more lines are too long
@ -1,316 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { stockTicker, screenWidth, wsBidPrice, wsAskPrice } from "$lib/store";
|
||||
|
||||
import { abbreviateNumber } from "$lib/utils";
|
||||
import { fade } from "svelte/transition";
|
||||
|
||||
export let stockDeck;
|
||||
export let data;
|
||||
|
||||
let info;
|
||||
|
||||
let cloudFrontUrl = import.meta.env.VITE_IMAGE_URL; // Set a default API URL
|
||||
|
||||
let earningDate = null;
|
||||
let tierList = "-";
|
||||
//let ceoName = "-";
|
||||
let sector = "-";
|
||||
let industry = "-";
|
||||
let exchange = "-";
|
||||
let employees = "-";
|
||||
//let country = "-";
|
||||
let description = "";
|
||||
let website = "-";
|
||||
let snippet;
|
||||
let forwardPE = "-";
|
||||
let beta = "-";
|
||||
|
||||
let showFullText = false;
|
||||
/*
|
||||
function getAbbreviatedName(fullName) {
|
||||
try {
|
||||
const names = fullName?.split(" ");
|
||||
let firstName = names?.at(0);
|
||||
// Remove any title prefix (e.g. Dr., Mr., Mrs., Ms.)
|
||||
if (names?.length > 1 && /^(Dr|Mr|Mrs|Ms)\.?$/i?.test(names?.at(0))) {
|
||||
firstName = names?.at(1);
|
||||
names?.splice(0, 1);
|
||||
}
|
||||
//const initials = names?.slice(0, -1)?.map(name => name?.charAt(0))?.join('. ');
|
||||
const lastName = names[names?.length - 1];
|
||||
return `${firstName?.charAt(0)}. ${lastName}`;
|
||||
} catch (e) {
|
||||
//console.log(e)
|
||||
return "-";
|
||||
}
|
||||
}
|
||||
*/
|
||||
$: {
|
||||
if (
|
||||
$stockTicker &&
|
||||
typeof window !== "undefined" &&
|
||||
typeof stockDeck !== "undefined" &&
|
||||
stockDeck?.length !== 0
|
||||
) {
|
||||
info = stockDeck?.at(0);
|
||||
earningDate =
|
||||
info?.earning !== undefined
|
||||
? new Date(info?.earning)?.toLocaleDateString("en-GB", {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
})
|
||||
: "";
|
||||
|
||||
tierList = info?.tierList;
|
||||
//ceoName = info?.ceoName?.length !== 0 ? getAbbreviatedName(info?.ceoName) : "-";
|
||||
sector = info?.sector ?? "-";
|
||||
industry = info?.industry ?? "-";
|
||||
exchange = info?.exchange;
|
||||
employees = abbreviateNumber(info?.fullTimeEmployees) ?? "-";
|
||||
//country = info?.country ?? "-";
|
||||
description =
|
||||
info?.description ??
|
||||
"A detailed description of the company is not yet available.";
|
||||
website = info?.website;
|
||||
snippet = description?.slice(0, 250) + "...";
|
||||
forwardPE = info?.forwardPE;
|
||||
beta = info?.beta !== undefined ? info?.beta?.toFixed(2) : "-";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="sm:space-y-3">
|
||||
<div
|
||||
class="sm:rounded-md lg:border lg:border-gray-600 bg-[#000] lg:bg-default h-auto w-screen pt-16 sm:w-full md:w-[420px] xl:w-[450px] lg:pt-0"
|
||||
>
|
||||
<!--Start Header-->
|
||||
<div
|
||||
class="sm:rounded-t-lg w-full h-[130px] bg-[#000] p-3 flex flex-col bg-cover bg-center bg-no-repeat"
|
||||
style="background-image: url({`${cloudFrontUrl}/stocks/cover/${$stockTicker?.toUpperCase()}.jpg`});"
|
||||
>
|
||||
<div class="flex flex-row pt-1 pb-2">
|
||||
{#if earningDate}
|
||||
<div
|
||||
class="badge bg-[#fff] gap-2 mt-2 font-semibold text-sm text-black"
|
||||
>
|
||||
Earnings Call - {earningDate}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
<!--
|
||||
<div class="flex flex-row justify-end items-center mt-2 relative z-10 -my-5">
|
||||
<div style={`background-image: url(${tierList === 'S' || tierList === 'S+' || tierList === 'S-' ? sTier : tierList === 'A' || tierList === 'A+' || tierList === 'A-' ? aTier : tierList === 'B' || tierList === 'B+' || tierList === 'B-' ? bTier : defaultTier});`} class="animate-bounce circle-background mr-5 w-20 h-20 z-10">
|
||||
<div class="tier-text italic m-auto text-xl">
|
||||
<span class="{tierList !== null ? 'text-4xl' : 'hidden'} " style="color: ${tierList === 'S' || tierList === 'S+' || tierList === 'S-' ? '#FFFFFF' : tierList === 'A' || tierList === 'A+' || tierList === 'A-' ? '#1239FA' : ''});`}">
|
||||
{tierList ?? 'n/a'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<!--End Header-->
|
||||
<!--Start Content-->
|
||||
<div class="w-full flex flex-wrap border-t border-gray-600 px-2">
|
||||
<h2 class="text-start ml-2 text-2xl font-bold text-white pb-2 mt-3">
|
||||
Company Info
|
||||
</h2>
|
||||
<div class="flex justify-center items-center w-full m-auto">
|
||||
<table class="table table-sm table-compact">
|
||||
<tbody>
|
||||
<!--
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap">CEO</td>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default whitespace-normal font-semibold">{ceoName}</td>
|
||||
<td class="text-start sm:text-end lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap">Country</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default whitespace-normal font-semibold">{country}</td>
|
||||
</tr>
|
||||
-->
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>Bid</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-default"
|
||||
>{$wsBidPrice !== 0 && $wsBidPrice !== null
|
||||
? $wsBidPrice
|
||||
: (data?.getStockQuote?.bid ?? "-")}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>Ask</td
|
||||
>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-default"
|
||||
>{$wsAskPrice !== 0 && $wsAskPrice !== null
|
||||
? $wsAskPrice
|
||||
: (data?.getStockQuote?.ask ?? "-")}</td
|
||||
>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>Mkt Cap</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-default"
|
||||
>{abbreviateNumber(data?.getStockQuote?.marketCap)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>Vol</td
|
||||
>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-default"
|
||||
>{abbreviateNumber(data?.getStockQuote?.volume)}</td
|
||||
>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>Beta</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-default"
|
||||
>{beta}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>Avg. Vol</td
|
||||
>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-default"
|
||||
>{abbreviateNumber(data?.getStockQuote?.avgVolume)}</td
|
||||
>
|
||||
</tr>
|
||||
<!--
|
||||
<tr class="text-white ">
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white whitespace-pre-line font-semibold whitespace-nowrap">Sector</td>
|
||||
<td class="text-center bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default whitespace-pre-line font-semibold">{sector}</td>
|
||||
<td class="text-start sm:text-center lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap">Employees</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default font-semibold">{employees}</td>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap">Industry</td>
|
||||
<td class="text-center bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default whitespace-normal font-semibold">{industry}</td>
|
||||
<td class="text-start sm:text-center lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap">Exchange</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-default font-semibold">{exchange}</td>
|
||||
</tr>
|
||||
-->
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>Open</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-default"
|
||||
>{data?.getStockQuote?.open?.toFixed(2)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>Prev. Close</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-default whitespace-nowrap"
|
||||
>{data?.getStockQuote?.previousClose?.toFixed(2) ?? "-"}</td
|
||||
>
|
||||
</tr>
|
||||
<!--
|
||||
{#if $screenWidth > 640}
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap">1D-Range</td>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-default">{data?.getStockQuote?.dayLow?.toFixed(2)} - {data?.getStockQuote?.dayHigh?.toFixed(2)}</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap ">1Y-Range</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-default whitespace-nowrap ">{data?.getStockQuote?.yearLow?.toFixed(2)} - {data?.getStockQuote?.yearHigh?.toFixed(2)}</td>
|
||||
</tr>
|
||||
{/if}
|
||||
-->
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>EPS (ttm)</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-default"
|
||||
>{data?.getStockQuote?.eps}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>PE Ratio (ttm)</td
|
||||
>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-default"
|
||||
>{data?.getStockQuote?.pe}</td
|
||||
>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>Shares Out.</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-default"
|
||||
>{abbreviateNumber(data?.getStockQuote?.sharesOutstanding)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-default text-white font-semibold whitespace-nowrap"
|
||||
>Forward PE</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-default whitespace-nowrap"
|
||||
>{forwardPE === undefined || forwardPE === null
|
||||
? "-"
|
||||
: forwardPE}</td
|
||||
>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2
|
||||
class="text-start sm:ml-4 text-xl font-bold text-white pb-2 pt-5 sm:pt-3 p-1 sm:p-0"
|
||||
>
|
||||
Description
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-100 sm:ml-2 text-sm whitespace-normal p-1 sm:p-2">
|
||||
{#if showFullText}
|
||||
<div transition:fade={{ delay: 0, duration: 80 }} in={showFullText}>
|
||||
{description}
|
||||
</div>
|
||||
{:else if $screenWidth <= 800}
|
||||
{description}
|
||||
{:else}
|
||||
{snippet}
|
||||
{/if}
|
||||
</p>
|
||||
{#if description.length !== 0}
|
||||
<div class="flex flex-row w-full items-center mt-4 pb-2 mb-2">
|
||||
<label
|
||||
on:click={() => (showFullText = !showFullText)}
|
||||
class="hidden lg:block ml-3 w-full text-md mt-1 cursor-pointer font-medium text-white sm:hover:text-blue-400 sm:hover:underline"
|
||||
>
|
||||
{#if showFullText}
|
||||
Show less
|
||||
{:else}
|
||||
Show more
|
||||
{/if}
|
||||
</label>
|
||||
|
||||
<div class="flex justify-end w-full relative bottom-0 right-0 mr-3">
|
||||
<a
|
||||
target="_blank"
|
||||
href={website}
|
||||
class="inline-flex text-sm font-medium text-white sm:hover:text-blue-400 sm:hover:underline"
|
||||
>
|
||||
Go to website
|
||||
<svg
|
||||
class="w-5 h-5 ml-2"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><path
|
||||
d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z"
|
||||
></path><path
|
||||
d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z"
|
||||
></path></svg
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user