commit
f8ed49b3d4
@ -1,305 +1,242 @@
|
||||
<script lang='ts'>
|
||||
<script lang="ts">
|
||||
//import ProgressBar from 'progressbar.js';
|
||||
import {stockTicker, screenWidth} from '$lib/store';
|
||||
import { abbreviateNumber } from '$lib/utils';
|
||||
|
||||
import { stockTicker, screenWidth } from "$lib/store";
|
||||
import { abbreviateNumber } from "$lib/utils";
|
||||
|
||||
export let lastPrice;
|
||||
export let analystRating = {};
|
||||
|
||||
|
||||
let buyCount = 0;
|
||||
let holdCount = 0;
|
||||
let sellCount = 0;
|
||||
let priceTarget = 'n/a';
|
||||
let priceTarget = "n/a";
|
||||
let numOfAnalyst = 0;
|
||||
let consensusRating = 'n/a';
|
||||
let changesPercentage = 0;
|
||||
|
||||
|
||||
|
||||
let consensusRating = "n/a";
|
||||
let changesPercentage = 0;
|
||||
|
||||
$: {
|
||||
|
||||
if ($stockTicker && typeof window !== 'undefined' && typeof analystRating !== 'undefined' && Object?.keys(analystRating)?.length !== 0)
|
||||
{
|
||||
numOfAnalyst = analystRating?.numOfAnalyst;
|
||||
buyCount = (analystRating?.Buy/numOfAnalyst * 100)?.toFixed(2);
|
||||
holdCount = (analystRating?.Hold/numOfAnalyst * 100)?.toFixed(2);
|
||||
sellCount = (analystRating?.Sell/numOfAnalyst * 100)?.toFixed(2);
|
||||
priceTarget = analystRating?.priceTarget
|
||||
consensusRating = analystRating?.consensusRating;
|
||||
console.log(lastPrice)
|
||||
try {
|
||||
changesPercentage = ((priceTarget/lastPrice -1)*100)?.toFixed(2) ?? 0;
|
||||
} catch(e) {
|
||||
if ($stockTicker && typeof window !== "undefined" && typeof analystRating !== "undefined" && Object?.keys(analystRating)?.length !== 0) {
|
||||
numOfAnalyst = analystRating?.numOfAnalyst;
|
||||
buyCount = ((analystRating?.Buy / numOfAnalyst) * 100)?.toFixed(2);
|
||||
holdCount = ((analystRating?.Hold / numOfAnalyst) * 100)?.toFixed(2);
|
||||
sellCount = ((analystRating?.Sell / numOfAnalyst) * 100)?.toFixed(2);
|
||||
priceTarget = analystRating?.priceTarget;
|
||||
consensusRating = analystRating?.consensusRating;
|
||||
console.log(lastPrice);
|
||||
try {
|
||||
changesPercentage = ((priceTarget / lastPrice - 1) * 100)?.toFixed(2) ?? 0;
|
||||
} catch (e) {
|
||||
changesPercentage = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</script>
|
||||
|
||||
<!--Start Analyst Card -->
|
||||
<div class="space-y-3 sm:pt-5 hidden sm:block sm:{Object?.keys(analystRating)?.length !== 0 ? '' : 'hidden'}">
|
||||
<div class="sm:rounded-lg shadow-lg bg-[#000] sm:bg-[#09090B] sm:border sm:border-slate-800 h-auto {$screenWidth < 640 ? 'w-screen pt-16' : ''} md:w-[420px] xl:w-[450px] -mx-1 sm:mx-0">
|
||||
<!--Start Content-->
|
||||
<div class="w-auto lg:w-full p-1 flex flex-col m-auto pb-14 sm:pb-10 px-2 sm:px-0">
|
||||
<h2 class="text-start text-2xl font-semibold text-white p-3 mt-3 ml-1">Analyst Rating</h2>
|
||||
|
||||
|
||||
|
||||
<!--Start Analyst Card -->
|
||||
<div class="space-y-3 sm:pt-5 hidden sm:block sm:{Object?.keys(analystRating)?.length !== 0 ? '' : 'hidden'}">
|
||||
<div class="sm:rounded-lg shadow-lg bg-[#000] sm:bg-[#09090B] sm:border sm:border-slate-800 h-auto {$screenWidth < 640 ? 'w-screen pt-16' : ''} md:w-[420px] xl:w-[450px] -mx-1 sm:mx-0">
|
||||
|
||||
<!--Start Content-->
|
||||
<div class="w-auto lg:w-full p-1 flex flex-col m-auto pb-14 sm:pb-10 px-2 sm:px-0">
|
||||
<h2 class="text-start text-2xl font-semibold text-white p-3 mt-3 ml-1">
|
||||
Analyst Rating
|
||||
</h2>
|
||||
|
||||
<div class="flex flex-col mt-5 w-full">
|
||||
<div class="flex flex-row m-auto w-full">
|
||||
<span class="text-start mr-auto ml-5 text-white font-medium text-xl">
|
||||
Signal
|
||||
</span>
|
||||
<span class="mr-5 text-white font-medium text-xl">
|
||||
Price Target
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-row m-auto w-full">
|
||||
{#if consensusRating === 'Buy' || consensusRating === 'Strong Buy'}
|
||||
<span class="text-start font-semibold text-[#10DB06] mr-auto ml-5 mt-2 text-xl">
|
||||
{consensusRating}
|
||||
</span>
|
||||
{:else if consensusRating === 'Sell' || consensusRating === 'Strong Sell' }
|
||||
<span class="text-start font-semibold text-[#FF2F1F] mr-auto ml-5 mt-2 text-xl">
|
||||
{consensusRating}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="text-start font-semibold text-[#FF2F1F] mr-auto ml-5 mt-2 text-xl">
|
||||
{consensusRating}
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
<span class="mr-5 mt-2 font-semibold text-xl text-white">
|
||||
{#if priceTarget !== 'n/a'}
|
||||
${priceTarget}
|
||||
{:else}
|
||||
-
|
||||
{/if}
|
||||
</span>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="flex flex-col mt-5 w-full">
|
||||
<div class="flex flex-row m-auto w-full">
|
||||
<span class="text-start mr-auto ml-5 text-white font-medium text-xl"> Signal </span>
|
||||
<span class="mr-5 text-white font-medium text-xl"> Price Target </span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="text-white pl-4 pr-4 mt-6">
|
||||
{#if changesPercentage < 0 }
|
||||
The Stock Price has a downside of
|
||||
<span style="color: #FF2F1F; font-weight: 500">{abbreviateNumber(Math.abs(changesPercentage))}%</span>
|
||||
{:else if changesPercentage >= 0 }
|
||||
The Stock Price has an upside of
|
||||
<span style="color: #10DB06; font-weight: 500">{abbreviateNumber(Math.abs(changesPercentage))}%</span>
|
||||
{/if}
|
||||
based on <span style="font-weight: 600">{numOfAnalyst}</span> analysts in the past 12 months.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="mt-5 w-full rounded-full flex justify-center items-center mb-5">
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<!--Start Progress-->
|
||||
|
||||
|
||||
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<div class="flex flex-row items-center w-11/12 mt-5 mb-2">
|
||||
<span class="text-white font-medium text-start mr-auto">
|
||||
Buy
|
||||
</span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{buyCount}%
|
||||
</span>
|
||||
</div>
|
||||
<progress class="progress bg-[#3B3D3F] w-11/12 [&::-webkit-progress-value]:bg-[#10DB06] [&::-moz-progress-bar]:bg-[#10DB06]" value={buyCount} max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<div class="flex flex-row items-center w-11/12 mt-5 mb-2">
|
||||
<span class="text-white font-medium text-start mr-auto">
|
||||
Hold
|
||||
</span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{holdCount}%
|
||||
</span>
|
||||
</div>
|
||||
<progress class="progress bg-[#3B3D3F] w-11/12 [&::-webkit-progress-value]:bg-[#fff] [&::-moz-progress-bar]:bg-[#fff]" value={holdCount} max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<div class="flex flex-row items-center w-11/12 mt-5 mb-2">
|
||||
<span class="text-white font-medium text-start mr-auto">
|
||||
Sell
|
||||
</span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{sellCount}%
|
||||
</span>
|
||||
</div>
|
||||
<progress class="progress bg-[#3B3D3F] w-11/12 [&::-webkit-progress-value]:bg-[#FF2F1F] [&::-moz-progress-bar]:bg-[#FF2F1F]" value={sellCount} max="100"></progress>
|
||||
</div>
|
||||
|
||||
|
||||
<!--End Progress-->
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href={`/stocks/${$stockTicker}/analyst`} class="rounded-lg cursor-pointer w-11/12 py-2 h-full mt-6 text-lg text-center font-bold text-white m-auto hover:bg-purple-700 bg-purple-600 transition duration-100">
|
||||
Analyst Ratings
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--End Analyst Card-->
|
||||
|
||||
|
||||
|
||||
|
||||
<!--Start Mobile Analyst Card-->
|
||||
<div class="space-y-3 sm:pt-5 sm:hidden">
|
||||
|
||||
<div class="bg-[#000] h-auto w-screen">
|
||||
|
||||
<!--Start Header-->
|
||||
<div class="bg-[#09090B] w-full p-1 flex flex-col items-center pb-5 h-auto rounded-b-[30px]">
|
||||
<h2 class="text-center m-auto text-[1.1rem] font-medium text-white mt-5">
|
||||
Analyst Rating
|
||||
</h2>
|
||||
|
||||
<div class="flex flex-col items-center mt-10 w-full">
|
||||
|
||||
<div class="flex flex-row justify-between items-center w-full mb-5">
|
||||
|
||||
|
||||
<div class="flex flex-col items-start ml-3 ">
|
||||
<span class="text-white text-lg font-medium inline-block">
|
||||
Recommendation:
|
||||
</span>
|
||||
<span class="text-white text-2xl font-medium inline-block">
|
||||
{#if consensusRating === 'Buy' || consensusRating === 'Strong Buy'}
|
||||
<span class="text-start font-medium text-[#10DB06] text-2xl">
|
||||
<div class="flex flex-row m-auto w-full">
|
||||
{#if consensusRating === "Buy" || consensusRating === "Strong Buy"}
|
||||
<span class="text-start font-semibold text-[#10DB06] mr-auto ml-5 mt-2 text-xl">
|
||||
{consensusRating}
|
||||
</span>
|
||||
{:else if consensusRating === 'Sell' || consensusRating === 'Strong Sell' }
|
||||
<span class="text-start font-medium text-[#FF2F1F] text-2xl">
|
||||
{consensusRating}
|
||||
</span>
|
||||
{:else if consensusRating === 'Hold'}
|
||||
<span class="text-start font-medium text-[#FF2F1F] text-2xl">
|
||||
{consensusRating ?? 'n/a'}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="text-start font-medium text-white text-2xl">
|
||||
n/a
|
||||
</span>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
{:else if consensusRating === "Sell" || consensusRating === "Strong Sell"}
|
||||
<span class="text-start font-semibold text-[#FF2F1F] mr-auto ml-5 mt-2 text-xl">
|
||||
{consensusRating}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="text-start font-semibold text-[#FF2F1F] mr-auto ml-5 mt-2 text-xl">
|
||||
{consensusRating}
|
||||
</span>
|
||||
{/if}
|
||||
|
||||
|
||||
|
||||
<div class="flex flex-col items-start mr-5">
|
||||
<span class="text-white ml-auto text-lg font-medium inline-block">
|
||||
Price Target:
|
||||
</span>
|
||||
<span class="text-white ml-auto text-2xl font-medium inline-block">
|
||||
{#if priceTarget !== 'n/a'}
|
||||
<span class="mr-5 mt-2 font-semibold text-xl text-white">
|
||||
{#if priceTarget !== "n/a"}
|
||||
${priceTarget}
|
||||
{:else}
|
||||
-
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{#if changesPercentage < 0 }
|
||||
<div class="text-white p-4 text-center">
|
||||
<div class="text-white pl-4 pr-4 mt-6">
|
||||
{#if changesPercentage < 0}
|
||||
The Stock Price has a downside of
|
||||
<span class="text-[#FF2F1F] font-medium">{abbreviateNumber(Math?.abs(changesPercentage))} %</span>
|
||||
based on <span class="font-semibold">{numOfAnalyst}</span> analysts.
|
||||
</div>
|
||||
{:else if changesPercentage >= 0 }
|
||||
<div class="text-white p-4 text-center">
|
||||
<span style="color: #FF2F1F; font-weight: 500">{abbreviateNumber(Math.abs(changesPercentage))}%</span>
|
||||
{:else if changesPercentage >= 0}
|
||||
The Stock Price has an upside of
|
||||
<span class="text-[#10DB06] font-medium">{abbreviateNumber(Math?.abs(changesPercentage))} %</span>
|
||||
based on <span class="font-semibold">{numOfAnalyst}</span> analysts.
|
||||
<span style="color: #10DB06; font-weight: 500">{abbreviateNumber(Math.abs(changesPercentage))}%</span>
|
||||
{/if}
|
||||
based on <span style="font-weight: 600">{numOfAnalyst}</span> analysts in the past 12 months.
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="mt-5 w-full rounded-full flex justify-center items-center mb-5">
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<!--Start Progress-->
|
||||
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<div class="flex flex-row items-center w-11/12 mt-5 mb-2">
|
||||
<span class="text-white font-medium text-start mr-auto"> Buy </span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{buyCount}%
|
||||
</span>
|
||||
</div>
|
||||
<progress class="progress bg-[#3B3D3F] w-11/12 [&::-webkit-progress-value]:bg-[#10DB06] [&::-moz-progress-bar]:bg-[#10DB06]" value={buyCount} max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<div class="flex flex-row items-center w-11/12 mt-5 mb-2">
|
||||
<span class="text-white font-medium text-start mr-auto"> Hold </span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{holdCount}%
|
||||
</span>
|
||||
</div>
|
||||
<progress class="progress bg-[#3B3D3F] w-11/12 [&::-webkit-progress-value]:bg-[#fff] [&::-moz-progress-bar]:bg-[#fff]" value={holdCount} max="100"></progress>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<div class="flex flex-row items-center w-11/12 mt-5 mb-2">
|
||||
<span class="text-white font-medium text-start mr-auto"> Sell </span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{sellCount}%
|
||||
</span>
|
||||
</div>
|
||||
<progress class="progress bg-[#3B3D3F] w-11/12 [&::-webkit-progress-value]:bg-[#FF2F1F] [&::-moz-progress-bar]:bg-[#FF2F1F]" value={sellCount} max="100"></progress>
|
||||
</div>
|
||||
|
||||
<!--End Progress-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href={`/stocks/${$stockTicker}/forecast/analyst`} class="rounded-lg cursor-pointer w-11/12 py-2 h-full mt-6 text-lg text-center font-bold text-white m-auto hover:bg-purple-700 bg-purple-600 transition duration-100"> Analyst Ratings </a>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Header-->
|
||||
</div>
|
||||
|
||||
<!--End Analyst Card-->
|
||||
|
||||
<!--Start Mobile Analyst Card-->
|
||||
<div class="space-y-3 sm:pt-5 sm:hidden">
|
||||
<div class="bg-[#000] h-auto w-screen">
|
||||
<!--Start Header-->
|
||||
<div class="bg-[#09090B] w-full p-1 flex flex-col items-center pb-5 h-auto rounded-b-[30px]">
|
||||
<h2 class="text-center m-auto text-[1.1rem] font-medium text-white mt-5">Analyst Rating</h2>
|
||||
|
||||
<div class="flex flex-col items-center mt-10 w-full">
|
||||
<div class="flex flex-row justify-between items-center w-full mb-5">
|
||||
<div class="flex flex-col items-start ml-3">
|
||||
<span class="text-white text-lg font-medium inline-block"> Recommendation: </span>
|
||||
<span class="text-white text-2xl font-medium inline-block">
|
||||
{#if consensusRating === "Buy" || consensusRating === "Strong Buy"}
|
||||
<span class="text-start font-medium text-[#10DB06] text-2xl">
|
||||
{consensusRating}
|
||||
</span>
|
||||
{:else if consensusRating === "Sell" || consensusRating === "Strong Sell"}
|
||||
<span class="text-start font-medium text-[#FF2F1F] text-2xl">
|
||||
{consensusRating}
|
||||
</span>
|
||||
{:else if consensusRating === "Hold"}
|
||||
<span class="text-start font-medium text-[#FF2F1F] text-2xl">
|
||||
{consensusRating ?? "n/a"}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="text-start font-medium text-white text-2xl"> n/a </span>
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-start mr-5">
|
||||
<span class="text-white ml-auto text-lg font-medium inline-block"> Price Target: </span>
|
||||
<span class="text-white ml-auto text-2xl font-medium inline-block">
|
||||
{#if priceTarget !== "n/a"}
|
||||
${priceTarget}
|
||||
{:else}
|
||||
-
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if changesPercentage < 0}
|
||||
<div class="text-white p-4 text-center">
|
||||
The Stock Price has a downside of
|
||||
<span class="text-[#FF2F1F] font-medium">{abbreviateNumber(Math?.abs(changesPercentage))} %</span>
|
||||
based on <span class="font-semibold">{numOfAnalyst}</span> analysts.
|
||||
</div>
|
||||
{:else if changesPercentage >= 0}
|
||||
<div class="text-white p-4 text-center">
|
||||
The Stock Price has an upside of
|
||||
<span class="text-[#10DB06] font-medium">{abbreviateNumber(Math?.abs(changesPercentage))} %</span>
|
||||
based on <span class="font-semibold">{numOfAnalyst}</span> analysts.
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<!--End Header-->
|
||||
|
||||
{#if numOfAnalyst !== 0}
|
||||
<div class="mt-5 flex flex-col m-auto items-center rounded-lg w-full mb-16 p-3">
|
||||
|
||||
|
||||
<div class="shadow-lg bg-[#09090B] w-full rounded-lg p-4 mb-5 flex flex-row items-center">
|
||||
<div class="flex flex-col -mt-2 w-full">
|
||||
<div class="mt-5 flex flex-col m-auto items-center rounded-lg w-full mb-16 p-3">
|
||||
<div class="shadow-lg bg-[#09090B] w-full rounded-lg p-4 mb-5 flex flex-row items-center">
|
||||
<div class="flex flex-col -mt-2 w-full">
|
||||
<div class="flex flex-row items-center w-full">
|
||||
<span class="text-white text-md font-medium text-start mb-2 mr-auto mt-2">
|
||||
Buy
|
||||
</span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{buyCount}%
|
||||
</span>
|
||||
<span class="text-white text-md font-medium text-start mb-2 mr-auto mt-2"> Buy </span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{buyCount}%
|
||||
</span>
|
||||
</div>
|
||||
<progress class="progress w-full {buyCount >= 50 ? '[&::-webkit-progress-value]:bg-[#10DB06] [&::-moz-progress-bar]:bg-[#10DB06]' : '[&::-webkit-progress-value]:bg-[#FF2F1F] [&::-moz-progress-bar]:bg-[#FF2F1F]'}" value={buyCount} max="100"></progress>
|
||||
<progress
|
||||
class="progress w-full {buyCount >= 50 ? '[&::-webkit-progress-value]:bg-[#10DB06] [&::-moz-progress-bar]:bg-[#10DB06]' : '[&::-webkit-progress-value]:bg-[#FF2F1F] [&::-moz-progress-bar]:bg-[#FF2F1F]'}"
|
||||
value={buyCount}
|
||||
max="100"
|
||||
></progress>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="shadow-lg bg-[#09090B] w-full rounded-lg p-4 mb-5 flex flex-row items-center">
|
||||
<div class="flex flex-col -mt-2 w-full">
|
||||
<div class="flex flex-row items-center w-full">
|
||||
<span class="text-white text-md font-medium text-start mb-2 mr-auto mt-2"> Hold </span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{holdCount}%
|
||||
</span>
|
||||
</div>
|
||||
<progress
|
||||
class="progress w-full {holdCount >= 50 ? '[&::-webkit-progress-value]:bg-[#10DB06] [&::-moz-progress-bar]:bg-[#10DB06]' : '[&::-webkit-progress-value]:bg-[#FF2F1F] [&::-moz-progress-bar]:bg-[#FF2F1F]'}"
|
||||
value={holdCount}
|
||||
max="100"
|
||||
></progress>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="shadow-lg bg-[#09090B] w-full rounded-lg p-4 mb-5 flex flex-row items-center">
|
||||
<div class="flex flex-col -mt-2 w-full">
|
||||
<div class="flex flex-row items-center w-full">
|
||||
<span class="text-white text-md font-medium text-start mb-2 mr-auto mt-2"> Sell </span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{sellCount}
|
||||
</span>
|
||||
</div>
|
||||
<progress
|
||||
class="progress w-full {sellCount >= 50 ? '[&::-webkit-progress-value]:bg-[#10DB06] [&::-moz-progress-bar]:bg-[#10DB06]' : '[&::-webkit-progress-value]:bg-[#FF2F1F] [&::-moz-progress-bar]:bg-[#FF2F1F]'}"
|
||||
value={sellCount}
|
||||
max="100"
|
||||
></progress>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="shadow-lg bg-[#09090B] w-full rounded-lg p-4 mb-5 flex flex-row items-center">
|
||||
<div class="flex flex-col -mt-2 w-full">
|
||||
<div class="flex flex-row items-center w-full">
|
||||
<span class="text-white text-md font-medium text-start mb-2 mr-auto mt-2">
|
||||
Hold
|
||||
</span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{holdCount}%
|
||||
</span>
|
||||
</div>
|
||||
<progress class="progress w-full {holdCount >= 50 ? '[&::-webkit-progress-value]:bg-[#10DB06] [&::-moz-progress-bar]:bg-[#10DB06]' : '[&::-webkit-progress-value]:bg-[#FF2F1F] [&::-moz-progress-bar]:bg-[#FF2F1F]'}" value={holdCount} max="100"></progress>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="shadow-lg bg-[#09090B] w-full rounded-lg p-4 mb-5 flex flex-row items-center">
|
||||
<div class="flex flex-col -mt-2 w-full">
|
||||
<div class="flex flex-row items-center w-full">
|
||||
<span class="text-white text-md font-medium text-start mb-2 mr-auto mt-2">
|
||||
Sell
|
||||
</span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{sellCount}
|
||||
</div>
|
||||
<progress class="progress w-full {sellCount >= 50 ? '[&::-webkit-progress-value]:bg-[#10DB06] [&::-moz-progress-bar]:bg-[#10DB06]' : '[&::-webkit-progress-value]:bg-[#FF2F1F] [&::-moz-progress-bar]:bg-[#FF2F1F]'}" value={sellCount} max="100"></progress>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
{:else}
|
||||
<div class=" mt-20 flex justify-center items-center text-3xl font-bold text-slate-700 mb-20 m-auto">
|
||||
No data available
|
||||
</div>
|
||||
<div class=" mt-20 flex justify-center items-center text-3xl font-bold text-slate-700 mb-20 m-auto">No data available</div>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Mobile Analyst Card-->
|
||||
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
<script lang ='ts'>
|
||||
import { analystInsightComponent, stockTicker, getCache, setCache} from '$lib/store';
|
||||
import InfoModal from '$lib/components/InfoModal.svelte';
|
||||
|
||||
export let data;
|
||||
|
||||
let isLoaded = false;
|
||||
|
||||
let rawData = {};
|
||||
<script lang="ts">
|
||||
import { analystInsightComponent, stockTicker, getCache, setCache } from "$lib/store";
|
||||
import InfoModal from "$lib/components/InfoModal.svelte";
|
||||
|
||||
export let data;
|
||||
|
||||
function latestInfoDate(inputDate) {
|
||||
let isLoaded = false;
|
||||
|
||||
let rawData = {};
|
||||
|
||||
function latestInfoDate(inputDate) {
|
||||
// Convert the input date string to milliseconds since epoch
|
||||
const inputDateMs = Date?.parse(inputDate);
|
||||
|
||||
@ -23,179 +22,145 @@ function latestInfoDate(inputDate) {
|
||||
const differenceInDays = Math?.floor(differenceInMs / (1000 * 60 * 60 * 24));
|
||||
|
||||
// Return the difference in days
|
||||
return differenceInDays <=1;
|
||||
}
|
||||
|
||||
return differenceInDays <= 1;
|
||||
}
|
||||
|
||||
const getAnalystInsight = async (ticker) => {
|
||||
// Get cached data for the specific tickerID
|
||||
const cachedData = getCache(ticker, 'getAnalystInsight');
|
||||
const cachedData = getCache(ticker, "getAnalystInsight");
|
||||
if (cachedData) {
|
||||
rawData = cachedData;
|
||||
} else {
|
||||
|
||||
const postData = {'ticker': ticker};
|
||||
const postData = { ticker: ticker };
|
||||
// make the POST request to the endpoint
|
||||
const response = await fetch(data?.apiURL + '/analyst-insight', {
|
||||
method: 'POST',
|
||||
const response = await fetch(data?.apiURL + "/analyst-insight", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json", "X-API-KEY": data?.apiKey
|
||||
"Content-Type": "application/json",
|
||||
"X-API-KEY": data?.apiKey,
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
body: JSON.stringify(postData),
|
||||
});
|
||||
|
||||
|
||||
rawData = await response.json();
|
||||
// Cache the data for this specific tickerID with a specific name 'getAnalystInsight'
|
||||
setCache(ticker, rawData, 'getAnalystInsight');
|
||||
setCache(ticker, rawData, "getAnalystInsight");
|
||||
}
|
||||
|
||||
if(Object?.keys(rawData)?.length !== 0) {
|
||||
|
||||
if (Object?.keys(rawData)?.length !== 0) {
|
||||
$analystInsightComponent = true;
|
||||
} else {
|
||||
$analystInsightComponent = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
$: {
|
||||
if($stockTicker && typeof window !== 'undefined') {
|
||||
isLoaded=false;
|
||||
const ticker = $stockTicker;
|
||||
const asyncFunctions = [
|
||||
getAnalystInsight(ticker)
|
||||
];
|
||||
if ($stockTicker && typeof window !== "undefined") {
|
||||
isLoaded = false;
|
||||
const ticker = $stockTicker;
|
||||
const asyncFunctions = [getAnalystInsight(ticker)];
|
||||
Promise.all(asyncFunctions)
|
||||
.then((results) => {
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('An error occurred:', error);
|
||||
});
|
||||
isLoaded = true;
|
||||
|
||||
.then((results) => {})
|
||||
.catch((error) => {
|
||||
console.error("An error occurred:", error);
|
||||
});
|
||||
isLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<section class="overflow-hidden text-white h-full pb-8">
|
||||
<main class="overflow-hidden ">
|
||||
|
||||
<div class="flex flex-row items-center">
|
||||
<label for="analystInsightInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
|
||||
<svg class="w-6 h-6 sm:w-7 sm:h-7 inline-block mr-1 mt-0.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#fff" d="M20.562 10.188c.25-.688.313-1.376.25-2.063c-.062-.687-.312-1.375-.625-2c-.562-.937-1.375-1.687-2.312-2.125c-1-.437-2.063-.562-3.125-.312c-.5-.5-1.063-.938-1.688-1.25S11.687 2 11 2a5.17 5.17 0 0 0-3 .938c-.875.624-1.5 1.5-1.813 2.5c-.75.187-1.375.5-2 .875c-.562.437-1 1-1.375 1.562c-.562.938-.75 2-.625 3.063a5.44 5.44 0 0 0 1.25 2.874a4.7 4.7 0 0 0-.25 2.063c.063.688.313 1.375.625 2c.563.938 1.375 1.688 2.313 2.125c1 .438 2.062.563 3.125.313c.5.5 1.062.937 1.687 1.25S12.312 22 13 22a5.17 5.17 0 0 0 3-.937c.875-.625 1.5-1.5 1.812-2.5a4.54 4.54 0 0 0 1.938-.875c.562-.438 1.062-.938 1.375-1.563c.562-.937.75-2 .625-3.062c-.125-1.063-.5-2.063-1.188-2.876m-7.5 10.5c-1 0-1.75-.313-2.437-.875c0 0 .062-.063.125-.063l4-2.312a.5.5 0 0 0 .25-.25a.57.57 0 0 0 .062-.313V11.25l1.688 1v4.625a3.685 3.685 0 0 1-3.688 3.813M5 17.25c-.438-.75-.625-1.625-.438-2.5c0 0 .063.063.125.063l4 2.312a.56.56 0 0 0 .313.063c.125 0 .25 0 .312-.063l4.875-2.812v1.937l-4.062 2.375A3.7 3.7 0 0 1 7.312 19c-1-.25-1.812-.875-2.312-1.75M3.937 8.563a3.8 3.8 0 0 1 1.938-1.626v4.751c0 .124 0 .25.062.312a.5.5 0 0 0 .25.25l4.875 2.813l-1.687 1l-4-2.313a3.7 3.7 0 0 1-1.75-2.25c-.25-.937-.188-2.062.312-2.937M17.75 11.75l-4.875-2.812l1.687-1l4 2.312c.625.375 1.125.875 1.438 1.5s.5 1.313.437 2.063a3.7 3.7 0 0 1-.75 1.937c-.437.563-1 1-1.687 1.25v-4.75c0-.125 0-.25-.063-.312c0 0-.062-.126-.187-.188m1.687-2.5s-.062-.062-.125-.062l-4-2.313c-.125-.062-.187-.062-.312-.062s-.25 0-.313.062L9.812 9.688V7.75l4.063-2.375c.625-.375 1.312-.5 2.062-.5c.688 0 1.375.25 2 .688c.563.437 1.063 1 1.313 1.625s.312 1.375.187 2.062m-10.5 3.5l-1.687-1V7.063c0-.688.187-1.438.562-2C8.187 4.438 8.75 4 9.375 3.688a3.37 3.37 0 0 1 2.062-.313c.688.063 1.375.375 1.938.813c0 0-.063.062-.125.062l-4 2.313a.5.5 0 0 0-.25.25c-.063.125-.063.187-.063.312zm.875-2L12 9.5l2.187 1.25v2.5L12 14.5l-2.188-1.25z"/></svg>
|
||||
AI Analyst Insight
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"AI Analyst Insight"}
|
||||
content={"We use large language models to analyze the latest reports from Wall Street analysts, providing concise summaries and key insights. This approach helps save time and allows you to focus on the most important information."}
|
||||
id={"analystInsightInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if data?.user?.tier === 'Pro'}
|
||||
{#if isLoaded}
|
||||
|
||||
</script>
|
||||
|
||||
<section class="overflow-hidden text-white h-full pb-8">
|
||||
<main class="overflow-hidden">
|
||||
<div class="flex flex-row items-center">
|
||||
<label for="analystInsightInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
|
||||
<svg class="w-6 h-6 sm:w-7 sm:h-7 inline-block mr-1 mt-0.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
|
||||
><path
|
||||
fill="#fff"
|
||||
d="M20.562 10.188c.25-.688.313-1.376.25-2.063c-.062-.687-.312-1.375-.625-2c-.562-.937-1.375-1.687-2.312-2.125c-1-.437-2.063-.562-3.125-.312c-.5-.5-1.063-.938-1.688-1.25S11.687 2 11 2a5.17 5.17 0 0 0-3 .938c-.875.624-1.5 1.5-1.813 2.5c-.75.187-1.375.5-2 .875c-.562.437-1 1-1.375 1.562c-.562.938-.75 2-.625 3.063a5.44 5.44 0 0 0 1.25 2.874a4.7 4.7 0 0 0-.25 2.063c.063.688.313 1.375.625 2c.563.938 1.375 1.688 2.313 2.125c1 .438 2.062.563 3.125.313c.5.5 1.062.937 1.687 1.25S12.312 22 13 22a5.17 5.17 0 0 0 3-.937c.875-.625 1.5-1.5 1.812-2.5a4.54 4.54 0 0 0 1.938-.875c.562-.438 1.062-.938 1.375-1.563c.562-.937.75-2 .625-3.062c-.125-1.063-.5-2.063-1.188-2.876m-7.5 10.5c-1 0-1.75-.313-2.437-.875c0 0 .062-.063.125-.063l4-2.312a.5.5 0 0 0 .25-.25a.57.57 0 0 0 .062-.313V11.25l1.688 1v4.625a3.685 3.685 0 0 1-3.688 3.813M5 17.25c-.438-.75-.625-1.625-.438-2.5c0 0 .063.063.125.063l4 2.312a.56.56 0 0 0 .313.063c.125 0 .25 0 .312-.063l4.875-2.812v1.937l-4.062 2.375A3.7 3.7 0 0 1 7.312 19c-1-.25-1.812-.875-2.312-1.75M3.937 8.563a3.8 3.8 0 0 1 1.938-1.626v4.751c0 .124 0 .25.062.312a.5.5 0 0 0 .25.25l4.875 2.813l-1.687 1l-4-2.313a3.7 3.7 0 0 1-1.75-2.25c-.25-.937-.188-2.062.312-2.937M17.75 11.75l-4.875-2.812l1.687-1l4 2.312c.625.375 1.125.875 1.438 1.5s.5 1.313.437 2.063a3.7 3.7 0 0 1-.75 1.937c-.437.563-1 1-1.687 1.25v-4.75c0-.125 0-.25-.063-.312c0 0-.062-.126-.187-.188m1.687-2.5s-.062-.062-.125-.062l-4-2.313c-.125-.062-.187-.062-.312-.062s-.25 0-.313.062L9.812 9.688V7.75l4.063-2.375c.625-.375 1.312-.5 2.062-.5c.688 0 1.375.25 2 .688c.563.437 1.063 1 1.313 1.625s.312 1.375.187 2.062m-10.5 3.5l-1.687-1V7.063c0-.688.187-1.438.562-2C8.187 4.438 8.75 4 9.375 3.688a3.37 3.37 0 0 1 2.062-.313c.688.063 1.375.375 1.938.813c0 0-.063.062-.125.062l-4 2.313a.5.5 0 0 0-.25.25c-.063.125-.063.187-.063.312zm.875-2L12 9.5l2.187 1.25v2.5L12 14.5l-2.188-1.25z"
|
||||
/></svg
|
||||
>
|
||||
AI Analyst Insight
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"AI Analyst Insight"}
|
||||
content={"We use large language models to analyze the latest reports from Wall Street analysts, providing concise summaries and key insights. This approach helps save time and allows you to focus on the most important information."}
|
||||
id={"analystInsightInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if data?.user?.tier === "Pro"}
|
||||
{#if isLoaded}
|
||||
{#if Object?.keys(rawData)?.length !== 0}
|
||||
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
|
||||
The AI model summarizes the latest Wallstreet Analyst Insight Report and extracts key points for you, focusing on what matters most.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="w-full mt-4">
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">The AI model summarizes the latest Wallstreet Analyst Insight Report and extracts key points for you, focusing on what matters most.</div>
|
||||
</div>
|
||||
|
||||
<div class="w-full mt-4">
|
||||
<a href={"/stocks/" + $stockTicker + "/forecast/analyst"} class="text-blue-400 hover:text-white flex justify-end mb-3 text-sm sm:text-[1rem]"> See All Ratings </a>
|
||||
|
||||
<a href="{'/stocks/'+$stockTicker+'/analyst'}" class="text-blue-400 hover:text-white flex justify-end mb-3 text-sm sm:text-[1rem]">
|
||||
See All Ratings
|
||||
</a>
|
||||
|
||||
<div class="relative">
|
||||
<div class="">
|
||||
|
||||
<div class="flex justify-center ">
|
||||
<!--<div class="{rawData.changesPercentage >= 0 ? 'bg-[#10DB06]' : 'bg-[#FF2F1F]'} w-1.5 mb-5 rounded-l-xl" />-->
|
||||
|
||||
<!--Start Item-->
|
||||
<div class="flex flex-row items-center w-full mb-6">
|
||||
|
||||
<div class="w-full rounded-lg {latestInfoDate(rawData?.date) ? 'bg-[#F9AB00] bg-opacity-[0.1]' : 'bg-[#27272A]'} shadow-lg h-full pl-3 pt-2 pb-4">
|
||||
<div class="flex flex-col items-start">
|
||||
<div class="">
|
||||
<div class="flex justify-center">
|
||||
<!--<div class="{rawData.changesPercentage >= 0 ? 'bg-[#10DB06]' : 'bg-[#FF2F1F]'} w-1.5 mb-5 rounded-l-xl" />-->
|
||||
|
||||
<div class="flex flex-row items-start w-full pt-2">
|
||||
<span class="text-white text-[0.915rem] pl-2 italic">Last Report from {rawData.date}</span>
|
||||
{#if latestInfoDate(rawData.date)}
|
||||
<label class="bg-[#2D4F8A] text-white font-medium text-xs rounded-lg px-2 py-0.5 ml-3">New</label>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col w-full pt-3 pl-2 pr-2 sm:pr-4">
|
||||
<span class="text-white text-[1rem] ">
|
||||
{rawData?.insight}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!--Start Item-->
|
||||
<div class="flex flex-row items-center w-full mb-6">
|
||||
<div class="w-full rounded-lg {latestInfoDate(rawData?.date) ? 'bg-[#F9AB00] bg-opacity-[0.1]' : 'bg-[#27272A]'} shadow-lg h-full pl-3 pt-2 pb-4">
|
||||
<div class="flex flex-col items-start">
|
||||
<div class="flex flex-row items-start w-full pt-2">
|
||||
<span class="text-white text-[0.915rem] pl-2 italic">Last Report from {rawData.date}</span>
|
||||
{#if latestInfoDate(rawData.date)}
|
||||
<label class="bg-[#2D4F8A] text-white font-medium text-xs rounded-lg px-2 py-0.5 ml-3">New</label>
|
||||
{/if}
|
||||
</div>
|
||||
<!--End Item-->
|
||||
|
||||
<div class="flex flex-col w-full pt-3 pl-2 pr-2 sm:pr-4">
|
||||
<span class="text-white text-[1rem]">
|
||||
{rawData?.insight}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Item-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{/if}
|
||||
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label class="bg-[#09090B] rounded-xl 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"></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>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label class="bg-[#09090B] rounded-xl 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"></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>
|
||||
|
||||
<style>
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 210px;
|
||||
.app {
|
||||
height: 210px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
113
src/routes/stocks/[tickerID]/forecast/+layout.svelte
Normal file
113
src/routes/stocks/[tickerID]/forecast/+layout.svelte
Normal file
@ -0,0 +1,113 @@
|
||||
<script lang="ts">
|
||||
import { stockTicker, screenWidth } from "$lib/store";
|
||||
import { onDestroy } from "svelte";
|
||||
import { page } from "$app/stores";
|
||||
|
||||
let displaySubSection = "overview";
|
||||
|
||||
if (displaySubSection) {
|
||||
const parts = $page?.url?.pathname.split("/");
|
||||
const sectionMap = {
|
||||
overview: "overview",
|
||||
ai: "ai",
|
||||
analyst: "analyst",
|
||||
};
|
||||
|
||||
const foundSection = parts?.find((part) => Object?.values(sectionMap)?.includes(part));
|
||||
|
||||
displaySubSection = Object?.keys(sectionMap)?.find((key) => sectionMap[key] === foundSection) || "overview";
|
||||
}
|
||||
|
||||
function changeSubSection(state) {
|
||||
const subSectionMap = {
|
||||
overview: "/forecast",
|
||||
ai: "/forecast/ai",
|
||||
analyst: "/forecast/analyst",
|
||||
};
|
||||
|
||||
console.log(state);
|
||||
console.log(subSectionMap[state]);
|
||||
|
||||
if (state !== "overview" && subSectionMap[state]) {
|
||||
displaySubSection = state;
|
||||
//goto(`/stocks/${$stockTicker}${subSectionMap[state]}`);
|
||||
} else {
|
||||
displaySubSection = state;
|
||||
//goto(`/stocks/${$stockTicker}/stats`);
|
||||
}
|
||||
}
|
||||
|
||||
const unsubscribe = page.subscribe(($page) => {
|
||||
const splitRoute = $page.url.pathname.split("/");
|
||||
const routeState = splitRoute[splitRoute.length - 1] !== "forecast" ? splitRoute[splitRoute.length - 1] : "overview";
|
||||
|
||||
changeSubSection(routeState);
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
unsubscribe();
|
||||
});
|
||||
</script>
|
||||
|
||||
<section class="w-auto max-w-5xl bg-[#09090B] overflow-hidden text-black h-full mb-40">
|
||||
<div class="m-auto h-full overflow-hidden">
|
||||
<main class="w-fit sm:w-full sm:max-w-2xl">
|
||||
<div class="m-auto">
|
||||
<div class="-ml-2 sm:ml-8 w-screen sm:w-full {$screenWidth < 640 ? 'overflow-auto scrollbar' : 'no-scrollbar'} mb-2">
|
||||
<ul class="pr-4 sm:pr-0 w-screen flex flex-row items-center bg-[#09090B] overflow-x-scroll sm:overflow-hidden space-x-4 rtl:space-x-reverse py-2">
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/forecast`}
|
||||
on:click={() => changeSubSection("overview")}
|
||||
class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'overview' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Overview
|
||||
</a>
|
||||
<div class="{displaySubSection === 'overview' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}/forecast/ai`} on:click={() => changeSubSection("ai")} class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'ai' ? 'text-white ' : 'bg-[#09090B]'}">
|
||||
AI
|
||||
</a>
|
||||
<div class="{displaySubSection === 'ai' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/forecast/analyst`}
|
||||
on:click={() => changeSubSection("analyst")}
|
||||
class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'analyst' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Analysts
|
||||
</a>
|
||||
<div class="{displaySubSection === 'analyst' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4rem]" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.scrollbar {
|
||||
display: grid;
|
||||
grid-gap: 18px;
|
||||
grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
|
||||
grid-auto-flow: column;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: thin; /* Hide the default scrollbar in Firefox */
|
||||
scrollbar-color: transparent transparent; /* Hide the default scrollbar in Firefox */
|
||||
}
|
||||
|
||||
/* Custom scrollbar for Webkit (Chrome, Safari) */
|
||||
.scrollbar::-webkit-scrollbar {
|
||||
width: 0; /* Hide the width of the scrollbar */
|
||||
height: 0; /* Hide the height of the scrollbar */
|
||||
}
|
||||
|
||||
.scrollbar::-webkit-scrollbar-thumb {
|
||||
background: transparent; /* Make the thumb transparent */
|
||||
}
|
||||
</style>
|
||||
44
src/routes/stocks/[tickerID]/forecast/+page.svelte
Normal file
44
src/routes/stocks/[tickerID]/forecast/+page.svelte
Normal file
@ -0,0 +1,44 @@
|
||||
<script lang="ts">
|
||||
import { numberOfUnreadNotification, displayCompanyName, stockTicker, analystEstimateComponent, currentPortfolioPrice } from "$lib/store";
|
||||
import Lazy from "$lib/components/Lazy.svelte";
|
||||
|
||||
export let data;
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>
|
||||
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
|
||||
{$displayCompanyName} ({$stockTicker}) Forecast Overview · stocknear
|
||||
</title>
|
||||
<meta name="description" content={`A list of analyst ratings for Advanced Micro Devices (AMD) stock. See upgrades, downgrades, price targets and more from top Wall Street stock analysts.`} />
|
||||
|
||||
<!-- Other meta tags -->
|
||||
<meta property="og:title" content={`${$displayCompanyName} (${$stockTicker}) Forecast Overview · stocknear`} />
|
||||
<meta property="og:description" content={`A list of analyst ratings for Advanced Micro Devices (AMD) stock. See upgrades, downgrades, price targets and more from top Wall Street stock analysts.`} />
|
||||
<meta property="og:type" content="website" />
|
||||
<!-- Add more Open Graph meta tags as needed -->
|
||||
|
||||
<!-- Twitter specific meta tags -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={`${$displayCompanyName} (${$stockTicker}) Forecast Overview · stocknear`} />
|
||||
<meta name="twitter:description" content={`A list of analyst ratings for Advanced Micro Devices (AMD) stock. See upgrades, downgrades, price targets and more from top Wall Street stock analysts.`} />
|
||||
<!-- Add more Twitter meta tags as needed -->
|
||||
</svelte:head>
|
||||
|
||||
<section class="bg-[#09090B] overflow-hidden text-white h-full mb-40 sm:mb-0 w-full">
|
||||
<div class="flex justify-center m-auto h-full overflow-hidden w-full">
|
||||
<div class="relative flex justify-center items-center overflow-hidden w-full">
|
||||
<div class="sm:p-7 w-full m-auto mt-2 sm:mt-0">
|
||||
<Lazy>
|
||||
<div class="w-full m-auto sm:pb-6 sm:pt-6 {!$analystEstimateComponent ? 'hidden' : ''}">
|
||||
{#await import("$lib/components/AnalystEstimate.svelte") then { default: Comp }}
|
||||
<svelte:component this={Comp} {data} />
|
||||
{/await}
|
||||
</div>
|
||||
</Lazy>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
76
src/routes/stocks/[tickerID]/forecast/ai/+page.svelte
Normal file
76
src/routes/stocks/[tickerID]/forecast/ai/+page.svelte
Normal file
@ -0,0 +1,76 @@
|
||||
<script lang="ts">
|
||||
import { numberOfUnreadNotification, displayCompanyName, stockTicker, analystInsightComponent, sentimentComponent, trendAnalysisComponent, priceAnalysisComponent, fundamentalAnalysisComponent } from "$lib/store";
|
||||
import Lazy from "$lib/components/Lazy.svelte";
|
||||
|
||||
export let data;
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>
|
||||
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""}
|
||||
{$displayCompanyName} ({$stockTicker}) Forecast AI · stocknear
|
||||
</title>
|
||||
<meta name="description" content={`A list of analyst ratings for Advanced Micro Devices (AMD) stock. See upgrades, downgrades, price targets and more from top Wall Street stock analysts.`} />
|
||||
|
||||
<!-- Other meta tags -->
|
||||
<meta property="og:title" content={`${$displayCompanyName} (${$stockTicker}) Forecast AI · stocknear`} />
|
||||
<meta property="og:description" content={`A list of analyst ratings for Advanced Micro Devices (AMD) stock. See upgrades, downgrades, price targets and more from top Wall Street stock analysts.`} />
|
||||
<meta property="og:type" content="website" />
|
||||
<!-- Add more Open Graph meta tags as needed -->
|
||||
|
||||
<!-- Twitter specific meta tags -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={`${$displayCompanyName} (${$stockTicker}) Forecast AI · stocknear`} />
|
||||
<meta name="twitter:description" content={`A list of analyst ratings for Advanced Micro Devices (AMD) stock. See upgrades, downgrades, price targets and more from top Wall Street stock analysts.`} />
|
||||
<!-- Add more Twitter meta tags as needed -->
|
||||
</svelte:head>
|
||||
|
||||
<section class="bg-[#09090B] overflow-hidden text-white h-full mb-40 sm:mb-0 w-full">
|
||||
<div class="flex justify-center m-auto h-full overflow-hidden w-full">
|
||||
<div class="relative flex justify-center items-center overflow-hidden w-full">
|
||||
<div class="sm:p-7 w-full m-auto mt-2 sm:mt-0">
|
||||
<Lazy>
|
||||
<div class="w-full mt-10 sm:mt-0 m-auto sm:pt-6 {!$analystInsightComponent ? 'hidden' : ''}">
|
||||
{#await import("$lib/components/AnalystInsight.svelte") then { default: Comp }}
|
||||
<svelte:component this={Comp} {data} />
|
||||
{/await}
|
||||
</div>
|
||||
</Lazy>
|
||||
|
||||
<Lazy>
|
||||
<div class="w-full mt-10 sm:mt-5 m-auto sm:pb-6 sm:pt-6 {!$priceAnalysisComponent ? 'hidden' : ''}">
|
||||
{#await import("$lib/components/PriceAnalysis.svelte") then { default: Comp }}
|
||||
<svelte:component this={Comp} {data} />
|
||||
{/await}
|
||||
</div>
|
||||
</Lazy>
|
||||
|
||||
<Lazy>
|
||||
<div class="w-full mt-10 sm:mt-5 m-auto sm:pb-6 sm:pt-6 {!$trendAnalysisComponent ? 'hidden' : ''}">
|
||||
{#await import("$lib/components/TrendAnalysis.svelte") then { default: Comp }}
|
||||
<svelte:component this={Comp} {data} />
|
||||
{/await}
|
||||
</div>
|
||||
</Lazy>
|
||||
|
||||
<Lazy>
|
||||
<div class="w-full mt-10 sm:mt-5 m-auto sm:pb-6 sm:pt-6 {!$fundamentalAnalysisComponent ? 'hidden' : ''}">
|
||||
{#await import("$lib/components/FundamentalAnalysis.svelte") then { default: Comp }}
|
||||
<svelte:component this={Comp} {data} />
|
||||
{/await}
|
||||
</div>
|
||||
</Lazy>
|
||||
|
||||
<Lazy>
|
||||
<div class="w-full mt-10 sm:mt-5 m-auto sm:pb-6 sm:pt-6 {!$sentimentComponent ? 'hidden' : ''}">
|
||||
{#await import("$lib/components/SentimentAnalysis.svelte") then { default: Comp }}
|
||||
<svelte:component this={Comp} {data} />
|
||||
{/await}
|
||||
</div>
|
||||
</Lazy>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
43
src/routes/stocks/[tickerID]/forecast/ai/+page.ts
Normal file
43
src/routes/stocks/[tickerID]/forecast/ai/+page.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { getCache, setCache } from '$lib/store';
|
||||
|
||||
|
||||
export const load = async ({ parent, params }) => {
|
||||
|
||||
const getAnalystTickerHistory = async () => {
|
||||
|
||||
let output;
|
||||
|
||||
const cachedData = getCache(params.tickerID, 'getAnalystTickerHistory');
|
||||
if (cachedData) {
|
||||
output = cachedData;
|
||||
} else {
|
||||
|
||||
const {apiURL, apiKey} = await parent();
|
||||
|
||||
const postData = {
|
||||
ticker: params.tickerID
|
||||
};
|
||||
|
||||
// make the POST request to the endpoint
|
||||
const response = await fetch(apiURL + '/analyst-ticker-history', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json", "X-API-KEY": apiKey
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
output = await response.json();
|
||||
|
||||
setCache(params.tickerID, output, 'getAnalystTickerHistory');
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
// Make sure to return a promise
|
||||
return {
|
||||
getAnalystTickerHistory: await getAnalystTickerHistory()
|
||||
};
|
||||
};
|
||||
43
src/routes/stocks/[tickerID]/forecast/analyst/+page.ts
Normal file
43
src/routes/stocks/[tickerID]/forecast/analyst/+page.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import { getCache, setCache } from '$lib/store';
|
||||
|
||||
|
||||
export const load = async ({ parent, params }) => {
|
||||
|
||||
const getAnalystTickerHistory = async () => {
|
||||
|
||||
let output;
|
||||
|
||||
const cachedData = getCache(params.tickerID, 'getAnalystTickerHistory');
|
||||
if (cachedData) {
|
||||
output = cachedData;
|
||||
} else {
|
||||
|
||||
const {apiURL, apiKey} = await parent();
|
||||
|
||||
const postData = {
|
||||
ticker: params.tickerID
|
||||
};
|
||||
|
||||
// make the POST request to the endpoint
|
||||
const response = await fetch(apiURL + '/analyst-ticker-history', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json", "X-API-KEY": apiKey
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
output = await response.json();
|
||||
|
||||
setCache(params.tickerID, output, 'getAnalystTickerHistory');
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
// Make sure to return a promise
|
||||
return {
|
||||
getAnalystTickerHistory: await getAnalystTickerHistory()
|
||||
};
|
||||
};
|
||||
@ -1,121 +1,132 @@
|
||||
<script lang='ts'>
|
||||
import { stockTicker, screenWidth } from "$lib/store";
|
||||
import { page } from "$app/stores";
|
||||
<script lang="ts">
|
||||
import { stockTicker, screenWidth } from "$lib/store";
|
||||
import { page } from "$app/stores";
|
||||
|
||||
let displaySubSection = 'fundamental';
|
||||
let displaySubSection = "overview";
|
||||
|
||||
if (displaySubSection) {
|
||||
const parts = $page?.url?.pathname.split("/");
|
||||
const sectionMap = {
|
||||
"market-cap": "market-cap",
|
||||
employees: "employees",
|
||||
income: "income",
|
||||
"balance-sheet": "balance-sheet",
|
||||
"cash-flow": "cash-flow",
|
||||
ratios: "ratios",
|
||||
};
|
||||
|
||||
const foundSection = parts?.find((part) => Object?.values(sectionMap)?.includes(part));
|
||||
|
||||
|
||||
if (displaySubSection) {
|
||||
const parts = $page?.url?.pathname.split('/');
|
||||
const sectionMap = {
|
||||
'market-cap': 'market-cap',
|
||||
'employees': 'employees',
|
||||
'income': 'income',
|
||||
'balance-sheet': 'balance-sheet',
|
||||
'cash-flow': 'cash-flow',
|
||||
'ratios': 'ratios',
|
||||
};
|
||||
|
||||
const foundSection = parts?.find(part => Object?.values(sectionMap)?.includes(part));
|
||||
|
||||
displaySubSection = Object?.keys(sectionMap)?.find(key => sectionMap[key] === foundSection) || 'fundamental';
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function changeSubSection(state) {
|
||||
const subSectionMap = {
|
||||
'market-cap': '/stats/market-cap',
|
||||
'employees': '/stats/employees',
|
||||
'income': '/stats/income',
|
||||
'balance-sheet': '/stats/balance-sheet',
|
||||
'cash-flow': '/stats/cash-flow',
|
||||
'ratios': '/stats/ratios',
|
||||
};
|
||||
|
||||
if (state !== 'fundamental' && subSectionMap[state]) {
|
||||
displaySubSection = state;
|
||||
//goto(`/stocks/${$stockTicker}${subSectionMap[state]}`);
|
||||
} else {
|
||||
displaySubSection = state;
|
||||
//goto(`/stocks/${$stockTicker}/stats`);
|
||||
displaySubSection = Object?.keys(sectionMap)?.find((key) => sectionMap[key] === foundSection) || "overview";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function changeSubSection(state) {
|
||||
const subSectionMap = {
|
||||
"market-cap": "/stats/market-cap",
|
||||
employees: "/stats/employees",
|
||||
income: "/stats/income",
|
||||
"balance-sheet": "/stats/balance-sheet",
|
||||
"cash-flow": "/stats/cash-flow",
|
||||
ratios: "/stats/ratios",
|
||||
};
|
||||
|
||||
if (state !== "overview" && subSectionMap[state]) {
|
||||
displaySubSection = state;
|
||||
//goto(`/stocks/${$stockTicker}${subSectionMap[state]}`);
|
||||
} else {
|
||||
displaySubSection = state;
|
||||
//goto(`/stocks/${$stockTicker}/stats`);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<section class="w-auto max-w-5xl bg-[#09090B] overflow-hidden text-black h-full mb-40">
|
||||
<div class="m-auto h-full overflow-hidden">
|
||||
<main class="w-fit sm:w-full sm:max-w-2xl">
|
||||
<div class="m-auto">
|
||||
|
||||
|
||||
<div class="-ml-2 sm:ml-8 w-screen sm:w-full {$screenWidth < 640 ? 'overflow-auto scrollbar' : 'no-scrollbar'} mb-2" >
|
||||
<ul class="pr-4 sm:pr-0 w-screen flex flex-row items-center bg-[#09090B] overflow-x-scroll sm:overflow-hidden space-x-4 rtl:space-x-reverse py-2">
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}/stats`} on:click={() => (changeSubSection('fundamental'))} class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'fundamental' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
Fundamental
|
||||
</a>
|
||||
<div class="{displaySubSection === 'fundamental' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}/stats/market-cap`} on:click={() => (changeSubSection('market-cap'))} class="whitespace-nowrap px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'market-cap' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
Market Cap
|
||||
</a>
|
||||
<div class="{displaySubSection === 'market-cap' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[3.5rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}/stats/employees`} on:click={() => (changeSubSection('employees'))} class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'employees' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
Employees
|
||||
</a>
|
||||
<div class="{displaySubSection === 'employees' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[3.5rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}/stats/income`} on:click={() => (changeSubSection('income'))} class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'income' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
Income
|
||||
</a>
|
||||
<div class="{displaySubSection === 'income' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2.5rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}/stats/balance-sheet`} on:click={() => (changeSubSection('balance-sheet'))} class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'balance-sheet' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
Balance
|
||||
</a>
|
||||
<div class="{displaySubSection === 'balance-sheet' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2.5rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}/stats/cash-flow`} on:click={() => (changeSubSection('cash-flow'))} class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'cash-flow' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
Cashflow
|
||||
</a>
|
||||
<div class="{displaySubSection === 'cash-flow' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2.5rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}/stats/ratios`} on:click={() => (changeSubSection('ratios'))} class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'ratios' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
Ratios
|
||||
</a>
|
||||
<div class="{displaySubSection === 'ratios' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2rem]" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<slot/>
|
||||
<main class="w-fit sm:w-full sm:max-w-2xl">
|
||||
<div class="m-auto">
|
||||
<div class="-ml-2 sm:ml-8 w-screen sm:w-full {$screenWidth < 640 ? 'overflow-auto scrollbar' : 'no-scrollbar'} mb-2">
|
||||
<ul class="pr-4 sm:pr-0 w-screen flex flex-row items-center bg-[#09090B] overflow-x-scroll sm:overflow-hidden space-x-4 rtl:space-x-reverse py-2">
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/stats`}
|
||||
on:click={() => changeSubSection("overview")}
|
||||
class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'overview' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Overview
|
||||
</a>
|
||||
<div class="{displaySubSection === 'overview' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/stats/ratios`}
|
||||
on:click={() => changeSubSection("ratios")}
|
||||
class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'ratios' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Ratios
|
||||
</a>
|
||||
<div class="{displaySubSection === 'ratios' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/stats/income`}
|
||||
on:click={() => changeSubSection("income")}
|
||||
class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'income' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Income
|
||||
</a>
|
||||
<div class="{displaySubSection === 'income' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2.5rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/stats/cash-flow`}
|
||||
on:click={() => changeSubSection("cash-flow")}
|
||||
class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'cash-flow' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Cashflow
|
||||
</a>
|
||||
<div class="{displaySubSection === 'cash-flow' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2.5rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/stats/balance-sheet`}
|
||||
on:click={() => changeSubSection("balance-sheet")}
|
||||
class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'balance-sheet' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Balance
|
||||
</a>
|
||||
<div class="{displaySubSection === 'balance-sheet' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2.5rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/stats/market-cap`}
|
||||
on:click={() => changeSubSection("market-cap")}
|
||||
class="whitespace-nowrap px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'market-cap' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Market Cap
|
||||
</a>
|
||||
<div class="{displaySubSection === 'market-cap' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[3.5rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/stats/employees`}
|
||||
on:click={() => changeSubSection("employees")}
|
||||
class="px-2 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySubSection === 'employees' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Employees
|
||||
</a>
|
||||
<div class="{displaySubSection === 'employees' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[3.5rem]" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
.scrollbar {
|
||||
.scrollbar {
|
||||
display: grid;
|
||||
grid-gap: 18px;
|
||||
grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
|
||||
@ -123,15 +134,15 @@ function changeSubSection(state) {
|
||||
overflow-x: auto;
|
||||
scrollbar-width: thin; /* Hide the default scrollbar in Firefox */
|
||||
scrollbar-color: transparent transparent; /* Hide the default scrollbar in Firefox */
|
||||
}
|
||||
}
|
||||
|
||||
/* Custom scrollbar for Webkit (Chrome, Safari) */
|
||||
.scrollbar::-webkit-scrollbar {
|
||||
/* Custom scrollbar for Webkit (Chrome, Safari) */
|
||||
.scrollbar::-webkit-scrollbar {
|
||||
width: 0; /* Hide the width of the scrollbar */
|
||||
height: 0; /* Hide the height of the scrollbar */
|
||||
}
|
||||
}
|
||||
|
||||
.scrollbar::-webkit-scrollbar-thumb {
|
||||
.scrollbar::-webkit-scrollbar-thumb {
|
||||
background: transparent; /* Make the thumb transparent */
|
||||
}
|
||||
</style>
|
||||
}
|
||||
</style>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user