commit
f8ed49b3d4
@ -1,73 +1,55 @@
|
||||
<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 consensusRating = "n/a";
|
||||
let changesPercentage = 0;
|
||||
|
||||
|
||||
|
||||
$: {
|
||||
|
||||
if ($stockTicker && typeof window !== 'undefined' && typeof analystRating !== 'undefined' && Object?.keys(analystRating)?.length !== 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
|
||||
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)
|
||||
console.log(lastPrice);
|
||||
try {
|
||||
changesPercentage = ((priceTarget / lastPrice - 1) * 100)?.toFixed(2) ?? 0;
|
||||
} catch (e) {
|
||||
changesPercentage = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</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>
|
||||
<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>
|
||||
<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'}
|
||||
{#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' }
|
||||
{: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>
|
||||
@ -78,18 +60,15 @@ if ($stockTicker && typeof window !== 'undefined' && typeof analystRating !== 'u
|
||||
{/if}
|
||||
|
||||
<span class="mr-5 mt-2 font-semibold text-xl text-white">
|
||||
{#if priceTarget !== 'n/a'}
|
||||
{#if priceTarget !== "n/a"}
|
||||
${priceTarget}
|
||||
{:else}
|
||||
-
|
||||
{/if}
|
||||
</span>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="text-white pl-4 pr-4 mt-6">
|
||||
{#if changesPercentage < 0}
|
||||
The Stock Price has a downside of
|
||||
@ -101,21 +80,13 @@ if ($stockTicker && typeof window !== 'undefined' && typeof analystRating !== 'u
|
||||
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 font-medium text-start mr-auto"> Buy </span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{buyCount}%
|
||||
</span>
|
||||
@ -125,9 +96,7 @@ if ($stockTicker && typeof window !== 'undefined' && typeof analystRating !== 'u
|
||||
|
||||
<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 font-medium text-start mr-auto"> Hold </span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{holdCount}%
|
||||
</span>
|
||||
@ -137,9 +106,7 @@ if ($stockTicker && typeof window !== 'undefined' && typeof analystRating !== 'u
|
||||
|
||||
<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 font-medium text-start mr-auto"> Sell </span>
|
||||
<span class="text-white text-md font-medium ml-auto">
|
||||
{sellCount}%
|
||||
</span>
|
||||
@ -147,82 +114,57 @@ if ($stockTicker && typeof window !== 'undefined' && typeof analystRating !== 'u
|
||||
<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>
|
||||
|
||||
<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>
|
||||
</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>
|
||||
<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-lg font-medium inline-block"> Recommendation: </span>
|
||||
<span class="text-white text-2xl font-medium inline-block">
|
||||
{#if consensusRating === 'Buy' || consensusRating === 'Strong Buy'}
|
||||
{#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' }
|
||||
{:else if consensusRating === "Sell" || consensusRating === "Strong Sell"}
|
||||
<span class="text-start font-medium text-[#FF2F1F] text-2xl">
|
||||
{consensusRating}
|
||||
</span>
|
||||
{:else if consensusRating === 'Hold'}
|
||||
{:else if consensusRating === "Hold"}
|
||||
<span class="text-start font-medium text-[#FF2F1F] text-2xl">
|
||||
{consensusRating ?? 'n/a'}
|
||||
{consensusRating ?? "n/a"}
|
||||
</span>
|
||||
{:else}
|
||||
<span class="text-start font-medium text-white text-2xl">
|
||||
n/a
|
||||
</span>
|
||||
<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-lg font-medium inline-block"> Price Target: </span>
|
||||
<span class="text-white ml-auto text-2xl font-medium inline-block">
|
||||
{#if priceTarget !== 'n/a'}
|
||||
{#if priceTarget !== "n/a"}
|
||||
${priceTarget}
|
||||
{:else}
|
||||
-
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{#if changesPercentage < 0}
|
||||
@ -238,68 +180,63 @@ if ($stockTicker && typeof window !== 'undefined' && typeof analystRating !== 'u
|
||||
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="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 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 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>
|
||||
<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 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>
|
||||
<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>
|
||||
<!--End Mobile Analyst Card-->
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<script lang ='ts'>
|
||||
import { analystInsightComponent, stockTicker, getCache, setCache} from '$lib/store';
|
||||
import InfoModal from '$lib/components/InfoModal.svelte';
|
||||
<script lang="ts">
|
||||
import { analystInsightComponent, stockTicker, getCache, setCache } from "$lib/store";
|
||||
import InfoModal from "$lib/components/InfoModal.svelte";
|
||||
|
||||
export let data;
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
|
||||
let rawData = {};
|
||||
|
||||
|
||||
function latestInfoDate(inputDate) {
|
||||
// Convert the input date string to milliseconds since epoch
|
||||
const inputDateMs = Date?.parse(inputDate);
|
||||
@ -26,27 +25,26 @@ function latestInfoDate(inputDate) {
|
||||
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) {
|
||||
@ -56,37 +54,31 @@ function latestInfoDate(inputDate) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
$: {
|
||||
if($stockTicker && typeof window !== 'undefined') {
|
||||
if ($stockTicker && typeof window !== "undefined") {
|
||||
isLoaded = false;
|
||||
const ticker = $stockTicker;
|
||||
const asyncFunctions = [
|
||||
getAnalystInsight(ticker)
|
||||
];
|
||||
const asyncFunctions = [getAnalystInsight(ticker)];
|
||||
Promise.all(asyncFunctions)
|
||||
.then((results) => {
|
||||
})
|
||||
.then((results) => {})
|
||||
.catch((error) => {
|
||||
console.error('An error occurred:', 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>
|
||||
<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
|
||||
@ -96,37 +88,25 @@ function latestInfoDate(inputDate) {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if data?.user?.tier === 'Pro'}
|
||||
{#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 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>
|
||||
|
||||
|
||||
|
||||
<div class="w-full mt-4">
|
||||
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<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="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)}
|
||||
@ -139,24 +119,15 @@ function latestInfoDate(inputDate) {
|
||||
{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">
|
||||
@ -166,26 +137,21 @@ function latestInfoDate(inputDate) {
|
||||
</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>
|
||||
<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 */
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
@ -197,5 +163,4 @@ function latestInfoDate(inputDate) {
|
||||
.chart {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -1,49 +1,38 @@
|
||||
<script lang='ts'>
|
||||
|
||||
import {searchBarData, globalForm, screenWidth, openPriceAlert, currentPortfolioPrice, realtimePrice, isCrosshairMoveActive, currentPrice, priceIncrease, displayCompanyName, stockTicker, isOpen } from '$lib/store';
|
||||
<script lang="ts">
|
||||
import { searchBarData, globalForm, screenWidth, openPriceAlert, currentPortfolioPrice, realtimePrice, isCrosshairMoveActive, currentPrice, priceIncrease, displayCompanyName, stockTicker, isOpen } from "$lib/store";
|
||||
|
||||
import { onMount, onDestroy, afterUpdate } from "svelte";
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import toast from 'svelte-french-toast';
|
||||
import Sidecard from '$lib/components/Sidecard.svelte';
|
||||
import Markethour from '$lib/components/Markethour.svelte';
|
||||
import { goto } from "$app/navigation";
|
||||
import { page } from "$app/stores";
|
||||
import toast from "svelte-french-toast";
|
||||
import Sidecard from "$lib/components/Sidecard.svelte";
|
||||
import Markethour from "$lib/components/Markethour.svelte";
|
||||
|
||||
export let data;
|
||||
|
||||
|
||||
$: $realtimePrice = data?.getStockQuote?.price?.toFixed(2);
|
||||
|
||||
|
||||
|
||||
async function loadSearchData() {
|
||||
|
||||
if($searchBarData?.length !== 0)
|
||||
{
|
||||
return
|
||||
}
|
||||
else {
|
||||
|
||||
if ($searchBarData?.length !== 0) {
|
||||
return;
|
||||
} else {
|
||||
// make the GET request to the endpoint
|
||||
const response = await fetch(data?.apiURL+'/searchbar-data', {
|
||||
method: 'GET',
|
||||
const response = await fetch(data?.apiURL + "/searchbar-data", {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json","X-API-KEY": data?.apiKey
|
||||
"Content-Type": "application/json",
|
||||
"X-API-KEY": data?.apiKey,
|
||||
},
|
||||
});
|
||||
|
||||
$searchBarData = await response.json();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
let previousRealtimePrice = null;
|
||||
let previousTicker;
|
||||
let socket;
|
||||
|
||||
|
||||
let isScrolled = false;
|
||||
let y;
|
||||
|
||||
@ -53,31 +42,26 @@ async function loadSearchData() {
|
||||
//let holdingShares = 0;
|
||||
//let availableCash = 0;
|
||||
|
||||
let displaySection = '';
|
||||
|
||||
|
||||
let displaySection = "";
|
||||
|
||||
let stockDeck;
|
||||
let similarstock = [];
|
||||
let topETFHolder = [];
|
||||
|
||||
|
||||
function shareContent(url) {
|
||||
|
||||
if (navigator.share) {
|
||||
navigator.share({
|
||||
navigator
|
||||
.share({
|
||||
title: document.title,
|
||||
url,
|
||||
})
|
||||
.then(() => console.log('Content shared successfully.'))
|
||||
.catch((error) => console.log('Error sharing content:', error));
|
||||
.then(() => console.log("Content shared successfully."))
|
||||
.catch((error) => console.log("Error sharing content:", error));
|
||||
} else {
|
||||
toast.error('Sharing is not supported by your device', {
|
||||
style: 'background: #333; color: #fff;'
|
||||
toast.error("Sharing is not supported by your device", {
|
||||
style: "background: #333; color: #fff;",
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -97,45 +81,38 @@ function handleTypeOfTrade(state:string)
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
function scrollToItem(itemId) {
|
||||
const item = document.getElementById(itemId);
|
||||
if (item) {
|
||||
|
||||
item.scrollIntoView({ behavior: 'smooth' });
|
||||
window.scrollTo(0,0)
|
||||
item.scrollIntoView({ behavior: "smooth" });
|
||||
window.scrollTo(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function changeSection(state, item) {
|
||||
scrollToItem(item);
|
||||
|
||||
const sectionMap = {
|
||||
'insider': '/insider',
|
||||
'options': '/options',
|
||||
'dividends': '/dividends',
|
||||
'stats': '/stats',
|
||||
'analyst': '/analyst',
|
||||
'news': '/news',
|
||||
insider: "/insider",
|
||||
options: "/options",
|
||||
dividends: "/dividends",
|
||||
fundamental: "/stats",
|
||||
forecast: "/forecast",
|
||||
news: "/news",
|
||||
};
|
||||
|
||||
if (state !== 'overview' && sectionMap[state]) {
|
||||
if (state !== "overview" && sectionMap[state]) {
|
||||
displaySection = state;
|
||||
//goto(`/stocks/${$stockTicker}${sectionMap[state]}`);
|
||||
} else {
|
||||
displaySection = 'overview';
|
||||
displaySection = "overview";
|
||||
//goto(`/stocks/${$stockTicker}/`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
async function toggleUserWatchlist(watchListId: string) {
|
||||
try {
|
||||
const watchlistIndex = userWatchList?.findIndex(item => item?.id === watchListId);
|
||||
const watchlistIndex = userWatchList?.findIndex((item) => item?.id === watchListId);
|
||||
const postData = {
|
||||
userId: data?.user?.id,
|
||||
watchListId,
|
||||
@ -143,13 +120,13 @@ async function toggleUserWatchlist(watchListId: string) {
|
||||
};
|
||||
|
||||
const response = await fetch(`${data?.fastifyURL}/update-watchlist`, {
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(postData),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
|
||||
const output = (await response.json())?.items;
|
||||
@ -162,14 +139,12 @@ async function toggleUserWatchlist(watchListId: string) {
|
||||
|
||||
userWatchList = [...userWatchList];
|
||||
isTickerIncluded = !isTickerIncluded;
|
||||
|
||||
} catch (error) {
|
||||
console.error('An error occurred:', error);
|
||||
console.error("An error occurred:", error);
|
||||
// Handle the error appropriately (e.g., show an error message to the user)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
async function fetchPortfolio()
|
||||
{
|
||||
@ -188,38 +163,31 @@ async function fetchPortfolio()
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
function sendMessage(message) {
|
||||
if (socket && socket.readyState === WebSocket.OPEN) {
|
||||
socket.send(message);
|
||||
} else {
|
||||
console.error('WebSocket is not open. Unable to send message.');
|
||||
console.error("WebSocket is not open. Unable to send message.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function websocketRealtimeData() {
|
||||
|
||||
previousTicker = $stockTicker;
|
||||
try {
|
||||
socket = new WebSocket(data?.wsURL + "/realtime-data");
|
||||
|
||||
socket.addEventListener('open', () => {
|
||||
socket.addEventListener("open", () => {
|
||||
//console.log('WebSocket connection opened');
|
||||
|
||||
// Send the initial value of stockTicker
|
||||
sendMessage($stockTicker?.toLowerCase());
|
||||
});
|
||||
|
||||
|
||||
socket.addEventListener('message', (event) => {
|
||||
socket.addEventListener("message", (event) => {
|
||||
const data = event.data;
|
||||
//console.log('Received message:', data);
|
||||
try {
|
||||
|
||||
$realtimePrice = typeof JSON.parse(data)?.bp !== 'undefined' ? JSON.parse(data)?.bp : null;
|
||||
$realtimePrice = typeof JSON.parse(data)?.bp !== "undefined" ? JSON.parse(data)?.bp : null;
|
||||
//console.log('Received message:', $realtimePrice);
|
||||
|
||||
if ($realtimePrice > previousRealtimePrice) {
|
||||
@ -230,84 +198,63 @@ async function websocketRealtimeData() {
|
||||
previousRealtimePrice = $realtimePrice;
|
||||
}
|
||||
|
||||
|
||||
$isCrosshairMoveActive = false;
|
||||
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
catch(e) {
|
||||
console.log(e)
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
socket.addEventListener('close', (event) => {
|
||||
console.log('WebSocket connection closed:', event.reason);
|
||||
socket.addEventListener("close", (event) => {
|
||||
console.log("WebSocket connection closed:", event.reason);
|
||||
// Handle disconnection, you might want to attempt to reconnect here
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('WebSocket connection error:', error);
|
||||
console.error("WebSocket connection error:", error);
|
||||
// Handle connection errors here
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let LoginPopup;
|
||||
let PriceAlert;
|
||||
|
||||
|
||||
onMount(async () => {
|
||||
|
||||
if(!data?.user)
|
||||
{
|
||||
LoginPopup = (await import('$lib/components/LoginPopup.svelte')).default;
|
||||
}
|
||||
else {
|
||||
if (!data?.user) {
|
||||
LoginPopup = (await import("$lib/components/LoginPopup.svelte")).default;
|
||||
} else {
|
||||
//AddPortfolio = (await import('$lib/components/AddPortfolio.svelte')).default;
|
||||
//BuyTrade = (await import('$lib/components/BuyTrade.svelte')).default;
|
||||
//SellTrade = (await import('$lib/components/SellTrade.svelte')).default;
|
||||
PriceAlert = (await import('$lib/components/PriceAlert.svelte')).default;
|
||||
PriceAlert = (await import("$lib/components/PriceAlert.svelte")).default;
|
||||
}
|
||||
|
||||
|
||||
if ($isOpen) //&& currentDateTime > startTime && currentDateTime < endTime
|
||||
{
|
||||
await websocketRealtimeData()
|
||||
if ($isOpen) {
|
||||
//&& currentDateTime > startTime && currentDateTime < endTime
|
||||
await websocketRealtimeData();
|
||||
}
|
||||
});
|
||||
|
||||
afterUpdate(async () => {
|
||||
|
||||
if(previousTicker !== $stockTicker && typeof socket !== 'undefined')
|
||||
{
|
||||
if (previousTicker !== $stockTicker && typeof socket !== "undefined") {
|
||||
previousTicker = $stockTicker;
|
||||
//socket.send('close')
|
||||
socket?.close();
|
||||
await new Promise((resolve, reject) => {
|
||||
socket?.addEventListener('close', resolve);
|
||||
socket?.addEventListener("close", resolve);
|
||||
});
|
||||
|
||||
if(socket?.readyState === WebSocket?.CLOSED)
|
||||
{
|
||||
await websocketRealtimeData()
|
||||
console.log('connecting again')
|
||||
if (socket?.readyState === WebSocket?.CLOSED) {
|
||||
await websocketRealtimeData();
|
||||
console.log("connecting again");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
onDestroy(() => {
|
||||
try {
|
||||
//socket?.send('close')
|
||||
socket?.close()
|
||||
}
|
||||
catch(e) {
|
||||
console.log(e)
|
||||
socket?.close();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
//$displayCompanyName = '';
|
||||
@ -315,16 +262,11 @@ onDestroy(() => {
|
||||
$currentPrice = null;
|
||||
$priceIncrease = null;
|
||||
//$traded = false
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
$: {
|
||||
if ($stockTicker && $stockTicker?.length !== 0 && typeof window !== 'undefined') // add a check to see if running on client-side
|
||||
{
|
||||
|
||||
if ($stockTicker && $stockTicker?.length !== 0 && typeof window !== "undefined") {
|
||||
// add a check to see if running on client-side
|
||||
stockDeck = data?.getStockDeck;
|
||||
similarstock = data?.getSimilarStock;
|
||||
topETFHolder = data?.getTopETFHolder;
|
||||
@ -332,8 +274,7 @@ $: {
|
||||
}
|
||||
}
|
||||
|
||||
$: isTickerIncluded = userWatchList?.some(item =>
|
||||
item.user === data?.user?.id && item.ticker?.includes($stockTicker));
|
||||
$: isTickerIncluded = userWatchList?.some((item) => item.user === data?.user?.id && item.ticker?.includes($stockTicker));
|
||||
|
||||
/*
|
||||
$: {
|
||||
@ -363,35 +304,30 @@ $: {
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
$: charNumber = $screenWidth < 640 ? 12 : 25;
|
||||
|
||||
$: {
|
||||
if($stockTicker && typeof window !== 'undefined' && $page.url.pathname === `/stocks/${$stockTicker}`)
|
||||
{
|
||||
displaySection = 'overview';
|
||||
if ($stockTicker && typeof window !== "undefined" && $page.url.pathname === `/stocks/${$stockTicker}`) {
|
||||
displaySection = "overview";
|
||||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
if($page.url.pathname)
|
||||
{
|
||||
const parts = $page?.url?.pathname?.split('/');
|
||||
if ($page.url.pathname) {
|
||||
const parts = $page?.url?.pathname?.split("/");
|
||||
const sectionMap = {
|
||||
'stats': 'stats',
|
||||
'options': 'options',
|
||||
'insider': 'insider',
|
||||
'dividends': 'dividends',
|
||||
'analyst': 'analyst',
|
||||
'news': 'news'
|
||||
stats: "fundamental",
|
||||
options: "options",
|
||||
insider: "insider",
|
||||
dividends: "dividends",
|
||||
forecast: "forecast",
|
||||
news: "news",
|
||||
};
|
||||
displaySection = sectionMap[parts?.find(part => Object?.keys(sectionMap)?.includes(part))] || 'overview';
|
||||
displaySection = sectionMap[parts?.find((part) => Object?.keys(sectionMap)?.includes(part))] || "overview";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$: isScrolled = y > 0;
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:window bind:scrollY={y} />
|
||||
@ -403,26 +339,26 @@ $: isScrolled = y > 0;
|
||||
<section class="w-full">
|
||||
<div class="w-full">
|
||||
<div class="sm:flex sm:justify-start w-full">
|
||||
|
||||
<!--Start Mobile Navbar-->
|
||||
<div class="fixed top-0 left-0 right-0 z-20 bg-[#09090B] sm:hidden">
|
||||
<div class="navbar w-full px-4 py-2">
|
||||
|
||||
<div class="{isScrolled ? 'border-b border-slate-800 ease-in' : 'ease-out'} m-auto w-full">
|
||||
|
||||
<div class="flex-1 flex-shrink-0 flex flex-row items-center justify-between -mt-2">
|
||||
|
||||
<label on:click={() => goto('/')} class="ml-2 cursor-pointer">
|
||||
<svg class="w-5 h-5 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><g transform="rotate(-90 512 512)"><path fill="white" d="M104.704 685.248a64 64 0 0 0 90.496 0l316.8-316.8l316.8 316.8a64 64 0 0 0 90.496-90.496L557.248 232.704a64 64 0 0 0-90.496 0L104.704 594.752a64 64 0 0 0 0 90.496z"/></g></svg>
|
||||
<label on:click={() => goto("/")} class="ml-2 cursor-pointer">
|
||||
<svg class="w-5 h-5 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"
|
||||
><g transform="rotate(-90 512 512)"
|
||||
><path fill="white" d="M104.704 685.248a64 64 0 0 0 90.496 0l316.8-316.8l316.8 316.8a64 64 0 0 0 90.496-90.496L557.248 232.704a64 64 0 0 0-90.496 0L104.704 594.752a64 64 0 0 0 0 90.496z" /></g
|
||||
></svg
|
||||
>
|
||||
</label>
|
||||
|
||||
<div class="{!isScrolled ? 'hidden' : 'flex flex-col items-center ml-6 transition-transform ease-in'}">
|
||||
<div class={!isScrolled ? "hidden" : "flex flex-col items-center ml-6 transition-transform ease-in"}>
|
||||
<span class="text-white text-[0.70rem] font-medium text-opacity-[0.6]">
|
||||
{$stockTicker}
|
||||
</span>
|
||||
<span class="text-white font-medium text-sm">
|
||||
{#if $currentPortfolioPrice !== null && $currentPortfolioPrice !== 0}
|
||||
{$stockTicker?.includes('.DE') || $stockTicker?.includes('.F') ? `${$currentPortfolioPrice}€` : ` $${$currentPortfolioPrice}`}
|
||||
{$stockTicker?.includes(".DE") || $stockTicker?.includes(".F") ? `${$currentPortfolioPrice}€` : ` $${$currentPortfolioPrice}`}
|
||||
{:else}
|
||||
{data?.getStockQuote?.price}
|
||||
{/if}
|
||||
@ -431,19 +367,27 @@ $: isScrolled = y > 0;
|
||||
|
||||
<!--Start Search Button-->
|
||||
<label on:click={loadSearchData} class="ml-auto mr-4" for="searchBarModal">
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m21 21l-4.343-4.343m0 0A8 8 0 1 0 5.343 5.343a8 8 0 0 0 11.314 11.314"/></svg>
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"
|
||||
><path fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="m21 21l-4.343-4.343m0 0A8 8 0 1 0 5.343 5.343a8 8 0 0 0 11.314 11.314" /></svg
|
||||
>
|
||||
</label>
|
||||
<!--End Search Button-->
|
||||
|
||||
|
||||
<!--Start Share Button-->
|
||||
<label class="mr-4" on:click={() => shareContent('https://stocknear.com/stocks/'+$stockTicker)} >
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M336 192h40a40 40 0 0 1 40 40v192a40 40 0 0 1-40 40H136a40 40 0 0 1-40-40V232a40 40 0 0 1 40-40h40m160-64l-80-80l-80 80m80 193V48"/></svg>
|
||||
<label class="mr-4" on:click={() => shareContent("https://stocknear.com/stocks/" + $stockTicker)}>
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"
|
||||
><path
|
||||
fill="none"
|
||||
stroke="white"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="32"
|
||||
d="M336 192h40a40 40 0 0 1 40 40v192a40 40 0 0 1-40 40H136a40 40 0 0 1-40-40V232a40 40 0 0 1 40-40h40m160-64l-80-80l-80 80m80 193V48"
|
||||
/></svg
|
||||
>
|
||||
</label>
|
||||
<!--End Share Button-->
|
||||
|
||||
|
||||
|
||||
<!--Start Watchlist-->
|
||||
|
||||
{#if data?.user}
|
||||
@ -451,56 +395,74 @@ $: isScrolled = y > 0;
|
||||
{#if userWatchList?.length !== 0}
|
||||
<label for="addWatchListModal" class="cursor-pointer flex-shrink-0">
|
||||
{#if isTickerIncluded}
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#FBCE3C" d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327l4.898.696c.441.062.612.636.282.95l-3.522 3.356l.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/></svg>
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
|
||||
><path
|
||||
fill="#FBCE3C"
|
||||
d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327l4.898.696c.441.062.612.636.282.95l-3.522 3.356l.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"
|
||||
/></svg
|
||||
>
|
||||
{:else}
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="white" d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"/></svg>
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
|
||||
><path
|
||||
fill="white"
|
||||
d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"
|
||||
/></svg
|
||||
>
|
||||
{/if}
|
||||
</label>
|
||||
|
||||
{:else if userWatchList?.length === 0}
|
||||
<label on:click={() => toggleUserWatchlist('firstList')} class="cursor-pointer flex-shrink-0">
|
||||
<label on:click={() => toggleUserWatchlist("firstList")} class="cursor-pointer flex-shrink-0">
|
||||
{#if isTickerIncluded}
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#FBCE3C" d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327l4.898.696c.441.062.612.636.282.95l-3.522 3.356l.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/></svg>
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
|
||||
><path
|
||||
fill="#FBCE3C"
|
||||
d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327l4.898.696c.441.062.612.636.282.95l-3.522 3.356l.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"
|
||||
/></svg
|
||||
>
|
||||
{:else}
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="white" d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"/></svg>
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
|
||||
><path
|
||||
fill="white"
|
||||
d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"
|
||||
/></svg
|
||||
>
|
||||
{/if}
|
||||
</label>
|
||||
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<label for="userLogin" class="cursor-pointer flex-shrink-0 text-white mr-4">
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="white" d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"/></svg>
|
||||
<svg class="w-6 h-6 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
|
||||
><path
|
||||
fill="white"
|
||||
d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"
|
||||
/></svg
|
||||
>
|
||||
</label>
|
||||
{/if}
|
||||
<!--End Watchlist-->
|
||||
|
||||
<!--Start Price Alert-->
|
||||
<label on:click={() => $openPriceAlert = true} for={data?.user ? 'priceAlertModal' : 'userLogin'} class="mr-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-7 h-7 inline-block mt-1" viewBox="0 0 24 24"><g fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"><path d="M3 5.231L6.15 3M21 5.231L17.85 3"/><circle cx="12" cy="13" r="8"/><path d="M9.5 13h5M12 10.5v5"/></g></svg>
|
||||
<label on:click={() => ($openPriceAlert = true)} for={data?.user ? "priceAlertModal" : "userLogin"} class="mr-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-7 h-7 inline-block mt-1" viewBox="0 0 24 24"
|
||||
><g fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"><path d="M3 5.231L6.15 3M21 5.231L17.85 3" /><circle cx="12" cy="13" r="8" /><path d="M9.5 13h5M12 10.5v5" /></g></svg
|
||||
>
|
||||
</label>
|
||||
<!--End Price Alert -->
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Mobile Navbar-->
|
||||
|
||||
|
||||
<div class="pt-20 sm:pt-0 w-auto max-w-3xl lg:max-w-content 2xl:max-w-6xl px-3 sm:px-0">
|
||||
|
||||
<div class="md:flex md:justify-between md:divide-x md:divide-slate-800">
|
||||
<!-- Main content -->
|
||||
<div class="pb-12 md:pb-20 w-full 2xl:max-w-5xl">
|
||||
<div class="md:pr-6 lg:pr-10">
|
||||
|
||||
|
||||
<!-----Start-Header-CandleChart-Indicators------>
|
||||
|
||||
<div class="m-auto pl-0 sm:pl-4 overflow-hidden mb-5 md:mt-10">
|
||||
|
||||
<div class="hidden sm:flex flex-row w-full justify-between items-center pb-10">
|
||||
<Markethour />
|
||||
|
||||
@ -512,30 +474,53 @@ $: isScrolled = y > 0;
|
||||
<div class="flex-shrink-0 rounded-full hover:bg-white hover:bg-opacity-[0.02] transition ease-out w-12 h-12 relative bg-[#09090B] flex items-center justify-center">
|
||||
<label for="addWatchListModal" class="cursor-pointer flex-shrink-0">
|
||||
{#if isTickerIncluded}
|
||||
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#FBCE3C" d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327l4.898.696c.441.062.612.636.282.95l-3.522 3.356l.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/></svg>
|
||||
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
|
||||
><path
|
||||
fill="#FBCE3C"
|
||||
d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327l4.898.696c.441.062.612.636.282.95l-3.522 3.356l.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"
|
||||
/></svg
|
||||
>
|
||||
{:else}
|
||||
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="white" d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"/></svg>
|
||||
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
|
||||
><path
|
||||
fill="white"
|
||||
d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"
|
||||
/></svg
|
||||
>
|
||||
{/if}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{:else if userWatchList?.length === 0}
|
||||
<div class="flex-shrink-0 rounded-full hover:bg-white hover:bg-opacity-[0.02] transition ease-out w-12 h-12 relative bg-[#09090B] flex items-center justify-center">
|
||||
<label on:click={() => toggleUserWatchlist('firstList')} class="cursor-pointer flex-shrink-0">
|
||||
<label on:click={() => toggleUserWatchlist("firstList")} class="cursor-pointer flex-shrink-0">
|
||||
{#if isTickerIncluded}
|
||||
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#FBCE3C" d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327l4.898.696c.441.062.612.636.282.95l-3.522 3.356l.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"/></svg>
|
||||
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
|
||||
><path
|
||||
fill="#FBCE3C"
|
||||
d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327l4.898.696c.441.062.612.636.282.95l-3.522 3.356l.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z"
|
||||
/></svg
|
||||
>
|
||||
{:else}
|
||||
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="white" d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"/></svg>
|
||||
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
|
||||
><path
|
||||
fill="white"
|
||||
d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"
|
||||
/></svg
|
||||
>
|
||||
{/if}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex-shrink-0 ml-auto mr-2 rounded-full hover:bg-white hover:bg-opacity-[0.02] transition ease-out w-12 h-12 relative bg-[#09090B] flex items-center justify-center">
|
||||
<label for="userLogin" class="cursor-pointer flex-shrink-0 text-white">
|
||||
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="white" d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"/></svg>
|
||||
<svg class="w-7 h-7 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"
|
||||
><path
|
||||
fill="white"
|
||||
d="M2.866 14.85c-.078.444.36.791.746.593l4.39-2.256l4.389 2.256c.386.198.824-.149.746-.592l-.83-4.73l3.522-3.356c.33-.314.16-.888-.282-.95l-4.898-.696L8.465.792a.513.513 0 0 0-.927 0L5.354 5.12l-4.898.696c-.441.062-.612.636-.283.95l3.523 3.356l-.83 4.73zm4.905-2.767l-3.686 1.894l.694-3.957a.565.565 0 0 0-.163-.505L1.71 6.745l4.052-.576a.525.525 0 0 0 .393-.288L8 2.223l1.847 3.658a.525.525 0 0 0 .393.288l4.052.575l-2.906 2.77a.565.565 0 0 0-.163.506l.694 3.957l-3.686-1.894a.503.503 0 0 0-.461 0z"
|
||||
/></svg
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
{/if}
|
||||
@ -544,14 +529,15 @@ $: isScrolled = y > 0;
|
||||
<!--Start Price Alert -->
|
||||
|
||||
<div class="flex-shrink-0 rounded-full hover:bg-white hover:bg-opacity-[0.02] transition ease-out w-12 h-12 relative bg-[#09090B] flex items-center justify-center">
|
||||
<label on:click={() => $openPriceAlert = true} for={data?.user ? 'priceAlertModal' : 'userLogin'} class="cursor-pointer flex-shrink-0 text-white">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-8 h-8 inline-block" viewBox="0 0 24 24"><g fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"><path d="M3 5.231L6.15 3M21 5.231L17.85 3"/><circle cx="12" cy="13" r="8"/><path d="M9.5 13h5M12 10.5v5"/></g></svg>
|
||||
<label on:click={() => ($openPriceAlert = true)} for={data?.user ? "priceAlertModal" : "userLogin"} class="cursor-pointer flex-shrink-0 text-white">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-8 h-8 inline-block" viewBox="0 0 24 24"
|
||||
><g fill="none" stroke="white" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"><path d="M3 5.231L6.15 3M21 5.231L17.85 3" /><circle cx="12" cy="13" r="8" /><path d="M9.5 13h5M12 10.5v5" /></g></svg
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
<!--End Price Alert -->
|
||||
</div>
|
||||
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
|
||||
@ -572,12 +558,10 @@ $: isScrolled = y > 0;
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="ml-auto sm:hidden">
|
||||
<Markethour />
|
||||
</div>
|
||||
|
||||
|
||||
<!--Start Trade-->
|
||||
<!--
|
||||
<div class="hidden sm:flex ml-auto">
|
||||
@ -600,58 +584,86 @@ $: isScrolled = y > 0;
|
||||
</div>
|
||||
-->
|
||||
<!--End Trade-->
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<!-----End-Header-CandleChart-Indicators------>
|
||||
|
||||
|
||||
<!--Start Ticker Section-->
|
||||
|
||||
<!--<div class="w-full max-w-3xl sm:max-w-2xl m-auto pt-2 pb-5 sm:pl-3 sticky z-20 bg-[#09090B]" style="top: {$screenWidth < 520 && $isScrollingUp ? '4rem' : '0rem'};">-->
|
||||
<div class="-ml-2 sm:ml-4 w-screen sm:w-full {$screenWidth < 640 ? 'overflow-auto scrollbar' : ''} mb-2">
|
||||
<ul class="pr-4 sm:pr-0 w-screen font-medium flex flex-row items-center bg-[#09090B] overflow-x-scroll no-scrollbar space-x-3 rtl:space-x-reverse py-2">
|
||||
<ul class="pr-4 sm:pr-0 w-screen font-medium flex flex-row items-center bg-[#09090B] space-x-3 rtl:space-x-reverse py-2">
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}`} id="item1" on:click={() => (changeSection('overview','item1'))} class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'overview' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}`}
|
||||
id="item1"
|
||||
on:click={() => changeSection("overview", "item1")}
|
||||
class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'overview' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Overview
|
||||
</a>
|
||||
<div class="{displaySection === 'overview' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4.2rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}/stats`} id="item2" on:click={() => (changeSection('stats','item2'))} class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'stats' ? 'text-white ' : 'bg-[#09090B]'}" >Stats</a>
|
||||
<div class="{displaySection === 'stats' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2.8rem]" />
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/stats`}
|
||||
id="item2"
|
||||
on:click={() => changeSection("fundamental", "item2")}
|
||||
class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'fundamental' ? 'text-white ' : 'bg-[#09090B]'}">Fundamental</a
|
||||
>
|
||||
<div class="{displaySection === 'fundamental' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2.8rem]" />
|
||||
</li>
|
||||
<li class="cursor-pointer flex flex-col items-center">
|
||||
<a href={`/stocks/${$stockTicker}/options`} id="item3" on:click={() => (changeSection('options','item3'))} class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'options' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/forecast`}
|
||||
id="item3"
|
||||
on:click={() => changeSection("forecast", "item3")}
|
||||
class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'forecast' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Forecast
|
||||
</a>
|
||||
<div class="{displaySection === 'forecast' ? '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}/options`}
|
||||
id="item3"
|
||||
on:click={() => changeSection("options", "item3")}
|
||||
class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'options' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Options
|
||||
</a>
|
||||
<div class="{displaySection === 'options' ? '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}/analyst`} id="item3" on:click={() => (changeSection('analyst','item3'))} class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'analyst' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
Analyst
|
||||
</a>
|
||||
<div class="{displaySection === 'analyst' ? '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}/insider`} id="item4" on:click={() => (changeSection('insider','item4'))} class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'insider' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/insider`}
|
||||
id="item4"
|
||||
on:click={() => changeSection("insider", "item4")}
|
||||
class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'insider' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Insider
|
||||
</a>
|
||||
<div class="{displaySection === 'insider' ? '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}/dividends`} id="item5" on:click={() => (changeSection('dividends','item5'))} class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'dividends' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/dividends`}
|
||||
id="item5"
|
||||
on:click={() => changeSection("dividends", "item5")}
|
||||
class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'dividends' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
Dividends
|
||||
</a>
|
||||
<div class="{displaySection === 'dividends' ? '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}/news`} id="item7" on:click={() => (changeSection('news','item7'))} class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'news' ? 'text-white ' : 'bg-[#09090B]'}" >
|
||||
<a
|
||||
href={`/stocks/${$stockTicker}/news`}
|
||||
id="item7"
|
||||
on:click={() => changeSection("news", "item7")}
|
||||
class="px-3 text-sm sm:text-[1rem] font-medium text-gray-400 sm:hover:text-white {displaySection === 'news' ? 'text-white ' : 'bg-[#09090B]'}"
|
||||
>
|
||||
News
|
||||
</a>
|
||||
<div class="{displaySection === 'news' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2.8rem]" />
|
||||
@ -659,14 +671,9 @@ $: isScrolled = y > 0;
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!--Start-Main Content-->
|
||||
<slot />
|
||||
<!--End Main Content-->
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -700,7 +707,6 @@ $: isScrolled = y > 0;
|
||||
{/if}
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
<div class="sm:hidden fixed z-20 bottom-8 sm:bottom-10 right-5">
|
||||
<div class="h-full mx-auto">
|
||||
@ -719,18 +725,15 @@ $: isScrolled = y > 0;
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--Start Login Modal-->
|
||||
{#if LoginPopup}
|
||||
<LoginPopup form={$globalForm} />
|
||||
@ -758,18 +761,13 @@ $: isScrolled = y > 0;
|
||||
{/if}
|
||||
-->
|
||||
|
||||
|
||||
<!--Start SellTrade Modal-->
|
||||
{#if PriceAlert}
|
||||
<PriceAlert
|
||||
data = {data}
|
||||
/>
|
||||
<PriceAlert {data} />
|
||||
{/if}
|
||||
|
||||
<!--End SellTrade Modal-->
|
||||
|
||||
|
||||
|
||||
<!--Start Type of Trade-->
|
||||
|
||||
<!--
|
||||
@ -839,77 +837,61 @@ $: isScrolled = y > 0;
|
||||
-->
|
||||
<!--End Type of Trade-->
|
||||
|
||||
|
||||
|
||||
|
||||
<!--Start Add Watchlist Modal-->
|
||||
<input type="checkbox" id="addWatchListModal" class="modal-toggle" />
|
||||
|
||||
<dialog id="addWatchListModal" class="modal modal-bottom sm:modal-middle">
|
||||
|
||||
|
||||
<label id="addWatchListModal" for="addWatchListModal" class="cursor-pointer modal-backdrop bg-[#09090B] bg-opacity-[0.5]"></label>
|
||||
|
||||
|
||||
<div class="modal-box w-full bg-[#09090B] sm:border sm:border-slate-800">
|
||||
|
||||
|
||||
|
||||
<label for="addWatchListModal" class="cursor-pointer absolute right-5 top-2 bg-[#09090B] text-[1.8rem] text-white">
|
||||
✕
|
||||
</label>
|
||||
<label for="addWatchListModal" class="cursor-pointer absolute right-5 top-2 bg-[#09090B] text-[1.8rem] text-white"> ✕ </label>
|
||||
|
||||
<div class="text-white">
|
||||
<h3 class="font-semibold text-lg sm:text-xl mb-10">
|
||||
Add to Watchlist
|
||||
</h3>
|
||||
<h3 class="font-semibold text-lg sm:text-xl mb-10">Add to Watchlist</h3>
|
||||
|
||||
<div class="flex flex-col items-center w-full max-w-3xl bg-[#09090B]">
|
||||
|
||||
{#each userWatchList as item}
|
||||
<label on:click|stopPropagation={() => toggleUserWatchlist(item?.id)} class="cursor-pointer w-full flex flex-row justify-start items-center mb-5">
|
||||
|
||||
<div class="flex flex-row items-center w-full bg-[#313131] p-3 rounded-lg {item?.ticker?.includes($stockTicker) ? 'ring-2 ring-[#04E000]' : ''}">
|
||||
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<span class="ml-1 text-white font-medium mr-auto">
|
||||
{item?.title}
|
||||
</span>
|
||||
<span class="ml-1 text-white text-opacity-40 text-sm font-medium mr-auto">
|
||||
{item?.ticker?.length} {item?.ticker?.length !==1 ? 'Companies' : 'Company'}
|
||||
{item?.ticker?.length}
|
||||
{item?.ticker?.length !== 1 ? "Companies" : "Company"}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="rounded-full w-8 h-8 relative border border-[#737373]">
|
||||
{#if item?.ticker?.includes($stockTicker)}
|
||||
<svg class="w-full h-full rounded-full" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#09090B000"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> <title>ic_fluent_checkmark_circle_48_filled</title> <desc>Created with Sketch.</desc> <g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> <g id="ic_fluent_checkmark_circle_48_filled" fill="#04E000" fill-rule="nonzero"> <path d="M24,4 C35.045695,4 44,12.954305 44,24 C44,35.045695 35.045695,44 24,44 C12.954305,44 4,35.045695 4,24 C4,12.954305 12.954305,4 24,4 Z M32.6338835,17.6161165 C32.1782718,17.1605048 31.4584514,17.1301307 30.9676119,17.5249942 L30.8661165,17.6161165 L20.75,27.732233 L17.1338835,24.1161165 C16.6457281,23.6279612 15.8542719,23.6279612 15.3661165,24.1161165 C14.9105048,24.5717282 14.8801307,25.2915486 15.2749942,25.7823881 L15.3661165,25.8838835 L19.8661165,30.3838835 C20.3217282,30.8394952 21.0415486,30.8698693 21.5323881,30.4750058 L21.6338835,30.3838835 L32.6338835,19.3838835 C33.1220388,18.8957281 33.1220388,18.1042719 32.6338835,17.6161165 Z" id="🎨-Color"> </path> </g> </g> </g></svg>
|
||||
<svg class="w-full h-full rounded-full" viewBox="0 0 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="#09090B000"
|
||||
><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier">
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> <title>ic_fluent_checkmark_circle_48_filled</title> <desc>Created with Sketch.</desc>
|
||||
<g id="🔍-Product-Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="ic_fluent_checkmark_circle_48_filled" fill="#04E000" fill-rule="nonzero">
|
||||
<path
|
||||
d="M24,4 C35.045695,4 44,12.954305 44,24 C44,35.045695 35.045695,44 24,44 C12.954305,44 4,35.045695 4,24 C4,12.954305 12.954305,4 24,4 Z M32.6338835,17.6161165 C32.1782718,17.1605048 31.4584514,17.1301307 30.9676119,17.5249942 L30.8661165,17.6161165 L20.75,27.732233 L17.1338835,24.1161165 C16.6457281,23.6279612 15.8542719,23.6279612 15.3661165,24.1161165 C14.9105048,24.5717282 14.8801307,25.2915486 15.2749942,25.7823881 L15.3661165,25.8838835 L19.8661165,30.3838835 C20.3217282,30.8394952 21.0415486,30.8698693 21.5323881,30.4750058 L21.6338835,30.3838835 L32.6338835,19.3838835 C33.1220388,18.8957281 33.1220388,18.1042719 32.6338835,17.6161165 Z"
|
||||
id="🎨-Color"
|
||||
>
|
||||
</path>
|
||||
</g>
|
||||
</g>
|
||||
</g></svg
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</label>
|
||||
{/each}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</dialog>
|
||||
|
||||
<!--End Add Watchlist Modal-->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style lang='scss'>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
.scrollbar {
|
||||
display: grid;
|
||||
grid-gap: 17px;
|
||||
@ -933,17 +915,16 @@ $: isScrolled = y > 0;
|
||||
::-webkit-scrollbar {
|
||||
height: 7px;
|
||||
width: 10px;
|
||||
background: #09090B;
|
||||
background: #09090b;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #6B6F79;
|
||||
background: #6b6f79;
|
||||
-webkit-border-radius: 1ex;
|
||||
-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background: #09090B;
|
||||
background: #09090b;
|
||||
}
|
||||
|
||||
</style>
|
||||
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,42 +1,36 @@
|
||||
<script lang='ts'>
|
||||
<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 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',
|
||||
"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';
|
||||
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 = {
|
||||
'market-cap': '/stats/market-cap',
|
||||
'employees': '/stats/employees',
|
||||
'income': '/stats/income',
|
||||
'balance-sheet': '/stats/balance-sheet',
|
||||
'cash-flow': '/stats/cash-flow',
|
||||
'ratios': '/stats/ratios',
|
||||
"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]) {
|
||||
if (state !== "overview" && subSectionMap[state]) {
|
||||
displaySubSection = state;
|
||||
//goto(`/stocks/${$stockTicker}${subSectionMap[state]}`);
|
||||
} else {
|
||||
@ -44,76 +38,93 @@ function changeSubSection(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
|
||||
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 === 'fundamental' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[4rem]" />
|
||||
<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/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
|
||||
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 === 'market-cap' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[3.5rem]" />
|
||||
<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/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]'}" >
|
||||
<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]'}" >
|
||||
<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
|
||||
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 === 'ratios' ? 'bg-[#75D377]' : 'bg-[#09090B]'} mt-1 h-[3px] rounded-full w-[2rem]" />
|
||||
<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 {
|
||||
display: grid;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user