ui fixes
This commit is contained in:
parent
da288f62e4
commit
3c2d7f3747
@ -17,7 +17,7 @@
|
||||
<main class="overflow-hidden">
|
||||
<div class="w-full">
|
||||
<div
|
||||
class="flex flex-col items-center w-auto p-4 sm:p-4 bg-[#09090B] sm:bg-[#09090B] rounded-lg relative"
|
||||
class="flex flex-col items-center w-auto p-4 sm:p-4 bg-[#09090B] sm:bg-[#09090B] rounded-md relative"
|
||||
>
|
||||
<div class="relative">
|
||||
<h3 class="text-center text-white text-sm sm:text-[1rem] mb-2">
|
||||
|
||||
@ -98,7 +98,7 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="text-white text-sm border bg-[#313131] border-gray-800 p-3 rounded-lg overflow-y-scroll h-56"
|
||||
class="text-white text-sm border bg-[#313131] border-gray-800 p-3 rounded-md overflow-y-scroll h-56"
|
||||
>
|
||||
<ol class="text-white list-decimal ml-3 p-2">
|
||||
<li class="p-1">
|
||||
@ -244,7 +244,7 @@
|
||||
>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn bg-[#fff] sm:hover:bg-gray-300 btn-md w-full rounded-lg m-auto text-white font-bold text-md"
|
||||
class="btn bg-[#fff] sm:hover:bg-gray-300 btn-md w-full rounded-md m-auto text-white font-bold text-md"
|
||||
>
|
||||
Create Portfolio
|
||||
</button>
|
||||
@ -252,7 +252,7 @@
|
||||
{:else}
|
||||
<div class="w-full max-w-lg pt-5 m-auto pb-8">
|
||||
<label
|
||||
class="opacity-[0.4] cursor-not-allowed btn bg-[#fff] btn-md w-full rounded-lg m-auto text-white font-bold text-md"
|
||||
class="opacity-[0.4] cursor-not-allowed btn bg-[#fff] btn-md w-full rounded-md m-auto text-white font-bold text-md"
|
||||
>
|
||||
{#if !isClicked}
|
||||
Create Portfolio
|
||||
@ -290,7 +290,7 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="text-white text-sm border bg-[#09090B] border-gray-800 p-3 rounded-lg overflow-y-scroll h-56"
|
||||
class="text-white text-sm border bg-[#09090B] border-gray-800 p-3 rounded-md overflow-y-scroll h-56"
|
||||
>
|
||||
<ol class="text-white list-decimal ml-3 p-2">
|
||||
<li class="p-1">
|
||||
@ -436,7 +436,7 @@
|
||||
>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn bg-[#fff] sm:hover:bg-gray-300 btn-md w-full rounded-lg m-auto text-white font-bold text-md"
|
||||
class="btn bg-[#fff] sm:hover:bg-gray-300 btn-md w-full rounded-md m-auto text-white font-bold text-md"
|
||||
>
|
||||
Create Portfolio
|
||||
</button>
|
||||
@ -444,7 +444,7 @@
|
||||
{:else}
|
||||
<div class="w-full max-w-lg m-auto pb-8 mt-10">
|
||||
<label
|
||||
class="opacity-[0.4] cursor-not-allowed btn bg-[#fff] btn-md w-full rounded-lg m-auto text-white font-bold text-md"
|
||||
class="opacity-[0.4] cursor-not-allowed btn bg-[#fff] btn-md w-full rounded-md m-auto text-white font-bold text-md"
|
||||
>
|
||||
{#if !isClicked}
|
||||
Create Portfolio
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
: 'hidden'}"
|
||||
>
|
||||
<div
|
||||
class="sm:rounded-lg shadow-lg bg-[#000] sm:bg-[#09090B] sm:border sm:border-slate-800 h-auto {$screenWidth <
|
||||
class="sm:rounded-md 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"
|
||||
|
||||
@ -504,7 +504,7 @@
|
||||
* This value depends on the forecast
|
||||
</div>
|
||||
<!--
|
||||
<div class="mt-5 text-gray-100 text-sm sm:text-[1rem] sm:rounded-lg h-auto border border-slate-800 p-4">
|
||||
<div class="mt-5 text-gray-100 text-sm sm:text-[1rem] sm:rounded-md h-auto border border-slate-800 p-4">
|
||||
<svg class="w-5 h-5 inline-block mr-0.5 flex-shrink-0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"
|
||||
><path fill="#fff" d="M128 24a104 104 0 1 0 104 104A104.11 104.11 0 0 0 128 24m-4 48a12 12 0 1 1-12 12a12 12 0 0 1 12-12m12 112a16 16 0 0 1-16-16v-40a8 8 0 0 1 0-16a16 16 0 0 1 16 16v40a8 8 0 0 1 0 16" /></svg
|
||||
>
|
||||
|
||||
@ -72,7 +72,7 @@
|
||||
<!--Start Item-->
|
||||
<div class="flex flex-row items-center w-full mb-6">
|
||||
<div
|
||||
class="w-full rounded-lg {latestInfoDate(
|
||||
class="w-full rounded-md {latestInfoDate(
|
||||
data?.getAnalystInsight?.date,
|
||||
)
|
||||
? 'bg-[#F9AB00] bg-opacity-[0.1]'
|
||||
@ -85,7 +85,7 @@
|
||||
>
|
||||
{#if latestInfoDate(data?.getAnalystInsight?.date)}
|
||||
<label
|
||||
class="bg-[#2D4F8A] text-white font-medium text-xs rounded-lg px-2 py-0.5 ml-3"
|
||||
class="bg-[#2D4F8A] text-white font-medium text-xs rounded-md px-2 py-0.5 ml-3"
|
||||
>New</label
|
||||
>
|
||||
{/if}
|
||||
|
||||
@ -1,340 +1,147 @@
|
||||
<script lang ='ts'>
|
||||
import { borrowedShareComponent, displayCompanyName, stockTicker, assetType, etfTicker, screenWidth, getCache, setCache} from '$lib/store';
|
||||
import InfoModal from '$lib/components/InfoModal.svelte';
|
||||
import { Chart } from 'svelte-echarts'
|
||||
import { abbreviateNumber, formatDateRange, monthNames } from "$lib/utils";
|
||||
<script lang 'ts'></script>
|
||||
|
||||
import { init, use } from 'echarts/core'
|
||||
import { LineChart } from 'echarts/charts'
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
|
||||
export let data;
|
||||
|
||||
use([LineChart, GridComponent, TooltipComponent, CanvasRenderer])
|
||||
<section class="overflow-hidden text-white h-full pb-8">
|
||||
<main class="overflow-hidden">
|
||||
<div class="flex flex-row items-center">
|
||||
<label
|
||||
for="borrowedShareInfo"
|
||||
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
|
||||
>
|
||||
Borrowed Share
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Borrowed Share Statistics"}
|
||||
content={"At Interactive Brokers, borrowed shares refer to shares lent by other investors for short selling. Borrowers pay a fee to lenders, aiming to profit from declining stock prices. Lenders earn interest on their lent shares, enhancing returns while still owning the stock."}
|
||||
id={"borrowedShareInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
let isLoaded = false;
|
||||
|
||||
let rawData = [];
|
||||
let optionsData;
|
||||
let avgFee;
|
||||
let lowestFee;
|
||||
let highestFee;
|
||||
let monthlyAvailableShares;
|
||||
let totalAvailableShares;
|
||||
|
||||
|
||||
function findLowestAndHighestFee(data, lastDateStr) {
|
||||
// Convert lastDateStr to Date object
|
||||
const lastDate = new Date(lastDateStr);
|
||||
|
||||
// Set the first date to the beginning of the month of lastDate
|
||||
const firstDate = new Date(lastDate.getFullYear(), lastDate.getMonth(), 1);
|
||||
|
||||
// Filter data to include only prices within the specified month period
|
||||
const filteredData = data.filter(item => {
|
||||
const currentDate = new Date(item?.date);
|
||||
return currentDate >= firstDate && currentDate <= lastDate;
|
||||
});
|
||||
|
||||
// Extract prices from filtered data
|
||||
let fees = filteredData?.map(item => parseFloat(item?.fee));
|
||||
monthlyAvailableShares = filteredData?.reduce((accumulator, currentItem) => {
|
||||
return accumulator + currentItem?.available;
|
||||
}, 0);
|
||||
|
||||
// Find the lowest and highest prices
|
||||
lowestFee = Math.min(...fees)?.toFixed(1);
|
||||
highestFee = Math.max(...fees)?.toFixed(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getPlotOptions() {
|
||||
let dates = [];
|
||||
let availableList = [];
|
||||
let feeList = [];
|
||||
// Iterate over the data and extract required information
|
||||
rawData?.forEach(item => {
|
||||
|
||||
dates?.push(item?.date);
|
||||
availableList?.push(item?.available);
|
||||
feeList?.push(item?.fee)
|
||||
});
|
||||
|
||||
// Find the lowest and highest prices
|
||||
findLowestAndHighestFee(rawData, rawData?.slice(-1)?.at(0)?.date)
|
||||
|
||||
// Compute the average of item?.traded
|
||||
const totalNumber = feeList?.reduce((acc, item) => acc + item, 0);
|
||||
avgFee = (totalNumber / feeList?.length)?.toFixed(1);
|
||||
totalAvailableShares = availableList?.reduce((accumulator, sum) => {
|
||||
return accumulator + sum;
|
||||
}, 0);
|
||||
|
||||
|
||||
const option = {
|
||||
silent: true,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
hideDelay: 100, // Set the delay in milliseconds
|
||||
},
|
||||
animation: false,
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '3%',
|
||||
bottom: '2%',
|
||||
top: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: dates,
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
formatter: function (value) {
|
||||
// Assuming dates are in the format 'yyyy-mm-dd'
|
||||
// Extract the month and day from the date string and convert the month to its abbreviated name
|
||||
const dateParts = value.split('-');
|
||||
const day = dateParts[2].substring(0); // Extracting the last two digits of the year
|
||||
const monthIndex = parseInt(dateParts[1]) - 1; // Months are zero-indexed in JavaScript Date objects
|
||||
return `${day} ${monthNames[monthIndex]}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
axisLabel: {
|
||||
show: false // Hide y-axis labels
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
position: 'right',
|
||||
axisLabel: {
|
||||
show: false // Hide y-axis labels
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Available Shares',
|
||||
data: availableList,
|
||||
type: 'line',
|
||||
itemStyle: {
|
||||
color: '#fff' // Change bar color to white
|
||||
},
|
||||
showSymbol: false
|
||||
},
|
||||
{
|
||||
name: 'Fee [%]',
|
||||
data: feeList,
|
||||
type: 'line',
|
||||
areaStyle: {opacity: 1},
|
||||
yAxisIndex: 1,
|
||||
itemStyle: {
|
||||
color: '#22C55E' // Change bar color to white
|
||||
},
|
||||
showSymbol: false
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
const getBorrowedShare = async (ticker) => {
|
||||
// Get cached data for the specific tickerID
|
||||
const cachedData = getCache(ticker, 'getBorrowedShare');
|
||||
if (cachedData) {
|
||||
rawData = cachedData;
|
||||
} else {
|
||||
|
||||
const postData = {'ticker': ticker, path: 'borrowed-share'};
|
||||
// make the POST request to the endpoint
|
||||
const response = await fetch('/api/ticker-data', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
rawData = (await response.json())?.slice(-100);
|
||||
// Cache the data for this specific tickerID with a specific name 'getBorrowedShare'
|
||||
setCache(ticker, rawData, 'getBorrowedShare');
|
||||
}
|
||||
|
||||
if(rawData?.length !== 0) {
|
||||
$borrowedShareComponent = true;
|
||||
} else {
|
||||
$borrowedShareComponent = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$: {
|
||||
if($assetType === 'stock' ? $stockTicker :$etfTicker && typeof window !== 'undefined') {
|
||||
isLoaded=false;
|
||||
const ticker = $assetType === 'stock' ? $stockTicker :$etfTicker
|
||||
const asyncFunctions = [
|
||||
getBorrowedShare(ticker)
|
||||
];
|
||||
Promise.all(asyncFunctions)
|
||||
.then((results) => {
|
||||
optionsData = getPlotOptions()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('An error occurred:', error);
|
||||
});
|
||||
isLoaded = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$: charNumber = $screenWidth < 640 ? 20 : 40;
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<section class="overflow-hidden text-white h-full pb-8">
|
||||
<main class="overflow-hidden ">
|
||||
|
||||
<div class="flex flex-row items-center">
|
||||
<label for="borrowedShareInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
|
||||
Borrowed Share
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Borrowed Share Statistics"}
|
||||
content={"At Interactive Brokers, borrowed shares refer to shares lent by other investors for short selling. Borrowers pay a fee to lenders, aiming to profit from declining stock prices. Lenders earn interest on their lent shares, enhancing returns while still owning the stock."}
|
||||
id={"borrowedShareInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if isLoaded}
|
||||
|
||||
{#if rawData?.length !== 0}
|
||||
|
||||
{#if isLoaded}
|
||||
{#if rawData?.length !== 0}
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
|
||||
Over the past six months, Interactive Brokers had {abbreviateNumber(totalAvailableShares)} shares available for borrowing, with an average fee of {avgFee}%.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pb-2 rounded-lg bg-[#09090B]">
|
||||
|
||||
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
|
||||
Over the past six months, Interactive Brokers had {abbreviateNumber(
|
||||
totalAvailableShares,
|
||||
)} shares available for borrowing, with an average fee of {avgFee}%.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12">
|
||||
<div class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block">
|
||||
Available Shares
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#22C55E] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block">
|
||||
Fee
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<h2 class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3">
|
||||
Latest Information
|
||||
</h2>
|
||||
|
||||
|
||||
<div class="flex justify-start items-center w-full m-auto ">
|
||||
<table class="w-full" data-test="statistics-table">
|
||||
<tbody>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Date</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right whitespace-nowrap font-medium xs:px-2.5 xs:py-2">
|
||||
{formatDateRange(rawData?.slice(-1)?.at(0)?.date)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Fee Range</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2">
|
||||
{lowestFee+'%'+'-'+highestFee+'%'}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Total Available Shares</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2">
|
||||
{abbreviateNumber(monthlyAvailableShares)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
{/if}
|
||||
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
|
||||
<span class="loading loading-spinner loading-md text-gray-400"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
|
||||
</main>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
<div class="pb-2 rounded-md bg-[#09090B]">
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12"
|
||||
>
|
||||
<div
|
||||
class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block"
|
||||
>
|
||||
Available Shares
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#22C55E] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block"
|
||||
>
|
||||
Fee
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2
|
||||
class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3"
|
||||
>
|
||||
Latest Information
|
||||
</h2>
|
||||
|
||||
<div class="flex justify-start items-center w-full m-auto">
|
||||
<table class="w-full" data-test="statistics-table">
|
||||
<tbody>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Date</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right whitespace-nowrap font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{formatDateRange(rawData?.slice(-1)?.at(0)?.date)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Fee Range</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{lowestFee + "%" + "-" + highestFee + "%"}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Total Available Shares</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{abbreviateNumber(monthlyAvailableShares)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label
|
||||
class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||
>
|
||||
<span class="loading loading-spinner loading-md text-gray-400"
|
||||
></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 210px;
|
||||
.app {
|
||||
height: 210px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -1,254 +1,46 @@
|
||||
<script lang ='ts'>
|
||||
import { clinicalTrialComponent, displayCompanyName, stockTicker, assetType, etfTicker, screenWidth, getCache, setCache} from '$lib/store';
|
||||
import InfoModal from '$lib/components/InfoModal.svelte';
|
||||
import { Chart } from 'svelte-echarts'
|
||||
import { abbreviateNumber, formatString } from "$lib/utils";
|
||||
import { init, use } from 'echarts/core'
|
||||
import { BarChart } from 'echarts/charts'
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
use([BarChart, GridComponent, TooltipComponent, CanvasRenderer])
|
||||
<script lang 'ts'></script>
|
||||
|
||||
export let data;
|
||||
|
||||
let isLoaded = false;
|
||||
|
||||
|
||||
let rawData = [];
|
||||
let displayList = []
|
||||
let trialId;
|
||||
let trialTitle;
|
||||
let trialStart;
|
||||
let trialEnd;
|
||||
let trialSummary;
|
||||
let trialSex;
|
||||
let trialAge;
|
||||
let trialStage;
|
||||
let trialPhase;
|
||||
let trialStudyType;
|
||||
let trialEnrollment;
|
||||
let trialSponsor;
|
||||
let trialResult;
|
||||
let trialLink;
|
||||
let trialFunderType;
|
||||
|
||||
let numOfActive;
|
||||
let numOfTerminated;
|
||||
let numOfCompleted;
|
||||
let numOfResults;
|
||||
|
||||
let optionsData;
|
||||
|
||||
function handleViewData(trialData) {
|
||||
trialId = trialData['NCT Number']
|
||||
trialStart = trialData['Start Date'] === null ? 'n/a' : new Date(trialData['Start Date'])?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' });
|
||||
trialEnd = trialData['Completion Date'] === null ? 'n/a' : new Date(trialData['Completion Date'])?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' });
|
||||
trialTitle = trialData["Study Title"];
|
||||
trialSummary = trialData['Brief Summary'];
|
||||
trialAge = trialData['Age'];
|
||||
trialSex = trialData['Sex'];
|
||||
trialStage = formatString(trialData['Study Status']);
|
||||
trialPhase = trialData['Phases'] !== 'NA' ? formatString(trialData["Phases"])?.replace('Phase','') : '-';
|
||||
trialStudyType = formatString(trialData['Study Type']);
|
||||
trialFunderType = formatString(trialData['Funder Type']);
|
||||
trialEnrollment = abbreviateNumber(trialData['Enrollment']);
|
||||
trialSponsor = trialData['Sponsor'];
|
||||
trialResult = formatString(trialData['Study Results'])
|
||||
trialLink = trialData['Study URL']
|
||||
|
||||
const openPopup = $screenWidth < 1024 ? document.getElementById("clinicalMobileModal") : document.getElementById("clinicalDesktopModal");
|
||||
openPopup?.dispatchEvent(new MouseEvent('click'))
|
||||
|
||||
}
|
||||
|
||||
function getPlotOptions() {
|
||||
let dates = [];
|
||||
let valueList = [];
|
||||
let fiscalYearCount = {};
|
||||
|
||||
|
||||
// Sort rawData by 'Start Date'
|
||||
rawData?.sort((a, b) => new Date(a['Start Date']) - new Date(b['Start Date']));
|
||||
|
||||
rawData?.forEach(item => {
|
||||
// Extract year from 'Start Date'
|
||||
const startDate = new Date(item['Start Date']);
|
||||
const year = startDate?.getFullYear();
|
||||
|
||||
// Check if the year is valid and at least 2000
|
||||
if (year && year >= 2000) {
|
||||
// Convert it to fiscal year format
|
||||
const fiscalYear = "FY" + String(year).slice(2);
|
||||
|
||||
// Ensure dates list is unique
|
||||
if (!dates.includes(fiscalYear)) {
|
||||
dates.push(fiscalYear);
|
||||
}
|
||||
|
||||
// Count the occurrences of each fiscal year
|
||||
fiscalYearCount[fiscalYear] = (fiscalYearCount[fiscalYear] || 0) + 1;
|
||||
}
|
||||
});
|
||||
|
||||
// Update valueList with the count of each fiscal year
|
||||
valueList = dates?.map(fiscalYear => fiscalYearCount[fiscalYear]);
|
||||
|
||||
const option = {
|
||||
silent: true,
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
hideDelay: 100, // Set the delay in milliseconds
|
||||
},
|
||||
grid: {
|
||||
left: $screenWidth < 640 ? '0%' : '2%',
|
||||
right: $screenWidth < 640 ? '2%' : '2%',
|
||||
bottom: $screenWidth < 640 ? '0%' : '2%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
data: dates,
|
||||
type: 'category',
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
axisLabel: {
|
||||
show: false // Hide y-axis labels
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '# of Trials',
|
||||
data: valueList,
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: '#F8901E' // Change bar color to white
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
const getClinicalTrial = async (ticker) => {
|
||||
// Get cached data for the specific tickerID
|
||||
const cachedData = getCache(ticker, 'getClinicalTrial');
|
||||
if (cachedData) {
|
||||
rawData = cachedData;
|
||||
displayList = cachedData;
|
||||
} else {
|
||||
|
||||
const postData = {'ticker': ticker, path: 'clinical-trial'};
|
||||
// make the POST request to the endpoint
|
||||
const response = await fetch('/api/ticker-data', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
rawData = await response?.json();
|
||||
displayList = rawData;
|
||||
// Cache the data for this specific tickerID with a specific name 'getClinicalTrial'
|
||||
setCache(ticker, rawData, 'getClinicalTrial');
|
||||
}
|
||||
if(rawData?.length >= 5) {
|
||||
$clinicalTrialComponent = true;
|
||||
} else {
|
||||
$clinicalTrialComponent = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$: {
|
||||
if($assetType === 'stock' ? $stockTicker :$etfTicker && typeof window !== 'undefined') {
|
||||
isLoaded=false;
|
||||
const ticker = $assetType === 'stock' ? $stockTicker :$etfTicker
|
||||
const asyncFunctions = [
|
||||
getClinicalTrial(ticker)
|
||||
];
|
||||
Promise.all(asyncFunctions)
|
||||
.then((results) => {
|
||||
numOfActive = rawData?.filter(item => item['Study Status'] === 'Active')?.length;
|
||||
numOfCompleted = rawData?.filter(item => item['Study Status'] === 'COMPLETED')?.length;
|
||||
numOfTerminated = rawData?.filter(item => item['Study Status'] === 'TERMINATED')?.length;
|
||||
numOfResults = rawData?.filter(item => item['Study Results'] === 'YES')?.length;
|
||||
|
||||
optionsData = getPlotOptions()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('An error occurred:', error);
|
||||
});
|
||||
isLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
let charNumber = 20;
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<section class="overflow-hidden text-white h-full pb-8">
|
||||
<main class="overflow-hidden ">
|
||||
|
||||
<div class="flex flex-row items-center">
|
||||
<label for="clinicalTrialInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
|
||||
Clinical Trials
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Clinical Trial"}
|
||||
content={"Info description coming soon! But first a word of our sponsor skillshare... just kidding"}
|
||||
id={"clinicalTrialInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if data?.user?.tier === 'Pro'}
|
||||
{#if isLoaded}
|
||||
<main class="overflow-hidden">
|
||||
<div class="flex flex-row items-center">
|
||||
<label
|
||||
for="clinicalTrialInfo"
|
||||
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
|
||||
>
|
||||
Clinical Trials
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Clinical Trial"}
|
||||
content={"Info description coming soon! But first a word of our sponsor skillshare... just kidding"}
|
||||
id={"clinicalTrialInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if data?.user?.tier === "Pro"}
|
||||
{#if isLoaded}
|
||||
{#if rawData?.length >= 5}
|
||||
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-sm sm:text-[1rem] mt-2 mb-2 w-full">
|
||||
The Biotech company {$displayCompanyName} has conducted a total of {abbreviateNumber(rawData?.length)} clinical trials.
|
||||
Out of these, {numOfActive === 0 ? 'none' : numOfActive} are currently active,
|
||||
{numOfCompleted} have been completed, {numOfTerminated} were terminated and {numOfResults} trials have produced results.
|
||||
|
||||
The Biotech company {$displayCompanyName} has conducted a total of
|
||||
{abbreviateNumber(rawData?.length)} clinical trials. Out of these,
|
||||
{numOfActive === 0 ? "none" : numOfActive} are currently active,
|
||||
{numOfCompleted} have been completed, {numOfTerminated} were terminated
|
||||
and {numOfResults} trials have produced results.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="pb-2 rounded-lg bg-[#09090B]">
|
||||
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="pb-2 rounded-md bg-[#09090B]">
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!--
|
||||
<!--
|
||||
<h2 class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3">
|
||||
Latest Information
|
||||
</h2>
|
||||
|
||||
<div class="rounded-lg sm:min-h-[330px]">
|
||||
<div class="rounded-md sm:min-h-[330px]">
|
||||
<div class="w-full m-auto h-auto max-h-[500px] overflow-x-scroll sm:overflow-hidden sm:overflow-y-scroll scroller ">
|
||||
<table class="table table-sm table-compact table-pin-rows table-pin-cols w-full">
|
||||
<thead>
|
||||
@ -290,45 +82,60 @@ let charNumber = 20;
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
|
||||
|
||||
{/if}
|
||||
|
||||
{:else}
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
|
||||
<span class="loading loading-spinner loading-md text-gray-400"></span>
|
||||
<div class="relative">
|
||||
<label
|
||||
class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||
>
|
||||
<span class="loading loading-spinner loading-md text-gray-400"
|
||||
></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{:else}
|
||||
<div class="shadow-lg shadow-bg-[#000] bg-[#111112] sm:bg-opacity-[0.5] text-sm sm:text-[1rem] rounded-md w-full p-4 min-h-24 mt-4 text-white m-auto flex justify-center items-center text-center font-semibold">
|
||||
<svg class="mr-1.5 w-5 h-5 inline-block"xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#A3A3A3" d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"/></svg>
|
||||
Unlock content with <a class="inline-block ml-2 text-blue-400 hover:sm:text-white" href="/pricing">Pro Subscription</a>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</main>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div
|
||||
class="shadow-lg shadow-bg-[#000] bg-[#111112] sm:bg-opacity-[0.5] text-sm sm:text-[1rem] rounded-md w-full p-4 min-h-24 mt-4 text-white m-auto flex justify-center items-center text-center font-semibold"
|
||||
>
|
||||
<svg
|
||||
class="mr-1.5 w-5 h-5 inline-block"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
><path
|
||||
fill="#A3A3A3"
|
||||
d="M17 9V7c0-2.8-2.2-5-5-5S7 4.2 7 7v2c-1.7 0-3 1.3-3 3v7c0 1.7 1.3 3 3 3h10c1.7 0 3-1.3 3-3v-7c0-1.7-1.3-3-3-3M9 7c0-1.7 1.3-3 3-3s3 1.3 3 3v2H9z"
|
||||
/></svg
|
||||
>
|
||||
Unlock content with
|
||||
<a
|
||||
class="inline-block ml-2 text-blue-400 hover:sm:text-white"
|
||||
href="/pricing">Pro Subscription</a
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Put this part before </body> tag -->
|
||||
<input type="checkbox" id="clinicalDesktopModal" class="modal-toggle" />
|
||||
|
||||
<label for="clinicalDesktopModal" class="hidden lg:modal modal-bottom sm:modal-middle cursor-pointer">
|
||||
|
||||
<label for="clinicalDesktopModal" class="cursor-pointer modal-backdrop"></label>
|
||||
|
||||
|
||||
<label
|
||||
for="clinicalDesktopModal"
|
||||
class="hidden lg:modal modal-bottom sm:modal-middle cursor-pointer"
|
||||
>
|
||||
<label for="clinicalDesktopModal" class="cursor-pointer modal-backdrop"
|
||||
></label>
|
||||
|
||||
<!-- svelte-ignore a11y-label-has-associated-control -->
|
||||
<label class="modal-box w-full relative bg-[#27272A] h-auto max-h-[900px] overflow-y-scroll">
|
||||
<label for="clinicalDesktopModal" class="cursor-pointer absolute right-5 top-2 bg-[#27272A] text-2xl text-white">
|
||||
<label
|
||||
class="modal-box w-full relative bg-[#27272A] h-auto max-h-[900px] overflow-y-scroll"
|
||||
>
|
||||
<label
|
||||
for="clinicalDesktopModal"
|
||||
class="cursor-pointer absolute right-5 top-2 bg-[#27272A] text-2xl text-white"
|
||||
>
|
||||
✕
|
||||
</label>
|
||||
|
||||
@ -338,182 +145,222 @@ let charNumber = 20;
|
||||
<p class="py-4 text-gray-200 bg-[#27272A] w-full">
|
||||
<span class="font-semibold text-white">Brief Summary:</span>
|
||||
{trialSummary}
|
||||
|
||||
</p>
|
||||
|
||||
<table class="table table-sm table-compact bg-[#27272A] w-full mt-5 mb-10 text-white">
|
||||
<table
|
||||
class="table table-sm table-compact bg-[#27272A] w-full mt-5 mb-10 text-white"
|
||||
>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">NCT Number</td>
|
||||
<td class="bg-[#27272A] ">{trialId}</td>
|
||||
<td class="bg-[#27272A] font-semibold">NCT Number</td>
|
||||
<td class="bg-[#27272A]">{trialId}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Start Date</td>
|
||||
<td class="bg-[#27272A] ">{trialStart}</td>
|
||||
<td class="bg-[#27272A] font-semibold">Start Date</td>
|
||||
<td class="bg-[#27272A]">{trialStart}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">End Date</td>
|
||||
<td class="bg-[#27272A] ">{trialEnd}</td>
|
||||
<td class="bg-[#27272A] font-semibold">End Date</td>
|
||||
<td class="bg-[#27272A]">{trialEnd}</td>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Study Status</td>
|
||||
<td class="bg-[#27272A] ">{trialStage}</td>
|
||||
<td class="bg-[#27272A] font-semibold">Study Status</td>
|
||||
<td class="bg-[#27272A]">{trialStage}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Phase Status</td>
|
||||
<td class="bg-[#27272A] ">{trialPhase}</td>
|
||||
<td class="bg-[#27272A] font-semibold">Phase Status</td>
|
||||
<td class="bg-[#27272A]">{trialPhase}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Study Results</td>
|
||||
<td class="bg-[#27272A] ">{trialResult}</td>
|
||||
<td class="bg-[#27272A] font-semibold">Study Results</td>
|
||||
<td class="bg-[#27272A]">{trialResult}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Sex</td>
|
||||
<td class="bg-[#27272A] ">{formatString(trialSex)}</td>
|
||||
<td class="bg-[#27272A] font-semibold">Sex</td>
|
||||
<td class="bg-[#27272A]">{formatString(trialSex)}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Age</td>
|
||||
<td class="bg-[#27272A] ">{formatString(trialAge)?.replace('Older_adult', 'Older Adult')}</td>
|
||||
<td class="bg-[#27272A] font-semibold">Age</td>
|
||||
<td class="bg-[#27272A]"
|
||||
>{formatString(trialAge)?.replace("Older_adult", "Older Adult")}</td
|
||||
>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Sponsor</td>
|
||||
<td class="bg-[#27272A] ">{trialSponsor}</td>
|
||||
<td class="bg-[#27272A] font-semibold">Sponsor</td>
|
||||
<td class="bg-[#27272A]">{trialSponsor}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Enrollment</td>
|
||||
<td class="bg-[#27272A] ">{trialEnrollment}</td>
|
||||
<td class="bg-[#27272A] font-semibold">Enrollment</td>
|
||||
<td class="bg-[#27272A]">{trialEnrollment}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Study Type</td>
|
||||
<td class="bg-[#27272A] ">{trialStudyType}</td>
|
||||
<td class="bg-[#27272A] font-semibold">Study Type</td>
|
||||
<td class="bg-[#27272A]">{trialStudyType}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Funder Type</td>
|
||||
<td class="bg-[#27272A] ">{trialFunderType}</td>
|
||||
<td class="bg-[#27272A] font-semibold">Funder Type</td>
|
||||
<td class="bg-[#27272A]">{trialFunderType}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700">
|
||||
<td class="bg-[#27272A] font-semibold ">Website</td>
|
||||
<td class="bg-[#27272A] "><a class="text-blue-400 sm:hover:text-white" href={trialLink} rel="noopener noreferrer" target="_blank">{trialLink}</a></td>
|
||||
<td class="bg-[#27272A] font-semibold">Website</td>
|
||||
<td class="bg-[#27272A]"
|
||||
><a
|
||||
class="text-blue-400 sm:hover:text-white"
|
||||
href={trialLink}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank">{trialLink}</a
|
||||
></td
|
||||
>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</label>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!--Start ETF Modal-->
|
||||
<div class="lg:hidden drawer drawer-end z-40 overflow-hidden w-screen">
|
||||
<input id="clinicalMobileModal" type="checkbox" class="drawer-toggle"/>
|
||||
<input id="clinicalMobileModal" type="checkbox" class="drawer-toggle" />
|
||||
<div class="drawer-side overflow-hidden">
|
||||
|
||||
|
||||
<div class="bg-[#09090B] min-h-screen w-screen pb-20 overflow-hidden">
|
||||
<label for="clinicalMobileModal" class="absolute left-6 top-6">
|
||||
<svg
|
||||
class="w-6 h-6 inline-block mb-0.5"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
><path
|
||||
fill="#fff"
|
||||
d="M9.125 21.1L.7 12.7q-.15-.15-.213-.325T.425 12q0-.2.063-.375T.7 11.3l8.425-8.425q.35-.35.875-.35t.9.375q.375.375.375.875t-.375.875L3.55 12l7.35 7.35q.35.35.35.863t-.375.887q-.375.375-.875.375t-.875-.375Z"
|
||||
/></svg
|
||||
>
|
||||
</label>
|
||||
|
||||
<label for="clinicalMobileModal" class="absolute left-6 top-6">
|
||||
<svg class="w-6 h-6 inline-block mb-0.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#fff" d="M9.125 21.1L.7 12.7q-.15-.15-.213-.325T.425 12q0-.2.063-.375T.7 11.3l8.425-8.425q.35-.35.875-.35t.9.375q.375.375.375.875t-.375.875L3.55 12l7.35 7.35q.35.35.35.863t-.375.887q-.375.375-.875.375t-.875-.375Z"/></svg>
|
||||
</label>
|
||||
<div class="w-full overflow-hidden overflow-y-scroll p-2">
|
||||
<h3 class="text-xl font-semibold text-white mt-14 p-3">
|
||||
Title: {trialTitle}
|
||||
</h3>
|
||||
<p class="py-4 text-gray-200 w-full p-3">
|
||||
<span class="font-semibold text-white">Brief Summary:</span>
|
||||
{trialSummary}
|
||||
</p>
|
||||
|
||||
|
||||
<div class="w-full overflow-hidden overflow-y-scroll p-2">
|
||||
|
||||
<h3 class="text-xl font-semibold text-white mt-14 p-3">
|
||||
Title: {trialTitle}
|
||||
</h3>
|
||||
<p class="py-4 text-gray-200 w-full p-3">
|
||||
<span class="font-semibold text-white">Brief Summary:</span>
|
||||
{trialSummary}
|
||||
</p>
|
||||
|
||||
<table class="table table-sm table-compact w-full mt-5 mb-10 text-white">
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A]">
|
||||
<td class="font-semibold w-full">NCT Number</td>
|
||||
<td class="">{trialId}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Start Date</td>
|
||||
<td class="">{trialStart}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">End Date</td>
|
||||
<td class="">{trialEnd}</td>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Study Status</td>
|
||||
<td class="">{trialStage}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Phase Status</td>
|
||||
<td class="">{trialPhase}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Study Results</td>
|
||||
<td class="">{trialResult}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Sex</td>
|
||||
<td class="">{formatString(trialSex)}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Age</td>
|
||||
<td class="">{formatString(trialAge)?.replace('Older_adult', 'Older Adult')}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Sponsor</td>
|
||||
<td class="">{trialSponsor}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Enrollment</td>
|
||||
<td class="">{trialEnrollment}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Study Type</td>
|
||||
<td class="">{trialStudyType}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Funder Type</td>
|
||||
<td class="">{trialFunderType}</td>
|
||||
</tr>
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]">
|
||||
<td class="font-semibold ">Website</td>
|
||||
<td class=""><a class="text-blue-400 sm:hover:text-white" href={trialLink} rel="noopener noreferrer" target="_blank">{trialLink}</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
<table
|
||||
class="table table-sm table-compact w-full mt-5 mb-10 text-white"
|
||||
>
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr class="border-b border-slate-700 odd:bg-[#27272A]">
|
||||
<td class="font-semibold w-full">NCT Number</td>
|
||||
<td class="">{trialId}</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Start Date</td>
|
||||
<td class="">{trialStart}</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">End Date</td>
|
||||
<td class="">{trialEnd}</td>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Study Status</td>
|
||||
<td class="">{trialStage}</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Phase Status</td>
|
||||
<td class="">{trialPhase}</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Study Results</td>
|
||||
<td class="">{trialResult}</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Sex</td>
|
||||
<td class="">{formatString(trialSex)}</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Age</td>
|
||||
<td class=""
|
||||
>{formatString(trialAge)?.replace(
|
||||
"Older_adult",
|
||||
"Older Adult",
|
||||
)}</td
|
||||
>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Sponsor</td>
|
||||
<td class="">{trialSponsor}</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Enrollment</td>
|
||||
<td class="">{trialEnrollment}</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Study Type</td>
|
||||
<td class="">{trialStudyType}</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Funder Type</td>
|
||||
<td class="">{trialFunderType}</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-b border-slate-700 odd:bg-[#27272A] even:bg-[#09090B]"
|
||||
>
|
||||
<td class="font-semibold">Website</td>
|
||||
<td class=""
|
||||
><a
|
||||
class="text-blue-400 sm:hover:text-white"
|
||||
href={trialLink}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank">{trialLink}</a
|
||||
></td
|
||||
>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End ETF Modal-->
|
||||
<!--End ETF Modal-->
|
||||
|
||||
<style>
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
}
|
||||
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
.chart {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,44 +1,69 @@
|
||||
<script lang='ts'>
|
||||
import { showCookieConsent } from "$lib/store";
|
||||
<script lang="ts">
|
||||
import { showCookieConsent } from "$lib/store";
|
||||
|
||||
async function cookieConsent(state:string) {
|
||||
async function cookieConsent(state: string) {
|
||||
const postData = {
|
||||
'consent': state
|
||||
}
|
||||
consent: state,
|
||||
};
|
||||
|
||||
const response = await fetch('/api/cookies', {
|
||||
method: 'POST',
|
||||
const response = await fetch("/api/cookies", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(postData),
|
||||
}); // make a POST request to the server with the FormData object
|
||||
}); // make a POST request to the server with the FormData object
|
||||
|
||||
const output = await response.json();
|
||||
$showCookieConsent = false;
|
||||
}
|
||||
const output = await response.json();
|
||||
$showCookieConsent = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<section style="z-index: 9999" class="shadow-lg fixed max-w-4xl md:max-w-2xl p-4 mx-auto md:gap-x-4 md:left-60 md:bottom-10 bg-gray-900 md:flex md:items-center justify-center border-gray-700 rounded-t-md md:rounded-2xl inset-x-0 md:inset-auto bottom-0">
|
||||
<div class="flex items-center gap-x-4">
|
||||
<span class="inline-flex p-2 text-white rounded-lg shrink-0 bg-gray-800">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.9803 8.5468C17.5123 8.69458 17.0197 8.7931 16.5271 8.7931C14.2118 8.76847 12.3399 6.89655 12.3153 4.58128C12.3153 4.13793 12.3892 3.69458 12.537 3.27586C11.9951 2.68473 11.6995 1.92118 11.6995 1.13301C11.6995 0.812808 11.7488 0.492611 11.8473 0.172414C11.2315 0.0738918 10.6158 0 10 0C4.48276 0 0 4.48276 0 10C0 15.5172 4.48276 20 10 20C15.5172 20 20 15.5172 20 10C20 9.77833 20 9.55665 19.9754 9.33498C19.2611 9.26108 18.5468 8.99015 17.9803 8.5468ZM4.58128 7.31527C6.30542 7.31527 6.30542 10.0246 4.58128 10.0246C2.85714 10.0246 2.61084 7.31527 4.58128 7.31527ZM6.05912 15.7635C4.08867 15.7635 4.08867 12.8079 6.05912 12.8079C8.02956 12.8079 8.02956 15.7635 6.05912 15.7635ZM9.01478 1.33005C10.7389 1.33005 10.7389 4.28571 9.01478 4.28571C7.29064 4.28571 7.04434 1.33005 9.01478 1.33005ZM10.2463 8.84237C11.7241 8.84237 11.7241 10.8128 10.2463 10.8128C8.76848 10.8128 9.01478 8.84237 10.2463 8.84237ZM11.9704 16.9458C10.4926 16.9458 10.4926 14.9754 11.9704 14.9754C13.4483 14.9754 13.202 16.9458 11.9704 16.9458ZM16.6503 13.1034C15.4187 13.1034 15.4187 11.133 16.6503 11.133C17.8818 11.133 17.8818 13.1034 16.6503 13.1034Z" fill="currentColor"/>
|
||||
</svg>
|
||||
</span>
|
||||
<section
|
||||
style="z-index: 9999"
|
||||
class="shadow-lg fixed max-w-4xl md:max-w-2xl p-4 mx-auto md:gap-x-4 md:left-60 md:bottom-10 bg-gray-900 md:flex md:items-center justify-center border-gray-700 rounded-t-md md:rounded-2xl inset-x-0 md:inset-auto bottom-0"
|
||||
>
|
||||
<div class="flex items-center gap-x-4">
|
||||
<span class="inline-flex p-2 text-white rounded-md shrink-0 bg-gray-800">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M17.9803 8.5468C17.5123 8.69458 17.0197 8.7931 16.5271 8.7931C14.2118 8.76847 12.3399 6.89655 12.3153 4.58128C12.3153 4.13793 12.3892 3.69458 12.537 3.27586C11.9951 2.68473 11.6995 1.92118 11.6995 1.13301C11.6995 0.812808 11.7488 0.492611 11.8473 0.172414C11.2315 0.0738918 10.6158 0 10 0C4.48276 0 0 4.48276 0 10C0 15.5172 4.48276 20 10 20C15.5172 20 20 15.5172 20 10C20 9.77833 20 9.55665 19.9754 9.33498C19.2611 9.26108 18.5468 8.99015 17.9803 8.5468ZM4.58128 7.31527C6.30542 7.31527 6.30542 10.0246 4.58128 10.0246C2.85714 10.0246 2.61084 7.31527 4.58128 7.31527ZM6.05912 15.7635C4.08867 15.7635 4.08867 12.8079 6.05912 12.8079C8.02956 12.8079 8.02956 15.7635 6.05912 15.7635ZM9.01478 1.33005C10.7389 1.33005 10.7389 4.28571 9.01478 4.28571C7.29064 4.28571 7.04434 1.33005 9.01478 1.33005ZM10.2463 8.84237C11.7241 8.84237 11.7241 10.8128 10.2463 10.8128C8.76848 10.8128 9.01478 8.84237 10.2463 8.84237ZM11.9704 16.9458C10.4926 16.9458 10.4926 14.9754 11.9704 14.9754C13.4483 14.9754 13.202 16.9458 11.9704 16.9458ZM16.6503 13.1034C15.4187 13.1034 15.4187 11.133 16.6503 11.133C17.8818 11.133 17.8818 13.1034 16.6503 13.1034Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
<p class="text-sm text-gray-300">We use cookies to ensure that we give you the best experience on our website. <a href="/privacy-policy" class="text-blue-500 hover:underline">Read Privacy Policy</a>. </p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-end sm:justify-start mt-2 mb-5 sm:mb-0 gap-x-4 shrink-0 lg:mt-0 ">
|
||||
<label for="cookieConsent" on:click={() => cookieConsent('false')} class="cursor-pointer w-auto text-sm text-gray-800 underline transition-colors duration-300 md:w-auto text-white hover:text-gray-400 focus:outline-none">
|
||||
Reject All
|
||||
</label>
|
||||
<p class="text-sm text-gray-300">
|
||||
We use cookies to ensure that we give you the best experience on our
|
||||
website. <a href="/privacy-policy" class="text-blue-500 hover:underline"
|
||||
>Read Privacy Policy</a
|
||||
>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<label for="cookieConsent" on:click={() => cookieConsent('true')} class="text-xs cursor-pointer w-auto md:w-auto font-medium bg-gray-800 rounded-lg hover:bg-gray-700 text-white px-4 py-2.5 duration-300 transition-colors focus:outline-none">
|
||||
Accept All Cookies
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center justify-end sm:justify-start mt-2 mb-5 sm:mb-0 gap-x-4 shrink-0 lg:mt-0"
|
||||
>
|
||||
<label
|
||||
for="cookieConsent"
|
||||
on:click={() => cookieConsent("false")}
|
||||
class="cursor-pointer w-auto text-sm text-gray-800 underline transition-colors duration-300 md:w-auto text-white hover:text-gray-400 focus:outline-none"
|
||||
>
|
||||
Reject All
|
||||
</label>
|
||||
|
||||
<label
|
||||
for="cookieConsent"
|
||||
on:click={() => cookieConsent("true")}
|
||||
class="text-xs cursor-pointer w-auto md:w-auto font-medium bg-gray-800 rounded-md hover:bg-gray-700 text-white px-4 py-2.5 duration-300 transition-colors focus:outline-none"
|
||||
>
|
||||
Accept All Cookies
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@ -1,232 +1,90 @@
|
||||
<script lang 'ts'></script>
|
||||
|
||||
<script lang ='ts'>
|
||||
import { corporateLobbyingComponent, displayCompanyName, stockTicker, screenWidth, getCache, setCache} from '$lib/store';
|
||||
import InfoModal from '$lib/components/InfoModal.svelte';
|
||||
import { Chart } from 'svelte-echarts'
|
||||
import { abbreviateNumber } from "$lib/utils";
|
||||
import { init, use } from 'echarts/core'
|
||||
import { BarChart } from 'echarts/charts'
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
use([BarChart, GridComponent, TooltipComponent, CanvasRenderer])
|
||||
<section class="overflow-hidden text-white h-full">
|
||||
<main class="overflow-hidden">
|
||||
<div class="flex flex-row items-center">
|
||||
<label
|
||||
for="lobbyingInfo"
|
||||
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
|
||||
>
|
||||
Corporate Lobbying
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Corporate Lobbying"}
|
||||
content={"Lobbying the Senate involves special interest groups hiring professional advocates to influence lawmakers and government policies. It is a constitutionally protected activity, but critics argue it can undermine democratic representation by giving disproportionate influence to wealthy and well-organized groups."}
|
||||
id={"lobbyingInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
export let data;
|
||||
|
||||
let isLoaded = false;
|
||||
let rawData = [];
|
||||
|
||||
let optionsData;
|
||||
let avgAmount = 0;
|
||||
let displayMaxLobbying = 0;
|
||||
let displayYear = 'n/a';
|
||||
|
||||
|
||||
|
||||
function getPlotOptions() {
|
||||
let dates = [];
|
||||
let valueList = [];
|
||||
// Iterate over the data and extract required information
|
||||
rawData?.forEach(item => {
|
||||
// Extract year and convert it to fiscal year format
|
||||
const fiscalYear = "FY" + String(item?.year)?.slice(2);
|
||||
dates?.push(fiscalYear);
|
||||
|
||||
// Extract amount
|
||||
valueList?.push(item?.amount);
|
||||
});
|
||||
|
||||
|
||||
const option = {
|
||||
silent: true,
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
hideDelay: 100, // Set the delay in milliseconds
|
||||
},
|
||||
grid: {
|
||||
left: $screenWidth < 640 ? '0%' : '2%',
|
||||
right: $screenWidth < 640 ? '5%' : '2%',
|
||||
bottom: $screenWidth < 640 ? '0%' : '2%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
data: dates,
|
||||
type: 'category',
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
|
||||
axisLabel: {
|
||||
show: false // Hide y-axis labels
|
||||
}
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Spending [$]',
|
||||
data: valueList,
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: '#F8901E' // Change bar color to white
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
const getCorporateLobbing = async (ticker) => {
|
||||
// Get cached data for the specific tickerID
|
||||
const cachedData = getCache(ticker, 'getCorporateLobbing');
|
||||
if (cachedData) {
|
||||
rawData = cachedData;
|
||||
} else {
|
||||
|
||||
const postData = {'ticker': ticker, path: 'corporate-lobbying'};
|
||||
// make the POST request to the endpoint
|
||||
const response = await fetch('/api/ticker-data', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
rawData = (await response.json())?.slice(-100);
|
||||
// Cache the data for this specific tickerID with a specific name 'getCorporateLobbing'
|
||||
setCache(ticker, rawData, 'getCorporateLobbing');
|
||||
}
|
||||
|
||||
if(rawData?.length !== 0) {
|
||||
$corporateLobbyingComponent = true;
|
||||
} else {
|
||||
$corporateLobbyingComponent = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
$: {
|
||||
if($stockTicker && typeof window !== 'undefined') {
|
||||
isLoaded=false;
|
||||
const asyncFunctions = [
|
||||
getCorporateLobbing($stockTicker)
|
||||
];
|
||||
Promise.all(asyncFunctions)
|
||||
.then((results) => {
|
||||
if (rawData?.length !== 0) {
|
||||
optionsData = getPlotOptions();
|
||||
// Calculate total number of contracts
|
||||
avgAmount = Math.floor((rawData?.reduce((sum, item) => sum + item?.amount, 0))/rawData?.length);
|
||||
const { year:yearWithMaxLobbying, amount: maxLobbying } = rawData?.reduce((max, item) => item?.amount > max?.amount ? item : max, rawData?.at(0));
|
||||
displayYear = yearWithMaxLobbying;
|
||||
displayMaxLobbying = maxLobbying;
|
||||
console.log('yes')
|
||||
}
|
||||
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('An error occurred:', error);
|
||||
});
|
||||
isLoaded = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<section class="overflow-hidden text-white h-full ">
|
||||
<main class="overflow-hidden ">
|
||||
|
||||
<div class="flex flex-row items-center">
|
||||
<label for="lobbyingInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
|
||||
Corporate Lobbying
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Corporate Lobbying"}
|
||||
content={"Lobbying the Senate involves special interest groups hiring professional advocates to influence lawmakers and government policies. It is a constitutionally protected activity, but critics argue it can undermine democratic representation by giving disproportionate influence to wealthy and well-organized groups."}
|
||||
id={"lobbyingInfo"}
|
||||
/>
|
||||
{#if isLoaded}
|
||||
{#if rawData?.length !== 0}
|
||||
<div class="mt-2 pb-8 sm:pb-2 rounded-md bg-[#09090B] sm:bg-[#09090B]">
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-[1rem] mt-1 sm:mt-3 mb-1 w-full">
|
||||
Explore {$displayCompanyName}'s lobbying strategy by analyzing
|
||||
their annual spending to influence lawmakers towards favorable
|
||||
regulation and legislation alignment.
|
||||
</div>
|
||||
|
||||
{#if isLoaded}
|
||||
{#if rawData?.length !== 0}
|
||||
<div class="mt-2 pb-8 sm:pb-2 rounded-lg bg-[#09090B] sm:bg-[#09090B]">
|
||||
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-[1rem] mt-1 sm:mt-3 mb-1 w-full">
|
||||
Explore {$displayCompanyName}'s lobbying strategy by analyzing their annual spending to influence lawmakers towards favorable regulation and legislation alignment.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="app w-full h-[300px] ">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
<div class="app w-full h-[300px]">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
<div class="w-full text-white text-[1rem] mt-6">
|
||||
The company allocated an average of {abbreviateNumber(avgAmount,true)} annually towards lobbying efforts, reaching its peak at {abbreviateNumber(displayMaxLobbying,true)} in {displayYear}.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
<h2 class="mt-10 mb-5 flex justify-center items-center text-3xl font-bold text-slate-700 m-auto">
|
||||
No data available
|
||||
<svg class="w-10 sm:w-12 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#334155" d="M18.68 12.32a4.49 4.49 0 0 0-6.36.01a4.49 4.49 0 0 0 0 6.36a4.508 4.508 0 0 0 5.57.63L21 22.39L22.39 21l-3.09-3.11c1.13-1.77.87-4.09-.62-5.57m-1.41 4.95c-.98.98-2.56.97-3.54 0c-.97-.98-.97-2.56.01-3.54c.97-.97 2.55-.97 3.53 0c.97.98.97 2.56 0 3.54M10.9 20.1a6.527 6.527 0 0 1-1.48-2.32C6.27 17.25 4 15.76 4 14v3c0 2.21 3.58 4 8 4c-.4-.26-.77-.56-1.1-.9M4 9v3c0 1.68 2.07 3.12 5 3.7v-.2c0-.93.2-1.85.58-2.69C6.34 12.3 4 10.79 4 9m8-6C7.58 3 4 4.79 4 7c0 2 3 3.68 6.85 4h.05c1.2-1.26 2.86-2 4.6-2c.91 0 1.81.19 2.64.56A3.215 3.215 0 0 0 20 7c0-2.21-3.58-4-8-4Z"/></svg>
|
||||
</h2>
|
||||
|
||||
{/if}
|
||||
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
|
||||
<span class="loading loading-spinner loading-md text-gray-400"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
|
||||
</main>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<div class="w-full text-white text-[1rem] mt-6">
|
||||
The company allocated an average of {abbreviateNumber(
|
||||
avgAmount,
|
||||
true,
|
||||
)} annually towards lobbying efforts, reaching its peak at {abbreviateNumber(
|
||||
displayMaxLobbying,
|
||||
true,
|
||||
)} in {displayYear}.
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<h2
|
||||
class="mt-10 mb-5 flex justify-center items-center text-3xl font-bold text-slate-700 m-auto"
|
||||
>
|
||||
No data available
|
||||
<svg
|
||||
class="w-10 sm:w-12 inline-block"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
><path
|
||||
fill="#334155"
|
||||
d="M18.68 12.32a4.49 4.49 0 0 0-6.36.01a4.49 4.49 0 0 0 0 6.36a4.508 4.508 0 0 0 5.57.63L21 22.39L22.39 21l-3.09-3.11c1.13-1.77.87-4.09-.62-5.57m-1.41 4.95c-.98.98-2.56.97-3.54 0c-.97-.98-.97-2.56.01-3.54c.97-.97 2.55-.97 3.53 0c.97.98.97 2.56 0 3.54M10.9 20.1a6.527 6.527 0 0 1-1.48-2.32C6.27 17.25 4 15.76 4 14v3c0 2.21 3.58 4 8 4c-.4-.26-.77-.56-1.1-.9M4 9v3c0 1.68 2.07 3.12 5 3.7v-.2c0-.93.2-1.85.58-2.69C6.34 12.3 4 10.79 4 9m8-6C7.58 3 4 4.79 4 7c0 2 3 3.68 6.85 4h.05c1.2-1.26 2.86-2 4.6-2c.91 0 1.81.19 2.64.56A3.215 3.215 0 0 0 20 7c0-2.21-3.58-4-8-4Z"
|
||||
/></svg
|
||||
>
|
||||
</h2>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label
|
||||
class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||
>
|
||||
<span class="loading loading-spinner loading-md text-gray-400"
|
||||
></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
|
||||
.app {
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 230px;
|
||||
}
|
||||
height: 230px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart {
|
||||
.chart {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -103,7 +103,7 @@
|
||||
>
|
||||
{#each showFullStats ? rawData : rawData?.slice(0, 3) as item, index}
|
||||
<div
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-lg p-4 sm:p-3 mb-5 flex flex-row items-center {index ===
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-md p-4 sm:p-3 mb-5 flex flex-row items-center {index ===
|
||||
0
|
||||
? 'mt-4'
|
||||
: ''} {index === 2 && !showFullStats && rawData?.length > 2
|
||||
|
||||
@ -72,7 +72,7 @@
|
||||
<!--Start Progress-->
|
||||
{#each showFullStats ? geographicList : geographicList?.slice(0, 3) as item, index}
|
||||
<div
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-lg p-4 sm:p-3 mb-5 flex flex-row items-center {index ===
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-md p-4 sm:p-3 mb-5 flex flex-row items-center {index ===
|
||||
0
|
||||
? 'mt-4'
|
||||
: ''} {index === 2 &&
|
||||
|
||||
@ -1,60 +1,63 @@
|
||||
<script lang="ts">
|
||||
import {cryptoTicker, screenWidth, displayCompanyName} from '$lib/store';
|
||||
|
||||
import { abbreviateNumber} from '$lib/utils';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { goto } from '$app/navigation';
|
||||
import defaultImage from '$lib/images/etf/cover/default.jpg';
|
||||
|
||||
export let cryptoProfile;
|
||||
|
||||
let cloudFrontUrl = import.meta.env.VITE_IMAGE_URL; // Set a default API URL
|
||||
import { cryptoTicker, screenWidth, displayCompanyName } from "$lib/store";
|
||||
|
||||
import { abbreviateNumber } from "$lib/utils";
|
||||
import { fade } from "svelte/transition";
|
||||
import { goto } from "$app/navigation";
|
||||
import defaultImage from "$lib/images/etf/cover/default.jpg";
|
||||
|
||||
let info;
|
||||
let imageUrl;
|
||||
let marketCap = '-';
|
||||
let totalVolume = '-';
|
||||
let circulatingSupply = '-';
|
||||
let maxSupply = '-';
|
||||
let description = '';
|
||||
let snippet;
|
||||
let website;
|
||||
let athPrice;
|
||||
let athDate;
|
||||
|
||||
export let cryptoProfile;
|
||||
|
||||
let showFullText = false;
|
||||
|
||||
|
||||
let cloudFrontUrl = import.meta.env.VITE_IMAGE_URL; // Set a default API URL
|
||||
|
||||
let info;
|
||||
let imageUrl;
|
||||
let marketCap = "-";
|
||||
let totalVolume = "-";
|
||||
let circulatingSupply = "-";
|
||||
let maxSupply = "-";
|
||||
let description = "";
|
||||
let snippet;
|
||||
let website;
|
||||
let athPrice;
|
||||
let athDate;
|
||||
|
||||
let showFullText = false;
|
||||
|
||||
$: {
|
||||
if ($cryptoTicker && typeof $cryptoTicker !== 'undefined' && typeof window !== 'undefined' && typeof cryptoProfile !== 'undefined' && Object?.keys(cryptoProfile)?.length !== 0)
|
||||
{
|
||||
|
||||
if (
|
||||
$cryptoTicker &&
|
||||
typeof $cryptoTicker !== "undefined" &&
|
||||
typeof window !== "undefined" &&
|
||||
typeof cryptoProfile !== "undefined" &&
|
||||
Object?.keys(cryptoProfile)?.length !== 0
|
||||
) {
|
||||
marketCap = cryptoProfile?.market_cap;
|
||||
totalVolume = cryptoProfile?.total_volume;
|
||||
description = cryptoProfile?.description ?? 'A detailed description of the company is not yet available.';
|
||||
snippet= description?.slice(0, 150) + "...";
|
||||
circulatingSupply = cryptoProfile?.circulating_supply
|
||||
maxSupply = cryptoProfile?.max_supply
|
||||
description =
|
||||
cryptoProfile?.description ??
|
||||
"A detailed description of the company is not yet available.";
|
||||
snippet = description?.slice(0, 150) + "...";
|
||||
circulatingSupply = cryptoProfile?.circulating_supply;
|
||||
maxSupply = cryptoProfile?.max_supply;
|
||||
website = cryptoProfile?.website;
|
||||
athPrice = cryptoProfile?.ath;
|
||||
athDate = cryptoProfile?.ath_date
|
||||
|
||||
athDate = cryptoProfile?.ath_date;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="sm:space-y-3">
|
||||
<div class="lg:rounded-lg shadow-lg sm:border sm:border-slate-800 bg-[#000] lg:bg-[#09090B] h-auto h-auto w-screen pt-16 sm:w-full md:w-[420px] xl:w-[450px] lg:pt-0">
|
||||
</script>
|
||||
|
||||
<!--Start Header-->
|
||||
<div class="sm:rounded-t-lg w-full h-[130px] bg-[#000] p-3 flex flex-col bg-cover bg-center bg-no-repeat" style="background-image: url({`${cloudFrontUrl}/stocks/cover/${$cryptoTicker?.toUpperCase()}.jpg`});">
|
||||
|
||||
<div class="flex flex-row pt-1 pb-2">
|
||||
</div>
|
||||
<!--
|
||||
<div class="sm:space-y-3">
|
||||
<div
|
||||
class="lg:rounded-md shadow-lg sm:border sm:border-slate-800 bg-[#000] lg:bg-[#09090B] h-auto h-auto w-screen pt-16 sm:w-full md:w-[420px] xl:w-[450px] lg:pt-0"
|
||||
>
|
||||
<!--Start Header-->
|
||||
<div
|
||||
class="sm:rounded-t-lg w-full h-[130px] bg-[#000] p-3 flex flex-col bg-cover bg-center bg-no-repeat"
|
||||
style="background-image: url({`${cloudFrontUrl}/stocks/cover/${$cryptoTicker?.toUpperCase()}.jpg`});"
|
||||
>
|
||||
<div class="flex flex-row pt-1 pb-2"></div>
|
||||
<!--
|
||||
<div class="flex flex-row justify-end items-center mt-2 relative z-10 -my-5">
|
||||
<div style={`background-image: url(${sTier}`} class="animate-bounce circle-background mr-5 w-20 h-20 z-10">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-28 h-28" viewBox="0 0 106 34">
|
||||
@ -73,97 +76,173 @@
|
||||
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<!--End Header-->
|
||||
</div>
|
||||
<!--End Header-->
|
||||
|
||||
<!--Start Content-->
|
||||
<div class="w-full flex flex-wrap border-t border-slate-800">
|
||||
<h2 class="text-start ml-4 text-2xl font-bold text-white pb-2 mt-3">Crypto Info</h2>
|
||||
<div class="flex items-center w-full">
|
||||
<table class="table table-md table-compact">
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr class="text-white border-b border-[#27272A]" style="font-size: 0.8rem">
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium">Name</td>
|
||||
<td class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B]">{$displayCompanyName?.length > 30 ? $displayCompanyName?.slice(0,30) + '...' : $displayCompanyName}</td>
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium">Ticker</td>
|
||||
<td class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B]">{$cryptoTicker}</td>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr class="text-white border-b border-[#27272A]" style="font-size: 0.8rem">
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium">Mkt Cap</td>
|
||||
<td class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal">{abbreviateNumber(marketCap,true)}</td>
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium">Total Volume</td>
|
||||
<td class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal">{abbreviateNumber(totalVolume)}</td>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr class="text-white border-b border-[#27272A]" style="font-size: 0.8rem">
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium">Circulating Supply</td>
|
||||
<td class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal">{abbreviateNumber(circulatingSupply)}</td>
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium">Max Supply</td>
|
||||
<td class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal">{maxSupply !== null ? abbreviateNumber(maxSupply) : 'Uncapped'}</td>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr class="text-white border-b border-[#27272A]" style="font-size: 0.8rem">
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium">ATH Price</td>
|
||||
<td class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal">${new Intl.NumberFormat("en", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2
|
||||
}).format(athPrice)}</td>
|
||||
<td class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium">ATH Date</td>
|
||||
<td class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal">{new Date(athDate).toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<!--Start Content-->
|
||||
<div class="w-full flex flex-wrap border-t border-slate-800">
|
||||
<h2 class="text-start ml-4 text-2xl font-bold text-white pb-2 mt-3">
|
||||
Crypto Info
|
||||
</h2>
|
||||
<div class="flex items-center w-full">
|
||||
<table class="table table-md table-compact">
|
||||
<tbody>
|
||||
<!-- row 1 -->
|
||||
<tr
|
||||
class="text-white border-b border-[#27272A]"
|
||||
style="font-size: 0.8rem"
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium"
|
||||
>Name</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B]"
|
||||
>{$displayCompanyName?.length > 30
|
||||
? $displayCompanyName?.slice(0, 30) + "..."
|
||||
: $displayCompanyName}</td
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium"
|
||||
>Ticker</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B]"
|
||||
>{$cryptoTicker}</td
|
||||
>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr
|
||||
class="text-white border-b border-[#27272A]"
|
||||
style="font-size: 0.8rem"
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium"
|
||||
>Mkt Cap</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal"
|
||||
>{abbreviateNumber(marketCap, true)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium"
|
||||
>Total Volume</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal"
|
||||
>{abbreviateNumber(totalVolume)}</td
|
||||
>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr
|
||||
class="text-white border-b border-[#27272A]"
|
||||
style="font-size: 0.8rem"
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium"
|
||||
>Circulating Supply</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal"
|
||||
>{abbreviateNumber(circulatingSupply)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium"
|
||||
>Max Supply</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal"
|
||||
>{maxSupply !== null
|
||||
? abbreviateNumber(maxSupply)
|
||||
: "Uncapped"}</td
|
||||
>
|
||||
</tr>
|
||||
<!-- row 2 -->
|
||||
<tr
|
||||
class="text-white border-b border-[#27272A]"
|
||||
style="font-size: 0.8rem"
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium"
|
||||
>ATH Price</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal"
|
||||
>${new Intl.NumberFormat("en", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
}).format(athPrice)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start lg:border-b lg:border-[#27272A] bg-[#000] lg:bg-[#09090B] text-white font-medium"
|
||||
>ATH Date</td
|
||||
>
|
||||
<td
|
||||
class="bg-[#000] lg:border-b lg:border-[#27272A] lg:bg-[#09090B] whitespace-normal"
|
||||
>{new Date(athDate).toLocaleString("en-US", {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
daySuffix: "2-digit",
|
||||
})}</td
|
||||
>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2
|
||||
class="text-start ml-2 text-xl font-bold text-white pb-2 pt-6 lg:pt-3"
|
||||
>
|
||||
Description
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-100 ml-2 text-sm whitespace-normal">
|
||||
{#if showFullText}
|
||||
<div transition:fade={{ delay: 0, duration: 80 }} in={showFullText}>
|
||||
{description}
|
||||
</div>
|
||||
|
||||
<h2 class="text-start ml-2 text-xl font-bold text-white pb-2 pt-6 lg:pt-3">
|
||||
Description
|
||||
</h2>
|
||||
|
||||
|
||||
<p class="text-gray-100 ml-2 text-sm whitespace-normal">
|
||||
{:else if $screenWidth <= 800}
|
||||
{description}
|
||||
{:else}
|
||||
{snippet}
|
||||
{/if}
|
||||
</p>
|
||||
{#if description.length !== 0}
|
||||
<div class="flex flex-row w-full items-center mt-4 pb-2 mb-2">
|
||||
<label
|
||||
on:click={() => (showFullText = !showFullText)}
|
||||
class="hidden lg:block ml-3 w-full text-md mt-1 cursor-pointer font-medium text-white sm:hover:text-blue-400 sm:hover:underline"
|
||||
>
|
||||
{#if showFullText}
|
||||
<div transition:fade={{ delay: 0, duration: 80 }} in={showFullText}>
|
||||
{description}
|
||||
</div>
|
||||
{:else if $screenWidth <= 800}
|
||||
{description}
|
||||
Show less
|
||||
{:else}
|
||||
{snippet}
|
||||
{/if}
|
||||
</p>
|
||||
{#if description.length !== 0 }
|
||||
<div class="flex flex-row w-full items-center mt-4 pb-2 mb-2">
|
||||
<label on:click={() => showFullText = !showFullText} class="hidden lg:block ml-3 w-full text-md mt-1 cursor-pointer font-medium text-white sm:hover:text-blue-400 sm:hover:underline">
|
||||
{#if showFullText}
|
||||
Show less
|
||||
{:else}
|
||||
Show more
|
||||
{/if}
|
||||
</label>
|
||||
|
||||
{/if}
|
||||
</label>
|
||||
|
||||
<div class="flex justify-end w-full relative bottom-0 right-0 mr-3">
|
||||
<a target ="_blank" href={website} class="inline-flex text-sm font-medium text-white sm:hover:text-blue-400 sm:hover:underline">
|
||||
<a
|
||||
target="_blank"
|
||||
href={website}
|
||||
class="inline-flex text-sm font-medium text-white sm:hover:text-blue-400 sm:hover:underline"
|
||||
>
|
||||
Go to website
|
||||
<svg class="w-5 h-5 ml-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z"></path><path d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z"></path></svg>
|
||||
<svg
|
||||
class="w-5 h-5 ml-2"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><path
|
||||
d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z"
|
||||
></path><path
|
||||
d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z"
|
||||
></path></svg
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@ -244,7 +244,7 @@
|
||||
{#if isLoaded}
|
||||
{#if fairPrice !== null}
|
||||
<div
|
||||
class="p-3 sm:p-0 mt-2 pb-8 sm:pb-2 rounded-lg bg-[#09090B] sm:bg-[#09090B]"
|
||||
class="p-3 sm:p-0 mt-2 pb-8 sm:pb-2 rounded-md bg-[#09090B] sm:bg-[#09090B]"
|
||||
>
|
||||
<div
|
||||
class="mt-4 text-white text-[1rem] sm:text-xl pb-4 sm:pb-0 m-auto text-start"
|
||||
@ -340,7 +340,7 @@
|
||||
|
||||
{#if Math?.abs(change) > 30}
|
||||
<div
|
||||
class=" mb-5 text-gray-100 text-sm sm:text-[1rem] sm:rounded-lg h-auto border border-slate-800 p-4"
|
||||
class=" mb-5 text-gray-100 text-sm sm:text-[1rem] sm:rounded-md h-auto border border-slate-800 p-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block mr-0.5 flex-shrink-0"
|
||||
|
||||
@ -1,319 +1,158 @@
|
||||
<script lang ='ts'>
|
||||
import { darkPoolComponent, displayCompanyName, stockTicker, assetType, etfTicker, screenWidth, getCache, setCache} from '$lib/store';
|
||||
import InfoModal from '$lib/components/InfoModal.svelte';
|
||||
import { Chart } from 'svelte-echarts'
|
||||
import { abbreviateNumber, formatDateRange } from "$lib/utils";
|
||||
import { init, use } from 'echarts/core'
|
||||
import { LineChart } from 'echarts/charts'
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
<script lang 'ts'></script>
|
||||
|
||||
use([LineChart, GridComponent, TooltipComponent, CanvasRenderer])
|
||||
|
||||
export let data;
|
||||
|
||||
let isLoaded = false;
|
||||
|
||||
let rawData = [];
|
||||
let optionsData;
|
||||
let avgVolume;
|
||||
let avgShortVolume;
|
||||
let monthlyVolume;
|
||||
let avgMonthlyShort;
|
||||
|
||||
|
||||
function findMonthlyValue(data, lastDateStr) {
|
||||
// Convert lastDateStr to Date object
|
||||
const lastDate = new Date(lastDateStr);
|
||||
|
||||
// Set the first date to the beginning of the month of lastDate
|
||||
const firstDate = new Date(lastDate.getFullYear(), lastDate.getMonth(), 1);
|
||||
|
||||
// Filter data to include only prices within the specified month period
|
||||
const filteredData = data.filter(item => {
|
||||
const currentDate = new Date(item?.date);
|
||||
return currentDate >= firstDate && currentDate <= lastDate;
|
||||
});
|
||||
|
||||
// Extract prices from filtered data
|
||||
monthlyVolume = abbreviateNumber(filteredData?.reduce((accumulator, currentItem) => {
|
||||
return accumulator + currentItem?.totalVolume;
|
||||
}, 0));
|
||||
|
||||
|
||||
const totalShortPercent = filteredData.reduce((accumulator, currentItem) => {
|
||||
return accumulator + (currentItem?.shortPercent || 0);
|
||||
}, 0);
|
||||
|
||||
avgMonthlyShort = (totalShortPercent / filteredData?.length)?.toFixed(2);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function getPlotOptions() {
|
||||
let dates = [];
|
||||
let totalVolumeList = [];
|
||||
let shortVolumeList = [];
|
||||
// Iterate over the data and extract required information
|
||||
rawData?.forEach(item => {
|
||||
|
||||
dates?.push(item?.date);
|
||||
totalVolumeList?.push(item?.totalVolume);
|
||||
shortVolumeList?.push(item?.shortVolume)
|
||||
|
||||
});
|
||||
|
||||
findMonthlyValue(rawData, rawData?.slice(-1)?.at(0)?.date)
|
||||
|
||||
// Compute the average of item?.traded
|
||||
const totalTraded = totalVolumeList?.reduce((acc, traded) => acc + traded, 0);
|
||||
avgVolume = totalTraded / totalVolumeList?.length;
|
||||
|
||||
const totalShort = shortVolumeList?.reduce((acc, sentiment) => acc + sentiment, 0);
|
||||
avgShortVolume = totalShort / shortVolumeList?.length;
|
||||
|
||||
|
||||
const option = {
|
||||
silent: true,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
hideDelay: 100, // Set the delay in milliseconds
|
||||
},
|
||||
animation: false,
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '3%',
|
||||
bottom: '2%',
|
||||
top: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: dates,
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
axisLabel: {
|
||||
show: false // Hide y-axis labels
|
||||
}
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Total Volume',
|
||||
data: totalVolumeList,
|
||||
type: 'line',
|
||||
itemStyle: {
|
||||
color: '#fff', // Change bar color to white
|
||||
},
|
||||
showSymbol: false
|
||||
},
|
||||
{
|
||||
name: 'Short Volume',
|
||||
data: shortVolumeList,
|
||||
type: 'line',
|
||||
areaStyle: {opacity: 1},
|
||||
itemStyle: {
|
||||
color: '#E11D48' // Change bar color to white
|
||||
},
|
||||
showSymbol: false
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
const getDarkPool = async (ticker) => {
|
||||
// Get cached data for the specific tickerID
|
||||
const cachedData = getCache(ticker, 'getDarkPool');
|
||||
if (cachedData) {
|
||||
rawData = cachedData;
|
||||
} else {
|
||||
|
||||
const postData = {'ticker': ticker, path: 'dark-pool'};
|
||||
// make the POST request to the endpoint
|
||||
const response = await fetch('/api/ticker-data', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
rawData = await response.json();
|
||||
// Cache the data for this specific tickerID with a specific name 'getDarkPool'
|
||||
setCache(ticker, rawData, 'getDarkPool');
|
||||
}
|
||||
if(rawData?.length !== 0) {
|
||||
$darkPoolComponent = true;
|
||||
} else {
|
||||
$darkPoolComponent = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$: {
|
||||
if($assetType === 'stock' ? $stockTicker :$etfTicker && typeof window !== 'undefined') {
|
||||
isLoaded=false;
|
||||
const ticker = $assetType === 'stock' ? $stockTicker : $etfTicker
|
||||
const asyncFunctions = [
|
||||
getDarkPool(ticker)
|
||||
];
|
||||
Promise.all(asyncFunctions)
|
||||
.then((results) => {
|
||||
optionsData = getPlotOptions()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('An error occurred:', error);
|
||||
});
|
||||
isLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<section class="overflow-hidden text-white h-full pb-8">
|
||||
<main class="overflow-hidden ">
|
||||
|
||||
<div class="flex flex-row items-center">
|
||||
<label for="darkPoolInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
|
||||
Dark Pool Activity
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Dark Pool Data"}
|
||||
content={"Dark pool data refers to information on trading activities that occur in private, non-public financial exchanges known as dark pools. These venues are used by hedge funds and major institutional traders to buy and sell large blocks of securities without exposing their orders to the public, minimizing market impact and price fluctuations. Currently, nearly 50% of all trades are executed in these dark pools, highlighting their significant role in the trading landscape."}
|
||||
id={"darkPoolInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if isLoaded}
|
||||
|
||||
{#if rawData?.length !== 0}
|
||||
<main class="overflow-hidden">
|
||||
<div class="flex flex-row items-center">
|
||||
<label
|
||||
for="darkPoolInfo"
|
||||
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
|
||||
>
|
||||
Dark Pool Activity
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Dark Pool Data"}
|
||||
content={"Dark pool data refers to information on trading activities that occur in private, non-public financial exchanges known as dark pools. These venues are used by hedge funds and major institutional traders to buy and sell large blocks of securities without exposing their orders to the public, minimizing market impact and price fluctuations. Currently, nearly 50% of all trades are executed in these dark pools, highlighting their significant role in the trading landscape."}
|
||||
id={"darkPoolInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if isLoaded}
|
||||
{#if rawData?.length !== 0}
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
|
||||
Over the past 12 months, {$displayCompanyName} has experienced an average dark pool trading volume of
|
||||
<span class="font-semibold">{abbreviateNumber(avgVolume)}</span> shares.
|
||||
Out of this total, an average of <span class="font-semibold">{abbreviateNumber(avgShortVolume)}</span> shares,
|
||||
constituting approximately <span class="font-semibold">{((avgShortVolume/avgVolume)*100)?.toFixed(2)}%</span>, were short volume.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pb-2 rounded-lg bg-[#09090B]">
|
||||
|
||||
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
|
||||
Over the past 12 months, {$displayCompanyName} has experienced an average
|
||||
dark pool trading volume of
|
||||
<span class="font-semibold">{abbreviateNumber(avgVolume)}</span>
|
||||
shares. Out of this total, an average of
|
||||
<span class="font-semibold">{abbreviateNumber(avgShortVolume)}</span
|
||||
>
|
||||
shares, constituting approximately
|
||||
<span class="font-semibold"
|
||||
>{((avgShortVolume / avgVolume) * 100)?.toFixed(2)}%</span
|
||||
>, were short volume.
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12">
|
||||
<div class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block">
|
||||
Total Volume
|
||||
<div class="pb-2 rounded-md bg-[#09090B]">
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12"
|
||||
>
|
||||
<div
|
||||
class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block"
|
||||
>
|
||||
Total Volume
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#E11D48] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block">
|
||||
Short Volume
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#E11D48] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block"
|
||||
>
|
||||
Short Volume
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h2 class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3">
|
||||
Latest Information
|
||||
<h2
|
||||
class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3"
|
||||
>
|
||||
Latest Information
|
||||
</h2>
|
||||
|
||||
|
||||
<div class="flex justify-start items-center w-full m-auto ">
|
||||
<table class="w-full" data-test="statistics-table">
|
||||
<tbody>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Date</span>
|
||||
</td>
|
||||
<td class="text-sm sm:text-[1rem] px-[5px] py-1.5 whitespace-nowrap text-right font-medium xs:px-2.5 xs:py-2">
|
||||
{ formatDateRange(rawData?.slice(-1)?.at(0)?.date)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 whitespace-nowrap odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Total Volume</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2">
|
||||
{monthlyVolume}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 whitespace-nowrap odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Avg. Short % of Volume</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2">
|
||||
{avgMonthlyShort}%
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<div class="flex justify-start items-center w-full m-auto">
|
||||
<table class="w-full" data-test="statistics-table">
|
||||
<tbody>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Date</span>
|
||||
</td>
|
||||
<td
|
||||
class="text-sm sm:text-[1rem] px-[5px] py-1.5 whitespace-nowrap text-right font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{formatDateRange(rawData?.slice(-1)?.at(0)?.date)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-y border-gray-800 whitespace-nowrap odd:bg-[#27272A]"
|
||||
>
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Total Volume</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{monthlyVolume}
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="border-y border-gray-800 whitespace-nowrap odd:bg-[#27272A]"
|
||||
>
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Avg. Short % of Volume</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{avgMonthlyShort}%
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
|
||||
<span class="loading loading-spinner loading-md text-gray-400"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
</main>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label
|
||||
class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||
>
|
||||
<span class="loading loading-spinner loading-md text-gray-400"
|
||||
></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
}
|
||||
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
.chart {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,84 +1,85 @@
|
||||
<script lang='ts'>
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
let targetDate = new Date("2024-07-14");
|
||||
|
||||
let days = "-";
|
||||
let hours = "-";
|
||||
let minutes = "-";
|
||||
let seconds = "-";
|
||||
|
||||
let targetDate = new Date("2024-07-14");
|
||||
const updateTime = () => {
|
||||
// Get the current time in the Berlin timezone
|
||||
const berlinTimeZone = "Europe/Berlin";
|
||||
const berlinCurrentTime = new Date().toLocaleString("en-US", {
|
||||
timeZone: berlinTimeZone,
|
||||
});
|
||||
const currentTime = new Date(berlinCurrentTime);
|
||||
|
||||
let days = '-';
|
||||
let hours = '-';
|
||||
let minutes = '-';
|
||||
let seconds = '-';
|
||||
// Calculate the time difference between the current time and the target date
|
||||
const timeDiff = targetDate - currentTime;
|
||||
|
||||
const updateTime = () => {
|
||||
// Get the current time in the Berlin timezone
|
||||
const berlinTimeZone = 'Europe/Berlin';
|
||||
const berlinCurrentTime = new Date().toLocaleString('en-US', { timeZone: berlinTimeZone });
|
||||
const currentTime = new Date(berlinCurrentTime);
|
||||
// Calculate the remaining days, hours, minutes, and seconds
|
||||
const totalSeconds = Math.floor(timeDiff / 1000);
|
||||
seconds = totalSeconds % 60;
|
||||
minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
hours = Math.floor((totalSeconds % (3600 * 24)) / 3600);
|
||||
days = Math.floor(totalSeconds / (3600 * 24));
|
||||
};
|
||||
|
||||
// Calculate the time difference between the current time and the target date
|
||||
const timeDiff = targetDate - currentTime;
|
||||
|
||||
// Calculate the remaining days, hours, minutes, and seconds
|
||||
const totalSeconds = Math.floor(timeDiff / 1000);
|
||||
seconds = totalSeconds % 60;
|
||||
minutes = Math.floor((totalSeconds % 3600) / 60);
|
||||
hours = Math.floor((totalSeconds % (3600 * 24)) / 3600);
|
||||
days = Math.floor(totalSeconds / (3600 * 24));
|
||||
};
|
||||
|
||||
|
||||
updateTime()
|
||||
|
||||
onMount( () => {
|
||||
|
||||
const interval = setInterval(updateTime, 1000);
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
|
||||
|
||||
});
|
||||
updateTime();
|
||||
|
||||
onMount(() => {
|
||||
const interval = setInterval(updateTime, 1000);
|
||||
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<div class="lg:max-w-xl w-full bg-gradient-to-r from-orange-400 to-purple-900 p-4 rounded-none sm:rounded-lg shadow-md m-auto">
|
||||
<div class="container bg-gradient-to-r from-orange-400 to-purple-900 p-4 mt-4">
|
||||
<h2 class="text-2xl font-bold text-white text-center">50% OFF Your Subscription!</h2>
|
||||
</div>
|
||||
<div class="container text-center">
|
||||
<p class="text-white font-bold text-xl">
|
||||
Use Promo Code: <span class="font-extrabold text-[#FFF374]">SUMMER50</span>
|
||||
</p>
|
||||
<div class="grid grid-flow-col gap-5 text-[#FFF374] font-bold text-center m-auto auto-cols-max justify-center mt-6">
|
||||
<div class="flex flex-col text-xs">
|
||||
<span class="countdown font-mono text-xl sm:text-2xl">
|
||||
<span style="--value:{days};"></span>
|
||||
</span>
|
||||
days
|
||||
</div>
|
||||
<div class="flex flex-col text-xs">
|
||||
<span class="countdown font-mono text-xl sm:text-2xl">
|
||||
<span style="--value:{hours};"></span>
|
||||
</span>
|
||||
hours
|
||||
</div>
|
||||
<div class="flex flex-col text-xs">
|
||||
<span class="countdown font-mono text-xl sm:text-2xl">
|
||||
<span style="--value:{minutes};"></span>
|
||||
</span>
|
||||
min
|
||||
</div>
|
||||
<div class="flex flex-col text-xs">
|
||||
<span class="countdown font-mono text-xl sm:text-2xl">
|
||||
<span style="--value:{seconds};"></span>
|
||||
</span>
|
||||
sec
|
||||
</div>
|
||||
<div
|
||||
class="lg:max-w-xl w-full bg-gradient-to-r from-orange-400 to-purple-900 p-4 rounded-none sm:rounded-md shadow-md m-auto"
|
||||
>
|
||||
<div
|
||||
class="container bg-gradient-to-r from-orange-400 to-purple-900 p-4 mt-4"
|
||||
>
|
||||
<h2 class="text-2xl font-bold text-white text-center">
|
||||
50% OFF Your Subscription!
|
||||
</h2>
|
||||
</div>
|
||||
<div class="container text-center">
|
||||
<p class="text-white font-bold text-xl">
|
||||
Use Promo Code: <span class="font-extrabold text-[#FFF374]">SUMMER50</span
|
||||
>
|
||||
</p>
|
||||
<div
|
||||
class="grid grid-flow-col gap-5 text-[#FFF374] font-bold text-center m-auto auto-cols-max justify-center mt-6"
|
||||
>
|
||||
<div class="flex flex-col text-xs">
|
||||
<span class="countdown font-mono text-xl sm:text-2xl">
|
||||
<span style="--value:{days};"></span>
|
||||
</span>
|
||||
days
|
||||
</div>
|
||||
<div class="flex flex-col text-xs">
|
||||
<span class="countdown font-mono text-xl sm:text-2xl">
|
||||
<span style="--value:{hours};"></span>
|
||||
</span>
|
||||
hours
|
||||
</div>
|
||||
<div class="flex flex-col text-xs">
|
||||
<span class="countdown font-mono text-xl sm:text-2xl">
|
||||
<span style="--value:{minutes};"></span>
|
||||
</span>
|
||||
min
|
||||
</div>
|
||||
<div class="flex flex-col text-xs">
|
||||
<span class="countdown font-mono text-xl sm:text-2xl">
|
||||
<span style="--value:{seconds};"></span>
|
||||
</span>
|
||||
sec
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -43,13 +43,19 @@
|
||||
>
|
||||
Dividend Announcement
|
||||
</h3>
|
||||
<label
|
||||
class="{latestInfoDate(rawData?.date)
|
||||
? ''
|
||||
: 'hidden'} text-black bg-[#fff] ml-2 font-semibold not-italic text-xs rounded px-2 py-0.5"
|
||||
>New</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="text-white text-[1rem] {latestInfoDate(rawData?.date)
|
||||
? 'bg-[#F9AB00] bg-opacity-[0.1] p-3 rounded-lg'
|
||||
? 'bg-[#F9AB00] bg-opacity-[0.1] p-3 rounded-md'
|
||||
: 'bg-[#09090B] pl-1'}"
|
||||
>
|
||||
<div class="mt-1">
|
||||
@ -72,10 +78,19 @@
|
||||
style="color: #fff; line-height: 22px; margin-bottom: 15px; list-style-type: disc;"
|
||||
>
|
||||
<span class="font-bold">Dividend:</span> ${rawData?.dividend} per share
|
||||
({rawData?.dividend / rawData?.dividendPrior - 1 > 0 ? "+" : ""}{(
|
||||
(rawData?.dividend / rawData?.dividendPrior - 1) *
|
||||
100
|
||||
)?.toFixed(2)}% YoY)
|
||||
(<span
|
||||
class="font-semibold {rawData?.dividend /
|
||||
rawData?.dividendPrior -
|
||||
1 >
|
||||
0
|
||||
? "before:content-['+'] text-[#00FC50]"
|
||||
: 'text-[#FF2F1F]'}"
|
||||
>
|
||||
{(
|
||||
(rawData?.dividend / rawData?.dividendPrior - 1) *
|
||||
100
|
||||
)?.toFixed(2)}%
|
||||
</span> YoY)
|
||||
</li>
|
||||
<li
|
||||
class="ml-[20px]"
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
|
||||
<Button
|
||||
on:click={() => exportData("csv")}
|
||||
class="ml-2 w-full border-gray-600 border bg-[#09090B] sm:hover:bg-[#27272A] ease-out flex flex-row justify-between items-center px-3 py-2 text-white rounded-lg truncate"
|
||||
class="ml-2 w-full border-gray-600 border bg-[#09090B] sm:hover:bg-[#27272A] ease-out flex flex-row justify-between items-center px-3 py-2 text-white rounded-md truncate"
|
||||
>
|
||||
<span class="truncate text-white">Download</span>
|
||||
<svg
|
||||
|
||||
@ -1,15 +1,31 @@
|
||||
|
||||
<script lang='ts'>
|
||||
|
||||
export let state;
|
||||
let color = state === 'active' ? '#0076FE' : '#D6D6DC'
|
||||
|
||||
<script lang="ts">
|
||||
export let state;
|
||||
let color = state === "active" ? "#0076FE" : "#D6D6DC";
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<div class="flex justify-center items-center {state === 'active' ? 'text-[#0076FE] bg-[#31304D] lg:bg-inherit' : 'text-[#A6ADBB]'} rounded-lg w-8 h-8 relative">
|
||||
<svg class="lg:hidden inline-block w-4 h-4 " version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512.171 512.171" xml:space="preserve"><path fill="currentColor" d="M479.046,283.925c-1.664-3.989-5.547-6.592-9.856-6.592H352.305V10.667C352.305,4.779,347.526,0,341.638,0H170.971 c-5.888,0-10.667,4.779-10.667,10.667v266.667H42.971c-4.309,0-8.192,2.603-9.856,6.571c-1.643,3.989-0.747,8.576,2.304,11.627 l212.8,213.504c2.005,2.005,4.715,3.136,7.552,3.136s5.547-1.131,7.552-3.115l213.419-213.504 C479.793,292.501,480.71,287.915,479.046,283.925z"></path></svg>
|
||||
<svg class="hidden lg:block cursor-pointer inline-block w-9 h-9 hover:text-[#fff] text-[#5C5C5C]" fill={state === 'active' ? color : "currentColor"} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M17.9188 8.17969H11.6888H6.07877C5.11877 8.17969 4.63877 9.33969 5.31877 10.0197L10.4988 15.1997C11.3288 16.0297 12.6788 16.0297 13.5088 15.1997L15.4788 13.2297L18.6888 10.0197C19.3588 9.33969 18.8788 8.17969 17.9188 8.17969Z" /></svg>
|
||||
<div
|
||||
class="flex justify-center items-center {state === 'active'
|
||||
? 'text-[#0076FE] bg-[#31304D] lg:bg-inherit'
|
||||
: 'text-[#A6ADBB]'} rounded-md w-8 h-8 relative"
|
||||
>
|
||||
<svg
|
||||
class="lg:hidden inline-block w-4 h-4"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512.171 512.171"
|
||||
xml:space="preserve"
|
||||
><path
|
||||
fill="currentColor"
|
||||
d="M479.046,283.925c-1.664-3.989-5.547-6.592-9.856-6.592H352.305V10.667C352.305,4.779,347.526,0,341.638,0H170.971 c-5.888,0-10.667,4.779-10.667,10.667v266.667H42.971c-4.309,0-8.192,2.603-9.856,6.571c-1.643,3.989-0.747,8.576,2.304,11.627 l212.8,213.504c2.005,2.005,4.715,3.136,7.552,3.136s5.547-1.131,7.552-3.115l213.419-213.504 C479.793,292.501,480.71,287.915,479.046,283.925z"
|
||||
></path></svg
|
||||
>
|
||||
<svg
|
||||
class="hidden lg:block cursor-pointer inline-block w-9 h-9 hover:text-[#fff] text-[#5C5C5C]"
|
||||
fill={state === "active" ? color : "currentColor"}
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><path
|
||||
d="M17.9188 8.17969H11.6888H6.07877C5.11877 8.17969 4.63877 9.33969 5.31877 10.0197L10.4988 15.1997C11.3288 16.0297 12.6788 16.0297 13.5088 15.1997L15.4788 13.2297L18.6888 10.0197C19.3588 9.33969 18.8788 8.17969 17.9188 8.17969Z"
|
||||
/></svg
|
||||
>
|
||||
</div>
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@
|
||||
: 'hidden'}"
|
||||
>
|
||||
<div
|
||||
class="sm:rounded-lg shadow-lg bg-[#000] sm:bg-[#09090B] sm:border sm:border-slate-800 h-auto sm:h-[470px] {$screenWidth <
|
||||
class="sm:rounded-md shadow-lg bg-[#000] sm:bg-[#09090B] sm:border sm:border-slate-800 h-auto sm:h-[470px] {$screenWidth <
|
||||
640
|
||||
? 'w-screen pt-16'
|
||||
: ''} md:w-[420px] xl:w-[450px] -mx-1 sm:mx-0"
|
||||
@ -70,7 +70,7 @@
|
||||
its ESG (Environmental, Social, and Governance) scores.
|
||||
</p>
|
||||
|
||||
<div class="flex flex-col m-auto items-center rounded-lg w-full mb-16">
|
||||
<div class="flex flex-col m-auto items-center rounded-md w-full mb-16">
|
||||
<div class="flex flex-col items-center w-full">
|
||||
<div class="flex flex-row items-center w-11/12 mt-2 mb-2">
|
||||
<span class="text-white font-medium text-start mr-auto">
|
||||
@ -178,10 +178,10 @@
|
||||
|
||||
{#if esgScore && esgRiskRating && environmentalScore && governanceScore !== "n/a"}
|
||||
<div
|
||||
class="mt-5 flex flex-col m-auto items-center rounded-lg w-full mb-16 p-3"
|
||||
class="mt-5 flex flex-col m-auto items-center rounded-md w-full mb-16 p-3"
|
||||
>
|
||||
<div
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-lg p-4 mb-5 flex flex-row items-center"
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-md 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">
|
||||
@ -205,7 +205,7 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-lg p-4 mb-5 flex flex-row items-center"
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-md 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">
|
||||
@ -229,7 +229,7 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-lg p-4 mb-5 flex flex-row items-center"
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-md 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">
|
||||
@ -253,7 +253,7 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-lg p-4 mb-5 flex flex-row items-center"
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-md 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">
|
||||
|
||||
@ -1,69 +1,97 @@
|
||||
<script lang="ts">
|
||||
import {etfTicker, wsBidPrice, wsAskPrice, screenWidth, displayCompanyName} from '$lib/store';
|
||||
|
||||
import { abbreviateNumber, formatETFName } from '$lib/utils';
|
||||
import { fade } from 'svelte/transition';
|
||||
import { goto } from '$app/navigation';
|
||||
import defaultImage from '$lib/images/etf/cover/default.jpg';
|
||||
|
||||
export let etfProfile;
|
||||
export let data;
|
||||
|
||||
let info;
|
||||
let assetClass = '-';
|
||||
let aum = '-';
|
||||
let avgVolume = '-';
|
||||
let inceptionDate = '-';
|
||||
let holdingsCount = '-';
|
||||
let provider = '-';
|
||||
let sectorExposed;
|
||||
let country;
|
||||
let description = '';
|
||||
let website = '-';
|
||||
let snippet;
|
||||
let dividendYield = '-';
|
||||
let payoutRatio = '-';
|
||||
import {
|
||||
etfTicker,
|
||||
wsBidPrice,
|
||||
wsAskPrice,
|
||||
screenWidth,
|
||||
displayCompanyName,
|
||||
} from "$lib/store";
|
||||
|
||||
let showFullText = false;
|
||||
|
||||
|
||||
import { abbreviateNumber, formatETFName } from "$lib/utils";
|
||||
import { fade } from "svelte/transition";
|
||||
import { goto } from "$app/navigation";
|
||||
import defaultImage from "$lib/images/etf/cover/default.jpg";
|
||||
|
||||
export let etfProfile;
|
||||
export let data;
|
||||
|
||||
let info;
|
||||
let assetClass = "-";
|
||||
let aum = "-";
|
||||
let avgVolume = "-";
|
||||
let inceptionDate = "-";
|
||||
let holdingsCount = "-";
|
||||
let provider = "-";
|
||||
let sectorExposed;
|
||||
let country;
|
||||
let description = "";
|
||||
let website = "-";
|
||||
let snippet;
|
||||
let dividendYield = "-";
|
||||
let payoutRatio = "-";
|
||||
|
||||
let showFullText = false;
|
||||
|
||||
$: {
|
||||
if ($etfTicker && typeof $etfTicker !== 'undefined' && typeof window !== 'undefined' && typeof etfProfile !== 'undefined' && etfProfile?.length !== 0)
|
||||
{
|
||||
|
||||
info = etfProfile?.at(0)
|
||||
if (
|
||||
$etfTicker &&
|
||||
typeof $etfTicker !== "undefined" &&
|
||||
typeof window !== "undefined" &&
|
||||
typeof etfProfile !== "undefined" &&
|
||||
etfProfile?.length !== 0
|
||||
) {
|
||||
info = etfProfile?.at(0);
|
||||
assetClass = info?.assetClass;
|
||||
sectorExposed = info?.sectorsList?.length;
|
||||
aum = info?.aum;
|
||||
country = info?.domicile;
|
||||
inceptionDate = new Date(info?.inceptionDate)?.toLocaleDateString('en-GB', { day: '2-digit', month: '2-digit', year: 'numeric' }).replace(/\//g, '.');
|
||||
inceptionDate = new Date(info?.inceptionDate)
|
||||
?.toLocaleDateString("en-GB", {
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
year: "numeric",
|
||||
})
|
||||
.replace(/\//g, ".");
|
||||
holdingsCount = info?.holdingsCount;
|
||||
avgVolume = info?.avgVolume;
|
||||
dividendYield = typeof data?.getStockDividend?.dividendYield !== 'undefined' ? data?.getStockDividend?.dividendYield?.toFixed(2)+'%' : '-'
|
||||
payoutRatio = (typeof data?.getStockDividend?.payoutRatio !== 'undefined' && data?.getStockDividend?.payoutRatio !== null) ? data?.getStockDividend?.payoutRatio?.toFixed(2)+'%' : '-'
|
||||
avgVolume = info?.avgVolume;
|
||||
dividendYield =
|
||||
typeof data?.getStockDividend?.dividendYield !== "undefined"
|
||||
? data?.getStockDividend?.dividendYield?.toFixed(2) + "%"
|
||||
: "-";
|
||||
payoutRatio =
|
||||
typeof data?.getStockDividend?.payoutRatio !== "undefined" &&
|
||||
data?.getStockDividend?.payoutRatio !== null
|
||||
? data?.getStockDividend?.payoutRatio?.toFixed(2) + "%"
|
||||
: "-";
|
||||
|
||||
provider = info?.etfProvider;
|
||||
country = info?.domicile ?? '-';
|
||||
description = info?.description ?? 'A detailed description of the company is not yet available.';
|
||||
country = info?.domicile ?? "-";
|
||||
description =
|
||||
info?.description ??
|
||||
"A detailed description of the company is not yet available.";
|
||||
website = info?.website;
|
||||
snippet= description?.slice(0, 150) + "...";
|
||||
snippet = description?.slice(0, 150) + "...";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="sm:space-y-3">
|
||||
<div class="sm:rounded-lg shadow-lg sm:border sm:border-slate-800 bg-[#000] lg:bg-[#09090B] h-auto h-auto w-screen pt-16 sm:w-full md:w-[420px] xl:w-[450px] lg:pt-0">
|
||||
</script>
|
||||
|
||||
<!--Start Header-->
|
||||
<div class="lg:rounded-t-sm w-full h-[130px] bg-[#09090B] p-3 flex flex-col bg-cover bg-center bg-no-repeat" style="background-image: url('{defaultImage}');">
|
||||
|
||||
<div class="flex flex-row pt-1 pb-2">
|
||||
<div class="badge badge-error gap-2 mt-2 font-medium text-sm text-white">
|
||||
Asset Class - {assetClass}
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="sm:space-y-3">
|
||||
<div
|
||||
class="sm:rounded-md shadow-lg sm:border sm:border-slate-800 bg-[#000] lg:bg-[#09090B] h-auto h-auto w-screen pt-16 sm:w-full md:w-[420px] xl:w-[450px] lg:pt-0"
|
||||
>
|
||||
<!--Start Header-->
|
||||
<div
|
||||
class="lg:rounded-t-sm w-full h-[130px] bg-[#09090B] p-3 flex flex-col bg-cover bg-center bg-no-repeat"
|
||||
style="background-image: url('{defaultImage}');"
|
||||
>
|
||||
<div class="flex flex-row pt-1 pb-2">
|
||||
<div
|
||||
class="badge badge-error gap-2 mt-2 font-medium text-sm text-white"
|
||||
>
|
||||
Asset Class - {assetClass}
|
||||
</div>
|
||||
</div>
|
||||
<!--
|
||||
<div class="flex flex-row justify-end items-center mt-2 relative z-10 -my-5">
|
||||
<div style={`background-image: url(${sTier}`} class="animate-bounce circle-background mr-5 w-20 h-20 z-10">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-28 h-28" viewBox="0 0 106 34">
|
||||
@ -82,47 +110,107 @@ let showFullText = false;
|
||||
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
<!--End Header-->
|
||||
</div>
|
||||
<!--End Header-->
|
||||
|
||||
<!--Start Content-->
|
||||
<div class="w-full flex flex-wrap border-t border-slate-800">
|
||||
<h2 class="text-start ml-4 text-2xl font-bold text-white pb-2 mt-3">ETF Info</h2>
|
||||
<div class="flex items-center w-full">
|
||||
<table class="table table-sm table-compact">
|
||||
<tbody>
|
||||
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">Bid</td>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]">{$wsBidPrice !== 0 && $wsBidPrice !== null ? $wsBidPrice : data?.getStockQuote?.bid}</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">Ask</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B]">{$wsAskPrice !== 0 && $wsAskPrice !== null ? $wsAskPrice : data?.getStockQuote?.ask}</td>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">Provider</td>
|
||||
<td on:click={() => goto(`/etf/etf-providers/${provider}`)} class="text-center sm:text-end text-blue-400 lg:hover:text-white cursor-pointer bg-[#000] lg:bg-[#09090B]">{formatETFName(provider)}</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap ">Country</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] whitespace-nowrap ">{country?.length !== 0 ? country : '-'}</td>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">AUM</td>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]">{abbreviateNumber(aum,true)}</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap ">Vol</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] whitespace-nowrap ">{abbreviateNumber(data?.getStockQuote?.volume)}</td>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">NAV</td>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]">{info?.nav?.toFixed(2)}</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">Expense Ratio</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B]">{info?.expenseRatio?.toFixed(2)}%</td>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">Shares Out.</td>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]">{abbreviateNumber(data?.getStockQuote?.sharesOutstanding)}</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap ">Avg. Vol</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] whitespace-nowrap ">{abbreviateNumber(avgVolume)}</td>
|
||||
</tr>
|
||||
<!--
|
||||
<!--Start Content-->
|
||||
<div class="w-full flex flex-wrap border-t border-slate-800">
|
||||
<h2 class="text-start ml-4 text-2xl font-bold text-white pb-2 mt-3">
|
||||
ETF Info
|
||||
</h2>
|
||||
<div class="flex items-center w-full">
|
||||
<table class="table table-sm table-compact">
|
||||
<tbody>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Bid</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]"
|
||||
>{$wsBidPrice !== 0 && $wsBidPrice !== null
|
||||
? $wsBidPrice
|
||||
: data?.getStockQuote?.bid}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Ask</td
|
||||
>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B]"
|
||||
>{$wsAskPrice !== 0 && $wsAskPrice !== null
|
||||
? $wsAskPrice
|
||||
: data?.getStockQuote?.ask}</td
|
||||
>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Provider</td
|
||||
>
|
||||
<td
|
||||
on:click={() => goto(`/etf/etf-providers/${provider}`)}
|
||||
class="text-center sm:text-end text-blue-400 lg:hover:text-white cursor-pointer bg-[#000] lg:bg-[#09090B]"
|
||||
>{formatETFName(provider)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Country</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] whitespace-nowrap"
|
||||
>{country?.length !== 0 ? country : "-"}</td
|
||||
>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>AUM</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]"
|
||||
>{abbreviateNumber(aum, true)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Vol</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] whitespace-nowrap"
|
||||
>{abbreviateNumber(data?.getStockQuote?.volume)}</td
|
||||
>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>NAV</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]"
|
||||
>{info?.nav?.toFixed(2)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Expense Ratio</td
|
||||
>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B]"
|
||||
>{info?.expenseRatio?.toFixed(2)}%</td
|
||||
>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Shares Out.</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]"
|
||||
>{abbreviateNumber(data?.getStockQuote?.sharesOutstanding)}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Avg. Vol</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] whitespace-nowrap"
|
||||
>{abbreviateNumber(avgVolume)}</td
|
||||
>
|
||||
</tr>
|
||||
<!--
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">Open</td>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]">{data?.getStockQuote?.open?.toFixed(2)}</td>
|
||||
@ -130,69 +218,94 @@ let showFullText = false;
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] whitespace-nowrap ">{data?.getStockQuote?.previousClose?.toFixed(2)}</td>
|
||||
</tr>
|
||||
-->
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">Dividend Yield</td>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]">{dividendYield}</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">Payout Ratio</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B]">{payoutRatio}</td>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">Holdings</td>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]">{holdingsCount} Assets</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap">Inception</td>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B]">{inceptionDate}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Dividend Yield</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]"
|
||||
>{dividendYield}</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Payout Ratio</td
|
||||
>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B]"
|
||||
>{payoutRatio}</td
|
||||
>
|
||||
</tr>
|
||||
<tr class="text-white border-b border-[#27272A]">
|
||||
<td
|
||||
class="text-start bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Holdings</td
|
||||
>
|
||||
<td class="text-center sm:text-end bg-[#000] lg:bg-[#09090B]"
|
||||
>{holdingsCount} Assets</td
|
||||
>
|
||||
<td
|
||||
class="text-start sm:text-end bg-[#000] lg:bg-[#09090B] text-white font-semibold whitespace-nowrap"
|
||||
>Inception</td
|
||||
>
|
||||
<td class="text-start sm:text-end bg-[#000] lg:bg-[#09090B]"
|
||||
>{inceptionDate}</td
|
||||
>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2
|
||||
class="text-start ml-4 text-xl font-bold text-white pb-2 pt-6 lg:pt-3"
|
||||
>
|
||||
Description
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-100 ml-2 text-sm whitespace-normal p-2">
|
||||
{#if showFullText}
|
||||
<div transition:fade={{ delay: 0, duration: 80 }} in={showFullText}>
|
||||
{description}
|
||||
</div>
|
||||
|
||||
<h2 class="text-start ml-4 text-xl font-bold text-white pb-2 pt-6 lg:pt-3">
|
||||
Description
|
||||
</h2>
|
||||
|
||||
|
||||
<p class="text-gray-100 ml-2 text-sm whitespace-normal p-2">
|
||||
{:else if $screenWidth <= 800}
|
||||
{description}
|
||||
{:else}
|
||||
{snippet}
|
||||
{/if}
|
||||
</p>
|
||||
{#if description.length !== 0}
|
||||
<div class="flex flex-row w-full items-center mt-4 pb-2 mb-2">
|
||||
<label
|
||||
on:click={() => (showFullText = !showFullText)}
|
||||
class="hidden lg:block ml-3 w-full text-md mt-1 cursor-pointer font-medium text-white sm:hover:text-blue-400 sm:hover:underline"
|
||||
>
|
||||
{#if showFullText}
|
||||
<div transition:fade={{ delay: 0, duration: 80 }} in={showFullText}>
|
||||
{description}
|
||||
</div>
|
||||
{:else if $screenWidth <= 800}
|
||||
{description}
|
||||
Show less
|
||||
{:else}
|
||||
{snippet}
|
||||
{/if}
|
||||
</p>
|
||||
{#if description.length !== 0 }
|
||||
<div class="flex flex-row w-full items-center mt-4 pb-2 mb-2">
|
||||
<label on:click={() => showFullText = !showFullText} class="hidden lg:block ml-3 w-full text-md mt-1 cursor-pointer font-medium text-white sm:hover:text-blue-400 sm:hover:underline">
|
||||
{#if showFullText}
|
||||
Show less
|
||||
{:else}
|
||||
Show more
|
||||
{/if}
|
||||
</label>
|
||||
|
||||
{/if}
|
||||
</label>
|
||||
|
||||
<div class="flex justify-end w-full relative bottom-0 right-0 mr-3">
|
||||
<a target ="_blank" href="{website}" class="inline-flex text-sm font-medium text-white sm:hover:text-blue-400 sm:hover:underline">
|
||||
<a
|
||||
target="_blank"
|
||||
href={website}
|
||||
class="inline-flex text-sm font-medium text-white sm:hover:text-blue-400 sm:hover:underline"
|
||||
>
|
||||
Go to website
|
||||
<svg class="w-5 h-5 ml-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z"></path><path d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z"></path></svg>
|
||||
<svg
|
||||
class="w-5 h-5 ml-2"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><path
|
||||
d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z"
|
||||
></path><path
|
||||
d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z"
|
||||
></path></svg
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/if}
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@ -53,13 +53,19 @@
|
||||
>
|
||||
Earnings Surprise
|
||||
</h3>
|
||||
<label
|
||||
class="{latestInfoDate(rawData?.date)
|
||||
? ''
|
||||
: 'hidden'} text-black bg-[#fff] ml-2 font-semibold not-italic text-xs rounded px-2 py-0.5"
|
||||
>New</label
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="text-white text-[1rem] {latestInfoDate(rawData?.date)
|
||||
? 'bg-[#F9AB00] bg-opacity-[0.1] p-3 rounded-lg'
|
||||
? 'bg-[#F9AB00] bg-opacity-[0.1] p-3 rounded-md'
|
||||
: 'bg-[#09090B] pl-1'} "
|
||||
>
|
||||
<div class="mt-1">
|
||||
|
||||
@ -182,7 +182,7 @@
|
||||
|
||||
{#if isLoaded}
|
||||
{#if Object?.keys(rawData)?.length !== 0}
|
||||
<div class="mt-2 pb-8 sm:pb-2 rounded-lg bg-[#09090B] sm:bg-[#09090B]">
|
||||
<div class="mt-2 pb-8 sm:pb-2 rounded-md bg-[#09090B] sm:bg-[#09090B]">
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-[1rem] mt-1 sm:mt-3 mb-1 w-full">
|
||||
Examine how sensitive {$displayCompanyName}'s stock price is to
|
||||
|
||||
@ -1,13 +1,22 @@
|
||||
<script lang='ts'>
|
||||
import { failToDeliverComponent, displayCompanyName, stockTicker, assetType, etfTicker, screenWidth, getCache, setCache } from '$lib/store';
|
||||
import InfoModal from '$lib/components/InfoModal.svelte';
|
||||
import { Chart } from 'svelte-echarts';
|
||||
<script lang="ts">
|
||||
import {
|
||||
failToDeliverComponent,
|
||||
displayCompanyName,
|
||||
stockTicker,
|
||||
assetType,
|
||||
etfTicker,
|
||||
screenWidth,
|
||||
getCache,
|
||||
setCache,
|
||||
} from "$lib/store";
|
||||
import InfoModal from "$lib/components/InfoModal.svelte";
|
||||
import { Chart } from "svelte-echarts";
|
||||
import { abbreviateNumber, formatDateRange, monthNames } from "$lib/utils";
|
||||
|
||||
import { init, use } from 'echarts/core';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { init, use } from "echarts/core";
|
||||
import { LineChart } from "echarts/charts";
|
||||
import { GridComponent, TooltipComponent } from "echarts/components";
|
||||
import { CanvasRenderer } from "echarts/renderers";
|
||||
|
||||
export let data;
|
||||
|
||||
@ -25,12 +34,12 @@
|
||||
const lastDate = new Date(lastDateStr);
|
||||
const firstDate = new Date(lastDate.getFullYear(), lastDate.getMonth(), 1);
|
||||
|
||||
const filteredData = data?.filter(item => {
|
||||
const filteredData = data?.filter((item) => {
|
||||
const currentDate = new Date(item?.date);
|
||||
return currentDate >= firstDate && currentDate <= lastDate;
|
||||
});
|
||||
|
||||
let prices = filteredData?.map(item => parseFloat(item.price));
|
||||
let prices = filteredData?.map((item) => parseFloat(item.price));
|
||||
|
||||
lowestPrice = Math.min(...prices);
|
||||
highestPrice = Math.max(...prices);
|
||||
@ -41,7 +50,7 @@
|
||||
let priceList = [];
|
||||
let failToDeliverList = [];
|
||||
|
||||
rawData?.forEach(item => {
|
||||
rawData?.forEach((item) => {
|
||||
dates?.push(item?.date);
|
||||
priceList?.push(item?.price);
|
||||
failToDeliverList?.push(item?.failToDeliver);
|
||||
@ -55,47 +64,47 @@
|
||||
const option = {
|
||||
silent: true,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
trigger: "axis",
|
||||
hideDelay: 100,
|
||||
},
|
||||
animation: false,
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '3%',
|
||||
bottom: '2%',
|
||||
top: '5%',
|
||||
containLabel: true
|
||||
left: "3%",
|
||||
right: "3%",
|
||||
bottom: "2%",
|
||||
top: "5%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
type: "category",
|
||||
boundaryGap: false,
|
||||
data: dates,
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
color: "#fff",
|
||||
formatter: function (value) {
|
||||
const dateParts = value.split('-');
|
||||
const dateParts = value.split("-");
|
||||
const day = dateParts[2].substring(0);
|
||||
const monthIndex = parseInt(dateParts[1]) - 1;
|
||||
return `${day} ${monthNames[monthIndex]}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
type: "value",
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
show: false,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
type: "value",
|
||||
splitLine: {
|
||||
show: false,
|
||||
},
|
||||
position: 'right',
|
||||
position: "right",
|
||||
axisLabel: {
|
||||
show: false,
|
||||
},
|
||||
@ -103,206 +112,229 @@
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'Price',
|
||||
name: "Price",
|
||||
data: priceList,
|
||||
type: 'line',
|
||||
type: "line",
|
||||
itemStyle: {
|
||||
color: '#fff',
|
||||
color: "#fff",
|
||||
},
|
||||
showSymbol: false,
|
||||
},
|
||||
{
|
||||
name: 'FTD Shares',
|
||||
name: "FTD Shares",
|
||||
data: failToDeliverList,
|
||||
type: 'line',
|
||||
type: "line",
|
||||
areaStyle: { opacity: 1 },
|
||||
yAxisIndex: 1,
|
||||
itemStyle: {
|
||||
color: '#E11D48',
|
||||
color: "#E11D48",
|
||||
},
|
||||
showSymbol: false,
|
||||
},
|
||||
]
|
||||
],
|
||||
};
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
const getFailToDeliver = async (ticker) => {
|
||||
const cachedData = getCache(ticker, 'getFailToDeliver');
|
||||
const cachedData = getCache(ticker, "getFailToDeliver");
|
||||
if (cachedData) {
|
||||
rawData = cachedData;
|
||||
} else {
|
||||
const postData = { 'ticker': ticker, path: 'fail-to-deliver' };
|
||||
const response = await fetch('/api/ticker-data', {
|
||||
method: 'POST',
|
||||
const postData = { ticker: ticker, path: "fail-to-deliver" };
|
||||
const response = await fetch("/api/ticker-data", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
body: JSON.stringify(postData),
|
||||
});
|
||||
|
||||
rawData = await response.json();
|
||||
setCache(ticker, rawData, 'getFailToDeliver');
|
||||
setCache(ticker, rawData, "getFailToDeliver");
|
||||
}
|
||||
|
||||
failToDeliverComponent.set(rawData?.length !== 0);
|
||||
};
|
||||
|
||||
$: {
|
||||
const ticker = $assetType === 'stock' ? $stockTicker : $etfTicker;
|
||||
if (ticker && typeof window !== 'undefined') {
|
||||
const ticker = $assetType === "stock" ? $stockTicker : $etfTicker;
|
||||
if (ticker && typeof window !== "undefined") {
|
||||
isLoaded = false;
|
||||
Promise.all([getFailToDeliver(ticker)])
|
||||
.then(() => {
|
||||
if (rawData?.length !== 0) {
|
||||
weightedFTD = ((rawData?.slice(-1)?.at(0)?.failToDeliver / data?.getStockQuote?.avgVolume) * 100)?.toFixed(2);
|
||||
weightedFTD = (
|
||||
(rawData?.slice(-1)?.at(0)?.failToDeliver /
|
||||
data?.getStockQuote?.avgVolume) *
|
||||
100
|
||||
)?.toFixed(2);
|
||||
optionsData = getPlotOptions();
|
||||
}
|
||||
})
|
||||
.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="failToDeliverInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
|
||||
Fail to Deliver
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Fail to Deliver"}
|
||||
content={"Failure to deliver in the stock market occurs when a seller does not deliver securities to the buyer within the settlement period. Naked shorts contribute to this by selling shares not owned or borrowed, potentially distorting market dynamics and regulations."}
|
||||
id={"failToDeliverInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if isLoaded}
|
||||
|
||||
{#if rawData?.length !== 0}
|
||||
|
||||
<section class="overflow-hidden text-white h-full pb-8">
|
||||
<main class="overflow-hidden">
|
||||
<div class="flex flex-row items-center">
|
||||
<label
|
||||
for="failToDeliverInfo"
|
||||
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
|
||||
>
|
||||
Fail to Deliver
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Fail to Deliver"}
|
||||
content={"Failure to deliver in the stock market occurs when a seller does not deliver securities to the buyer within the settlement period. Naked shorts contribute to this by selling shares not owned or borrowed, potentially distorting market dynamics and regulations."}
|
||||
id={"failToDeliverInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if isLoaded}
|
||||
{#if rawData?.length !== 0}
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
|
||||
Over the past year, {$displayCompanyName} has seen a monthly average of
|
||||
<span class="font-semibold">{abbreviateNumber(avgFailToDeliver)}</span> fail to deliver shares.
|
||||
</div>
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
|
||||
Over the past year, {$displayCompanyName} has seen a monthly average
|
||||
of
|
||||
<span class="font-semibold"
|
||||
>{abbreviateNumber(avgFailToDeliver)}</span
|
||||
> fail to deliver shares.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pb-2 rounded-lg bg-[#09090B]">
|
||||
|
||||
|
||||
|
||||
<div class="pb-2 rounded-md bg-[#09090B]">
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12">
|
||||
<div class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block">
|
||||
Price
|
||||
|
||||
<div
|
||||
class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12"
|
||||
>
|
||||
<div
|
||||
class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block"
|
||||
>
|
||||
Price
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#E11D48] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block"
|
||||
>
|
||||
Share Quantity
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#E11D48] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block">
|
||||
Share Quantity
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<h2 class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3">
|
||||
Latest Information
|
||||
</h2>
|
||||
|
||||
|
||||
<div class="flex justify-start items-center w-full m-auto ">
|
||||
<table class="w-full" data-test="statistics-table">
|
||||
<tbody>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Date</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right whitespace-nowrap font-medium xs:px-2.5 xs:py-2">
|
||||
{formatDateRange(rawData?.slice(-1)?.at(0)?.date)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Price Range</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2">
|
||||
{lowestPrice+'-'+highestPrice}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Latest FTD</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2">
|
||||
{abbreviateNumber(rawData?.slice(-1)?.at(0)?.failToDeliver)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="w-full flex flex-col items-start mt-3">
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
|
||||
Using the latest FTD data, we divide it with the monthly average volume to determine that
|
||||
<strong>{weightedFTD < 0.01 ? 'less than < 0.01' : weightedFTD}%</strong> of shares failed to deliver.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{/if}
|
||||
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
|
||||
<span class="loading loading-spinner loading-md text-gray-400"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<h2
|
||||
class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3"
|
||||
>
|
||||
Latest Information
|
||||
</h2>
|
||||
|
||||
|
||||
</main>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
<div class="flex justify-start items-center w-full m-auto">
|
||||
<table class="w-full" data-test="statistics-table">
|
||||
<tbody>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Date</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right whitespace-nowrap font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{formatDateRange(rawData?.slice(-1)?.at(0)?.date)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Price Range</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{lowestPrice + "-" + highestPrice}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Latest FTD</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{abbreviateNumber(rawData?.slice(-1)?.at(0)?.failToDeliver)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="w-full flex flex-col items-start mt-3">
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
|
||||
Using the latest FTD data, we divide it with the monthly average
|
||||
volume to determine that
|
||||
<strong
|
||||
>{weightedFTD < 0.01 ? "less than < 0.01" : weightedFTD}%</strong
|
||||
> of shares failed to deliver.
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label
|
||||
class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||
>
|
||||
<span class="loading loading-spinner loading-md text-gray-400"
|
||||
></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 210px;
|
||||
.app {
|
||||
height: 210px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -211,7 +211,7 @@
|
||||
inputValue?.length !== 0) ||
|
||||
(category !== 'general' && inputValue?.length !== 0)
|
||||
? 'opacity-100 cursor-pointer'
|
||||
: 'opacity-60 cursor-not-allowed'} w-11/12 rounded-lg m-auto text-black font-semibold text-md"
|
||||
: 'opacity-60 cursor-not-allowed'} w-11/12 rounded-md m-auto text-black font-semibold text-md"
|
||||
>
|
||||
Send Feedback
|
||||
</button>
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
>
|
||||
<!--Start Flow Sentiment-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="font-medium text-gray-200 text-sm"
|
||||
@ -68,7 +68,7 @@
|
||||
<!--End Flow Sentiment-->
|
||||
<!--Start Put/Call-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="font-medium text-gray-200 text-sm">Accuracy</span>
|
||||
@ -130,7 +130,7 @@
|
||||
|
||||
<!--Start Precision-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="font-medium text-gray-200 text-sm">Precision</span>
|
||||
|
||||
@ -187,7 +187,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pb-2 rounded-lg bg-[#09090B]">
|
||||
<div class="pb-2 rounded-md bg-[#09090B]">
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
@ -1,215 +1,157 @@
|
||||
<script lang 'ts'></script>
|
||||
|
||||
<script lang ='ts'>
|
||||
import { displayCompanyName, stockTicker, screenWidth} from '$lib/store';
|
||||
import InfoModal from '$lib/components/InfoModal.svelte';
|
||||
import { Chart } from 'svelte-echarts'
|
||||
import { abbreviateNumber } from "$lib/utils";
|
||||
<section class="overflow-hidden text-white h-full pb-8 sm:pb-2">
|
||||
<main class="overflow-hidden">
|
||||
<div class="flex flex-row items-center">
|
||||
<label
|
||||
for="h1bVisaInfo"
|
||||
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
|
||||
>
|
||||
Talent Acquisition
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"H1B Visa"}
|
||||
content={"Add explanation"}
|
||||
id={"h1bVisaInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
import Lazy from 'svelte-lazy';
|
||||
{#if h1bVisaList?.length !== 0}
|
||||
<div
|
||||
class="p-3 sm:p-0 mt-2 pb-8 sm:pb-2 rounded-md bg-[#09090B] sm:bg-[#09090B]"
|
||||
>
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div
|
||||
class="text-white text-sm sm:text-[1rem] mt-1 sm:mt-3 mb-1 w-full"
|
||||
>
|
||||
Explore {$displayCompanyName} talent acquisition strategies for attracting
|
||||
top global talent, securing exceptional employees worldwide through the
|
||||
H1B Visa program, spanning sales to engineering roles.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href={"/stocks/" + $stockTicker + "/stats/employees"}
|
||||
class="text-blue-400 hover:text-white flex justify-end mt-3 text-sm sm:text-[1rem]"
|
||||
>
|
||||
Full Report
|
||||
</a>
|
||||
|
||||
export let h1bVisaList;
|
||||
let optionsData;
|
||||
<Lazy
|
||||
height={300}
|
||||
fadeOption={{ delay: 100, duration: 500 }}
|
||||
keep={true}
|
||||
>
|
||||
<div class="app w-full h-[300px]">
|
||||
<Chart options={optionsData} class="chart" />
|
||||
</div>
|
||||
</Lazy>
|
||||
|
||||
|
||||
function getPlotOptions() {
|
||||
let dates = [];
|
||||
let engineerApplication = [];
|
||||
let saleApplication = [];
|
||||
let marketingApplication = [];
|
||||
let managerApplication = [];
|
||||
// Iterate over the data and extract required information
|
||||
h1bVisaList?.forEach(item => {
|
||||
// Extract year and convert it to fiscal year format
|
||||
const fiscalYear = "FY" + String(item?.year)?.slice(2);
|
||||
dates?.push(fiscalYear);
|
||||
|
||||
// Extract totalValue
|
||||
engineerApplication?.push(item?.engineerApplication);
|
||||
saleApplication?.push(item?.saleApplication);
|
||||
marketingApplication?.push(item?.marketingApplication);
|
||||
managerApplication?.push(item?.managerApplication);
|
||||
});
|
||||
|
||||
|
||||
|
||||
const option = {
|
||||
silent: true,
|
||||
grid: {
|
||||
left: $screenWidth < 640 ? '0%' : '2%',
|
||||
right: $screenWidth < 640 ? '5%' : '2%',
|
||||
bottom: $screenWidth < 640 ? '0%' : '2%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
data: dates,
|
||||
type: 'category',
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#6E7079', // Change label color to white
|
||||
formatter: function (value) {
|
||||
return '#'+value // Format value in millions
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
data: saleApplication,
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: '#fff' // Change bar color to white
|
||||
}
|
||||
},
|
||||
{
|
||||
data: marketingApplication,
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: '#5470C6' // Change bar color to white
|
||||
}
|
||||
},
|
||||
{
|
||||
data: managerApplication,
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: '#FF2F1F' // Change bar color to white
|
||||
}
|
||||
},
|
||||
{
|
||||
data: engineerApplication,
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
color: '#F8901E' // Change bar color to white
|
||||
}
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
$: {
|
||||
if($stockTicker && typeof window !== 'undefined' && h1bVisaList?.length !== 0) {
|
||||
|
||||
optionsData = getPlotOptions()
|
||||
|
||||
// Calculate total number of contracts
|
||||
/*
|
||||
avgTotalValue = Math.floor((h1bVisaList?.reduce((sum, item) => sum + item?.totalValue, 0))/h1bVisaList?.length);
|
||||
const { year:yearWithMaxLobbying, totalValue: maxLobbying } = h1bVisaList?.reduce((max, item) => item?.totalValue > max?.totalValue ? item : max, h1bVisaList?.at(0));
|
||||
displayYear = yearWithMaxLobbying;
|
||||
displayMaxLobbying = maxLobbying
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
<section class="overflow-hidden text-white h-full pb-8 sm:pb-2">
|
||||
<main class="overflow-hidden ">
|
||||
|
||||
<div class="flex flex-row items-center">
|
||||
<label for="h1bVisaInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
|
||||
Talent Acquisition
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"H1B Visa"}
|
||||
content={"Add explanation"}
|
||||
id={"h1bVisaInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if h1bVisaList?.length !== 0}
|
||||
<div class="p-3 sm:p-0 mt-2 pb-8 sm:pb-2 rounded-lg bg-[#09090B] sm:bg-[#09090B]">
|
||||
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-sm sm:text-[1rem] mt-1 sm:mt-3 mb-1 w-full">
|
||||
Explore {$displayCompanyName} talent acquisition strategies for attracting top global talent, securing exceptional employees worldwide through the H1B Visa program, spanning sales to engineering roles.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a href="{'/stocks/'+$stockTicker+'/stats/employees'}" class="text-blue-400 hover:text-white flex justify-end mt-3 text-sm sm:text-[1rem]">
|
||||
Full Report
|
||||
</a>
|
||||
|
||||
<Lazy height={300} fadeOption={{delay: 100, duration: 500}} keep={true}>
|
||||
<div class="app w-full h-[300px] ">
|
||||
<Chart options={optionsData} class="chart" />
|
||||
</div>
|
||||
</Lazy>
|
||||
|
||||
<div class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-5/6">
|
||||
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full bg-gray-800 transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#F8901E] border-4 box-content border-gray-900 rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-sm sm:text-md inline-block">
|
||||
Engineer
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row items-center w-1/2 justify-center">
|
||||
<div class="h-full bg-gray-800 transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#fff] border-4 box-content border-gray-900 rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-sm sm:text-md sm:font-medium inline-block">
|
||||
Sale
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full bg-gray-800 transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#5470C6] border-4 box-content border-gray-900 rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-sm sm:text-md inline-block">
|
||||
Marketing
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full bg-gray-800 transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#FF2F1F] border-4 box-content border-gray-900 rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-sm sm:text-md inline-block">
|
||||
Manager
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
<h2 class="mt-10 mb-5 flex justify-center items-center text-3xl font-bold text-slate-700 m-auto">
|
||||
No data available
|
||||
<svg class="w-10 sm:w-12 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#334155" d="M18.68 12.32a4.49 4.49 0 0 0-6.36.01a4.49 4.49 0 0 0 0 6.36a4.508 4.508 0 0 0 5.57.63L21 22.39L22.39 21l-3.09-3.11c1.13-1.77.87-4.09-.62-5.57m-1.41 4.95c-.98.98-2.56.97-3.54 0c-.97-.98-.97-2.56.01-3.54c.97-.97 2.55-.97 3.53 0c.97.98.97 2.56 0 3.54M10.9 20.1a6.527 6.527 0 0 1-1.48-2.32C6.27 17.25 4 15.76 4 14v3c0 2.21 3.58 4 8 4c-.4-.26-.77-.56-1.1-.9M4 9v3c0 1.68 2.07 3.12 5 3.7v-.2c0-.93.2-1.85.58-2.69C6.34 12.3 4 10.79 4 9m8-6C7.58 3 4 4.79 4 7c0 2 3 3.68 6.85 4h.05c1.2-1.26 2.86-2 4.6-2c.91 0 1.81.19 2.64.56A3.215 3.215 0 0 0 20 7c0-2.21-3.58-4-8-4Z"/></svg>
|
||||
</h2>
|
||||
|
||||
{/if}
|
||||
|
||||
</main>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<div
|
||||
class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-5/6"
|
||||
>
|
||||
<div
|
||||
class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full bg-gray-800 transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#F8901E] border-4 box-content border-gray-900 rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-sm sm:text-md inline-block"
|
||||
>
|
||||
Engineer
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col sm:flex-row items-center w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full bg-gray-800 transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#fff] border-4 box-content border-gray-900 rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-sm sm:text-md sm:font-medium inline-block"
|
||||
>
|
||||
Sale
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full bg-gray-800 transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#5470C6] border-4 box-content border-gray-900 rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-sm sm:text-md inline-block"
|
||||
>
|
||||
Marketing
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full bg-gray-800 transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#FF2F1F] border-4 box-content border-gray-900 rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-sm sm:text-md inline-block"
|
||||
>
|
||||
Manager
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<h2
|
||||
class="mt-10 mb-5 flex justify-center items-center text-3xl font-bold text-slate-700 m-auto"
|
||||
>
|
||||
No data available
|
||||
<svg
|
||||
class="w-10 sm:w-12 inline-block"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
><path
|
||||
fill="#334155"
|
||||
d="M18.68 12.32a4.49 4.49 0 0 0-6.36.01a4.49 4.49 0 0 0 0 6.36a4.508 4.508 0 0 0 5.57.63L21 22.39L22.39 21l-3.09-3.11c1.13-1.77.87-4.09-.62-5.57m-1.41 4.95c-.98.98-2.56.97-3.54 0c-.97-.98-.97-2.56.01-3.54c.97-.97 2.55-.97 3.53 0c.97.98.97 2.56 0 3.54M10.9 20.1a6.527 6.527 0 0 1-1.48-2.32C6.27 17.25 4 15.76 4 14v3c0 2.21 3.58 4 8 4c-.4-.26-.77-.56-1.1-.9M4 9v3c0 1.68 2.07 3.12 5 3.7v-.2c0-.93.2-1.85.58-2.69C6.34 12.3 4 10.79 4 9m8-6C7.58 3 4 4.79 4 7c0 2 3 3.68 6.85 4h.05c1.2-1.26 2.86-2 4.6-2c.91 0 1.81.19 2.64.56A3.215 3.215 0 0 0 20 7c0-2.21-3.58-4-8-4Z"
|
||||
/></svg
|
||||
>
|
||||
</h2>
|
||||
{/if}
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<style>
|
||||
|
||||
.app {
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 230px;
|
||||
}
|
||||
height: 230px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart {
|
||||
.chart {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
<option value="252dclshv"> 1 Year historical volatility </option>
|
||||
</select>
|
||||
|
||||
<div class="pb-2 rounded-lg bg-[#09090B]">
|
||||
<div class="pb-2 rounded-md bg-[#09090B]">
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
@ -1,239 +1,198 @@
|
||||
<script lang="ts">
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import { markdownValue, markdownClicked } from '$lib/store';
|
||||
import showdown from 'showdown';
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { markdownValue, markdownClicked } from "$lib/store";
|
||||
import showdown from "showdown";
|
||||
|
||||
export let id;
|
||||
export let outputCounter;
|
||||
export let name;
|
||||
export let id;
|
||||
export let outputCounter;
|
||||
export let name;
|
||||
|
||||
const converter = new showdown.Converter();
|
||||
|
||||
const toolbarOptions = {
|
||||
container: [
|
||||
["bold"],
|
||||
["italic"],
|
||||
["link"],
|
||||
["image"],
|
||||
[{ list: "ordered" }, { list: "bullet" }],
|
||||
[{ header: [1, 2, 3, 4, 5, 6, false] }],
|
||||
],
|
||||
};
|
||||
|
||||
const converter = new showdown.Converter();
|
||||
let quill;
|
||||
let html;
|
||||
let value;
|
||||
|
||||
const toolbarOptions = {
|
||||
container: [
|
||||
['bold'],
|
||||
['italic'],
|
||||
['link'],
|
||||
['image'],
|
||||
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
|
||||
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
let quill;
|
||||
let html;
|
||||
let value;
|
||||
|
||||
async function initializeQuillEditor()
|
||||
{
|
||||
async function initializeQuillEditor() {
|
||||
const container = document.getElementById(id);
|
||||
|
||||
try {
|
||||
const { default: Quill } = await import('quill');
|
||||
const { default: Quill } = await import("quill");
|
||||
|
||||
quill = new Quill(container, {
|
||||
modules: {
|
||||
toolbar: toolbarOptions,
|
||||
},
|
||||
theme: 'snow',
|
||||
placeholder: 'Markdown your code here...',
|
||||
keepFocus: true,
|
||||
});
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
console.log(e)
|
||||
quill = new Quill(container, {
|
||||
modules: {
|
||||
toolbar: toolbarOptions,
|
||||
},
|
||||
theme: "snow",
|
||||
placeholder: "Markdown your code here...",
|
||||
keepFocus: true,
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
quill.on("editor-change", function () {
|
||||
const editor = quill.root;
|
||||
// Add text-4xl class to all h1 elements
|
||||
editor.querySelectorAll("h1").forEach((h1) => {
|
||||
h1.classList.add("text-4xl");
|
||||
});
|
||||
editor.querySelectorAll("h2").forEach((h2) => {
|
||||
h2.classList.add("text-3xl");
|
||||
});
|
||||
editor.querySelectorAll("h3").forEach((h3) => {
|
||||
h3.classList.add("text-xl");
|
||||
});
|
||||
editor.querySelectorAll("h4").forEach((h4) => {
|
||||
h4.classList.add("text-md");
|
||||
});
|
||||
editor.querySelectorAll("h5").forEach((h5) => {
|
||||
h5.classList.add("text-sm");
|
||||
});
|
||||
editor.querySelectorAll("h6").forEach((h6) => {
|
||||
h6.classList.add("text-xs");
|
||||
});
|
||||
|
||||
quill.on('editor-change', function() {
|
||||
const editor = quill.root;
|
||||
// Add text-4xl class to all h1 elements
|
||||
editor.querySelectorAll('h1').forEach((h1) => {
|
||||
h1.classList.add('text-4xl');
|
||||
});
|
||||
editor.querySelectorAll('h2').forEach((h2) => {
|
||||
h2.classList.add('text-3xl');
|
||||
});
|
||||
editor.querySelectorAll('h3').forEach((h3) => {
|
||||
h3.classList.add('text-xl');
|
||||
});
|
||||
editor.querySelectorAll('h4').forEach((h4) => {
|
||||
h4.classList.add('text-md');
|
||||
});
|
||||
editor.querySelectorAll('h5').forEach((h5) => {
|
||||
h5.classList.add('text-sm');
|
||||
});
|
||||
editor.querySelectorAll('h6').forEach((h6) => {
|
||||
h6.classList.add('text-xs');
|
||||
});
|
||||
editor.querySelectorAll("a").forEach((a) => {
|
||||
a.classList.add("text-blue-400", "hover:text-white", "underline");
|
||||
});
|
||||
|
||||
editor.querySelectorAll('a').forEach((a) => {
|
||||
a.classList.add('text-blue-400', 'hover:text-white','underline');
|
||||
});
|
||||
editor.querySelectorAll("ol").forEach((ol) => {
|
||||
ol.classList.add("list-decimal", "ml-10", "mt-3");
|
||||
});
|
||||
|
||||
editor.querySelectorAll('ol').forEach((ol) => {
|
||||
ol.classList.add('list-decimal','ml-10','mt-3');
|
||||
});
|
||||
editor.querySelectorAll("ul").forEach((ul) => {
|
||||
ul.classList.add("list-disc", "ml-10", "mt-3");
|
||||
});
|
||||
|
||||
editor.querySelectorAll('ul').forEach((ul) => {
|
||||
ul.classList.add('list-disc','ml-10','mt-3');
|
||||
});
|
||||
$: value = editor.innerHTML;
|
||||
|
||||
|
||||
$: value = editor.innerHTML;
|
||||
const contents = editor.innerHTML;
|
||||
markdownValue.update((value) => [
|
||||
...value.filter((item) => item.id !== id),
|
||||
{ id: id, name: name, input: contents },
|
||||
]);
|
||||
|
||||
const contents = editor.innerHTML;
|
||||
markdownValue.update((value) => [
|
||||
...value.filter((item) => item.id !== id),
|
||||
{ id: id , name: name, input: contents},
|
||||
]);
|
||||
console.log($markdownValue);
|
||||
|
||||
|
||||
console.log($markdownValue)
|
||||
|
||||
// Force Svelte to update the DOM
|
||||
$: {}
|
||||
});
|
||||
|
||||
// Convert the markdown value to HTML and set it as the content of the Quill editor
|
||||
html = converter.makeHtml($markdownValue[id]?.input || '');
|
||||
quill.setContents(quill.clipboard.convert(html));
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
onMount(async () => {
|
||||
|
||||
await initializeQuillEditor()
|
||||
// Force Svelte to update the DOM
|
||||
$: {
|
||||
}
|
||||
});
|
||||
|
||||
// Convert the markdown value to HTML and set it as the content of the Quill editor
|
||||
html = converter.makeHtml($markdownValue[id]?.input || "");
|
||||
quill.setContents(quill.clipboard.convert(html));
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
await initializeQuillEditor();
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (quill) {
|
||||
quill.off('text-change');
|
||||
quill.off("text-change");
|
||||
quill = null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
/** Dispatch event on click outside of node */
|
||||
function clickOutside(node) {
|
||||
|
||||
const handleClick = event => {
|
||||
if (node && !node.contains(event.target) && !event.defaultPrevented) {
|
||||
node.dispatchEvent(
|
||||
new CustomEvent('click_outside', node)
|
||||
)
|
||||
}
|
||||
const handleClick = (event) => {
|
||||
if (node && !node.contains(event.target) && !event.defaultPrevented) {
|
||||
node.dispatchEvent(new CustomEvent("click_outside", node));
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("click", handleClick, true);
|
||||
|
||||
return {
|
||||
destroy() {
|
||||
document.removeEventListener("click", handleClick, true);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
document.addEventListener('click', handleClick, true);
|
||||
|
||||
return {
|
||||
destroy() {
|
||||
document.removeEventListener('click', handleClick, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleClickOutside(event) {
|
||||
function handleClickOutside(event) {
|
||||
$markdownClicked[id] = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
function handleClick() {
|
||||
|
||||
function handleClick() {
|
||||
$markdownClicked[id] = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function hasContent(html) {
|
||||
const el = document.createElement('div');
|
||||
const el = document.createElement("div");
|
||||
el.innerHTML = html;
|
||||
let content = el.firstChild.innerHTML.trim();
|
||||
// Remove <br> tags
|
||||
content = content.replace(/<br\s*\/?>/gi, '');
|
||||
content = content.replace(/<br\s*\/?>/gi, "");
|
||||
|
||||
return content !== '';
|
||||
return content !== "";
|
||||
}
|
||||
|
||||
|
||||
|
||||
function keyCombination(event) {
|
||||
|
||||
if (event.key === "Enter" && event.shiftKey) {
|
||||
$markdownClicked[id] = false;
|
||||
event.preventDefault();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$: {
|
||||
if($markdownClicked)
|
||||
{
|
||||
console.log($markdownClicked)
|
||||
function keyCombination(event) {
|
||||
if (event.key === "Enter" && event.shiftKey) {
|
||||
$markdownClicked[id] = false;
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
$: {
|
||||
if ($markdownClicked) {
|
||||
console.log($markdownClicked);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
on:keydown={keyCombination}
|
||||
on:click={handleClick}
|
||||
use:clickOutside
|
||||
on:click_outside={handleClickOutside}
|
||||
class="text-gray-100 w-full sm:w-3/4 max-w-2xl mt-3 rounded-md"
|
||||
>
|
||||
<div
|
||||
class="{$markdownClicked[id] === false
|
||||
? 'hidden'
|
||||
: ''} text-gray-100 w-full sm:w-3/4 max-w-2xl mb-4 rounded-md"
|
||||
>
|
||||
<textarea bind:value {id} class="bg-[#1A1A27] min-h-12 w-full" />
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div on:keydown={keyCombination} on:click={handleClick} use:clickOutside on:click_outside={handleClickOutside} class="text-gray-100 w-full sm:w-3/4 max-w-2xl mt-3 rounded-lg ">
|
||||
|
||||
|
||||
<div class="{$markdownClicked[id] === false ? 'hidden' : '' } text-gray-100 w-full sm:w-3/4 max-w-2xl mb-4 rounded-lg ">
|
||||
|
||||
<textarea bind:value={value} id ={id} class="bg-[#1A1A27] min-h-12 w-full" />
|
||||
|
||||
</div>
|
||||
|
||||
<div class="{$markdownClicked[id] === true ? 'hidden' : '' } text-white mt-3 cursor-pointer w-full sm:w-3/4 max-w-2xl text-sm p-2">
|
||||
{#each $markdownValue as mk}
|
||||
{#if mk?.id === id}
|
||||
<div class="flex flex-col">
|
||||
<span class="text-gray-400 mb-4">[{outputCounter}] : </span>
|
||||
<div class="border-b border-slate-800 rounded-md ">
|
||||
{#if hasContent(value)}
|
||||
{@html value}
|
||||
{:else}
|
||||
<p class="italic text-gray-400">Markdown your code here...</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="{$markdownClicked[id] === true
|
||||
? 'hidden'
|
||||
: ''} text-white mt-3 cursor-pointer w-full sm:w-3/4 max-w-2xl text-sm p-2"
|
||||
>
|
||||
{#each $markdownValue as mk}
|
||||
{#if mk?.id === id}
|
||||
<div class="flex flex-col">
|
||||
<span class="text-gray-400 mb-4">[{outputCounter}] : </span>
|
||||
<div class="border-b border-slate-800 rounded-md">
|
||||
{#if hasContent(value)}
|
||||
{@html value}
|
||||
{:else}
|
||||
<p class="italic text-gray-400">Markdown your code here...</p>
|
||||
{/if}
|
||||
{/each}
|
||||
</div >
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
@import '/src/lib/assets/style_quill.css';
|
||||
|
||||
</style>
|
||||
@import "/src/lib/assets/style_quill.css";
|
||||
</style>
|
||||
|
||||
@ -1,394 +1,258 @@
|
||||
<script lang ='ts'>
|
||||
import { marketMakerComponent, displayCompanyName, stockTicker, assetType, etfTicker, screenWidth, getCache, setCache} from '$lib/store';
|
||||
import InfoModal from '$lib/components/InfoModal.svelte';
|
||||
import { Chart } from 'svelte-echarts'
|
||||
import { abbreviateNumber, formatString, formatDateRange, monthNames } from "$lib/utils";
|
||||
<script lang 'ts'></script>
|
||||
|
||||
import { init, use } from 'echarts/core'
|
||||
import { LineChart } from 'echarts/charts'
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components'
|
||||
import { CanvasRenderer } from 'echarts/renderers'
|
||||
|
||||
use([LineChart, GridComponent, TooltipComponent, CanvasRenderer])
|
||||
|
||||
|
||||
export let data;
|
||||
|
||||
let isLoaded = false;
|
||||
|
||||
|
||||
let rawData = {};
|
||||
let historyData = [];
|
||||
let topMarketMakers = [];
|
||||
let optionsData;
|
||||
let avgTradeCount;
|
||||
let avgShareQuantity;
|
||||
let avgNotionalSum;
|
||||
let showFullStats = false;
|
||||
|
||||
|
||||
|
||||
|
||||
function getPlotOptions() {
|
||||
let dates = [];
|
||||
let tradeCountList = [];
|
||||
let shareQuantityList = [];
|
||||
let notionalSumList = [];
|
||||
// Iterate over the data and extract required information
|
||||
historyData?.forEach(item => {
|
||||
|
||||
dates?.push(item?.date);
|
||||
tradeCountList?.push(item?.totalWeeklyTradeCount);
|
||||
shareQuantityList?.push(item?.totalWeeklyShareQuantity)
|
||||
notionalSumList?.push(item?.totalNotionalSum)
|
||||
});
|
||||
|
||||
|
||||
// Compute the average of item?.traded
|
||||
const totalTraded = tradeCountList?.reduce((acc, traded) => acc + traded, 0);
|
||||
avgTradeCount = totalTraded / tradeCountList?.length;
|
||||
|
||||
const totalShare = shareQuantityList?.reduce((acc, item) => acc + item, 0);
|
||||
avgShareQuantity = totalShare / shareQuantityList?.length;
|
||||
|
||||
const totalSum = notionalSumList?.reduce((acc, sentiment) => acc + sentiment, 0);
|
||||
avgNotionalSum = totalSum / notionalSumList?.length;
|
||||
|
||||
|
||||
|
||||
const option = {
|
||||
silent: true,
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
hideDelay: 100, // Set the delay in milliseconds
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '3%',
|
||||
bottom: '2%',
|
||||
top: '5%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: dates,
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
formatter: function (value) {
|
||||
// Assuming dates are in the format 'yyyy-mm-dd'
|
||||
// Extract the month and day from the date string and convert the month to its abbreviated name
|
||||
const dateParts = value.split('-');
|
||||
const day = dateParts[2].substring(0); // Extracting the last two digits of the year
|
||||
const monthIndex = parseInt(dateParts[1]) - 1; // Months are zero-indexed in JavaScript Date objects
|
||||
return `${day} ${monthNames[monthIndex]}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
axisLabel: {
|
||||
show: false // Hide y-axis labels
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
splitLine: {
|
||||
show: false, // Disable x-axis grid lines
|
||||
},
|
||||
position: 'right',
|
||||
axisLabel: {
|
||||
show: false // Hide y-axis labels
|
||||
},
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{ name: 'Notional Sum',
|
||||
data: notionalSumList,
|
||||
type: 'line',
|
||||
itemStyle: {
|
||||
color: '#fff' // Change bar color to white
|
||||
},
|
||||
showSymbol: false
|
||||
},
|
||||
{
|
||||
name: 'Shares',
|
||||
data: shareQuantityList,
|
||||
type: 'line',
|
||||
areaStyle: {opacity: 1},
|
||||
yAxisIndex: 1,
|
||||
itemStyle: {
|
||||
color: '#408FFF' // Change bar color to white
|
||||
},
|
||||
showSymbol: false
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
return option;
|
||||
}
|
||||
|
||||
const getMarketMaker = async (ticker) => {
|
||||
// Get cached data for the specific tickerID
|
||||
const cachedData = getCache(ticker, 'getMarketMaker');
|
||||
if (cachedData) {
|
||||
rawData = cachedData;
|
||||
} else {
|
||||
|
||||
const postData = {'ticker': ticker, path: 'market-maker'};
|
||||
// make the POST request to the endpoint
|
||||
const response = await fetch('/api/ticker-data', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
rawData = await response?.json();
|
||||
// Cache the data for this specific tickerID with a specific name 'getMarketMaker'
|
||||
setCache(ticker, rawData, 'getMarketMaker');
|
||||
}
|
||||
|
||||
if(Object?.keys(rawData)?.length !== 0) {
|
||||
$marketMakerComponent = true;
|
||||
} else {
|
||||
$marketMakerComponent = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$: {
|
||||
if($assetType === 'stock' ? $stockTicker :$etfTicker && typeof window !== 'undefined') {
|
||||
isLoaded=false;
|
||||
showFullStats = false;
|
||||
const ticker = $assetType === 'stock' ? $stockTicker :$etfTicker
|
||||
const asyncFunctions = [
|
||||
getMarketMaker(ticker)
|
||||
];
|
||||
Promise.all(asyncFunctions)
|
||||
.then((results) => {
|
||||
topMarketMakers = rawData?.topMarketMakers ?? [];
|
||||
historyData = rawData?.history;
|
||||
optionsData = getPlotOptions()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('An error occurred:', error);
|
||||
});
|
||||
isLoaded = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
let charNumber = 20;
|
||||
|
||||
$: {
|
||||
if($screenWidth < 640)
|
||||
{
|
||||
charNumber = 20;
|
||||
}
|
||||
else {
|
||||
charNumber =40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<section class="overflow-hidden text-white h-full pb-8">
|
||||
<main class="overflow-hidden ">
|
||||
|
||||
<div class="flex flex-row items-center">
|
||||
<label for="marketMakerInfo" class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold">
|
||||
Market Maker Activity
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Market Maker Activity"}
|
||||
content={"Market makers provide liquidity by quoting buy and sell prices, stabilizing markets. For retail traders, understanding this helps navigate tight spreads, execute trades effectively, and gauge market sentiment."}
|
||||
id={"marketMakerInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if isLoaded}
|
||||
<main class="overflow-hidden">
|
||||
<div class="flex flex-row items-center">
|
||||
<label
|
||||
for="marketMakerInfo"
|
||||
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-3xl font-bold"
|
||||
>
|
||||
Market Maker Activity
|
||||
</label>
|
||||
<InfoModal
|
||||
title={"Market Maker Activity"}
|
||||
content={"Market makers provide liquidity by quoting buy and sell prices, stabilizing markets. For retail traders, understanding this helps navigate tight spreads, execute trades effectively, and gauge market sentiment."}
|
||||
id={"marketMakerInfo"}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{#if isLoaded}
|
||||
{#if historyData?.length !== 0}
|
||||
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="w-full flex flex-col items-start">
|
||||
<div class="text-white text-[1rem] mt-2 mb-2 w-full">
|
||||
Over the past year, {$displayCompanyName} has seen a weekly average of
|
||||
<span class="font-semibold">{abbreviateNumber(avgTradeCount)}</span> trades, involving an average of
|
||||
<span class="font-semibold">{abbreviateNumber(avgShareQuantity)}</span> shares bought and sold.
|
||||
This activity sums up to an average total notional value of
|
||||
<span class="font-semibold">{abbreviateNumber(avgNotionalSum,true)}</span>.
|
||||
Over the past year, {$displayCompanyName} has seen a weekly average of
|
||||
<span class="font-semibold">{abbreviateNumber(avgTradeCount)}</span>
|
||||
trades, involving an average of
|
||||
<span class="font-semibold"
|
||||
>{abbreviateNumber(avgShareQuantity)}</span
|
||||
>
|
||||
shares bought and sold. This activity sums up to an average total
|
||||
notional value of
|
||||
<span class="font-semibold"
|
||||
>{abbreviateNumber(avgNotionalSum, true)}</span
|
||||
>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pb-2 rounded-lg bg-[#09090B]">
|
||||
|
||||
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12">
|
||||
<div class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block">
|
||||
Notional Sum
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center">
|
||||
<div class="h-full transform -translate-x-1/2 " aria-hidden="true"></div>
|
||||
<div class="w-3 h-3 bg-[#3B82F6] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2" aria-hidden="true"></div>
|
||||
<span class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block">
|
||||
Share Quantity
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<h2 class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3">
|
||||
Latest Information
|
||||
</h2>
|
||||
|
||||
|
||||
<div class="flex justify-start items-center w-full m-auto ">
|
||||
<table class="w-full" data-test="statistics-table">
|
||||
<tbody>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Date</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right whitespace-nowrap font-medium xs:px-2.5 xs:py-2">
|
||||
{formatDateRange(historyData?.slice(-1)?.at(0)?.date)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Total Notional Sum</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2">
|
||||
${abbreviateNumber(historyData?.slice(-1)?.at(0)?.totalNotionalSum)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Total Trade Count</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2">
|
||||
{abbreviateNumber(historyData?.slice(-1)?.at(0)?.totalWeeklyTradeCount)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Total Share Quantity</span>
|
||||
</td>
|
||||
<td class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2">
|
||||
{abbreviateNumber(historyData?.slice(-1)?.at(0)?.totalWeeklyShareQuantity)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="pb-2 rounded-md bg-[#09090B]">
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3">
|
||||
<div
|
||||
class="flex flex-row items-center justify-between mx-auto mt-5 w-full sm:w-11/12"
|
||||
>
|
||||
<div
|
||||
class="mt-3.5 sm:mt-0 flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#fff] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-center sm:text-start text-xs sm:text-md inline-block"
|
||||
>
|
||||
Notional Sum
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col sm:flex-row items-center ml-3 sm:ml-0 w-1/2 justify-center"
|
||||
>
|
||||
<div
|
||||
class="h-full transform -translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<div
|
||||
class="w-3 h-3 bg-[#3B82F6] border-4 box-content border-[#27272A] rounded-full transform sm:-translate-x-1/2"
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
<span
|
||||
class="mt-2 sm:mt-0 text-white text-xs sm:text-md sm:font-medium inline-block"
|
||||
>
|
||||
Share Quantity
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2
|
||||
class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3"
|
||||
>
|
||||
Latest Information
|
||||
</h2>
|
||||
|
||||
<div class="flex justify-start items-center w-full m-auto">
|
||||
<table class="w-full" data-test="statistics-table">
|
||||
<tbody>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Date</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right whitespace-nowrap font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{formatDateRange(historyData?.slice(-1)?.at(0)?.date)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Total Notional Sum</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
${abbreviateNumber(
|
||||
historyData?.slice(-1)?.at(0)?.totalNotionalSum,
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Total Trade Count</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{abbreviateNumber(
|
||||
historyData?.slice(-1)?.at(0)?.totalWeeklyTradeCount,
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A]">
|
||||
<td class="px-[5px] py-1.5 xs:px-2.5 xs:py-2">
|
||||
<span>Total Share Quantity</span>
|
||||
</td>
|
||||
<td
|
||||
class="px-[5px] py-1.5 text-right font-medium xs:px-2.5 xs:py-2"
|
||||
>
|
||||
{abbreviateNumber(
|
||||
historyData?.slice(-1)?.at(0)?.totalWeeklyShareQuantity,
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h3
|
||||
class="mt-10 mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold mb-3"
|
||||
>
|
||||
Top 10 Market Makers Activity
|
||||
</h3>
|
||||
These market makers represent the highest average trading activity for {$displayCompanyName} over the past 12 months, calculated on a weekly basis.
|
||||
|
||||
<div class="flex justify-start items-center w-full m-auto mt-6 overflow-x-scroll no-scrollbar">
|
||||
</h3>
|
||||
These market makers represent the highest average trading activity for {$displayCompanyName}
|
||||
over the past 12 months, calculated on a weekly basis.
|
||||
|
||||
<div
|
||||
class="flex justify-start items-center w-full m-auto mt-6 overflow-x-scroll no-scrollbar"
|
||||
>
|
||||
<table class="table table-sm table-compact w-full">
|
||||
<thead>
|
||||
<tr class="">
|
||||
<th class="text-white shadow-md font-semibold text-sm text-start bg-[#09090B]">Name</th>
|
||||
<th class="text-white shadow-md font-semibold text-sm text-end bg-[#09090B]">Trade Count</th>
|
||||
<th class="text-white shadow-md font-semibold text-sm text-end bg-[#09090B]">Share Quantity</th>
|
||||
<th class="text-white shadow-md font-semibold text-sm text-end bg-[#09090B]">Notional Sum</th>
|
||||
<th
|
||||
class="text-white shadow-md font-semibold text-sm text-start bg-[#09090B]"
|
||||
>Name</th
|
||||
>
|
||||
<th
|
||||
class="text-white shadow-md font-semibold text-sm text-end bg-[#09090B]"
|
||||
>Trade Count</th
|
||||
>
|
||||
<th
|
||||
class="text-white shadow-md font-semibold text-sm text-end bg-[#09090B]"
|
||||
>Share Quantity</th
|
||||
>
|
||||
<th
|
||||
class="text-white shadow-md font-semibold text-sm text-end bg-[#09090B]"
|
||||
>Notional Sum</th
|
||||
>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each (showFullStats ? topMarketMakers?.slice(0,10) : topMarketMakers?.slice(0,3)) as item,index}
|
||||
<tr class="border-y border-gray-800 odd:bg-[#27272A] {index === 2 && !showFullStats && topMarketMakers?.length > 3 ? 'opacity-[0.5]' : '' } sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-[#09090B] border-b-[#09090B]">
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] font-medium whitespace-nowrap">
|
||||
{item?.name?.length > charNumber ? formatString(item?.name?.slice(0,charNumber)) + "..." : formatString(item?.name)}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-end text-sm sm:text-[1rem] font-medium whitespace-nowrap">
|
||||
{abbreviateNumber(Math.floor(item?.avgWeeklyTradeCount))}
|
||||
{#each showFullStats ? topMarketMakers?.slice(0, 10) : topMarketMakers?.slice(0, 3) as item, index}
|
||||
<tr
|
||||
class="border-y border-gray-800 odd:bg-[#27272A] {index ===
|
||||
2 &&
|
||||
!showFullStats &&
|
||||
topMarketMakers?.length > 3
|
||||
? 'opacity-[0.5]'
|
||||
: ''} sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-[#09090B] border-b-[#09090B]"
|
||||
>
|
||||
<td
|
||||
class="text-white text-sm sm:text-[1rem] font-medium whitespace-nowrap"
|
||||
>
|
||||
{item?.name?.length > charNumber
|
||||
? formatString(item?.name?.slice(0, charNumber)) + "..."
|
||||
: formatString(item?.name)}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-end text-sm sm:text-[1rem] font-medium whitespace-nowrap">
|
||||
{abbreviateNumber(Math.floor(item?.avgWeeklyShareQuantity))}
|
||||
<td
|
||||
class="text-white text-end text-sm sm:text-[1rem] font-medium whitespace-nowrap"
|
||||
>
|
||||
{abbreviateNumber(Math.floor(item?.avgWeeklyTradeCount))}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-end text-sm sm:text-[1rem] font-medium whitespace-nowrap">
|
||||
{abbreviateNumber(item?.avgNotionalSum, true)}
|
||||
|
||||
<td
|
||||
class="text-white text-end text-sm sm:text-[1rem] font-medium whitespace-nowrap"
|
||||
>
|
||||
{abbreviateNumber(Math.floor(item?.avgWeeklyShareQuantity))}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<td
|
||||
class="text-white text-end text-sm sm:text-[1rem] font-medium whitespace-nowrap"
|
||||
>
|
||||
{abbreviateNumber(item?.avgNotionalSum, true)}
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<label on:click={() => showFullStats = !showFullStats} class="cursor-pointer flex justify-center items-center mt-5">
|
||||
<svg class="w-10 h-10 transform {showFullStats ? 'rotate-180' : ''} " xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#2A323C" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2zm0 13.5L7.5 11l1.42-1.41L12 12.67l3.08-3.08L16.5 11L12 15.5z"/></svg>
|
||||
</label>
|
||||
|
||||
|
||||
<label
|
||||
on:click={() => (showFullStats = !showFullStats)}
|
||||
class="cursor-pointer flex justify-center items-center mt-5"
|
||||
>
|
||||
<svg
|
||||
class="w-10 h-10 transform {showFullStats ? 'rotate-180' : ''} "
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
><path
|
||||
fill="#2A323C"
|
||||
d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10s10-4.48 10-10S17.52 2 12 2zm0 13.5L7.5 11l1.42-1.41L12 12.67l3.08-3.08L16.5 11L12 15.5z"
|
||||
/></svg
|
||||
>
|
||||
</label>
|
||||
{/if}
|
||||
|
||||
{:else}
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
|
||||
<span class="loading loading-spinner loading-md"></span>
|
||||
<div class="relative">
|
||||
<label
|
||||
class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||
>
|
||||
<span class="loading loading-spinner loading-md"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
|
||||
{/if}
|
||||
</main>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
}
|
||||
|
||||
.app {
|
||||
height: 300px;
|
||||
max-width: 100%; /* Ensure chart width doesn't exceed the container */
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.app {
|
||||
height: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
.chart {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -128,7 +128,7 @@
|
||||
|
||||
<label
|
||||
on:click={etfSelector}
|
||||
class="sm:hover:border-[#3C74D4] duration-100 transition ease-in-out cursor-pointer flex flex-row items-center rounded-lg shadow-lg border border-gray-600 bg-[#09090B]"
|
||||
class="sm:hover:border-[#3C74D4] duration-100 transition ease-in-out cursor-pointer flex flex-row items-center rounded-md shadow-lg border border-gray-600 bg-[#09090B]"
|
||||
>
|
||||
<div class="flex flex-col items-center lg:mr-5">
|
||||
<span
|
||||
|
||||
@ -283,7 +283,7 @@
|
||||
for={imageId}
|
||||
class="{imageInput.length !== 0
|
||||
? 'hidden'
|
||||
: ''} inline-flex mr-auto items-center py-2.5 px-4 text-xs font-medium text-center text-white rounded-lg hover:bg-gray-800 cursor-pointer"
|
||||
: ''} inline-flex mr-auto items-center py-2.5 px-4 text-xs font-medium text-center text-white rounded-md hover:bg-gray-800 cursor-pointer"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block"
|
||||
@ -336,7 +336,7 @@
|
||||
<div class="relative flex justify-end items-center ml-auto mr-2">
|
||||
<label
|
||||
on:click={handleCancel}
|
||||
class="inline-flex justify-end items-center py-2.5 px-4 text-xs font-medium text-center text-white rounded-lg hover:bg-gray-800 cursor-pointer mr-3"
|
||||
class="inline-flex justify-end items-center py-2.5 px-4 text-xs font-medium text-center text-white rounded-md hover:bg-gray-800 cursor-pointer mr-3"
|
||||
>
|
||||
Cancel
|
||||
</label>
|
||||
@ -345,7 +345,7 @@
|
||||
class="inline-flex justify-end items-center bg-[#fff] {inputValue.length !==
|
||||
0
|
||||
? 'opacity-100 cursor-pointer'
|
||||
: 'opacity-60'} py-2.5 px-4 text-xs font-medium text-center text-white rounded-lg focus:ring-purple-300"
|
||||
: 'opacity-60'} py-2.5 px-4 text-xs font-medium text-center text-white rounded-md focus:ring-purple-300"
|
||||
>
|
||||
Post
|
||||
</label>
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
<a
|
||||
href="/notifications"
|
||||
on:click={toggle}
|
||||
class="text-gray-300 sm:hover:text-white cursor-pointer sm:hover:bg-[#27272A] relative border p-2 rounded-lg border-gray-600 ml-3 -mr-1"
|
||||
class="text-gray-300 sm:hover:text-white cursor-pointer sm:hover:bg-[#27272A] relative border p-2 rounded-md border-gray-600 ml-3 -mr-1"
|
||||
>
|
||||
<Bell class="h-[20px] w-[20px]" />
|
||||
|
||||
|
||||
@ -250,7 +250,7 @@
|
||||
{:else}
|
||||
<div class="flex justify-center items-center m-auto mt-16 mb-6">
|
||||
<div
|
||||
class="text-gray-100 text-sm sm:text-[1rem] sm:rounded-lg h-auto border border-slate-800 p-4"
|
||||
class="text-gray-100 text-sm sm:text-[1rem] sm:rounded-md h-auto border border-slate-800 p-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -135,7 +135,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pb-2 rounded-lg bg-[#09090B]">
|
||||
<div class="pb-2 rounded-md bg-[#09090B]">
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
@ -162,7 +162,7 @@
|
||||
>
|
||||
<!--Start Flow Sentiment-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="font-medium text-gray-200 text-sm"
|
||||
@ -180,7 +180,7 @@
|
||||
<!--End Flow Sentiment-->
|
||||
<!--Start Put/Call-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="font-medium text-gray-200 text-sm"
|
||||
@ -239,7 +239,7 @@
|
||||
|
||||
<!--Start mape-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="font-medium text-gray-200 text-sm">MAPE</span>
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
Flexible plans and features
|
||||
</h1>
|
||||
<div
|
||||
class="w-full flex justify-center items-center h-16 bg-[#09090B] rounded-lg"
|
||||
class="w-full flex justify-center items-center h-16 bg-[#09090B] rounded-md"
|
||||
>
|
||||
<p
|
||||
class="font-medium font-serif text-center w-3/4 sm:w-full text-white text-[1rem] sm:text-xl italic"
|
||||
@ -78,7 +78,7 @@
|
||||
>
|
||||
<!-- Pricing Card -->
|
||||
<div
|
||||
class="order-last sm:order-1 flex flex-col p-6 lg:p-8 mx-auto w-full text-center text-white border border-gray-800 bg-[#09090B] rounded-lg"
|
||||
class="order-last sm:order-1 flex flex-col p-6 lg:p-8 mx-auto w-full text-center text-white border border-gray-800 bg-[#09090B] rounded-md"
|
||||
>
|
||||
<div class="flex flex-row items-center justify-start items-center mt-2">
|
||||
<img
|
||||
@ -215,7 +215,7 @@
|
||||
{#if !data?.user}
|
||||
<label
|
||||
for="userLogin"
|
||||
class="py-3 cursor-pointer rounded-lg text-white bg-[#fff] sm:hover:bg-gray-300 transition duration-100 ease-in-out group"
|
||||
class="py-3 cursor-pointer rounded-md text-white bg-[#fff] sm:hover:bg-gray-300 transition duration-100 ease-in-out group"
|
||||
>
|
||||
Get Sign In
|
||||
<span
|
||||
@ -244,7 +244,7 @@
|
||||
|
||||
<!-- Pricing Card -->
|
||||
<div
|
||||
class="sm:order-2 rounded-lg box sm:-mt-10 flex flex-col p-6 lg:p-8 mx-auto w-full text-center text-white bg-[#27272A]"
|
||||
class="sm:order-2 rounded-md box sm:-mt-10 flex flex-col p-6 lg:p-8 mx-auto w-full text-center text-white bg-[#27272A]"
|
||||
>
|
||||
<div class="{!mode ? 'hidden' : ''} ribbon ribbon-top-right">
|
||||
<span class="text-white">Discount</span>
|
||||
@ -535,7 +535,7 @@
|
||||
</div>
|
||||
<label
|
||||
for={"userLogin"}
|
||||
class="cursor-pointer py-3 rounded-lg text-white bg-[#fff] sm:hover:bg-gray-300 transition duration-100 ease-in-out group"
|
||||
class="cursor-pointer py-3 rounded-md text-white bg-[#fff] sm:hover:bg-gray-300 transition duration-100 ease-in-out group"
|
||||
>
|
||||
30 Days Free Trial
|
||||
<span
|
||||
@ -567,7 +567,7 @@
|
||||
|
||||
<!--Start Pricing Card-->
|
||||
<!--
|
||||
<div class="sm:h-[660px] sm:order-2 box sm:-mt-10 flex flex-col p-6 lg:p-8 mx-auto ring-[1px] ring-gray-400 rounded-lg w-full text-center text-white">
|
||||
<div class="sm:h-[660px] sm:order-2 box sm:-mt-10 flex flex-col p-6 lg:p-8 mx-auto ring-[1px] ring-gray-400 rounded-md w-full text-center text-white">
|
||||
|
||||
<div class="absolute top-0 left-1/2 transform -translate-x-1/2 rounded-b-2xl flex flex-row border-l border-r border-b border-gray-400 items-center p-2">
|
||||
<span class="text-white text-md font-semibold px-3">
|
||||
@ -614,19 +614,19 @@
|
||||
</div>
|
||||
|
||||
{#if data?.user?.tier === 'Pro' && !data?.user?.freeTrial}
|
||||
<a class="py-3 rounded-lg text-white bg-[#fff] sm:hover:bg-gray-300 transition duration-100 ease-in-out group" href="#">
|
||||
<a class="py-3 rounded-md text-white bg-[#fff] sm:hover:bg-gray-300 transition duration-100 ease-in-out group" href="#">
|
||||
Active Plan
|
||||
</a>
|
||||
{:else if data?.user?.tier === 'Pro' && data?.user?.freeTrial === true}
|
||||
|
||||
<label for={!data?.user ? 'userLogin' : ''} on:click={() => purchasePlan('lifeTime')} class="py-3 rounded-lg text-white bg-[#fff] sm:hover:bg-gray-300 transition duration-100 ease-in-out group">
|
||||
<label for={!data?.user ? 'userLogin' : ''} on:click={() => purchasePlan('lifeTime')} class="py-3 rounded-md text-white bg-[#fff] sm:hover:bg-gray-300 transition duration-100 ease-in-out group">
|
||||
Get Lifetime Access
|
||||
<span class="tracking-normal group-hover:translate-x-0.5 transition-transform duration-150 ease-in-out">
|
||||
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g transform="rotate(90 12 12)"><g fill="none"><path d="M24 0v24H0V0h24ZM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035c-.01-.004-.019-.001-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427c-.002-.01-.009-.017-.017-.018Zm.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093c.012.004.023 0 .029-.008l.004-.014l-.034-.614c-.003-.012-.01-.02-.02-.022Zm-.715.002a.023.023 0 0 0-.027.006l-.006.014l-.034.614c0 .012.007.02.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01l-.184-.092Z"/><path fill="white" d="M13.06 3.283a1.5 1.5 0 0 0-2.12 0L5.281 8.939a1.5 1.5 0 0 0 2.122 2.122L10.5 7.965V19.5a1.5 1.5 0 0 0 3 0V7.965l3.096 3.096a1.5 1.5 0 1 0 2.122-2.122L13.06 3.283Z"/></g></g></svg>
|
||||
</span>
|
||||
</label>
|
||||
{:else}
|
||||
<label for={!data?.user ? 'userLogin' : ''} on:click={() => purchasePlan('lifeTime')} class="cursor-pointer py-3 rounded-lg text-white bg-[#fff] sm:hover:bg-gray-300 transition duration-100 ease-in-out group">
|
||||
<label for={!data?.user ? 'userLogin' : ''} on:click={() => purchasePlan('lifeTime')} class="cursor-pointer py-3 rounded-md text-white bg-[#fff] sm:hover:bg-gray-300 transition duration-100 ease-in-out group">
|
||||
Get Lifetime Access
|
||||
<span class="tracking-normal group-hover:translate-x-0.5 transition-transform duration-150 ease-in-out">
|
||||
<svg class="w-4 h-4 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><g transform="rotate(90 12 12)"><g fill="none"><path d="M24 0v24H0V0h24ZM12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035c-.01-.004-.019-.001-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427c-.002-.01-.009-.017-.017-.018Zm.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093c.012.004.023 0 .029-.008l.004-.014l-.034-.614c-.003-.012-.01-.02-.02-.022Zm-.715.002a.023.023 0 0 0-.027.006l-.006.014l-.034.614c0 .012.007.02.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01l-.184-.092Z"/><path fill="white" d="M13.06 3.283a1.5 1.5 0 0 0-2.12 0L5.281 8.939a1.5 1.5 0 0 0 2.122 2.122L10.5 7.965V19.5a1.5 1.5 0 0 0 3 0V7.965l3.096 3.096a1.5 1.5 0 1 0 2.122-2.122L13.06 3.283Z"/></g></g></svg>
|
||||
|
||||
@ -239,7 +239,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pb-8 sm:pb-2 rounded-lg bg-[#09090B]">
|
||||
<div class="pb-8 sm:pb-2 rounded-md bg-[#09090B]">
|
||||
<div class="app w-full h-[300px] mt-5">
|
||||
<Chart {init} options={optionsData} class="chart" />
|
||||
</div>
|
||||
|
||||
@ -241,7 +241,7 @@
|
||||
<!--Start Progress-->
|
||||
{#each showFullStats ? geographicList : geographicList?.slice(0, 3) as item, index}
|
||||
<div
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-lg p-4 sm:p-3 mb-5 flex flex-row items-center {index ===
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-md p-4 sm:p-3 mb-5 flex flex-row items-center {index ===
|
||||
0
|
||||
? 'mt-4'
|
||||
: ''} {index === 2 &&
|
||||
|
||||
@ -74,7 +74,7 @@
|
||||
<div class="dropdown dropdown-end">
|
||||
<button
|
||||
tabindex="0"
|
||||
class="bg-[#000] h-[33px] flex flex-row justify-between items-center w-[150px] xs:w-[140px] sm:w-[150px] px-3 text-white rounded-lg truncate"
|
||||
class="bg-[#000] h-[33px] flex flex-row justify-between items-center w-[150px] xs:w-[140px] sm:w-[150px] px-3 text-white rounded-md truncate"
|
||||
>
|
||||
<span class="truncate ml-2">
|
||||
{#if value === "" || condition === ""}
|
||||
|
||||
@ -1,232 +1,253 @@
|
||||
<script lang="ts">
|
||||
import {secFilingsClicked, stockTicker, clientSideCache, } from '$lib/store';
|
||||
import * as Tabs from "$lib/components/shadcn/tabs/index.js";
|
||||
import { secFilingsClicked, stockTicker, clientSideCache } from "$lib/store";
|
||||
import * as Tabs from "$lib/components/shadcn/tabs/index.js";
|
||||
|
||||
import { fade } from "svelte/transition";
|
||||
|
||||
import { fade } from 'svelte/transition';
|
||||
|
||||
let secFilingsList;
|
||||
|
||||
let displayList = [];
|
||||
let accordionOpen = {};
|
||||
let newData;
|
||||
let isLoaded = false;
|
||||
|
||||
|
||||
let displayList = [];
|
||||
let accordionOpen = {};
|
||||
let newData;
|
||||
let isLoaded = false;
|
||||
|
||||
function changeSECType(secType) {
|
||||
function changeSECType(secType) {
|
||||
switch (secType) {
|
||||
case '8-K':
|
||||
prepareData(secFilingsList?.eightK);
|
||||
break;
|
||||
case '10-K':
|
||||
prepareData(secFilingsList?.tenK);
|
||||
break;
|
||||
case '10-Q':
|
||||
prepareData(secFilingsList?.tenQ);
|
||||
break;
|
||||
// Default case in case changeType doesn't match any of the specified cases
|
||||
default:
|
||||
// Handle the default case or leave it empty if not needed
|
||||
break;
|
||||
case "8-K":
|
||||
prepareData(secFilingsList?.eightK);
|
||||
break;
|
||||
case "10-K":
|
||||
prepareData(secFilingsList?.tenK);
|
||||
break;
|
||||
case "10-Q":
|
||||
prepareData(secFilingsList?.tenQ);
|
||||
break;
|
||||
// Default case in case changeType doesn't match any of the specified cases
|
||||
default:
|
||||
// Handle the default case or leave it empty if not needed
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function prepareData(dataset) {
|
||||
if (dataset?.length !== 0)
|
||||
{
|
||||
newData = {};
|
||||
accordionOpen = {};
|
||||
|
||||
dataset?.forEach(item => {
|
||||
// Extract year from the date
|
||||
const year = new Date(item?.date)?.getFullYear()?.toString();
|
||||
|
||||
// Check if the year already exists in newData
|
||||
if (!newData[year]) {
|
||||
// If not, initialize a new entry for the year
|
||||
newData[year] = {
|
||||
'year': year,
|
||||
'totalReports': 0,
|
||||
'data': []
|
||||
};
|
||||
}
|
||||
// Increment the totalReports count
|
||||
newData[year].totalReports++;
|
||||
|
||||
// Add the current item to the 'data' array
|
||||
newData[year].data?.push(item);
|
||||
});
|
||||
|
||||
// Convert newData object to an array of values
|
||||
displayList = Object?.values(newData);
|
||||
displayList = displayList?.sort((a,b) => b?.year - a?.year);
|
||||
// Output the displayList
|
||||
displayList = [...displayList];
|
||||
//console.log(displayList)
|
||||
}
|
||||
else {
|
||||
displayList = [];
|
||||
}
|
||||
|
||||
}
|
||||
function prepareData(dataset) {
|
||||
if (dataset?.length !== 0) {
|
||||
newData = {};
|
||||
accordionOpen = {};
|
||||
|
||||
dataset?.forEach((item) => {
|
||||
// Extract year from the date
|
||||
const year = new Date(item?.date)?.getFullYear()?.toString();
|
||||
|
||||
async function handleAccordion(year) {
|
||||
accordionOpen[year] = !accordionOpen[year];
|
||||
}
|
||||
// Check if the year already exists in newData
|
||||
if (!newData[year]) {
|
||||
// If not, initialize a new entry for the year
|
||||
newData[year] = {
|
||||
year: year,
|
||||
totalReports: 0,
|
||||
data: [],
|
||||
};
|
||||
}
|
||||
// Increment the totalReports count
|
||||
newData[year].totalReports++;
|
||||
|
||||
// Add the current item to the 'data' array
|
||||
newData[year].data?.push(item);
|
||||
});
|
||||
|
||||
async function fetchData() {
|
||||
|
||||
if($clientSideCache[$stockTicker]?.getSECFilings)
|
||||
{
|
||||
secFilingsList = $clientSideCache[$stockTicker]?.getSECFilings;
|
||||
}
|
||||
else {
|
||||
const postData = { ticker: $stockTicker, path: 'get-sec-filings'};
|
||||
const response = await fetch('/api/ticker-data', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
body: JSON.stringify(postData)
|
||||
});
|
||||
|
||||
secFilingsList = await response.json();
|
||||
$clientSideCache[$stockTicker].getSECFilings = secFilingsList;
|
||||
// Convert newData object to an array of values
|
||||
displayList = Object?.values(newData);
|
||||
displayList = displayList?.sort((a, b) => b?.year - a?.year);
|
||||
// Output the displayList
|
||||
displayList = [...displayList];
|
||||
//console.log(displayList)
|
||||
} else {
|
||||
displayList = [];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
async function handleAccordion(year) {
|
||||
accordionOpen[year] = !accordionOpen[year];
|
||||
}
|
||||
|
||||
async function fetchData() {
|
||||
if ($clientSideCache[$stockTicker]?.getSECFilings) {
|
||||
secFilingsList = $clientSideCache[$stockTicker]?.getSECFilings;
|
||||
} else {
|
||||
const postData = { ticker: $stockTicker, path: "get-sec-filings" };
|
||||
const response = await fetch("/api/ticker-data", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(postData),
|
||||
});
|
||||
|
||||
secFilingsList = await response.json();
|
||||
$clientSideCache[$stockTicker].getSECFilings = secFilingsList;
|
||||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
$: {
|
||||
if (
|
||||
$stockTicker &&
|
||||
typeof window !== "undefined" &&
|
||||
$secFilingsClicked === true
|
||||
) {
|
||||
isLoaded = false;
|
||||
$secFilingsClicked = false;
|
||||
accordionOpen = {};
|
||||
|
||||
if($stockTicker && typeof window !== 'undefined' && $secFilingsClicked === true) {
|
||||
isLoaded = false;
|
||||
$secFilingsClicked = false;
|
||||
accordionOpen = {}
|
||||
|
||||
const asyncFunctions = [
|
||||
fetchData()
|
||||
];
|
||||
const asyncFunctions = [fetchData()];
|
||||
Promise.all(asyncFunctions)
|
||||
.then((results) => {
|
||||
prepareData(secFilingsList?.eightK);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('An error occurred:', error);
|
||||
});
|
||||
.then((results) => {
|
||||
prepareData(secFilingsList?.eightK);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("An error occurred:", error);
|
||||
});
|
||||
|
||||
isLoaded = true;
|
||||
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<div class="space-y-3 sm:pt-5">
|
||||
|
||||
<div class="space-y-3 sm:pt-5">
|
||||
<div class="bg-[#000] h-auto w-screen">
|
||||
|
||||
<!--Start Header-->
|
||||
<div class="bg-[#000] w-full p-1 flex flex-col items-center pb-5 h-auto">
|
||||
<h2 class="text-center m-auto text-lg font-semibold text-white mt-5">
|
||||
SEC Filings
|
||||
</h2>
|
||||
|
||||
|
||||
<div class="w-11/12 mt-5">
|
||||
<div class="relative right-0 bg-[#27272A] rounded-lg">
|
||||
|
||||
<div class="relative right-0 bg-[#27272A] rounded-md">
|
||||
<Tabs.Root value="eightK" class="w-full">
|
||||
<Tabs.List class="grid w-full grid-cols-3 bg-[#27272A]">
|
||||
<Tabs.Trigger on:click={() => changeSECType('8-K')} value="eightK">8-K</Tabs.Trigger>
|
||||
<Tabs.Trigger on:click={() => changeSECType('10-K')} value="tenK">10-K</Tabs.Trigger>
|
||||
<Tabs.Trigger on:click={() => changeSECType('10-Q')} value="tenQ">10-Q</Tabs.Trigger>
|
||||
<Tabs.Trigger on:click={() => changeSECType("8-K")} value="eightK"
|
||||
>8-K</Tabs.Trigger
|
||||
>
|
||||
<Tabs.Trigger on:click={() => changeSECType("10-K")} value="tenK"
|
||||
>10-K</Tabs.Trigger
|
||||
>
|
||||
<Tabs.Trigger on:click={() => changeSECType("10-Q")} value="tenQ"
|
||||
>10-Q</Tabs.Trigger
|
||||
>
|
||||
</Tabs.List>
|
||||
</Tabs.Root>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Header-->
|
||||
{#if isLoaded}
|
||||
{#if displayList?.length !== 0}
|
||||
<div class="mt-5 w-full">
|
||||
|
||||
{#each displayList as item}
|
||||
<div class="flex flex-col justify-center m-auto items-start rounded-md bg-[#27272A] shadow-lg h-auto w-11/12 mb-3" transition:fade={{ delay: 0, duration: 80 }} in={accordionOpen[item?.year]}>
|
||||
|
||||
|
||||
<div class="flex flex-row items-center w-full p-3">
|
||||
|
||||
<div class="flex-shrink-0 mr-2 rounded-full w-12 h-12 relative bg-[#000]">
|
||||
<svg class="rounded-full w-7 h-7 absolute inset-1/2 transform -translate-x-1/2 -translate-y-1/2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="white" d="m18 22l3-3l-.7-.7l-1.8 1.8V16h-1v4.1l-1.8-1.8l-.7.7zm-6-11.15l5.925-3.425L12 4L6.075 7.425zm-9 6.275V6.875L12 1.7l9 5.175V12h-2V9.1l-7.025 4.05L5 9.1v6.85l6.025 3.475v2.3zM18 24q-2.075 0-3.537-1.463T13 19q0-2.075 1.463-3.537T18 14q2.075 0 3.538 1.463T23 19q0 2.075-1.463 3.538T18 24m-6.975-12.275"/></svg>
|
||||
<div class="mt-5 w-full">
|
||||
{#each displayList as item}
|
||||
<div
|
||||
class="flex flex-col justify-center m-auto items-start rounded-md bg-[#27272A] shadow-lg h-auto w-11/12 mb-3"
|
||||
transition:fade={{ delay: 0, duration: 80 }}
|
||||
in={accordionOpen[item?.year]}
|
||||
>
|
||||
<div class="flex flex-row items-center w-full p-3">
|
||||
<div
|
||||
class="flex-shrink-0 mr-2 rounded-full w-12 h-12 relative bg-[#000]"
|
||||
>
|
||||
<svg
|
||||
class="rounded-full w-7 h-7 absolute inset-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
><path
|
||||
fill="white"
|
||||
d="m18 22l3-3l-.7-.7l-1.8 1.8V16h-1v4.1l-1.8-1.8l-.7.7zm-6-11.15l5.925-3.425L12 4L6.075 7.425zm-9 6.275V6.875L12 1.7l9 5.175V12h-2V9.1l-7.025 4.05L5 9.1v6.85l6.025 3.475v2.3zM18 24q-2.075 0-3.537-1.463T13 19q0-2.075 1.463-3.537T18 14q2.075 0 3.538 1.463T23 19q0 2.075-1.463 3.538T18 24m-6.975-12.275"
|
||||
/></svg
|
||||
>
|
||||
</div>
|
||||
|
||||
<div on:click={() => handleAccordion(item?.year)} class="flex flex-row items-center w-full">
|
||||
<div class="flex flex-col items-start w-full ">
|
||||
<span class="text-white text-sm sm:text-md font-medium text-start mt-2">
|
||||
{item?.year}
|
||||
</span>
|
||||
<span class="text-white text-opacity-[0.6] text-xs text-start mb-2">
|
||||
Total Reports: {item?.totalReports}
|
||||
</span>
|
||||
</div>
|
||||
<svg class="h-6 w-6 inline-block transform transition-transform mr-5 {accordionOpen[item?.year] ? '' : 'rotate-180'}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024"><path fill="#fff" d="m488.832 344.32l-339.84 356.672a32 32 0 0 0 0 44.16l.384.384a29.44 29.44 0 0 0 42.688 0l320-335.872l319.872 335.872a29.44 29.44 0 0 0 42.688 0l.384-.384a32 32 0 0 0 0-44.16L535.168 344.32a32 32 0 0 0-46.336 0z"/></svg>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{#if accordionOpen[item?.year]}
|
||||
{#each item?.data as entry}
|
||||
<div class="shadow-lg bg-[#000] bg-opacity-[0.5] w-11/12 rounded-md p-4 mb-3 m-auto flex flex-row justify-center 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-sm sm:text-md font-medium text-start mb-2 mr-auto mt-2">
|
||||
{new Date(entry?.date)?.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', daySuffix: '2-digit' })}
|
||||
</span>
|
||||
<span class="text-white text-sm sm:text-md font-medium ml-auto">
|
||||
<a href={entry?.link} rel="noopener noreferrer" target="_blank" >
|
||||
Check Report
|
||||
</a>
|
||||
<div
|
||||
on:click={() => handleAccordion(item?.year)}
|
||||
class="flex flex-row items-center w-full"
|
||||
>
|
||||
<div class="flex flex-col items-start w-full">
|
||||
<span
|
||||
class="text-white text-sm sm:text-md font-medium text-start mt-2"
|
||||
>
|
||||
{item?.year}
|
||||
</span>
|
||||
<span
|
||||
class="text-white text-opacity-[0.6] text-xs text-start mb-2"
|
||||
>
|
||||
Total Reports: {item?.totalReports}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<svg
|
||||
class="h-6 w-6 inline-block transform transition-transform mr-5 {accordionOpen[
|
||||
item?.year
|
||||
]
|
||||
? ''
|
||||
: 'rotate-180'}"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 1024 1024"
|
||||
><path
|
||||
fill="#fff"
|
||||
d="m488.832 344.32l-339.84 356.672a32 32 0 0 0 0 44.16l.384.384a29.44 29.44 0 0 0 42.688 0l320-335.872l319.872 335.872a29.44 29.44 0 0 0 42.688 0l.384-.384a32 32 0 0 0 0-44.16L535.168 344.32a32 32 0 0 0-46.336 0z"
|
||||
/></svg
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
|
||||
{/if}
|
||||
{#if accordionOpen[item?.year]}
|
||||
{#each item?.data as entry}
|
||||
<div
|
||||
class="shadow-lg bg-[#000] bg-opacity-[0.5] w-11/12 rounded-md p-4 mb-3 m-auto flex flex-row justify-center 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-sm sm:text-md font-medium text-start mb-2 mr-auto mt-2"
|
||||
>
|
||||
{new Date(entry?.date)?.toLocaleString("en-US", {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
daySuffix: "2-digit",
|
||||
})}
|
||||
</span>
|
||||
<span
|
||||
class="text-white text-sm sm:text-md font-medium ml-auto"
|
||||
>
|
||||
<a
|
||||
href={entry?.link}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
Check Report
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class=" mt-20 flex justify-center items-center text-2xl font-bold text-slate-700 mb-20 m-auto">
|
||||
<div
|
||||
class=" mt-20 flex justify-center items-center text-2xl font-bold text-slate-700 mb-20 m-auto"
|
||||
>
|
||||
No data available
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{:else}
|
||||
<div class="flex justify-center items-center h-80">
|
||||
<div class="relative">
|
||||
<label class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
|
||||
<span class="loading loading-spinner loading-md text-gray-400"></span>
|
||||
<label
|
||||
class="bg-[#09090B] rounded-xl h-14 w-14 flex justify-center items-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"
|
||||
>
|
||||
<span class="loading loading-spinner loading-md text-gray-400"
|
||||
></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!--End Similar Stocks Card -->
|
||||
|
||||
|
||||
</div>
|
||||
<!--End Similar Stocks Card -->
|
||||
|
||||
@ -270,7 +270,7 @@
|
||||
|
||||
<label
|
||||
for="searchBarModal"
|
||||
class="cursor-pointer p-2 sm:hover:bg-[#27272A] text-gray-300 sm:hover:text-white flex-shrink-0 flex items-center justify-center border border-gray-600 rounded-lg"
|
||||
class="cursor-pointer p-2 sm:hover:bg-[#27272A] text-gray-300 sm:hover:text-white flex-shrink-0 flex items-center justify-center border border-gray-600 rounded-md"
|
||||
>
|
||||
<Search class="h-[20px] w-[20px]" />
|
||||
</label>
|
||||
@ -298,7 +298,7 @@
|
||||
<label for="modal-search" class="sr-only">Search</label>
|
||||
<input
|
||||
id="modal-search"
|
||||
class="rounded-lg w-full text-white bg-[#09090B] border border-gray-600 focus:ring-transparent placeholder-gray-200 py-3 pl-10 pr-4"
|
||||
class="rounded-md w-full text-white bg-[#09090B] border border-gray-600 focus:ring-transparent placeholder-gray-200 py-3 pl-10 pr-4"
|
||||
type="search"
|
||||
placeholder="Search Anything…"
|
||||
bind:value={searchQuery}
|
||||
@ -347,7 +347,7 @@
|
||||
on:click={() => popularTicker(item?.symbol)}
|
||||
class="mb-2 {item?.symbol === focusedSuggestion
|
||||
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group'
|
||||
: 'shake-ticker cursor-pointer bg-[#09090B] sm:hover:bg-[#27272A] rounded-lg flex justify-start items-center p-2 text-white group'} w-full"
|
||||
: 'shake-ticker cursor-pointer bg-[#09090B] sm:hover:bg-[#27272A] rounded-md flex justify-start items-center p-2 text-white group'} w-full"
|
||||
>
|
||||
<div class="flex flex-row items-center w-full">
|
||||
<div
|
||||
@ -389,7 +389,7 @@
|
||||
on:click={() => searchBarTicker(item?.symbol)}
|
||||
class="mb-2 {item?.symbol === focusedSuggestion
|
||||
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group'
|
||||
: 'cursor-pointer mb-2 bg-[#09090B] sm:hover:bg-[#27272A] rounded-lg flex justify-start items-center p-2 text-white group'}"
|
||||
: 'cursor-pointer mb-2 bg-[#09090B] sm:hover:bg-[#27272A] rounded-md flex justify-start items-center p-2 text-white group'}"
|
||||
>
|
||||
<div class="flex flex-row items-center w-full">
|
||||
<div class="flex flex-col">
|
||||
@ -469,7 +469,7 @@
|
||||
<label for="modal-search" class="sr-only">Search</label>
|
||||
<input
|
||||
id="modal-search"
|
||||
class="rounded-lg w-full text-white bg-[#09090B] border border-slate-800 focus:ring-transparent placeholder-gray-200 py-3 pl-10 pr-4"
|
||||
class="rounded-md w-full text-white bg-[#09090B] border border-slate-800 focus:ring-transparent placeholder-gray-200 py-3 pl-10 pr-4"
|
||||
type="search"
|
||||
placeholder="Search Anything…"
|
||||
bind:value={searchQuery}
|
||||
@ -518,7 +518,7 @@
|
||||
on:click={() => popularTicker(item?.symbol)}
|
||||
class="mb-2 {item?.symbol === focusedSuggestion
|
||||
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group'
|
||||
: 'cursor-pointer bg-[#09090B] bg-opacity-[0.4] rounded-lg flex justify-start items-center p-2 text-white group'} w-full"
|
||||
: 'cursor-pointer bg-[#09090B] bg-opacity-[0.4] rounded-md flex justify-start items-center p-2 text-white group'} w-full"
|
||||
>
|
||||
<div class="flex flex-row items-center w-full">
|
||||
<div
|
||||
@ -560,7 +560,7 @@
|
||||
on:click={() => searchBarTicker(item?.symbol)}
|
||||
class="mb-2 {item?.symbol === focusedSuggestion
|
||||
? 'shake-ticker cursor-pointer flex justify-start items-center p-2 text-white bg-[#27272A] rounded group'
|
||||
: 'cursor-pointer mb-2 bg-[#09090B] bg-opacity-[0.4] rounded-lg flex justify-start items-center p-2 text-white group'}"
|
||||
: 'cursor-pointer mb-2 bg-[#09090B] bg-opacity-[0.4] rounded-md flex justify-start items-center p-2 text-white group'}"
|
||||
>
|
||||
<div class="flex flex-row items-center w-full">
|
||||
<div class="flex flex-col ml-1">
|
||||
|
||||
@ -64,7 +64,7 @@
|
||||
{#each showFullStats ? sectorList : sectorList?.slice(0, 3) as item, index}
|
||||
<div
|
||||
on:click={() => sectorSelector(item?.industry)}
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-lg p-4 mb-5 flex flex-row items-center {index ===
|
||||
class="shadow-lg bg-[#27272A] w-full rounded-md p-4 mb-5 flex flex-row items-center {index ===
|
||||
0
|
||||
? 'mt-4'
|
||||
: ''} {index === 2 &&
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
{#if sentimentList?.length !== 0}
|
||||
<div class="pb-4 w-full mt-5">
|
||||
<div
|
||||
class="w-auto p-4 sm:p-6 bg-[#09090B] sm:bg-[#09090B] rounded-lg relative"
|
||||
class="w-auto p-4 sm:p-6 bg-[#09090B] sm:bg-[#09090B] rounded-md relative"
|
||||
>
|
||||
<h3 class="text-gray-300 font-medium text-sm uppercase mb-3">
|
||||
Average Score
|
||||
@ -178,7 +178,7 @@
|
||||
|
||||
<div class="w-full">
|
||||
<div
|
||||
class="w-auto p-4 sm:p-6 bg-[#09090B] sm:bg-[#09090B] rounded-lg relative"
|
||||
class="w-auto p-4 sm:p-6 bg-[#09090B] sm:bg-[#09090B] rounded-md relative"
|
||||
>
|
||||
<h3 class="text-gray-300 font-medium text-sm uppercase mb-3">
|
||||
Average Score Trend
|
||||
|
||||
@ -230,7 +230,7 @@
|
||||
</div>
|
||||
|
||||
{#if shareholderList?.length !== 0}
|
||||
<div class="pb-2 rounded-lg bg-[#09090B] sm:bg-[#09090B]">
|
||||
<div class="pb-2 rounded-md bg-[#09090B] sm:bg-[#09090B]">
|
||||
<div class="text-white text-[1rem] mt-3">
|
||||
As of {new Date(rawData?.date)?.toLocaleString("en-US", {
|
||||
month: "short",
|
||||
|
||||
@ -78,7 +78,7 @@
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class="mt-5 text-gray-100 text-sm sm:text-[1rem] sm:rounded-lg h-auto border border-slate-800 p-4"
|
||||
class="mt-5 text-gray-100 text-sm sm:text-[1rem] sm:rounded-md h-auto border border-slate-800 p-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block mr-0.5 flex-shrink-0"
|
||||
|
||||
@ -1,187 +1,242 @@
|
||||
<script lang="ts">
|
||||
import { etfTicker, similarTickerClicked, screenWidth } from "$lib/store";
|
||||
import { goto } from "$app/navigation";
|
||||
import { abbreviateNumber } from "$lib/utils";
|
||||
|
||||
import {etfTicker, similarTickerClicked, screenWidth} from '$lib/store';
|
||||
import { goto } from '$app/navigation';
|
||||
import { abbreviateNumber } from '$lib/utils';
|
||||
export let similarTicker;
|
||||
|
||||
|
||||
export let similarTicker;
|
||||
|
||||
|
||||
|
||||
async function etfSelector(state)
|
||||
{
|
||||
window?.scroll({ top: 0, left: 0, behavior: 'smooth' });
|
||||
etfTicker.update(value => state);
|
||||
$similarTickerClicked = true;
|
||||
goto("/etf/"+state+"/")
|
||||
async function etfSelector(state) {
|
||||
window?.scroll({ top: 0, left: 0, behavior: "smooth" });
|
||||
etfTicker.update((value) => state);
|
||||
$similarTickerClicked = true;
|
||||
goto("/etf/" + state + "/");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<!--Start Similar Stocks Card -->
|
||||
|
||||
<div class="space-y-3 sm:pt-5 hidden lg:block sm:{similarTicker?.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]">
|
||||
|
||||
<div class="w-auto lg:w-full p-1 flex-1 flex flex-wrap pb-5">
|
||||
<h2 class="text-start ml-2 text-2xl font-bold text-white pb-2 p-3">
|
||||
Similar ETFs
|
||||
</h2>
|
||||
{#if similarTicker?.length !== 0}
|
||||
|
||||
|
||||
<div class="flex justify-start items-center w-full m-auto pl-2">
|
||||
<table class="table table-sm table-compact mt-3 text-start flex justify-start items-center w-full px-3 m-auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-white font-semibold text-sm text-start bg-[#000] sm:bg-[#09090B]">Fund Name</th>
|
||||
<th class="text-white font-semibold text-sm text-end bg-[#000] sm:bg-[#09090B]">Total Assets</th>
|
||||
<th class="text-white font-semibold text-sm text-end bg-[#000] sm:bg-[#09090B]">Holdings</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each similarTicker as item, index}
|
||||
<tr on:click={() => etfSelector(item?.symbol)} class="shake-ticker sm:hover:text-white text-blue-400 cursor-pointer sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-[#000] sm:bg-[#09090B] border-b border-[#000] sm:border-[#27272A]">
|
||||
{#if index <=6}
|
||||
|
||||
<td class="">
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="rounded-full w-10 h-10 relative flex items-center justify-center">
|
||||
<img style="clip-path: circle(50%);" class="w-6 h-6 rounded-full" src={`https://financialmodelingprep.com/image-stock/${item.symbol}.png`} loading="lazy"/>
|
||||
</div>
|
||||
<div class="flex flex-col ml-3 w-full">
|
||||
<span class="text-sm font-medium">{item?.symbol}</span>
|
||||
<span class="text-white text-sm">
|
||||
{#if typeof item?.name !== 'undefined'}
|
||||
{item?.name?.length > 20 ? item?.name?.slice(0,20) + "..." : item?.name}
|
||||
{:else}
|
||||
n/a
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
<td class="text-white text-end font-semibold ">
|
||||
{item?.totalAssets !== null ? abbreviateNumber(item?.totalAssets, true) : '-'}
|
||||
</td>
|
||||
|
||||
<td class="text-white font-semibold text-end">
|
||||
{abbreviateNumber(item?.numberOfHoldings)}
|
||||
</td>
|
||||
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
<h2 class=" mt-20 justify-center items-center text-3xl font-bold text-slate-700 mb-20 m-auto">
|
||||
No data available
|
||||
<svg class="w-10 sm:w-12 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#334155" d="M18.68 12.32a4.49 4.49 0 0 0-6.36.01a4.49 4.49 0 0 0 0 6.36a4.508 4.508 0 0 0 5.57.63L21 22.39L22.39 21l-3.09-3.11c1.13-1.77.87-4.09-.62-5.57m-1.41 4.95c-.98.98-2.56.97-3.54 0c-.97-.98-.97-2.56.01-3.54c.97-.97 2.55-.97 3.53 0c.97.98.97 2.56 0 3.54M10.9 20.1a6.527 6.527 0 0 1-1.48-2.32C6.27 17.25 4 15.76 4 14v3c0 2.21 3.58 4 8 4c-.4-.26-.77-.56-1.1-.9M4 9v3c0 1.68 2.07 3.12 5 3.7v-.2c0-.93.2-1.85.58-2.69C6.34 12.3 4 10.79 4 9m8-6C7.58 3 4 4.79 4 7c0 2 3 3.68 6.85 4h.05c1.2-1.26 2.86-2 4.6-2c.91 0 1.81.19 2.64.56A3.215 3.215 0 0 0 20 7c0-2.21-3.58-4-8-4Z"/></svg>
|
||||
<div
|
||||
class="space-y-3 sm:pt-5 hidden lg:block sm:{similarTicker?.length !== 0
|
||||
? ''
|
||||
: 'hidden'}"
|
||||
>
|
||||
<div
|
||||
class="sm:rounded-md 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]"
|
||||
>
|
||||
<div class="w-auto lg:w-full p-1 flex-1 flex flex-wrap pb-5">
|
||||
<h2 class="text-start ml-2 text-2xl font-bold text-white pb-2 p-3">
|
||||
Similar ETFs
|
||||
</h2>
|
||||
{#if similarTicker?.length !== 0}
|
||||
<div class="flex justify-start items-center w-full m-auto pl-2">
|
||||
<table
|
||||
class="table table-sm table-compact mt-3 text-start flex justify-start items-center w-full px-3 m-auto"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
class="text-white font-semibold text-sm text-start bg-[#000] sm:bg-[#09090B]"
|
||||
>Fund Name</th
|
||||
>
|
||||
<th
|
||||
class="text-white font-semibold text-sm text-end bg-[#000] sm:bg-[#09090B]"
|
||||
>Total Assets</th
|
||||
>
|
||||
<th
|
||||
class="text-white font-semibold text-sm text-end bg-[#000] sm:bg-[#09090B]"
|
||||
>Holdings</th
|
||||
>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each similarTicker as item, index}
|
||||
<tr
|
||||
on:click={() => etfSelector(item?.symbol)}
|
||||
class="shake-ticker sm:hover:text-white text-blue-400 cursor-pointer sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-[#000] sm:bg-[#09090B] border-b border-[#000] sm:border-[#27272A]"
|
||||
>
|
||||
{#if index <= 6}
|
||||
<td class="">
|
||||
<div class="flex flex-row items-center">
|
||||
<div
|
||||
class="rounded-full w-10 h-10 relative flex items-center justify-center"
|
||||
>
|
||||
<img
|
||||
style="clip-path: circle(50%);"
|
||||
class="w-6 h-6 rounded-full"
|
||||
src={`https://financialmodelingprep.com/image-stock/${item.symbol}.png`}
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col ml-3 w-full">
|
||||
<span class="text-sm font-medium">{item?.symbol}</span
|
||||
>
|
||||
<span class="text-white text-sm">
|
||||
{#if typeof item?.name !== "undefined"}
|
||||
{item?.name?.length > 20
|
||||
? item?.name?.slice(0, 20) + "..."
|
||||
: item?.name}
|
||||
{:else}
|
||||
n/a
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class="text-white text-end font-semibold">
|
||||
{item?.totalAssets !== null
|
||||
? abbreviateNumber(item?.totalAssets, true)
|
||||
: "-"}
|
||||
</td>
|
||||
|
||||
<td class="text-white font-semibold text-end">
|
||||
{abbreviateNumber(item?.numberOfHoldings)}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{:else}
|
||||
<h2
|
||||
class=" mt-20 justify-center items-center text-3xl font-bold text-slate-700 mb-20 m-auto"
|
||||
>
|
||||
No data available
|
||||
<svg
|
||||
class="w-10 sm:w-12 inline-block"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
><path
|
||||
fill="#334155"
|
||||
d="M18.68 12.32a4.49 4.49 0 0 0-6.36.01a4.49 4.49 0 0 0 0 6.36a4.508 4.508 0 0 0 5.57.63L21 22.39L22.39 21l-3.09-3.11c1.13-1.77.87-4.09-.62-5.57m-1.41 4.95c-.98.98-2.56.97-3.54 0c-.97-.98-.97-2.56.01-3.54c.97-.97 2.55-.97 3.53 0c.97.98.97 2.56 0 3.54M10.9 20.1a6.527 6.527 0 0 1-1.48-2.32C6.27 17.25 4 15.76 4 14v3c0 2.21 3.58 4 8 4c-.4-.26-.77-.56-1.1-.9M4 9v3c0 1.68 2.07 3.12 5 3.7v-.2c0-.93.2-1.85.58-2.69C6.34 12.3 4 10.79 4 9m8-6C7.58 3 4 4.79 4 7c0 2 3 3.68 6.85 4h.05c1.2-1.26 2.86-2 4.6-2c.91 0 1.81.19 2.64.56A3.215 3.215 0 0 0 20 7c0-2.21-3.58-4-8-4Z"
|
||||
/></svg
|
||||
>
|
||||
</h2>
|
||||
{/if}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Similar Stocks Card -->
|
||||
|
||||
|
||||
<!--End Similar Stocks Card -->
|
||||
|
||||
<!--Start Mobile Similar Ticker Card-->
|
||||
<div class="lg:hidden space-y-3 sm:pt-5">
|
||||
|
||||
<div class="lg:hidden space-y-3 sm:pt-5">
|
||||
<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">
|
||||
Similar Ticker
|
||||
</h2>
|
||||
<div class="flex flex-col items-center mt-10 w-full">
|
||||
<span class="text-white text-center text-md text-opacity-[0.8] pl-8 pr-8">
|
||||
Identify trends in similar assets and explore superior competing options in your portfolio.
|
||||
</span>
|
||||
<!--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">
|
||||
Similar Ticker
|
||||
</h2>
|
||||
<div class="flex flex-col items-center mt-10 w-full">
|
||||
<span
|
||||
class="text-white text-center text-md text-opacity-[0.8] pl-8 pr-8"
|
||||
>
|
||||
Identify trends in similar assets and explore superior competing
|
||||
options in your portfolio.
|
||||
</span>
|
||||
|
||||
<div class="flex flex-row justify-center items-center w-full mt-5">
|
||||
<div
|
||||
class="flex flex-row justify-center items-center w-full mt-5"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!--End Header-->
|
||||
|
||||
{#if similarTicker?.length !== 0}
|
||||
<div
|
||||
class="flex justify-start items-center w-full m-auto pl-2 mt-10 overflow-x-scroll"
|
||||
>
|
||||
<table
|
||||
class="table table-sm table-compact mt-3 text-start flex justify-start items-center w-full px-3 m-auto"
|
||||
>
|
||||
<thead>
|
||||
<tr class="border-b border-blue-400">
|
||||
<th
|
||||
class="text-white font-bold text-sm text-start bg-[#000] border-b border-blue-400"
|
||||
>Company</th
|
||||
>
|
||||
<th
|
||||
class="text-white font-bold text-sm text-end bg-[#000] border-b border-blue-400"
|
||||
>Market Cap</th
|
||||
>
|
||||
<th
|
||||
class="text-white font-bold text-sm text-end bg-[#000] border-b border-blue-400"
|
||||
>Change</th
|
||||
>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each similarTicker as item, index}
|
||||
<tr
|
||||
on:click={() => etfSelector(item?.symbol)}
|
||||
class="shake-ticker text-white cursor-pointer border-b border-[#000]"
|
||||
>
|
||||
{#if index <= 6}
|
||||
<td class="text-gray-200 whitespace-nowrap">
|
||||
<div class="flex flex-row items-center">
|
||||
<div
|
||||
class="rounded-full w-10 h-10 relative flex items-center justify-center"
|
||||
>
|
||||
<img
|
||||
style="clip-path: circle(50%);"
|
||||
class="w-6 h-6 rounded-full"
|
||||
src={`https://financialmodelingprep.com/image-stock/${item.symbol}.png`}
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col ml-3 w-full">
|
||||
<span class="text-blue-400 text-sm font-medium"
|
||||
>{item?.symbol}</span
|
||||
>
|
||||
<span class="text-white text-sm">
|
||||
{#if typeof item?.name !== "undefined"}
|
||||
{item?.name?.length > 15
|
||||
? item?.name?.slice(0, 15) + "..."
|
||||
: item?.name}
|
||||
{:else}
|
||||
n/a
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class="text-white text-end font-semibold">
|
||||
{item?.totalAssets !== null
|
||||
? abbreviateNumber(item?.totalAssets, true)
|
||||
: "-"}
|
||||
</td>
|
||||
|
||||
<td class="text-white font-semibold text-end">
|
||||
{abbreviateNumber(item?.numberOfHoldings)}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{:else}
|
||||
<h2
|
||||
class="mt-20 flex justify-center items-center text-3xl font-bold text-slate-700 mb-20 m-auto"
|
||||
>
|
||||
No data available
|
||||
<svg
|
||||
class="w-10 sm:w-12 inline-block"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
><path
|
||||
fill="#334155"
|
||||
d="M18.68 12.32a4.49 4.49 0 0 0-6.36.01a4.49 4.49 0 0 0 0 6.36a4.508 4.508 0 0 0 5.57.63L21 22.39L22.39 21l-3.09-3.11c1.13-1.77.87-4.09-.62-5.57m-1.41 4.95c-.98.98-2.56.97-3.54 0c-.97-.98-.97-2.56.01-3.54c.97-.97 2.55-.97 3.53 0c.97.98.97 2.56 0 3.54M10.9 20.1a6.527 6.527 0 0 1-1.48-2.32C6.27 17.25 4 15.76 4 14v3c0 2.21 3.58 4 8 4c-.4-.26-.77-.56-1.1-.9M4 9v3c0 1.68 2.07 3.12 5 3.7v-.2c0-.93.2-1.85.58-2.69C6.34 12.3 4 10.79 4 9m8-6C7.58 3 4 4.79 4 7c0 2 3 3.68 6.85 4h.05c1.2-1.26 2.86-2 4.6-2c.91 0 1.81.19 2.64.56A3.215 3.215 0 0 0 20 7c0-2.21-3.58-4-8-4Z"
|
||||
/></svg
|
||||
>
|
||||
</h2>
|
||||
{/if}
|
||||
</div>
|
||||
<!--End Header-->
|
||||
|
||||
{#if similarTicker?.length !== 0}
|
||||
<div class="flex justify-start items-center w-full m-auto pl-2 mt-10 overflow-x-scroll">
|
||||
<table class="table table-sm table-compact mt-3 text-start flex justify-start items-center w-full px-3 m-auto">
|
||||
<thead>
|
||||
<tr class="border-b border-blue-400">
|
||||
<th class="text-white font-bold text-sm text-start bg-[#000] border-b border-blue-400">Company</th>
|
||||
<th class="text-white font-bold text-sm text-end bg-[#000] border-b border-blue-400">Market Cap</th>
|
||||
<th class="text-white font-bold text-sm text-end bg-[#000] border-b border-blue-400">Change</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each similarTicker as item, index}
|
||||
<tr on:click={() => etfSelector(item?.symbol)} class="shake-ticker text-white cursor-pointer border-b border-[#000]">
|
||||
{#if index <=6}
|
||||
|
||||
<td class="text-gray-200 whitespace-nowrap">
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="rounded-full w-10 h-10 relative flex items-center justify-center">
|
||||
<img style="clip-path: circle(50%);" class="w-6 h-6 rounded-full" src={`https://financialmodelingprep.com/image-stock/${item.symbol}.png`} loading="lazy"/>
|
||||
</div>
|
||||
<div class="flex flex-col ml-3 w-full">
|
||||
<span class="text-blue-400 text-sm font-medium">{item?.symbol}</span>
|
||||
<span class="text-white text-sm">
|
||||
{#if typeof item?.name !== 'undefined'}
|
||||
{item?.name?.length > 15 ? item?.name?.slice(0,15) + "..." : item?.name}
|
||||
{:else}
|
||||
n/a
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
<td class="text-white text-end font-semibold ">
|
||||
{item?.totalAssets !== null ? abbreviateNumber(item?.totalAssets, true) : '-'}
|
||||
</td>
|
||||
|
||||
<td class="text-white font-semibold text-end">
|
||||
{abbreviateNumber(item?.numberOfHoldings)}
|
||||
</td>
|
||||
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
<h2 class="mt-20 flex justify-center items-center text-3xl font-bold text-slate-700 mb-20 m-auto">
|
||||
No data available
|
||||
<svg class="w-10 sm:w-12 inline-block" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#334155" d="M18.68 12.32a4.49 4.49 0 0 0-6.36.01a4.49 4.49 0 0 0 0 6.36a4.508 4.508 0 0 0 5.57.63L21 22.39L22.39 21l-3.09-3.11c1.13-1.77.87-4.09-.62-5.57m-1.41 4.95c-.98.98-2.56.97-3.54 0c-.97-.98-.97-2.56.01-3.54c.97-.97 2.55-.97 3.53 0c.97.98.97 2.56 0 3.54M10.9 20.1a6.527 6.527 0 0 1-1.48-2.32C6.27 17.25 4 15.76 4 14v3c0 2.21 3.58 4 8 4c-.4-.26-.77-.56-1.1-.9M4 9v3c0 1.68 2.07 3.12 5 3.7v-.2c0-.93.2-1.85.58-2.69C6.34 12.3 4 10.79 4 9m8-6C7.58 3 4 4.79 4 7c0 2 3 3.68 6.85 4h.05c1.2-1.26 2.86-2 4.6-2c.91 0 1.81.19 2.64.56A3.215 3.215 0 0 0 20 7c0-2.21-3.58-4-8-4Z"/></svg>
|
||||
</h2>
|
||||
{/if}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!--End Mobile Similar Ticker Card-->
|
||||
|
||||
|
||||
|
||||
@ -1,175 +1,210 @@
|
||||
<script lang="ts">
|
||||
import { similarTickerClicked, screenWidth } from "$lib/store";
|
||||
import { goto } from "$app/navigation";
|
||||
import { abbreviateNumber } from "$lib/utils";
|
||||
|
||||
import {similarTickerClicked, screenWidth} from '$lib/store';
|
||||
import { goto } from '$app/navigation';
|
||||
import { abbreviateNumber } from '$lib/utils';
|
||||
export let similarstock;
|
||||
|
||||
|
||||
export let similarstock;
|
||||
|
||||
|
||||
|
||||
async function stockSelector(symbol)
|
||||
{
|
||||
window?.scroll({ top: 0, left: 0, behavior: 'smooth' });
|
||||
async function stockSelector(symbol) {
|
||||
window?.scroll({ top: 0, left: 0, behavior: "smooth" });
|
||||
//stockTicker.update(value => symbol);
|
||||
$similarTickerClicked = true;
|
||||
goto("/stocks/"+symbol)
|
||||
$similarTickerClicked = true;
|
||||
goto("/stocks/" + symbol);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</script>
|
||||
<!--Start Similar Stocks Card -->
|
||||
|
||||
<div class="space-y-3 sm:pt-5 hidden lg:block lg:{similarstock?.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]">
|
||||
|
||||
<div class="w-auto lg:w-full p-1 flex flex-col m-auto pb-14 sm:pb-10 px-2 sm:px-0">
|
||||
<!--Start Similar Stocks Card -->
|
||||
|
||||
<div
|
||||
class="space-y-3 sm:pt-5 hidden lg:block lg:{similarstock?.length !== 0
|
||||
? ''
|
||||
: 'hidden'}"
|
||||
>
|
||||
<div
|
||||
class="sm:rounded-md 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]"
|
||||
>
|
||||
<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">
|
||||
Similar Stocks
|
||||
</h2>
|
||||
{#if similarstock?.length !== 0}
|
||||
{#if similarstock?.length !== 0}
|
||||
<div class="flex justify-start items-center w-full m-auto">
|
||||
<table
|
||||
class="table table-sm table-compact mt-3 text-start flex justify-start items-center w-full px-3 m-auto"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
class="text-white font-semibold text-sm text-start bg-[#000] sm:bg-[#09090B]"
|
||||
>Company</th
|
||||
>
|
||||
<th
|
||||
class="text-white font-semibold text-sm text-end bg-[#000] sm:bg-[#09090B]"
|
||||
>Market Cap</th
|
||||
>
|
||||
<th
|
||||
class="text-white font-semibold text-sm text-end bg-[#000] sm:bg-[#09090B]"
|
||||
>Avg Volume</th
|
||||
>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each similarstock as item, index}
|
||||
<tr
|
||||
on:click={() => stockSelector(item?.symbol)}
|
||||
class="shake-ticker sm:hover:text-white text-blue-400 cursor-pointer sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-[#000] sm:bg-[#09090B] border-b border-[#000] sm:border-[#27272A]"
|
||||
>
|
||||
{#if index <= 6}
|
||||
<td class="whitespace-nowrap">
|
||||
<div class="flex flex-row items-center">
|
||||
<div
|
||||
class="rounded-full w-10 h-10 relative flex items-center justify-center"
|
||||
>
|
||||
<img
|
||||
style="clip-path: circle(50%);"
|
||||
class="w-6 h-6 rounded-full"
|
||||
src={`https://financialmodelingprep.com/image-stock/${item?.symbol}.png`}
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-col ml-3 w-full">
|
||||
<span class="text-sm sm:text-[1rem] font-medium"
|
||||
>{item?.symbol}</span
|
||||
>
|
||||
<span class="text-white text-sm">
|
||||
{#if typeof item?.name !== "undefined"}
|
||||
{item?.name?.length > 15
|
||||
? item?.name?.slice(0, 15) + "..."
|
||||
: item?.name}
|
||||
{:else}
|
||||
n/a
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
|
||||
<div class="flex justify-start items-center w-full m-auto ">
|
||||
<table class="table table-sm table-compact mt-3 text-start flex justify-start items-center w-full px-3 m-auto">
|
||||
<td class="text-white text-end text-sm sm:text-[1rem]">
|
||||
{item?.marketCap !== null
|
||||
? abbreviateNumber(item?.marketCap)
|
||||
: "-"}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] text-end">
|
||||
{item?.avgVolume !== null
|
||||
? abbreviateNumber(item?.avgVolume)
|
||||
: "-"}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class=" mt-20 flex justify-center items-center text-2xl font-bold text-slate-700 mb-20 m-auto"
|
||||
>
|
||||
No data available
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Similar Stocks Card -->
|
||||
|
||||
<!--Start Mobile Similar Ticker Card-->
|
||||
<div class="lg:hidden space-y-3 sm:pt-5">
|
||||
<div class="bg-[#000] h-auto w-screen">
|
||||
<!--Start Header-->
|
||||
<div class="w-full p-1 flex flex-col items-center pb-5 h-auto">
|
||||
<h2 class="text-center m-auto text-lg font-semibold text-white mt-5">
|
||||
Similar Ticker
|
||||
</h2>
|
||||
<div class="flex flex-col items-center mt-10 mb-5 w-full px-8">
|
||||
<span class="text-white text-center text-md">
|
||||
Identify trends in similar assets and explore superior competing
|
||||
options in your portfolio.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Header-->
|
||||
|
||||
{#if similarstock?.length !== 0}
|
||||
<div
|
||||
class="flex justify-start items-center w-full m-auto mt-10 overflow-x-scroll"
|
||||
>
|
||||
<table
|
||||
class="table table-sm table-compact mt-3 text-start flex justify-start items-center w-full px-3 m-auto"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-white font-semibold text-sm text-start bg-[#000] sm:bg-[#09090B]">Company</th>
|
||||
<th class="text-white font-semibold text-sm text-end bg-[#000] sm:bg-[#09090B]">Market Cap</th>
|
||||
<th class="text-white font-semibold text-sm text-end bg-[#000] sm:bg-[#09090B]">Avg Volume</th>
|
||||
<th class="text-white font-semibold text-sm text-start bg-[#000]"
|
||||
>Company</th
|
||||
>
|
||||
<th class="text-white font-semibold text-sm text-end bg-[#000]"
|
||||
>Market Cap</th
|
||||
>
|
||||
<th class="text-white font-semibold text-sm text-end bg-[#000]"
|
||||
>Avg Volume</th
|
||||
>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each similarstock as item, index}
|
||||
<tr on:click={() => stockSelector(item?.symbol)} class="shake-ticker sm:hover:text-white text-blue-400 cursor-pointer sm:hover:bg-[#245073] sm:hover:bg-opacity-[0.2] bg-[#000] sm:bg-[#09090B] border-b border-[#000] sm:border-[#27272A]">
|
||||
{#if index <=6}
|
||||
|
||||
<td class="whitespace-nowrap">
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="rounded-full w-10 h-10 relative flex items-center justify-center">
|
||||
<img style="clip-path: circle(50%);" class="w-6 h-6 rounded-full" src={`https://financialmodelingprep.com/image-stock/${item?.symbol}.png`} loading="lazy"/>
|
||||
<tr
|
||||
on:click={() => stockSelector(item?.symbol)}
|
||||
class="text-white cursor-pointer bg-[#000] border-b border-[#000]"
|
||||
>
|
||||
{#if index <= 6}
|
||||
<td class="text-white whitespace-nowrap">
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="flex flex-col w-full">
|
||||
<span class="text-blue-400 text-sm font-medium"
|
||||
>{item?.symbol}</span
|
||||
>
|
||||
<span class="text-white text-sm">
|
||||
{#if typeof item?.name !== "undefined"}
|
||||
{item?.name?.length > 20
|
||||
? item?.name?.slice(0, 20) + "..."
|
||||
: item?.name}
|
||||
{:else}
|
||||
n/a
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col ml-3 w-full">
|
||||
<span class="text-sm sm:text-[1rem] font-medium">{item?.symbol}</span>
|
||||
<span class="text-white text-sm">
|
||||
{#if typeof item?.name !== 'undefined'}
|
||||
{item?.name?.length > 15 ? item?.name?.slice(0,15) + "..." : item?.name}
|
||||
{:else}
|
||||
n/a
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
<td class="text-white text-end text-sm sm:text-[1rem] ">
|
||||
{item?.marketCap !== null ? abbreviateNumber(item?.marketCap) : '-'}
|
||||
</td>
|
||||
|
||||
<td class="text-white text-sm sm:text-[1rem] text-end">
|
||||
{item?.avgVolume !== null ? abbreviateNumber(item?.avgVolume) : '-'}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
</td>
|
||||
|
||||
<td class="text-white text-end font-semibold text-sm">
|
||||
{item?.marketCap !== null
|
||||
? abbreviateNumber(item?.marketCap, true)
|
||||
: "-"}
|
||||
</td>
|
||||
|
||||
<td class="text-white font-semibold text-end text-sm">
|
||||
{item?.avgVolume !== null
|
||||
? abbreviateNumber(item?.avgVolume)
|
||||
: "-"}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
<div class=" mt-20 flex justify-center items-center text-2xl font-bold text-slate-700 mb-20 m-auto">
|
||||
No data available
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Similar Stocks Card -->
|
||||
|
||||
|
||||
|
||||
<!--Start Mobile Similar Ticker Card-->
|
||||
<div class="lg:hidden space-y-3 sm:pt-5">
|
||||
|
||||
<div class="bg-[#000] h-auto w-screen">
|
||||
|
||||
<!--Start Header-->
|
||||
<div class="w-full p-1 flex flex-col items-center pb-5 h-auto">
|
||||
<h2 class="text-center m-auto text-lg font-semibold text-white mt-5">
|
||||
Similar Ticker
|
||||
</h2>
|
||||
<div class="flex flex-col items-center mt-10 mb-5 w-full px-8">
|
||||
<span class="text-white text-center text-md">
|
||||
Identify trends in similar assets and explore superior competing options in your portfolio.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!--End Header-->
|
||||
|
||||
{#if similarstock?.length !== 0}
|
||||
<div class="flex justify-start items-center w-full m-auto mt-10 overflow-x-scroll">
|
||||
<table class="table table-sm table-compact mt-3 text-start flex justify-start items-center w-full px-3 m-auto">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-white font-semibold text-sm text-start bg-[#000]">Company</th>
|
||||
<th class="text-white font-semibold text-sm text-end bg-[#000]">Market Cap</th>
|
||||
<th class="text-white font-semibold text-sm text-end bg-[#000]">Avg Volume</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each similarstock as item, index}
|
||||
<tr on:click={() => stockSelector(item?.symbol)} class="text-white cursor-pointer bg-[#000] border-b border-[#000]">
|
||||
{#if index <=6}
|
||||
|
||||
<td class="text-white whitespace-nowrap">
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="flex flex-col w-full">
|
||||
<span class="text-blue-400 text-sm font-medium">{item?.symbol}</span>
|
||||
<span class="text-white text-sm">
|
||||
{#if typeof item?.name !== 'undefined'}
|
||||
{item?.name?.length > 20 ? item?.name?.slice(0,20) + "..." : item?.name}
|
||||
{:else}
|
||||
n/a
|
||||
{/if}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
<td class="text-white text-end font-semibold text-sm">
|
||||
{item?.marketCap !== null ? abbreviateNumber(item?.marketCap,true) : '-'}
|
||||
</td>
|
||||
|
||||
<td class="text-white font-semibold text-end text-sm">
|
||||
{item?.avgVolume !== null ? abbreviateNumber(item?.avgVolume) : '-'}
|
||||
</td>
|
||||
{/if}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
<div class=" mt-20 flex justify-center items-center text-2xl font-bold text-slate-700 mb-20 m-auto">
|
||||
<div
|
||||
class=" mt-20 flex justify-center items-center text-2xl font-bold text-slate-700 mb-20 m-auto"
|
||||
>
|
||||
No data available
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--End Mobile Similar Ticker Card-->
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
<!--Start Item-->
|
||||
<div class="flex flex-row items-center ml-5 w-full mb-6">
|
||||
<div
|
||||
class="w-full rounded-lg bg-[#27272A] shadow-lg h-16 pl-3 ml-6 sm:ml-3 pt-2"
|
||||
class="w-full rounded-md bg-[#27272A] shadow-lg h-16 pl-3 ml-6 sm:ml-3 pt-2"
|
||||
>
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="flex flex-col">
|
||||
|
||||
@ -218,9 +218,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pb-2 rounded-lg bg-[#09090B]">
|
||||
<div class="pb-2 rounded-md bg-[#09090B]">
|
||||
<div
|
||||
class="bg-[#313131] w-fit relative flex flex-wrap items-center justify-center rounded-lg p-1 mt-4"
|
||||
class="bg-[#313131] w-fit relative flex flex-wrap items-center justify-center rounded-md p-1 mt-4"
|
||||
>
|
||||
{#each tabs as item, i}
|
||||
<button
|
||||
@ -231,7 +231,7 @@
|
||||
: ''} "
|
||||
>
|
||||
{#if activeIdx === i}
|
||||
<div class="absolute inset-0 rounded-lg bg-[#fff]"></div>
|
||||
<div class="absolute inset-0 rounded-md bg-[#fff]"></div>
|
||||
{/if}
|
||||
<span
|
||||
class="relative text-sm block font-medium duration-200 text-white"
|
||||
|
||||
@ -744,7 +744,7 @@
|
||||
: "Bearish"}
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 px-1.5 py-1.5 border text-center rounded-lg text-xs font-semibold"
|
||||
class="ml-2 px-1.5 py-1.5 border text-center rounded-md text-xs font-semibold"
|
||||
>
|
||||
{item[column.key]}
|
||||
</div>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,17 +1,14 @@
|
||||
<script lang='ts'>
|
||||
|
||||
|
||||
|
||||
import {tagList, stockTicker} from '$lib/store';
|
||||
import TagSearchbar from '$lib/components/TagSearchbar.svelte';
|
||||
<script lang="ts">
|
||||
import { tagList, stockTicker } from "$lib/store";
|
||||
import TagSearchbar from "$lib/components/TagSearchbar.svelte";
|
||||
//import { afterNavigate } from '$app/navigation';
|
||||
//import { base } from '$app/paths'
|
||||
//import { onMount } from 'svelte';
|
||||
|
||||
|
||||
export let id;
|
||||
export let errors;
|
||||
export let placeholder = '';
|
||||
|
||||
export let placeholder = "";
|
||||
|
||||
/*
|
||||
let previousPage : string = base ;
|
||||
|
||||
@ -28,115 +25,147 @@
|
||||
|
||||
})
|
||||
*/
|
||||
|
||||
|
||||
$stockTicker = '';
|
||||
|
||||
$stockTicker = "";
|
||||
let selectedTags = [];
|
||||
|
||||
function toggleTag(tag) {
|
||||
|
||||
if (selectedTags.includes(tag)) {
|
||||
selectedTags = selectedTags.filter((t) => t !== tag);
|
||||
} else if (selectedTags.length < 3) {
|
||||
selectedTags = [...selectedTags, tag];
|
||||
}
|
||||
|
||||
if (!selectedTags.includes($stockTicker))
|
||||
{
|
||||
$stockTicker = '';
|
||||
selectedTags = [...selectedTags];
|
||||
}
|
||||
|
||||
|
||||
function toggleTag(tag) {
|
||||
if (selectedTags.includes(tag)) {
|
||||
selectedTags = selectedTags.filter((t) => t !== tag);
|
||||
} else if (selectedTags.length < 3) {
|
||||
selectedTags = [...selectedTags, tag];
|
||||
}
|
||||
|
||||
|
||||
$: {
|
||||
if($stockTicker )
|
||||
{
|
||||
toggleTag($stockTicker)
|
||||
|
||||
if (!selectedTags.includes($stockTicker)) {
|
||||
$stockTicker = "";
|
||||
selectedTags = [...selectedTags];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$: {
|
||||
if (selectedTags)
|
||||
{
|
||||
errors = '';
|
||||
if ($stockTicker) {
|
||||
toggleTag($stockTicker);
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
{#if selectedTags?.length === 0}
|
||||
<span class="w-full max-w-2xl pt-3 text-sm text-gray-400">{placeholder}</span>
|
||||
{:else}
|
||||
<span class="w-full max-w-2xl pt-3 text-sm text-gray-400">Tags selected: {selectedTags}</span>
|
||||
{/if}
|
||||
<div class="form-control flex flex-col flex flex-wrap rounded-lg pt-3 items-center bg-[#242527] w-full max-w-2xl">
|
||||
<div class="flex flex-wrap m-auto p-3 ">
|
||||
|
||||
|
||||
<!--Start Add stock tag-->
|
||||
<div class="-mr-1.5">
|
||||
{#if $stockTicker?.length ===0}
|
||||
{#if selectedTags.length === 3 && !selectedTags.includes($stockTicker) }
|
||||
<label class="mr-2 border border-slate-500 flex flex-wrap pl-4 pr-4 py-2 m-1 justify-between items-center text-sm font-medium rounded-xl cursor-not-allowed opacity-50 text-gray-200 hover:text-gray-100">
|
||||
<span class="sr-only">Search</span>
|
||||
<svg class="w-4 h-4 mr-2" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path class="fill-current text-white" d="M7 14c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7zM7 2C4.243 2 2 4.243 2 7s2.243 5 5 5 5-2.243 5-5-2.243-5-5-5z" />
|
||||
<path class="fill-current text-white" d="M15.707 14.293L13.314 11.9a8.019 8.019 0 01-1.414 1.414l2.393 2.393a.997.997 0 001.414 0 .999.999 0 000-1.414z" />
|
||||
</svg>
|
||||
<span class="text-gray-300">Search a ticker...</span>
|
||||
|
||||
$: {
|
||||
if (selectedTags) {
|
||||
errors = "";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if selectedTags?.length === 0}
|
||||
<span class="w-full max-w-2xl pt-3 text-sm text-gray-400">{placeholder}</span>
|
||||
{:else}
|
||||
<span class="w-full max-w-2xl pt-3 text-sm text-gray-400"
|
||||
>Tags selected: {selectedTags}</span
|
||||
>
|
||||
{/if}
|
||||
<div
|
||||
class="form-control flex flex-col flex flex-wrap rounded-md pt-3 items-center bg-[#242527] w-full max-w-2xl"
|
||||
>
|
||||
<div class="flex flex-wrap m-auto p-3">
|
||||
<!--Start Add stock tag-->
|
||||
<div class="-mr-1.5">
|
||||
{#if $stockTicker?.length === 0}
|
||||
{#if selectedTags.length === 3 && !selectedTags.includes($stockTicker)}
|
||||
<label
|
||||
class="mr-2 border border-slate-500 flex flex-wrap pl-4 pr-4 py-2 m-1 justify-between items-center text-sm font-medium rounded-xl cursor-not-allowed opacity-50 text-gray-200 hover:text-gray-100"
|
||||
>
|
||||
<span class="sr-only">Search</span>
|
||||
<svg
|
||||
class="w-4 h-4 mr-2"
|
||||
viewBox="0 0 16 16"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
class="fill-current text-white"
|
||||
d="M7 14c-3.86 0-7-3.14-7-7s3.14-7 7-7 7 3.14 7 7-3.14 7-7 7zM7 2C4.243 2 2 4.243 2 7s2.243 5 5 5 5-2.243 5-5-2.243-5-5-5z"
|
||||
/>
|
||||
<path
|
||||
class="fill-current text-white"
|
||||
d="M15.707 14.293L13.314 11.9a8.019 8.019 0 01-1.414 1.414l2.393 2.393a.997.997 0 001.414 0 .999.999 0 000-1.414z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="text-gray-300">Search a ticker...</span>
|
||||
</label>
|
||||
{:else}
|
||||
<TagSearchbar />
|
||||
{/if}
|
||||
{:else}
|
||||
<label on:click={() => toggleTag($stockTicker)} class="cursor-pointer mr-2 border border-slate-500 flex flex-wrap pl-4 pr-4 py-2 m-1 mb-2 justify-between items-center text-sm font-medium rounded-xl text-gray-200 hover:text-gray-100">
|
||||
<TagSearchbar />
|
||||
{/if}
|
||||
{:else}
|
||||
<label
|
||||
on:click={() => toggleTag($stockTicker)}
|
||||
class="cursor-pointer mr-2 border border-slate-500 flex flex-wrap pl-4 pr-4 py-2 m-1 mb-2 justify-between items-center text-sm font-medium rounded-xl text-gray-200 hover:text-gray-100"
|
||||
>
|
||||
{$stockTicker}
|
||||
{#if selectedTags?.includes($stockTicker)}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="inline-block h-5 w-5 ml-1 hover:text-gray-300" viewBox="0 0 20 20"
|
||||
fill="currentColor">
|
||||
<path fill-rule="evenodd"
|
||||
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="inline-block h-5 w-5 ml-1 hover:text-gray-300"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
{/if}
|
||||
</label>
|
||||
{/if}
|
||||
</div>
|
||||
<!--End add stock tag-->
|
||||
{#each $tagList as tag}
|
||||
<label
|
||||
on:click={() => toggleTag(tag.name)}
|
||||
class="flex flex-wrap pl-4 pr-4 py-2 m-1 mb-2 justify-between items-center text-sm font-medium rounded-xl {selectedTags.length ===
|
||||
3 && !selectedTags.includes(tag.name)
|
||||
? 'cursor-not-allowed opacity-50'
|
||||
: 'cursor-pointer'} text-gray-200 hover:text-gray-100"
|
||||
style={`background-color: ${tag.color};`}
|
||||
>
|
||||
{tag.name}
|
||||
{#if selectedTags?.includes(tag.name)}
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="inline-block h-5 w-5 ml-1 hover:text-gray-300"
|
||||
viewBox="0 0 20 20"
|
||||
fill="currentColor"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
{/if}
|
||||
</div>
|
||||
<!--End add stock tag-->
|
||||
{#each $tagList as tag}
|
||||
<label on:click={() => toggleTag(tag.name)}
|
||||
class="flex flex-wrap pl-4 pr-4 py-2 m-1 mb-2 justify-between items-center text-sm font-medium rounded-xl {selectedTags.length === 3 && !selectedTags.includes(tag.name) ? 'cursor-not-allowed opacity-50' : 'cursor-pointer'} text-gray-200 hover:text-gray-100"
|
||||
style={`background-color: ${tag.color};`} >
|
||||
{tag.name}
|
||||
{#if selectedTags?.includes(tag.name)}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="inline-block h-5 w-5 ml-1 hover:text-gray-300" viewBox="0 0 20 20"
|
||||
fill="currentColor">
|
||||
<path fill-rule="evenodd"
|
||||
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
{/if}
|
||||
</label>
|
||||
{/each}
|
||||
|
||||
<input class="hidden" value={JSON.stringify([selectedTags.filter((t) => t !== $stockTicker) ])} id="tagTopic" name="tagTopic" />
|
||||
<input class="hidden" value={$stockTicker} id ="tagline" name="tagline" />
|
||||
<input class="hidden" value={selectedTags+$stockTicker} id='atLeastOneTag' name = "atLeastOneTag" />
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</label>
|
||||
{/each}
|
||||
|
||||
<input
|
||||
class="hidden"
|
||||
value={JSON.stringify([selectedTags.filter((t) => t !== $stockTicker)])}
|
||||
id="tagTopic"
|
||||
name="tagTopic"
|
||||
/>
|
||||
<input class="hidden" value={$stockTicker} id="tagline" name="tagline" />
|
||||
<input
|
||||
class="hidden"
|
||||
value={selectedTags + $stockTicker}
|
||||
id="atLeastOneTag"
|
||||
name="atLeastOneTag"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="w-full max-w-2xl ">
|
||||
</div>
|
||||
|
||||
<div class="w-full max-w-2xl">
|
||||
{#if errors?.length}
|
||||
<label for={id} class="label py-0 pt-1">
|
||||
<span class="label-text-alt text-error">
|
||||
{errors}
|
||||
</span>
|
||||
</label>
|
||||
<label for={id} class="label py-0 pt-1">
|
||||
<span class="label-text-alt text-error">
|
||||
{errors}
|
||||
</span>
|
||||
</label>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,79 +1,74 @@
|
||||
<script lang='ts'>
|
||||
<script lang="ts">
|
||||
export let value = "";
|
||||
export let placeholder = "";
|
||||
export let id;
|
||||
export let label;
|
||||
export let type = "text";
|
||||
export let disabled = false;
|
||||
export let required = false;
|
||||
export let hidden = false;
|
||||
|
||||
export let maxLength = 512;
|
||||
export let showCounter = false;
|
||||
|
||||
export let errors;
|
||||
|
||||
export let value = '';
|
||||
export let placeholder = '';
|
||||
export let id;
|
||||
export let label;
|
||||
export let type = 'text';
|
||||
export let disabled = false;
|
||||
export let required = false;
|
||||
export let hidden = false;
|
||||
let inputValue = value;
|
||||
let counterColor;
|
||||
|
||||
export let maxLength = 512;
|
||||
export let showCounter = false;
|
||||
$: counter = `${inputValue.length}/${maxLength}`;
|
||||
|
||||
export let errors;
|
||||
|
||||
let inputValue = value;
|
||||
let counterColor;
|
||||
|
||||
$: counter = `${inputValue.length}/${maxLength}`;
|
||||
|
||||
$: {
|
||||
if (inputValue.length > maxLength) {
|
||||
counterColor = 'text-error';
|
||||
} else {
|
||||
counterColor = 'text-white';
|
||||
}
|
||||
}
|
||||
|
||||
function handleInput(event) {
|
||||
inputValue = event.target.value;
|
||||
$: {
|
||||
if (inputValue.length > maxLength) {
|
||||
counterColor = "text-error";
|
||||
} else {
|
||||
counterColor = "text-white";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleInput(event) {
|
||||
inputValue = event.target.value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, maximum-scale=1.0"
|
||||
/>
|
||||
</svelte:head>
|
||||
|
||||
|
||||
<div class="form-control w-full h-auto max-w-2xl {hidden ? 'hidden' : ''}">
|
||||
<label for={id} class="label font-medium pb-1">
|
||||
<span class="label-text">{label}</span>
|
||||
</label>
|
||||
<label for={id} class="label font-medium pb-1">
|
||||
<span class="label-text">{label}</span>
|
||||
</label>
|
||||
|
||||
|
||||
<textarea
|
||||
input="text"
|
||||
class="min-h-[290px] placeholder:text-gray-300 h-auto text-sm bg-[#242527] w-full resize-none focus-none ring-none rounded-md text-white"
|
||||
{type}
|
||||
{placeholder}
|
||||
{required}
|
||||
{disabled}
|
||||
{id}
|
||||
name={id}
|
||||
value={inputValue}
|
||||
on:input={handleInput}
|
||||
/>
|
||||
|
||||
<textarea
|
||||
input='text'
|
||||
class="min-h-[290px] placeholder:text-gray-300 h-auto text-sm bg-[#242527] w-full resize-none focus-none ring-none rounded-lg text-white"
|
||||
{type}
|
||||
{placeholder}
|
||||
{required}
|
||||
{disabled}
|
||||
{id}
|
||||
name={id}
|
||||
value={inputValue}
|
||||
on:input={handleInput}
|
||||
/>
|
||||
|
||||
{#if showCounter}
|
||||
<div class="flex justify-end mt-1 -mb-1">
|
||||
<span class={`label-text text-xs ${counterColor}`}>{counter}</span>
|
||||
</div>
|
||||
{/if}
|
||||
{#if showCounter}
|
||||
<div class="flex justify-end mt-1 -mb-1">
|
||||
<span class={`label-text text-xs ${counterColor}`}>{counter}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if errors}
|
||||
{#each errors as error}
|
||||
<label for={id} class="label py-0 pt-1">
|
||||
<span class="label-text-alt text-error">
|
||||
{error}
|
||||
</span>
|
||||
</label>
|
||||
{/each}
|
||||
{/if}
|
||||
{#if errors}
|
||||
{#each errors as error}
|
||||
<label for={id} class="label py-0 pt-1">
|
||||
<span class="label-text-alt text-error">
|
||||
{error}
|
||||
</span>
|
||||
</label>
|
||||
{/each}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@ -81,7 +81,7 @@
|
||||
|
||||
<div class="sm:space-y-3">
|
||||
<div
|
||||
class="sm:rounded-lg lg:border lg:border-slate-800 bg-[#000] lg:bg-[#09090B] h-auto w-screen pt-16 sm:w-full md:w-[420px] xl:w-[450px] lg:pt-0"
|
||||
class="sm:rounded-md lg:border lg:border-slate-800 bg-[#000] lg:bg-[#09090B] h-auto w-screen pt-16 sm:w-full md:w-[420px] xl:w-[450px] lg:pt-0"
|
||||
>
|
||||
<!--Start Header-->
|
||||
<div
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
: 'hidden'}"
|
||||
>
|
||||
<div
|
||||
class="sm:rounded-lg shadow-lg bg-[#000] sm:bg-[#09090B] sm:border sm:border-slate-800 h-auto {$screenWidth <
|
||||
class="sm:rounded-md 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]"
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
>
|
||||
<!--Start Flow Sentiment-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="font-medium text-gray-200 text-sm"
|
||||
@ -50,7 +50,7 @@
|
||||
<!--End Flow Sentiment-->
|
||||
<!--Start Put/Call-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="font-medium text-gray-200 text-sm">Accuracy</span>
|
||||
@ -112,7 +112,7 @@
|
||||
|
||||
<!--Start Precision-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#27272A] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span class="font-medium text-gray-200 text-sm">Precision</span>
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
</script>
|
||||
|
||||
<section
|
||||
class="relative flex justify-between items-center bg-[{color}] rounded-lg"
|
||||
class="relative flex justify-between items-center bg-[{color}] rounded-md"
|
||||
>
|
||||
<div class="max-w-3xl m-auto">
|
||||
<div
|
||||
@ -93,19 +93,19 @@
|
||||
<div class="w-full flex flex-row items-center">
|
||||
<div class="flex flex-col items-center mr-10 sm:mr-14">
|
||||
<div class="bg-slate-400 rounded-full w-12 h-12"></div>
|
||||
<div class="bg-slate-400 rounded-lg w-12 h-4 mt-3"></div>
|
||||
<div class="bg-slate-400 rounded-md w-12 h-4 mt-3"></div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center mr-10 sm:mr-14">
|
||||
<div class="bg-slate-400 rounded-full w-12 h-12"></div>
|
||||
<div class="bg-slate-400 rounded-lg w-12 h-4 mt-3"></div>
|
||||
<div class="bg-slate-400 rounded-md w-12 h-4 mt-3"></div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center mr-10 sm:mr-14">
|
||||
<div class="bg-slate-400 rounded-full w-12 h-12"></div>
|
||||
<div class="bg-slate-400 rounded-lg w-12 h-4 mt-3"></div>
|
||||
<div class="bg-slate-400 rounded-md w-12 h-4 mt-3"></div>
|
||||
</div>
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="bg-slate-400 rounded-full w-12 h-12"></div>
|
||||
<div class="bg-slate-400 rounded-lg w-12 h-4 mt-3"></div>
|
||||
<div class="bg-slate-400 rounded-md w-12 h-4 mt-3"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
<script lang="ts">
|
||||
export let state;
|
||||
let color = state === "active" ? "#0076FE" : "#A6ADBB";
|
||||
|
||||
<script lang='ts'>
|
||||
|
||||
export let state;
|
||||
let color = state === 'active' ? '#0076FE' : '#A6ADBB'
|
||||
|
||||
/*
|
||||
/*
|
||||
async function clickEvent()
|
||||
{ if(state === 'active')
|
||||
{
|
||||
@ -16,12 +14,31 @@
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div class="flex justify-center items-center {state === 'active' ? 'text-[#0076FE] bg-[#31304D] lg:bg-inherit' : 'text-[#A6ADBB]'} rounded-lg w-8 h-8 relative">
|
||||
<svg class="lg:hidden inline-block rotate-180 w-4 h-4" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512.171 512.171" xml:space="preserve"><path fill="currentColor" d="M479.046,283.925c-1.664-3.989-5.547-6.592-9.856-6.592H352.305V10.667C352.305,4.779,347.526,0,341.638,0H170.971 c-5.888,0-10.667,4.779-10.667,10.667v266.667H42.971c-4.309,0-8.192,2.603-9.856,6.571c-1.643,3.989-0.747,8.576,2.304,11.627 l212.8,213.504c2.005,2.005,4.715,3.136,7.552,3.136s5.547-1.131,7.552-3.115l213.419-213.504 C479.793,292.501,480.71,287.915,479.046,283.925z"></path></svg>
|
||||
<svg class="hidden lg:block cursor-pointer rotate-180 inline-block w-9 h-9 hover:text-[#fff] text-[#5C5C5C]" fill={state === 'active' ? color : "currentColor"} viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M17.9188 8.17969H11.6888H6.07877C5.11877 8.17969 4.63877 9.33969 5.31877 10.0197L10.4988 15.1997C11.3288 16.0297 12.6788 16.0297 13.5088 15.1997L15.4788 13.2297L18.6888 10.0197C19.3588 9.33969 18.8788 8.17969 17.9188 8.17969Z" /></svg>
|
||||
<div
|
||||
class="flex justify-center items-center {state === 'active'
|
||||
? 'text-[#0076FE] bg-[#31304D] lg:bg-inherit'
|
||||
: 'text-[#A6ADBB]'} rounded-md w-8 h-8 relative"
|
||||
>
|
||||
<svg
|
||||
class="lg:hidden inline-block rotate-180 w-4 h-4"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512.171 512.171"
|
||||
xml:space="preserve"
|
||||
><path
|
||||
fill="currentColor"
|
||||
d="M479.046,283.925c-1.664-3.989-5.547-6.592-9.856-6.592H352.305V10.667C352.305,4.779,347.526,0,341.638,0H170.971 c-5.888,0-10.667,4.779-10.667,10.667v266.667H42.971c-4.309,0-8.192,2.603-9.856,6.571c-1.643,3.989-0.747,8.576,2.304,11.627 l212.8,213.504c2.005,2.005,4.715,3.136,7.552,3.136s5.547-1.131,7.552-3.115l213.419-213.504 C479.793,292.501,480.71,287.915,479.046,283.925z"
|
||||
></path></svg
|
||||
>
|
||||
<svg
|
||||
class="hidden lg:block cursor-pointer rotate-180 inline-block w-9 h-9 hover:text-[#fff] text-[#5C5C5C]"
|
||||
fill={state === "active" ? color : "currentColor"}
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><path
|
||||
d="M17.9188 8.17969H11.6888H6.07877C5.11877 8.17969 4.63877 9.33969 5.31877 10.0197L10.4988 15.1997C11.3288 16.0297 12.6788 16.0297 13.5088 15.1997L15.4788 13.2297L18.6888 10.0197C19.3588 9.33969 18.8788 8.17969 17.9188 8.17969Z"
|
||||
/></svg
|
||||
>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,13 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { varComponent, displayCompanyName, stockTicker, etfTicker, cryptoTicker, assetType, getCache, setCache } from '$lib/store';
|
||||
import InfoModal from '$lib/components/InfoModal.svelte';
|
||||
import {
|
||||
varComponent,
|
||||
displayCompanyName,
|
||||
stockTicker,
|
||||
etfTicker,
|
||||
cryptoTicker,
|
||||
assetType,
|
||||
getCache,
|
||||
setCache,
|
||||
} from "$lib/store";
|
||||
import InfoModal from "$lib/components/InfoModal.svelte";
|
||||
|
||||
import { Chart } from 'svelte-echarts';
|
||||
import { Chart } from "svelte-echarts";
|
||||
|
||||
import { init, use } from 'echarts/core';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import { GridComponent, TooltipComponent } from 'echarts/components';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
import { init, use } from "echarts/core";
|
||||
import { LineChart } from "echarts/charts";
|
||||
import { GridComponent, TooltipComponent } from "echarts/components";
|
||||
import { CanvasRenderer } from "echarts/renderers";
|
||||
|
||||
export let data;
|
||||
|
||||
@ -36,43 +45,46 @@
|
||||
const option = {
|
||||
silent: true,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
trigger: "axis",
|
||||
hideDelay: 100,
|
||||
},
|
||||
animation: false,
|
||||
grid: {
|
||||
left: '2%',
|
||||
right: '2%',
|
||||
bottom: '2%',
|
||||
top: '5%',
|
||||
left: "2%",
|
||||
right: "2%",
|
||||
bottom: "2%",
|
||||
top: "5%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
type: "category",
|
||||
boundaryGap: false,
|
||||
data: dates,
|
||||
axisLabel: {
|
||||
color: '#fff',
|
||||
color: "#fff",
|
||||
formatter: (value: string) => {
|
||||
const date = new Date(value + '-01');
|
||||
return new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'short' }).format(date);
|
||||
const date = new Date(value + "-01");
|
||||
return new Intl.DateTimeFormat("en-US", {
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
}).format(date);
|
||||
},
|
||||
},
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
type: "value",
|
||||
splitLine: { show: false },
|
||||
axisLabel: { show: false },
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: 'VaR',
|
||||
name: "VaR",
|
||||
data: varList,
|
||||
type: 'line',
|
||||
type: "line",
|
||||
areaStyle: { opacity: 0.8 },
|
||||
itemStyle: { color: '#E11D48' },
|
||||
itemStyle: { color: "#E11D48" },
|
||||
showSymbol: false,
|
||||
},
|
||||
],
|
||||
@ -82,27 +94,32 @@
|
||||
}
|
||||
|
||||
const getVaR = async (ticker: string) => {
|
||||
const cachedData = getCache(ticker, 'getVaR');
|
||||
const cachedData = getCache(ticker, "getVaR");
|
||||
if (cachedData) {
|
||||
varDict = cachedData;
|
||||
} else {
|
||||
const postData = { ticker, path: 'value-at-risk' };
|
||||
const response = await fetch('/api/ticker-data', {
|
||||
method: 'POST',
|
||||
const postData = { ticker, path: "value-at-risk" };
|
||||
const response = await fetch("/api/ticker-data", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(postData),
|
||||
});
|
||||
|
||||
varDict = await response.json();
|
||||
setCache(ticker, varDict, 'getVaR');
|
||||
setCache(ticker, varDict, "getVaR");
|
||||
}
|
||||
|
||||
$varComponent = Object.keys(varDict).length !== 0;
|
||||
};
|
||||
|
||||
$: {
|
||||
const ticker = $assetType === 'stock' ? $stockTicker : $assetType === 'etf' ? $etfTicker : $cryptoTicker;
|
||||
if (ticker && typeof window !== 'undefined') {
|
||||
const ticker =
|
||||
$assetType === "stock"
|
||||
? $stockTicker
|
||||
: $assetType === "etf"
|
||||
? $etfTicker
|
||||
: $cryptoTicker;
|
||||
if (ticker && typeof window !== "undefined") {
|
||||
isLoaded = false;
|
||||
|
||||
getVaR(ticker)
|
||||
@ -112,7 +129,7 @@
|
||||
valueAtRisk = varDict.history?.slice(-1)?.at(0)?.var ?? "n/a";
|
||||
optionsData = getPlotOptions();
|
||||
})
|
||||
.catch((error) => console.error('An error occurred:', error))
|
||||
.catch((error) => console.error("An error occurred:", error))
|
||||
.finally(() => {
|
||||
isLoaded = true;
|
||||
});
|
||||
@ -120,7 +137,6 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<section class="overflow-hidden text-white h-full pb-10 sm:pb-0">
|
||||
<main class="overflow-hidden">
|
||||
<div class="flex flex-row items-center">
|
||||
@ -140,7 +156,7 @@
|
||||
{#if Object?.keys(varDict)?.length !== 0}
|
||||
<div class="pb-4 w-full mt-5">
|
||||
<div
|
||||
class="w-auto p-4 sm:p-6 bg-[#09090B] sm:bg-[#09090B] rounded-lg relative"
|
||||
class="w-auto p-4 sm:p-6 bg-[#09090B] sm:bg-[#09090B] rounded-md relative"
|
||||
>
|
||||
<div class="flex flex-row items-center justify-between">
|
||||
<div class="relative size-[60px] sm:size-[90px] ml-auto">
|
||||
|
||||
@ -5,7 +5,7 @@ import Description from "./alert-description.svelte";
|
||||
import Title from "./alert-title.svelte";
|
||||
|
||||
export const alertVariants = tv({
|
||||
base: "relative w-full rounded-lg border p-4 [&:has(svg)]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
|
||||
base: "relative w-full rounded-md border p-4 [&:has(svg)]:pl-11 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground",
|
||||
|
||||
variants: {
|
||||
variant: {
|
||||
|
||||
@ -1,16 +1,19 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils";
|
||||
import type { HTMLAttributes } from "svelte/elements";
|
||||
import { cn } from "$lib/utils";
|
||||
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
type $$Props = HTMLAttributes<HTMLDivElement>;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
let className: $$Props["class"] = undefined;
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={cn("rounded-lg border border-gray-800 bg-[#09090B] text-white shadow-sm", className)}
|
||||
{...$$restProps}
|
||||
class={cn(
|
||||
"rounded-md border border-gray-800 bg-[#09090B] text-white shadow-sm",
|
||||
className,
|
||||
)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
@ -1,36 +1,36 @@
|
||||
<script lang="ts">
|
||||
import { Dialog as DialogPrimitive } from "bits-ui";
|
||||
import X from "lucide-svelte/icons/x";
|
||||
import * as Dialog from "./index.js";
|
||||
import { cn, flyAndScale } from "$lib/utils";
|
||||
import { Dialog as DialogPrimitive } from "bits-ui";
|
||||
import X from "lucide-svelte/icons/x";
|
||||
import * as Dialog from "./index.js";
|
||||
import { cn, flyAndScale } from "$lib/utils";
|
||||
|
||||
type $$Props = DialogPrimitive.ContentProps;
|
||||
type $$Props = DialogPrimitive.ContentProps;
|
||||
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let transition: $$Props["transition"] = flyAndScale;
|
||||
export let transitionConfig: $$Props["transitionConfig"] = {
|
||||
duration: 200,
|
||||
};
|
||||
export { className as class };
|
||||
let className: $$Props["class"] = undefined;
|
||||
export let transition: $$Props["transition"] = flyAndScale;
|
||||
export let transitionConfig: $$Props["transitionConfig"] = {
|
||||
duration: 200,
|
||||
};
|
||||
export { className as class };
|
||||
</script>
|
||||
|
||||
<Dialog.Portal>
|
||||
<Dialog.Overlay />
|
||||
<DialogPrimitive.Content
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
class={cn(
|
||||
"bg-background fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg sm:rounded-lg md:w-full",
|
||||
className
|
||||
)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
<DialogPrimitive.Close
|
||||
class="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none"
|
||||
>
|
||||
<X class="h-4 w-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
</DialogPrimitive.Content>
|
||||
</Dialog.Portal>
|
||||
<Dialog.Overlay />
|
||||
<DialogPrimitive.Content
|
||||
{transition}
|
||||
{transitionConfig}
|
||||
class={cn(
|
||||
"bg-background fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg sm:rounded-md md:w-full",
|
||||
className,
|
||||
)}
|
||||
{...$$restProps}
|
||||
>
|
||||
<slot />
|
||||
<DialogPrimitive.Close
|
||||
class="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute right-4 top-4 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none"
|
||||
>
|
||||
<X class="h-4 w-4" />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
</DialogPrimitive.Content>
|
||||
</Dialog.Portal>
|
||||
|
||||
@ -294,7 +294,7 @@ const handleTwitchMessage = (event) => {
|
||||
class="w-full flex flex-row items-center mr-auto mt-5"
|
||||
>
|
||||
<div
|
||||
class="flex h-9 w-9 items-center justify-center rounded-lg text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
>
|
||||
<Home class="h-5.5 w-5.5" />
|
||||
</div>
|
||||
@ -688,7 +688,7 @@ const handleTwitchMessage = (event) => {
|
||||
>
|
||||
<div class="flex flex-row items-center mr-auto">
|
||||
<div
|
||||
class="flex h-9 w-9 items-center justify-center rounded-lg text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
>
|
||||
<Option class="h-5.5 w-5.5" />
|
||||
</div>
|
||||
@ -712,7 +712,7 @@ const handleTwitchMessage = (event) => {
|
||||
>
|
||||
<div class="flex flex-row items-center mr-auto">
|
||||
<div
|
||||
class="flex h-9 w-9 items-center justify-center rounded-lg text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
>
|
||||
<Boxes class="h-5.5 w-5.5" />
|
||||
</div>
|
||||
@ -736,7 +736,7 @@ const handleTwitchMessage = (event) => {
|
||||
>
|
||||
<div class="flex flex-row items-center mr-auto">
|
||||
<div
|
||||
class="flex h-9 w-9 items-center justify-center rounded-lg text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
>
|
||||
<Newspaper class="h-5.5 w-5.5" />
|
||||
</div>
|
||||
@ -758,7 +758,7 @@ const handleTwitchMessage = (event) => {
|
||||
>
|
||||
<div class="flex flex-row items-center mr-auto">
|
||||
<div
|
||||
class="flex h-9 w-9 items-center justify-center rounded-lg text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
>
|
||||
<Gem class="h-5.5 w-5.5" />
|
||||
</div>
|
||||
@ -819,7 +819,7 @@ const handleTwitchMessage = (event) => {
|
||||
<Input
|
||||
type="search"
|
||||
placeholder="Search..."
|
||||
class="w-full rounded-lg bg-[#202327] placeholder-gray-400 border-none pl-8 md:w-[300px] lg:w-[700px] border-transparent focus:border-transparent focus:ring-0 "
|
||||
class="w-full rounded-md bg-[#202327] placeholder-gray-400 border-none pl-8 md:w-[300px] lg:w-[700px] border-transparent focus:border-transparent focus:ring-0 "
|
||||
autocomplete="off"
|
||||
/>
|
||||
-->
|
||||
@ -833,7 +833,7 @@ const handleTwitchMessage = (event) => {
|
||||
<DropdownMenu.Trigger asChild let:builder>
|
||||
<Button
|
||||
size="icon"
|
||||
class="overflow-hidden rounded-lg bg-[#09090B] sm:hover:bg-[#27272A] border border-gray-600 w-10 h-10"
|
||||
class="overflow-hidden rounded-md bg-[#09090B] sm:hover:bg-[#27272A] border border-gray-600 w-10 h-10"
|
||||
builders={[builder]}
|
||||
>
|
||||
<svg
|
||||
@ -909,7 +909,7 @@ const handleTwitchMessage = (event) => {
|
||||
|
||||
<a href="/" class="flex flex-row items-center ml-9 w-full">
|
||||
<div
|
||||
class="flex h-9 w-9 items-center justify-center rounded-lg text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
>
|
||||
<Home class="h-5.5 w-5.5" />
|
||||
</div>
|
||||
@ -1134,7 +1134,7 @@ const handleTwitchMessage = (event) => {
|
||||
class="flex flex-row items-center ml-9 w-full mt-3"
|
||||
>
|
||||
<div
|
||||
class="flex h-9 w-9 items-center justify-center rounded-lg text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
>
|
||||
<Option class="h-5.5 w-5.5" />
|
||||
</div>
|
||||
@ -1146,7 +1146,7 @@ const handleTwitchMessage = (event) => {
|
||||
class="flex flex-row items-center ml-9 w-full mt-3"
|
||||
>
|
||||
<div
|
||||
class="flex h-9 w-9 items-center justify-center rounded-lg text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
>
|
||||
<Boxes class="h-5.5 w-5.5" />
|
||||
</div>
|
||||
@ -1158,7 +1158,7 @@ const handleTwitchMessage = (event) => {
|
||||
class="flex flex-row items-center ml-9 w-full mt-3"
|
||||
>
|
||||
<div
|
||||
class="flex h-9 w-9 items-center justify-center rounded-lg text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
>
|
||||
<Newspaper class="h-5.5 w-5.5" />
|
||||
</div>
|
||||
@ -1170,7 +1170,7 @@ const handleTwitchMessage = (event) => {
|
||||
class="flex flex-row items-center ml-9 w-full mt-3"
|
||||
>
|
||||
<div
|
||||
class="flex h-9 w-9 items-center justify-center rounded-lg text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
class="flex h-9 w-9 items-center justify-center rounded-md text-white transition-colors hover:text-white md:h-8 md:w-8"
|
||||
>
|
||||
<Gem class="h-5.5 w-5.5" />
|
||||
</div>
|
||||
@ -1192,7 +1192,7 @@ const handleTwitchMessage = (event) => {
|
||||
<Card.Content class="p-2 pt-0 md:p-4 md:pt-0">
|
||||
<a
|
||||
href="/pricing"
|
||||
class="flex justify-center items-center text-center rounded-lg text-sm py-2 m-auto text-center w-full bg-white text-black font-semibold hover:bg-white/80"
|
||||
class="flex justify-center items-center text-center rounded-md text-sm py-2 m-auto text-center w-full bg-white text-black font-semibold hover:bg-white/80"
|
||||
>
|
||||
Become Pro
|
||||
</a>
|
||||
|
||||
@ -171,7 +171,7 @@
|
||||
<div class="w-full m-auto mt-16">
|
||||
{#if isLoaded}
|
||||
<div
|
||||
class="w-full m-auto rounded-none sm:rounded-lg mb-4 overflow-x-scroll sm:overflow-hidden"
|
||||
class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-scroll sm:overflow-hidden"
|
||||
>
|
||||
<table
|
||||
class="table table-sm table-compact rounded-none sm:rounded-md w-full bg-[#09090B] border-bg-[#09090B] m-auto"
|
||||
|
||||
@ -300,7 +300,7 @@
|
||||
href={sectorNavigation?.find(
|
||||
(listItem) => listItem?.title === item,
|
||||
)?.link}
|
||||
class="px-3 text-sm py-1 sm:text-[1rem] rounded-lg bg-white bg-opacity-[0.1] sm:hover:bg-opacity-[0.2] ml-0"
|
||||
class="px-3 text-sm py-1 sm:text-[1rem] rounded-md bg-white bg-opacity-[0.1] sm:hover:bg-opacity-[0.2] ml-0"
|
||||
>
|
||||
{item}
|
||||
</a>
|
||||
@ -315,7 +315,7 @@
|
||||
{#each data?.getAnalystStats?.mainIndustries as item}
|
||||
<a
|
||||
href={`/list/industry/${item?.replace(/ /g, "-")?.replace(/&/g, "and")?.replace(/-{2,}/g, "-")?.toLowerCase()}`}
|
||||
class="px-3 text-sm py-1 sm:text-[1rem] rounded-lg bg-white bg-opacity-[0.1] sm:hover:bg-opacity-[0.2] ml-0"
|
||||
class="px-3 text-sm py-1 sm:text-[1rem] rounded-md bg-white bg-opacity-[0.1] sm:hover:bg-opacity-[0.2] ml-0"
|
||||
>
|
||||
{item}
|
||||
</a>
|
||||
@ -331,7 +331,7 @@
|
||||
|
||||
<div class="w-full m-auto mt-10">
|
||||
<div
|
||||
class="w-full m-auto rounded-none sm:rounded-lg mb-4 overflow-x-scroll"
|
||||
class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-scroll"
|
||||
>
|
||||
<table
|
||||
class="table table-sm table-compact rounded-none sm:rounded-md w-full bg-[#09090B] border-bg-[#09090B] m-auto"
|
||||
|
||||
@ -182,7 +182,7 @@
|
||||
class="w-screen sm:w-full flex flex-row items-start mt-20 sm:mt-10"
|
||||
>
|
||||
<div
|
||||
class="w-screen sm:w-full rounded-none sm:rounded-lg mb-4 overflow-x-scroll lg:overflow-hidden"
|
||||
class="w-screen sm:w-full rounded-none sm:rounded-md mb-4 overflow-x-scroll lg:overflow-hidden"
|
||||
>
|
||||
<table
|
||||
class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md w-full bg-[#09090B] border-bg-[#09090B] m-auto"
|
||||
|
||||
@ -255,7 +255,7 @@
|
||||
|
||||
{#if isLoaded}
|
||||
<div
|
||||
class="mb-8 w-full text-center sm:text-start sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-lg h-auto p-5"
|
||||
class="mb-8 w-full text-center sm:text-start sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-md h-auto p-5"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
@ -278,7 +278,7 @@
|
||||
|
||||
<div class="w-full m-auto mt-20 sm:mt-10">
|
||||
<div
|
||||
class="w-full m-auto rounded-none sm:rounded-lg mb-4 overflow-x-scroll"
|
||||
class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-scroll"
|
||||
>
|
||||
<table
|
||||
class="table table-sm table-compact no-scrollbar rounded-none sm:rounded-md w-full bg-[#09090B] border-bg-[#09090B] m-auto"
|
||||
|
||||
@ -1073,7 +1073,7 @@
|
||||
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(
|
||||
class="flex flex-row items-center w-full bg-[#313131] p-3 rounded-md {item?.ticker?.includes(
|
||||
$cryptoTicker,
|
||||
)
|
||||
? 'ring-2 ring-[#04E000]'
|
||||
|
||||
@ -830,7 +830,7 @@ afterUpdate(async () => {
|
||||
|
||||
<Button
|
||||
on:click={changeChartType}
|
||||
class="ml-auto border-gray-600 border bg-[#09090B] sm:hover:bg-[#27272A] ease-out flex flex-row justify-between items-center px-3 py-2 text-white rounded-lg truncate"
|
||||
class="ml-auto border-gray-600 border bg-[#09090B] sm:hover:bg-[#27272A] ease-out flex flex-row justify-between items-center px-3 py-2 text-white rounded-md truncate"
|
||||
>
|
||||
{#if displayChartType === "line"}
|
||||
<svg
|
||||
|
||||
@ -166,7 +166,7 @@
|
||||
</h1>
|
||||
|
||||
<div
|
||||
class="text-white p-3 sm:p-5 mb-10 rounded-lg sm:flex sm:flex-row sm:items-center border border-slate-800 text-sm sm:text-[1rem]"
|
||||
class="text-white p-3 sm:p-5 mb-10 rounded-md sm:flex sm:flex-row sm:items-center border border-slate-800 text-sm sm:text-[1rem]"
|
||||
>
|
||||
<svg
|
||||
class="w-6 h-6 flex-shrink-0 inline-block sm:mr-2"
|
||||
@ -195,7 +195,7 @@
|
||||
>
|
||||
<!--Start Buy/Sell-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-4 bg-[#262626] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-4 bg-[#262626] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span
|
||||
@ -257,7 +257,7 @@
|
||||
<!--End Buy/Sell-->
|
||||
<!--Start Dem/Rep-->
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-4 bg-[#262626] shadow-lg rounded-lg h-20"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-4 bg-[#262626] shadow-lg rounded-md h-20"
|
||||
>
|
||||
<div class="flex flex-col items-start">
|
||||
<span
|
||||
@ -321,7 +321,7 @@
|
||||
|
||||
<label
|
||||
on:click={changeStructure}
|
||||
class="sm:hidden w-24 sm:ml-3 mr-2 sm:mr-0 cursor-pointer bg-[#27272A] px-4 py-2 rounded-lg shadow-md"
|
||||
class="sm:hidden w-24 sm:ml-3 mr-2 sm:mr-0 cursor-pointer bg-[#27272A] px-4 py-2 rounded-md shadow-md"
|
||||
>
|
||||
<span class="m-auto mr-0.5 text-white text-sm">
|
||||
Switch To: {displayStructure}
|
||||
@ -330,7 +330,7 @@
|
||||
|
||||
{#if displayStructure === "Card"}
|
||||
<div
|
||||
class="mt-6 flex justify-start items-center w-full m-auto rounded-none sm:rounded-lg mb-4 overflow-x-scroll"
|
||||
class="mt-6 flex justify-start items-center w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-scroll"
|
||||
>
|
||||
<table
|
||||
class="table table-sm sm:table-md table-compact rounded-none sm:rounded-md w-full bg-[#09090B] border-bg-[#09090B] m-auto"
|
||||
@ -453,7 +453,7 @@
|
||||
/>
|
||||
{/if}
|
||||
<div
|
||||
class="flex flex-col justify-center items-center rounded-lg"
|
||||
class="flex flex-col justify-center items-center rounded-md"
|
||||
>
|
||||
<div
|
||||
class="-mt-3 shadow-lg rounded-full border border-slate-600 w-20 h-20 relative {item?.party ===
|
||||
|
||||
@ -112,10 +112,10 @@
|
||||
{#if newsList?.length !== 0}
|
||||
<div class="grid grid-cols-1 gap-2 pb-5">
|
||||
{#each newsList as item}
|
||||
<div class="w-full flex flex-col bg-[#09090B] rounded-lg m-auto">
|
||||
<div class="w-full flex flex-col bg-[#09090B] rounded-md m-auto">
|
||||
{#if (videoId = checkIfYoutubeVideo(item.url))}
|
||||
<iframe
|
||||
class="w-full h-96 rounded-lg border border-gray-800"
|
||||
class="w-full h-96 rounded-md border border-gray-800"
|
||||
src={`https://www.youtube.com/embed/${videoId}`}
|
||||
frameborder="0"
|
||||
allow="clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
@ -126,12 +126,12 @@
|
||||
href={item?.url}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
class="border border-gray-800 rounded-lg"
|
||||
class="border border-gray-800 rounded-md"
|
||||
>
|
||||
<div class="flex-shrink-0 m-auto">
|
||||
<img
|
||||
src={item?.image}
|
||||
class=" w-full rounded-lg"
|
||||
class=" w-full rounded-md"
|
||||
alt="news image"
|
||||
loading="lazy"
|
||||
/>
|
||||
@ -165,14 +165,14 @@
|
||||
{#if newsList?.length !== rawNews?.length}
|
||||
<label
|
||||
on:click={loadMoreData}
|
||||
class="shadow-lg rounded-lg cursor-pointer w-5/6 sm:w-3/5 sm:max-w-3xl flex justify-center items-center py-3 h-full text-sm sm:text-[1rem] text-center font-semibold text-white m-auto hover:bg-[#fff] bg-[#fff] bg-opacity-[0.6]"
|
||||
class="shadow-lg rounded-md cursor-pointer w-5/6 sm:w-3/5 sm:max-w-3xl flex justify-center items-center py-3 h-full text-sm sm:text-[1rem] text-center font-semibold text-white m-auto hover:bg-[#fff] bg-[#fff] bg-opacity-[0.6]"
|
||||
>
|
||||
Load More News
|
||||
</label>
|
||||
{/if}
|
||||
{:else}
|
||||
<div
|
||||
class="w-screen max-w-xl sm:flex sm:flex-row sm:items-center justify-center m-auto text-gray-100 font-medium bg-[#09090B] sm:rounded-lg h-auto p-5 mb-4"
|
||||
class="w-screen max-w-xl sm:flex sm:flex-row sm:items-center justify-center m-auto text-gray-100 font-medium bg-[#09090B] sm:rounded-md h-auto p-5 mb-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -123,7 +123,7 @@ updateYearRange()
|
||||
</h1>
|
||||
|
||||
<div
|
||||
class="text-white p-3 sm:p-5 mb-10 rounded-lg sm:flex sm:flex-row sm:items-center border border-slate-800 text-sm sm:text-[1rem]"
|
||||
class="text-white p-3 sm:p-5 mb-10 rounded-md sm:flex sm:flex-row sm:items-center border border-slate-800 text-sm sm:text-[1rem]"
|
||||
>
|
||||
<svg
|
||||
class="w-6 h-6 flex-shrink-0 inline-block sm:mr-2"
|
||||
@ -145,7 +145,7 @@ updateYearRange()
|
||||
class="w-full grid grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-y-3 gap-x-3"
|
||||
>
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-lg h-auto"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-md h-auto"
|
||||
>
|
||||
<div class="flex flex-col items-center w-full p-3">
|
||||
<span class="font-medium text-white text-xl font-semibold"
|
||||
@ -197,7 +197,7 @@ updateYearRange()
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-lg h-auto"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-md h-auto"
|
||||
>
|
||||
<div class="flex flex-col items-center w-full p-3">
|
||||
<span class="font-medium text-white text-xl font-semibold"
|
||||
@ -249,7 +249,7 @@ updateYearRange()
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-lg h-auto"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-md h-auto"
|
||||
>
|
||||
<div class="flex flex-col items-center w-full p-3">
|
||||
<span class="font-medium text-white text-xl font-semibold"
|
||||
|
||||
@ -540,7 +540,7 @@
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class="text-white p-5 mt-5 w-fit m-auto rounded-lg sm:flex sm:flex-row sm:items-center border border-slate-800 text-[1rem]"
|
||||
class="text-white p-5 mt-5 w-fit m-auto rounded-md sm:flex sm:flex-row sm:items-center border border-slate-800 text-[1rem]"
|
||||
>
|
||||
<svg
|
||||
class="w-6 h-6 flex-shrink-0 inline-block sm:mr-2"
|
||||
|
||||
@ -606,7 +606,7 @@
|
||||
</div>
|
||||
{:else}
|
||||
<div
|
||||
class="text-white p-5 mt-5 w-fit m-auto rounded-lg sm:flex sm:flex-row sm:items-center border border-slate-800 text-[1rem]"
|
||||
class="text-white p-5 mt-5 w-fit m-auto rounded-md sm:flex sm:flex-row sm:items-center border border-slate-800 text-[1rem]"
|
||||
>
|
||||
<svg
|
||||
class="w-6 h-6 flex-shrink-0 inline-block sm:mr-2"
|
||||
|
||||
@ -673,7 +673,7 @@
|
||||
|
||||
{#if isLoaded}
|
||||
<div
|
||||
class="mb-8 w-full text-start sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-lg h-auto p-5"
|
||||
class="mb-8 w-full text-start sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-md h-auto p-5"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -784,7 +784,7 @@
|
||||
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(
|
||||
class="flex flex-row items-center w-full bg-[#313131] p-3 rounded-md {item?.ticker?.includes(
|
||||
$etfTicker,
|
||||
)
|
||||
? 'ring-2 ring-[#04E000]'
|
||||
|
||||
@ -906,7 +906,7 @@
|
||||
<DropdownMenu.Trigger asChild let:builder>
|
||||
<Button
|
||||
builders={[builder]}
|
||||
class="ml-auto border-gray-600 border bg-[#09090B] sm:hover:bg-[#27272A] ease-out flex flex-row justify-between items-center px-3 py-2 text-white rounded-lg truncate"
|
||||
class="ml-auto border-gray-600 border bg-[#09090B] sm:hover:bg-[#27272A] ease-out flex flex-row justify-between items-center px-3 py-2 text-white rounded-md truncate"
|
||||
>
|
||||
<span class="truncate text-white">Export</span>
|
||||
<svg
|
||||
|
||||
@ -307,7 +307,7 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="overflow-x-scroll no-scrollbar flex justify-start items-center w-full m-auto shadow-md rounded-none sm:rounded-lg mb-4"
|
||||
class="overflow-x-scroll no-scrollbar flex justify-start items-center w-full m-auto shadow-md rounded-none sm:rounded-md mb-4"
|
||||
>
|
||||
<table
|
||||
class="table table-sm table-compact flex justify-start items-center w-full m-auto"
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
</h2>
|
||||
|
||||
<div
|
||||
class="text-white p-3 sm:p-5 mb-10 rounded-lg sm:flex sm:flex-row sm:items-center border border-slate-800 text-sm sm:text-[1rem]"
|
||||
class="text-white p-3 sm:p-5 mb-10 rounded-md sm:flex sm:flex-row sm:items-center border border-slate-800 text-sm sm:text-[1rem]"
|
||||
>
|
||||
<svg
|
||||
class="w-6 h-6 flex-shrink-0 inline-block sm:mr-2"
|
||||
|
||||
@ -290,7 +290,7 @@
|
||||
<!--End Widget-->
|
||||
|
||||
<div
|
||||
class="mt-6 flex justify-start items-center w-full m-auto rounded-none sm:rounded-lg mb-4 overflow-x-scroll"
|
||||
class="mt-6 flex justify-start items-center w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-scroll"
|
||||
>
|
||||
<table
|
||||
class="table table-sm sm:table-md table-compact rounded-none sm:rounded-md w-full bg-[#09090B] border-bg-[#09090B] m-auto"
|
||||
|
||||
@ -112,10 +112,10 @@
|
||||
{#if newsList.length !== 0}
|
||||
<div class="grid grid-cols-1 gap-2 pb-5">
|
||||
{#each newsList as item}
|
||||
<div class="w-full flex flex-col bg-[#09090B] rounded-lg m-auto">
|
||||
<div class="w-full flex flex-col bg-[#09090B] rounded-md m-auto">
|
||||
{#if (videoId = checkIfYoutubeVideo(item.url))}
|
||||
<iframe
|
||||
class="w-full h-96 rounded-lg border border-gray-800"
|
||||
class="w-full h-96 rounded-md border border-gray-800"
|
||||
src={`https://www.youtube.com/embed/${videoId}`}
|
||||
frameborder="0"
|
||||
allow="clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
@ -126,12 +126,12 @@
|
||||
href={item?.url}
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
class="border border-gray-800 rounded-lg"
|
||||
class="border border-gray-800 rounded-md"
|
||||
>
|
||||
<div class="flex-shrink-0 m-auto">
|
||||
<img
|
||||
src={item?.image}
|
||||
class=" w-full rounded-lg"
|
||||
class=" w-full rounded-md"
|
||||
alt="news image"
|
||||
loading="lazy"
|
||||
/>
|
||||
@ -165,14 +165,14 @@
|
||||
{#if newsList?.length !== rawNews?.length}
|
||||
<label
|
||||
on:click={loadMoreData}
|
||||
class="shadow-lg rounded-lg cursor-pointer w-5/6 sm:w-3/5 sm:max-w-3xl flex justify-center items-center py-3 h-full text-sm sm:text-[1rem] text-center font-semibold text-white m-auto hover:bg-[#fff] bg-[#fff] bg-opacity-[0.6]"
|
||||
class="shadow-lg rounded-md cursor-pointer w-5/6 sm:w-3/5 sm:max-w-3xl flex justify-center items-center py-3 h-full text-sm sm:text-[1rem] text-center font-semibold text-white m-auto hover:bg-[#fff] bg-[#fff] bg-opacity-[0.6]"
|
||||
>
|
||||
Load More News
|
||||
</label>
|
||||
{/if}
|
||||
{:else}
|
||||
<div
|
||||
class="w-screen max-w-xl sm:flex sm:flex-row sm:items-center justify-center m-auto text-gray-100 font-medium bg-[#09090B] sm:rounded-lg h-auto p-5 mb-4"
|
||||
class="w-screen max-w-xl sm:flex sm:flex-row sm:items-center justify-center m-auto text-gray-100 font-medium bg-[#09090B] sm:rounded-md h-auto p-5 mb-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -588,7 +588,7 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="w-fit text-white p-3 sm:p-5 mb-5 rounded-lg sm:flex sm:flex-row sm:items-center border border-slate-800 text-sm sm:text-[1rem]"
|
||||
class="w-fit text-white p-3 sm:p-5 mb-5 rounded-md sm:flex sm:flex-row sm:items-center border border-slate-800 text-sm sm:text-[1rem]"
|
||||
>
|
||||
<svg
|
||||
class="w-6 h-6 flex-shrink-0 inline-block sm:mr-2"
|
||||
@ -725,7 +725,7 @@
|
||||
class="text-xl text-white m-auto flex justify-center items-center h-full"
|
||||
>
|
||||
<div
|
||||
class="text-gray-100 text-sm sm:text-[1rem] sm:rounded-lg h-auto border border-slate-800 p-4"
|
||||
class="text-gray-100 text-sm sm:text-[1rem] sm:rounded-md h-auto border border-slate-800 p-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
@ -750,7 +750,7 @@
|
||||
</h3>
|
||||
|
||||
<div
|
||||
class="bg-[#313131] w-fit relative flex flex-wrap items-center justify-center rounded-lg p-1 mt-6 mb-6"
|
||||
class="bg-[#313131] w-fit relative flex flex-wrap items-center justify-center rounded-md p-1 mt-6 mb-6"
|
||||
>
|
||||
{#each tabEX as item, i}
|
||||
<button
|
||||
@ -761,7 +761,7 @@
|
||||
: ''} "
|
||||
>
|
||||
{#if activeEX === i}
|
||||
<div class="absolute inset-0 rounded-lg bg-[#fff]"></div>
|
||||
<div class="absolute inset-0 rounded-md bg-[#fff]"></div>
|
||||
{/if}
|
||||
<span
|
||||
class="relative text-sm block font-semibold {activeEX === i
|
||||
@ -785,7 +785,7 @@
|
||||
|
||||
{#if optionList?.length !== 0}
|
||||
<div
|
||||
class="bg-[#313131] w-fit relative flex flex-wrap items-center justify-center rounded-lg p-1 mt-6 mb-6"
|
||||
class="bg-[#313131] w-fit relative flex flex-wrap items-center justify-center rounded-md p-1 mt-6 mb-6"
|
||||
>
|
||||
{#each tabs as item, i}
|
||||
<button
|
||||
@ -796,7 +796,7 @@
|
||||
: ''} "
|
||||
>
|
||||
{#if activeIdx === i}
|
||||
<div class="absolute inset-0 rounded-lg bg-[#fff]"></div>
|
||||
<div class="absolute inset-0 rounded-md bg-[#fff]"></div>
|
||||
{/if}
|
||||
<span
|
||||
class="relative text-sm block font-semibold {activeIdx === i
|
||||
@ -1093,7 +1093,7 @@
|
||||
: 'text-[#FF2F1F]'} text-end"
|
||||
>
|
||||
<div
|
||||
class="rounded-lg w-fit px-2 text-center font-semibold badge gap-2 bg-[#fff] text-black m-auto flex justify-center items-center"
|
||||
class="rounded-md w-fit px-2 text-center font-semibold badge gap-2 bg-[#fff] text-black m-auto flex justify-center items-center"
|
||||
>
|
||||
{item?.strike_price}
|
||||
</div>
|
||||
@ -1130,7 +1130,7 @@
|
||||
{:else}
|
||||
<div class="flex justify-center items-center m-auto mt-16 mb-6">
|
||||
<div
|
||||
class="text-gray-100 text-sm sm:text-[1rem] rounded-lg h-auto border border-slate-800 p-4"
|
||||
class="text-gray-100 text-sm sm:text-[1rem] rounded-md h-auto border border-slate-800 p-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -123,7 +123,7 @@ updateYearRange()
|
||||
</h1>
|
||||
|
||||
<div
|
||||
class="text-white p-3 sm:p-5 mb-10 rounded-lg sm:flex sm:flex-row sm:items-center border border-slate-800 text-sm sm:text-[1rem]"
|
||||
class="text-white p-3 sm:p-5 mb-10 rounded-md sm:flex sm:flex-row sm:items-center border border-slate-800 text-sm sm:text-[1rem]"
|
||||
>
|
||||
<svg
|
||||
class="w-6 h-6 flex-shrink-0 inline-block sm:mr-2"
|
||||
@ -145,7 +145,7 @@ updateYearRange()
|
||||
class="w-full grid grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-y-3 gap-x-3"
|
||||
>
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-lg h-auto"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-md h-auto"
|
||||
>
|
||||
<div class="flex flex-col items-center w-full p-3">
|
||||
<span class="font-medium text-white text-xl font-semibold"
|
||||
@ -197,7 +197,7 @@ updateYearRange()
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-lg h-auto"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-md h-auto"
|
||||
>
|
||||
<div class="flex flex-col items-center w-full p-3">
|
||||
<span class="font-medium text-white text-xl font-semibold"
|
||||
@ -249,7 +249,7 @@ updateYearRange()
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-lg h-auto"
|
||||
class="flex flex-row items-center flex-wrap w-full px-3 sm:px-5 bg-[#09090B] border border-gray-800 rounded-md h-auto"
|
||||
>
|
||||
<div class="flex flex-col items-center w-full p-3">
|
||||
<span class="font-medium text-white text-xl font-semibold"
|
||||
|
||||
@ -120,7 +120,7 @@
|
||||
|
||||
<section class="w-full overflow-hidden m-auto">
|
||||
<div
|
||||
class="w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-lg h-auto p-5 mb-4"
|
||||
class="w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-md h-auto p-5 mb-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block flex-shrink-0 mr-0.5 sm:mr-2"
|
||||
|
||||
@ -150,7 +150,7 @@
|
||||
<section class="w-full overflow-hidden m-auto">
|
||||
{#if rawData?.length !== 0}
|
||||
<div
|
||||
class="w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-600 sm:rounded-lg h-auto p-5 mb-4"
|
||||
class="w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-600 sm:rounded-md h-auto p-5 mb-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block flex-shrink-0 mr-0.5 sm:mr-2"
|
||||
|
||||
@ -145,7 +145,7 @@
|
||||
|
||||
{#if isLoaded}
|
||||
<div
|
||||
class="w-full text-center sm:text-start sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-lg h-auto p-5"
|
||||
class="w-full text-center sm:text-start sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-md h-auto p-5"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
@ -163,7 +163,7 @@
|
||||
|
||||
<div class="w-screen sm:w-full m-auto mt-20 sm:mt-10">
|
||||
<div
|
||||
class="w-screen sm:w-full m-auto rounded-none sm:rounded-lg mb-4 overflow-x-scroll sm:overflow-hidden"
|
||||
class="w-screen sm:w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-scroll sm:overflow-hidden"
|
||||
>
|
||||
<table
|
||||
class="table table-sm table-compact rounded-none sm:rounded-md w-full bg-[#09090B] border-bg-[#09090B] m-auto"
|
||||
|
||||
@ -374,7 +374,7 @@ async function exportTreemap() {
|
||||
>
|
||||
<main class="w-full">
|
||||
<div
|
||||
class="w-full text-center sm:text-start sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-lg h-auto p-5 mb-4"
|
||||
class="w-full text-center sm:text-start sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-md h-auto p-5 mb-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
@ -512,7 +512,7 @@ async function exportTreemap() {
|
||||
class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
|
||||
>
|
||||
<div
|
||||
class="flex flex-row items-center w-full bg-[#09090B] bg-opacity-[0.7] sm:bg-opacity-[1.0] sm:bg-[#303030] p-3 rounded-lg {displayIndex ===
|
||||
class="flex flex-row items-center w-full bg-[#09090B] bg-opacity-[0.7] sm:bg-opacity-[1.0] sm:bg-[#303030] p-3 rounded-md {displayIndex ===
|
||||
'S&P500'
|
||||
? 'ring-2 ring-[#04E000]'
|
||||
: ''}"
|
||||
@ -527,7 +527,7 @@ async function exportTreemap() {
|
||||
class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
|
||||
>
|
||||
<div
|
||||
class="flex flex-row items-center w-full bg-[#09090B] bg-opacity-[0.7] sm:bg-opacity-[1.0] sm:bg-[#303030] p-3 rounded-lg {displayIndex ===
|
||||
class="flex flex-row items-center w-full bg-[#09090B] bg-opacity-[0.7] sm:bg-opacity-[1.0] sm:bg-[#303030] p-3 rounded-md {displayIndex ===
|
||||
'Dow Jones'
|
||||
? 'ring-2 ring-[#04E000]'
|
||||
: ''}"
|
||||
@ -542,7 +542,7 @@ async function exportTreemap() {
|
||||
class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
|
||||
>
|
||||
<div
|
||||
class="flex flex-row items-center w-full bg-[#09090B] bg-opacity-[0.7] sm:bg-opacity-[1.0] sm:bg-[#303030] p-3 rounded-lg {displayIndex ===
|
||||
class="flex flex-row items-center w-full bg-[#09090B] bg-opacity-[0.7] sm:bg-opacity-[1.0] sm:bg-[#303030] p-3 rounded-md {displayIndex ===
|
||||
'Nasdaq'
|
||||
? 'ring-2 ring-[#04E000]'
|
||||
: ''}"
|
||||
@ -587,7 +587,7 @@ async function exportTreemap() {
|
||||
class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
|
||||
>
|
||||
<div
|
||||
class="flex flex-row items-center w-full bg-[#09090B] bg-opacity-[0.7] sm:bg-opacity-[1.0] sm:bg-[#303030] p-3 rounded-lg ring-2 ring-[#04E000]"
|
||||
class="flex flex-row items-center w-full bg-[#09090B] bg-opacity-[0.7] sm:bg-opacity-[1.0] sm:bg-[#303030] p-3 rounded-md ring-2 ring-[#04E000]"
|
||||
>
|
||||
<span class="ml-1 text-white font-medium mr-auto">
|
||||
Save as PNG
|
||||
@ -600,7 +600,7 @@ async function exportTreemap() {
|
||||
class="cursor-pointer w-full flex flex-row justify-start items-center mb-5"
|
||||
>
|
||||
<div
|
||||
class="flex flex-row items-center w-full bg-[#09090B] bg-opacity-[0.7] sm:bg-opacity-[1.0] sm:bg-[#303030] p-3 rounded-lg ring-2 ring-[#04E000]"
|
||||
class="flex flex-row items-center w-full bg-[#09090B] bg-opacity-[0.7] sm:bg-opacity-[1.0] sm:bg-[#303030] p-3 rounded-md ring-2 ring-[#04E000]"
|
||||
>
|
||||
<span class="ml-1 text-white font-medium mr-auto">
|
||||
Save as JPG
|
||||
|
||||
@ -166,11 +166,11 @@
|
||||
{#each displayList as item}
|
||||
<a
|
||||
href={`/hedge-funds/${item?.cik}`}
|
||||
class="w-full cursor-pointer bg-[#141417] sm:hover:bg-[#000] transition-colors ease-in-out border sm:hover:border-[#000] sm:hover:shadow-[#8C5F1B] border-gray-800 shadow-md rounded-lg h-auto pb-4 pt-4 mb-7"
|
||||
class="w-full cursor-pointer bg-[#141417] sm:hover:bg-[#000] transition-colors ease-in-out border sm:hover:border-[#000] sm:hover:shadow-[#8C5F1B] border-gray-800 shadow-md rounded-md h-auto pb-4 pt-4 mb-7"
|
||||
>
|
||||
<div class="flex flex-col relative">
|
||||
<img
|
||||
class="absolute -mt-4 w-full m-auto rounded-lg"
|
||||
class="absolute -mt-4 w-full m-auto rounded-md"
|
||||
src={cardBackground}
|
||||
/>
|
||||
<div
|
||||
|
||||
@ -200,7 +200,7 @@
|
||||
href={sectorNavigation?.find(
|
||||
(listItem) => listItem?.title === item,
|
||||
)?.link}
|
||||
class="px-3 text-sm py-1 sm:text-[1rem] rounded-lg bg-white bg-opacity-[0.1] sm:hover:bg-opacity-[0.2] ml-0"
|
||||
class="px-3 text-sm py-1 sm:text-[1rem] rounded-md bg-white bg-opacity-[0.1] sm:hover:bg-opacity-[0.2] ml-0"
|
||||
>
|
||||
{item}
|
||||
</a>
|
||||
@ -215,7 +215,7 @@
|
||||
{#each data?.getHedgeFundsData?.mainIndustries as item}
|
||||
<a
|
||||
href={`/list/industry/${item?.replace(/ /g, "-")?.replace(/&/g, "and")?.replace(/-{2,}/g, "-")?.toLowerCase()}`}
|
||||
class="px-3 text-sm py-1 sm:text-[1rem] rounded-lg bg-white bg-opacity-[0.1] sm:hover:bg-opacity-[0.2] ml-0"
|
||||
class="px-3 text-sm py-1 sm:text-[1rem] rounded-md bg-white bg-opacity-[0.1] sm:hover:bg-opacity-[0.2] ml-0"
|
||||
>
|
||||
{item}
|
||||
</a>
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
<section class="w-full overflow-hidden m-auto">
|
||||
<div
|
||||
class="border border-gray-800 w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 bg-[#09090B] sm:rounded-lg h-auto p-5 mb-4"
|
||||
class="border border-gray-800 w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 bg-[#09090B] sm:rounded-md h-auto p-5 mb-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -204,7 +204,7 @@
|
||||
|
||||
<div class="w-full m-auto mt-20 sm:mt-10">
|
||||
<div
|
||||
class="w-full m-auto rounded-none sm:rounded-lg mb-4 overflow-x-scroll sm:overflow-hidden"
|
||||
class="w-full m-auto rounded-none sm:rounded-md mb-4 overflow-x-scroll sm:overflow-hidden"
|
||||
>
|
||||
<table
|
||||
class="table table-sm table-compact rounded-none sm:rounded-md w-full bg-[#09090B] border-bg-[#09090B] m-auto"
|
||||
@ -281,7 +281,7 @@
|
||||
{abbreviateNumber(item?.avgValue)}
|
||||
</div>
|
||||
<div
|
||||
class="ml-2 px-1.5 py-1.5 border text-center rounded-lg text-xs font-semibold"
|
||||
class="ml-2 px-1.5 py-1.5 border text-center rounded-md text-xs font-semibold"
|
||||
>
|
||||
{item?.transactionType}
|
||||
</div>
|
||||
|
||||
@ -46,7 +46,7 @@
|
||||
{#if isLoaded}
|
||||
<div class="flex flex-col justify-center items-center p-3 sm:p-0">
|
||||
<div
|
||||
class="mt-0 sm:mt-5 mb-2 w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 font-medium border border-gray-800 sm:rounded-lg h-auto p-5"
|
||||
class="mt-0 sm:mt-5 mb-2 w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 font-medium border border-gray-800 sm:rounded-md h-auto p-5"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -232,7 +232,7 @@
|
||||
{:else}
|
||||
<div class="flex justify-center items-center m-auto mt-10 mb-6">
|
||||
<div
|
||||
class="text-gray-100 text-center text-sm sm:text-[1rem] rounded-lg h-auto border border-slate-800 p-4"
|
||||
class="text-gray-100 text-center text-sm sm:text-[1rem] rounded-md h-auto border border-slate-800 p-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -101,7 +101,7 @@
|
||||
|
||||
<section class="w-full overflow-hidden m-auto">
|
||||
<div
|
||||
class="border border-gray-600 w-full sm:flex sm:flex-row sm:items-center m-auto text-white bg-[#09090B] sm:rounded-lg h-auto p-5 mb-4"
|
||||
class="border border-gray-600 w-full sm:flex sm:flex-row sm:items-center m-auto text-white bg-[#09090B] sm:rounded-md h-auto p-5 mb-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
<section class="w-full overflow-hidden m-auto">
|
||||
<div
|
||||
class="w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-lg h-auto p-5 mb-4"
|
||||
class="w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 border border-gray-800 sm:rounded-md h-auto p-5 mb-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
<section class="w-full overflow-hidden m-auto">
|
||||
<div
|
||||
class="w-full border border-gray-600 sm:flex sm:flex-row sm:items-center m-auto text-white bg-[#09090B] sm:rounded-lg h-auto p-5 mb-4"
|
||||
class="w-full border border-gray-600 sm:flex sm:flex-row sm:items-center m-auto text-white bg-[#09090B] sm:rounded-md h-auto p-5 mb-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
|
||||
<section class="w-full overflow-hidden m-auto">
|
||||
<div
|
||||
class="border border-gray-800 w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 bg-[#09090B] sm:rounded-lg h-auto p-5 mb-4"
|
||||
class="border border-gray-800 w-full sm:flex sm:flex-row sm:items-center m-auto text-gray-100 bg-[#09090B] sm:rounded-md h-auto p-5 mb-4"
|
||||
>
|
||||
<svg
|
||||
class="w-5 h-5 inline-block sm:mr-2 flex-shrink-0"
|
||||
|
||||
@ -1,31 +1,42 @@
|
||||
<script>
|
||||
import { numberOfUnreadNotification } from '$lib/store';
|
||||
import { numberOfUnreadNotification } from "$lib/store";
|
||||
</script>
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<svelte:head>
|
||||
<title> {$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ''} Markdown Guide · stocknear</title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
|
||||
<meta name="description" content="Markdown Guide to Post on Stocknear Community Page">
|
||||
<!-- Other meta tags -->
|
||||
<meta property="og:title" content="Markdown Guide · stocknear"/>
|
||||
<meta property="og:description" content="Markdown Guide to Post on Stocknear Community Page">
|
||||
<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="Markdown Guide · stocknear"/>
|
||||
<meta name="twitter:description" content="Markdown Guide to Post on Stocknear Community Page">
|
||||
<!-- Add more Twitter meta tags as needed -->
|
||||
</svelte:head>
|
||||
|
||||
|
||||
<section class="w-full max-w-4xl overflow-hidden m-auto min-h-screen pt-10 pb-40 px-3">
|
||||
<!--
|
||||
<svelte:head>
|
||||
<title>
|
||||
{$numberOfUnreadNotification > 0 ? `(${$numberOfUnreadNotification})` : ""} Markdown
|
||||
Guide · stocknear</title
|
||||
>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
|
||||
<meta
|
||||
name="description"
|
||||
content="Markdown Guide to Post on Stocknear Community Page"
|
||||
/>
|
||||
<!-- Other meta tags -->
|
||||
<meta property="og:title" content="Markdown Guide · stocknear" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Markdown Guide to Post on Stocknear Community Page"
|
||||
/>
|
||||
<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="Markdown Guide · stocknear" />
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content="Markdown Guide to Post on Stocknear Community Page"
|
||||
/>
|
||||
<!-- Add more Twitter meta tags as needed -->
|
||||
</svelte:head>
|
||||
|
||||
<section
|
||||
class="w-full max-w-4xl overflow-hidden m-auto min-h-screen pt-10 pb-40 px-3"
|
||||
>
|
||||
<!--
|
||||
<div class="text-sm breadcrumbs ml-4">
|
||||
<ul>
|
||||
<li><a href="/" class="text-gray-300">Home</a></li>
|
||||
@ -34,58 +45,62 @@
|
||||
</div>
|
||||
-->
|
||||
|
||||
<h1 class="text-white text-2xl sm:text-3xl font-bold mb-3">
|
||||
Markdown Guide
|
||||
</h1>
|
||||
|
||||
<span class="text-white">
|
||||
We use <a href="https://en.wikipedia.org/wiki/Markdown" rel="noopener noreferrer" target="_blank" class="text-blue-400 sm:hover:text-white">Markdown</a> to format posts and comments on Stocknear. We support CommonMark and Github Flavored Markdown (with the exception of image tags and raw HTML).
|
||||
</span>
|
||||
<h1 class="text-white text-2xl sm:text-3xl font-bold mb-3">Markdown Guide</h1>
|
||||
|
||||
<div class="w-full m-auto mt-10 bg-[#09090B] rounded-lg">
|
||||
<span class="text-white">
|
||||
We use <a
|
||||
href="https://en.wikipedia.org/wiki/Markdown"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
class="text-blue-400 sm:hover:text-white">Markdown</a
|
||||
> to format posts and comments on Stocknear. We support CommonMark and Github
|
||||
Flavored Markdown (with the exception of image tags and raw HTML).
|
||||
</span>
|
||||
|
||||
<div class="w-full m-auto mt-10 bg-[#09090B] rounded-md">
|
||||
<table class="table table-sm table-compact h-full w-full text-white">
|
||||
<tbody class="">
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Heading</td>
|
||||
<td class="text-md sm:text-lg font-semibold"># heading</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Bold</td>
|
||||
<td class="text-md sm:text-lg font-semibold">**bold text**</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Italic</td>
|
||||
<td class="text-md sm:text-lg font-semibold">*italic text*</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">List</td>
|
||||
<td class="text-md font-semibold">- Item 1 <br>- Item 2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Ordered list</td>
|
||||
<td class="text-md font-semibold">1. Item 1<br>2. Item 2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Inline code</td>
|
||||
<td class="text-md sm:text-lg font-semibold">`some inline code`</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Code block</td>
|
||||
<td class="text-md sm:text-lg font-semibold">```<br>some code here<br>```</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Link</td>
|
||||
<td class="text-md sm:text-lg font-semibold">[link-text](https://en.wikipedia.org)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Blockquote</td>
|
||||
<td class="text-md sm:text-lg font-semibold">> blockquote</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tbody class="">
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Heading</td>
|
||||
<td class="text-md sm:text-lg font-semibold"># heading</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Bold</td>
|
||||
<td class="text-md sm:text-lg font-semibold">**bold text**</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Italic</td>
|
||||
<td class="text-md sm:text-lg font-semibold">*italic text*</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">List</td>
|
||||
<td class="text-md font-semibold">- Item 1 <br />- Item 2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Ordered list</td>
|
||||
<td class="text-md font-semibold">1. Item 1<br />2. Item 2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Inline code</td>
|
||||
<td class="text-md sm:text-lg font-semibold">`some inline code`</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Code block</td>
|
||||
<td class="text-md sm:text-lg font-semibold"
|
||||
>```<br />some code here<br />```</td
|
||||
>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Link</td>
|
||||
<td class="text-md sm:text-lg font-semibold"
|
||||
>[link-text](https://en.wikipedia.org)</td
|
||||
>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-md sm:text-lg font-semibold">Blockquote</td>
|
||||
<td class="text-md sm:text-lg font-semibold">> blockquote</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -200,7 +200,7 @@
|
||||
errors=''
|
||||
/>
|
||||
<div class="w-full sm:w-5/6 max-w-lg m-auto pb-5">
|
||||
<button type="submit" class="py-3 bg-[#fff] text-white sm:hover:bg-gray-300 w-full rounded-lg m-auto font-bold text-md">
|
||||
<button type="submit" class="py-3 bg-[#fff] text-white sm:hover:bg-gray-300 w-full rounded-md m-auto font-bold text-md">
|
||||
Subscribe
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user