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