This commit is contained in:
MuslemRahimi 2024-10-27 23:19:31 +01:00
parent 29d69c32db
commit d6edfe2dc9
5 changed files with 99 additions and 125 deletions

View File

@ -1,6 +1,5 @@
<script lang="ts"> <script lang="ts">
import { stockTicker, displayCompanyName } from "$lib/store"; import { stockTicker, displayCompanyName } from "$lib/store";
import InfoModal from "$lib/components/InfoModal.svelte";
export let data; export let data;
let rawData = {}; let rawData = {};
@ -39,17 +38,11 @@
<div class="flex flex-row justify-start mr-auto items-center"> <div class="flex flex-row justify-start mr-auto items-center">
<!--<img class="h-10 inline-block mr-2" src={copilotIcon} />--> <!--<img class="h-10 inline-block mr-2" src={copilotIcon} />-->
<div class="flex flex-row items-center"> <div class="flex flex-row items-center">
<label <h3
for="dividendAnnouncement" class="mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-2xl font-bold"
> >
Dividend Announcement Dividend Announcement
</label> </h3>
<InfoModal
title={"Dividend Announcement"}
content={`Dividend announcements are company declarations of cash or stock distributions to shareholders, usually reflecting profit and providing investment returns.`}
id={"dividendAnnouncement"}
/>
</div> </div>
</div> </div>
</div> </div>
@ -57,7 +50,7 @@
<div <div
class="text-white text-[1rem] {latestInfoDate(rawData?.date) 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-lg'
: 'bg-[#09090B] pl-1'} " : 'bg-[#09090B] pl-1'}"
> >
<div class="mt-1"> <div class="mt-1">
{$displayCompanyName} has announced its upcoming dividend details on {new Date( {$displayCompanyName} has announced its upcoming dividend details on {new Date(
@ -70,9 +63,13 @@
})}: })}:
</div> </div>
<!-- Added grid container -->
<ul class="grid grid-cols-1 sm:grid-cols-2 gap-x-4 mt-5">
<!-- First column -->
<div>
<li <li
class="ml-[20px] sm:ml-[30px]" class="ml-[20px]"
style="color: #fff; line-height: 22px; margin-top:20px; margin-bottom: 15px; list-style-type: disc;" style="color: #fff; line-height: 22px; margin-bottom: 15px; list-style-type: disc;"
> >
<span class="font-bold">Dividend:</span> ${rawData?.dividend} per share <span class="font-bold">Dividend:</span> ${rawData?.dividend} per share
({rawData?.dividend / rawData?.dividendPrior - 1 > 0 ? "+" : ""}{( ({rawData?.dividend / rawData?.dividendPrior - 1 > 0 ? "+" : ""}{(
@ -81,15 +78,19 @@
)?.toFixed(2)}% YoY) )?.toFixed(2)}% YoY)
</li> </li>
<li <li
class="ml-[20px] sm:ml-[30px]" class="ml-[20px]"
style="color: #fff; line-height: 22px; margin-top:0px; margin-bottom: 15px; list-style-type: disc;" style="color: #fff; line-height: 22px; margin-bottom: 15px; list-style-type: disc;"
> >
<span class="font-bold">Dividend Yield:</span> <span class="font-bold">Dividend Yield:</span>
{rawData?.dividendYield?.toFixed(2)}% {rawData?.dividendYield?.toFixed(2)}%
</li> </li>
</div>
<!-- Second column -->
<div>
<li <li
class="ml-[20px] sm:ml-[30px]" class="ml-[20px]"
style="color: #fff; line-height: 22px; margin-top:0px; margin-bottom: 15px; list-style-type: disc;" style="color: #fff; line-height: 22px; margin-bottom: 15px; list-style-type: disc;"
> >
<span class="font-bold">Ex-Dividend Date:</span> <span class="font-bold">Ex-Dividend Date:</span>
{new Date(rawData?.exDividendDate)?.toLocaleString("en-US", { {new Date(rawData?.exDividendDate)?.toLocaleString("en-US", {
@ -99,10 +100,9 @@
daySuffix: "2-digit", daySuffix: "2-digit",
})} })}
</li> </li>
<li <li
class="ml-[20px] sm:ml-[30px]" class="ml-[20px]"
style="color: #fff; line-height: 22px; margin-top:0px; margin-bottom: 15px; list-style-type: disc;" style="color: #fff; line-height: 22px; margin-bottom: 15px; list-style-type: disc;"
> >
<span class="font-bold">Payable Date:</span> <span class="font-bold">Payable Date:</span>
{new Date(rawData?.payableDate)?.toLocaleString("en-US", { {new Date(rawData?.payableDate)?.toLocaleString("en-US", {
@ -112,10 +112,13 @@
daySuffix: "2-digit", daySuffix: "2-digit",
})} })}
</li> </li>
</div>
</ul>
<!-- Keep the Record Date outside the grid as a full-width item -->
<li <li
class="ml-[20px] sm:ml-[30px]" class="ml-[20px]"
style="color: #fff; line-height: 22px; margin-top:0px; margin-bottom: 15px; list-style-type: disc;" style="color: #fff; line-height: 22px; margin-bottom: 15px; list-style-type: disc;"
> >
<span class="font-bold">Record Date:</span> <span class="font-bold">Record Date:</span>
{new Date(rawData?.recordDate)?.toLocaleString("en-US", { {new Date(rawData?.recordDate)?.toLocaleString("en-US", {

View File

@ -5,7 +5,8 @@
export let data; export let data;
let rawData = {}; let rawData = {};
let epsRatio = 0;
let revenueRatio = 0;
function latestInfoDate(inputDate) { function latestInfoDate(inputDate) {
// Convert the input date string to milliseconds since epoch // Convert the input date string to milliseconds since epoch
const inputDateMs = Date?.parse(inputDate); const inputDateMs = Date?.parse(inputDate);
@ -28,6 +29,14 @@
$: { $: {
if ($stockTicker && typeof window !== "undefined") { if ($stockTicker && typeof window !== "undefined") {
rawData = data?.getEarningsSurprise; rawData = data?.getEarningsSurprise;
epsRatio = (
((rawData?.eps - rawData?.epsPrior) / Math.abs(rawData?.epsPrior)) *
100
)?.toFixed(2);
revenueRatio = (
(rawData?.revenue / rawData?.revenuePrior - 1) *
100
)?.toFixed(2);
} }
} }
</script> </script>
@ -80,14 +89,12 @@
Math.abs(rawData?.revenueSurprise), Math.abs(rawData?.revenueSurprise),
true, true,
)}, with )}, with
<strong <span
>{((rawData?.revenue / rawData?.revenuePrior - 1) * 100)?.toFixed( class="font-semibold {revenueRatio > 0
2, ? 'text-[#00FC50]'
)}%</strong : 'text-[#FF2F1F]'}">{revenueRatio}%</span
> >
YoY {rawData?.revenue / rawData?.revenuePrior - 1 < 0 YoY {revenueRatio < 0 ? "decline" : "growth"}.
? "decline"
: "growth"}.
</li> </li>
<li <li
class="ml-[20px] sm:ml-[30px]" class="ml-[20px] sm:ml-[30px]"
@ -97,18 +104,12 @@
{rawData?.epsSurprise > 0 ? "exceeds" : "misses"} estimates by ${rawData?.epsSurprise?.toFixed( {rawData?.epsSurprise > 0 ? "exceeds" : "misses"} estimates by ${rawData?.epsSurprise?.toFixed(
2, 2,
)}, with )}, with
<strong <span
>{( class="font-semibold {epsRatio > 0
((rawData?.eps - rawData?.epsPrior) / ? 'text-[#00FC50]'
Math.abs(rawData?.epsPrior)) * : 'text-[#FF2F1F]'}">{epsRatio}%</span
100
)?.toFixed(2)}%</strong
> >
YoY {(rawData?.eps - rawData?.epsPrior) / YoY {epsRatio < 0 ? "decline" : "growth"}.
Math.abs(rawData?.epsPrior) <
0
? "decline"
: "growth"}.
</li> </li>
</div> </div>
</div> </div>

View File

@ -1,6 +1,5 @@
<script lang="ts"> <script lang="ts">
import { stockTicker, displayCompanyName } from "$lib/store"; import { stockTicker, displayCompanyName } from "$lib/store";
import InfoModal from "$lib/components/InfoModal.svelte";
import { abbreviateNumber } from "$lib/utils"; import { abbreviateNumber } from "$lib/utils";
export let data; export let data;
@ -39,17 +38,11 @@
<div class="flex flex-row justify-start mr-auto items-center"> <div class="flex flex-row justify-start mr-auto items-center">
<!--<img class="h-10 inline-block mr-2" src={copilotIcon} />--> <!--<img class="h-10 inline-block mr-2" src={copilotIcon} />-->
<div class="flex flex-row items-center"> <div class="flex flex-row items-center">
<label <h3
for="nextEarningsInfo" class="mr-1 flex flex-row items-center text-white text-xl sm:text-2xl font-bold"
class="mr-1 cursor-pointer flex flex-row items-center text-white text-xl sm:text-2xl font-bold"
> >
Next Earnings Release Next Earnings Release
</label> </h3>
<InfoModal
title={"Next Earnings"}
content={`Earnings represent a company's net profit after expenses, taxes, and costs. Reported quarterly, they show financial health, including revenue and EPS, influencing stock prices and investor decisions.`}
id={"nextEarningsInfo"}
/>
</div> </div>
</div> </div>
</div> </div>
@ -73,13 +66,19 @@
<br />Analysts project revenue of <br />Analysts project revenue of
<strong>{abbreviateNumber(rawData?.revenueEst, true)}</strong>, <strong>{abbreviateNumber(rawData?.revenueEst, true)}</strong>,
reflecting a reflecting a
<strong>{revenueRatio}%</strong> YoY {revenueRatio > 0 <span
? "growth" class="font-semibold {revenueRatio > 0
: revenueRatio < 0 ? 'text-[#00FC50]'
? "shrinking" : 'text-[#FF2F1F]'} ">{abbreviateNumber(revenueRatio)}%</span
: ""} and earnings per share of >
YoY {revenueRatio > 0 ? "growth" : revenueRatio < 0 ? "shrinking" : ""} and
earnings per share of
<strong>{rawData?.epsEst}</strong>, making a <strong>{rawData?.epsEst}</strong>, making a
<strong>{epsRatio}%</strong> <span
class="font-semibold {epsRatio > 0
? 'text-[#00FC50]'
: 'text-[#FF2F1F]'} ">{epsRatio}%</span
>
{epsRatio > 0 ? "increase" : epsRatio < 0 ? "decrease" : ""} YoY. {epsRatio > 0 ? "increase" : epsRatio < 0 ? "decrease" : ""} YoY.
</div> </div>
</div> </div>

View File

@ -43,23 +43,6 @@ const fetchWatchlist = async (pb, userId) => {
return output; return output;
}; };
const fetchCommunitySentiment = async (pb, ticker, cookies) => {
const cookieVote = cookies.get(`community-sentiment-${ticker}`);
const today = new Date().toISOString().split("T")[0];
const pastNDays = new Date(new Date().setDate(new Date().getDate() - 7))
.toISOString()
.split("T")[0];
const output = await pb.collection("sentiment").getFullList({
filter: `ticker="${ticker}" && created < "${today}" && created >= "${pastNDays}"`,
});
return {
alreadyVoted: cookieVote || null,
sentimentData: output?.at(0) || {},
};
};
export const load = async ({ params, locals, cookies, setHeaders }) => { export const load = async ({ params, locals, cookies, setHeaders }) => {
const { apiURL, apiKey, pb, user } = locals; const { apiURL, apiKey, pb, user } = locals;
const { tickerID } = params; const { tickerID } = params;
@ -84,8 +67,6 @@ export const load = async ({ params, locals, cookies, setHeaders }) => {
fetchData(apiURL, apiKey, endpoint, tickerID), fetchData(apiURL, apiKey, endpoint, tickerID),
), ),
fetchWatchlist(pb, user?.id), fetchWatchlist(pb, user?.id),
//fetchFromFastify(fastifyURL, '/get-portfolio-data', user?.id),
fetchCommunitySentiment(pb, tickerID, cookies),
]; ];
const [ const [
@ -102,7 +83,6 @@ export const load = async ({ params, locals, cookies, setHeaders }) => {
getDividendAnnouncement, getDividendAnnouncement,
getNews, getNews,
getUserWatchlist, getUserWatchlist,
getCommunitySentiment,
] = await Promise.all(promises); ] = await Promise.all(promises);
return { return {
@ -119,7 +99,6 @@ export const load = async ({ params, locals, cookies, setHeaders }) => {
getDividendAnnouncement, getDividendAnnouncement,
getNews, getNews,
getUserWatchlist, getUserWatchlist,
getCommunitySentiment,
companyName: cleanString(getStockDeck?.at(0)?.companyName), companyName: cleanString(getStockDeck?.at(0)?.companyName),
}; };
}; };

View File

@ -25,7 +25,6 @@
import EarningsSurprise from "$lib/components/EarningsSurprise.svelte"; import EarningsSurprise from "$lib/components/EarningsSurprise.svelte";
import DividendAnnouncement from "$lib/components/DividendAnnouncement.svelte"; import DividendAnnouncement from "$lib/components/DividendAnnouncement.svelte";
import CommunitySentiment from "$lib/components/CommunitySentiment.svelte";
import Lazy from "$lib/components/Lazy.svelte"; import Lazy from "$lib/components/Lazy.svelte";
import { convertTimestamp } from "$lib/utils"; import { convertTimestamp } from "$lib/utils";
import { Button } from "$lib/components/shadcn/button/index.js"; import { Button } from "$lib/components/shadcn/button/index.js";
@ -36,7 +35,6 @@
export let form; export let form;
let prePostData = {}; let prePostData = {};
let communitySentiment = {};
$: previousClose = data?.getStockQuote?.previousClose; $: previousClose = data?.getStockQuote?.previousClose;
@ -668,11 +666,8 @@
oneYearPrice = []; oneYearPrice = [];
maxPrice = []; maxPrice = [];
prePostData = {}; prePostData = {};
communitySentiment = {};
output = null; output = null;
communitySentiment = data?.getCommunitySentiment;
const asyncFunctions = [getPrePostQuote()]; const asyncFunctions = [getPrePostQuote()];
Promise.all(asyncFunctions) Promise.all(asyncFunctions)
@ -1651,10 +1646,10 @@
</div> </div>
</div> </div>
<div> <div>
<h2 class="mb-2" data-svelte-h="svelte-avjv7o"> <h2 class="mb-2 text-white text-2xl font-semibold">
Analyst Forecast Analyst Forecast
</h2> </h2>
<p class="mb-4" data-test="overview-forecast-intro"> <p class="mb-4 text-gray-200">
According to 40 analysts, the average rating for NVDA stock is According to 40 analysts, the average rating for NVDA stock is
"Strong Buy." The 12-month stock price forecast is $145.84, "Strong Buy." The 12-month stock price forecast is $145.84,
which is an increase of 3.04% from the latest price. which is an increase of 3.04% from the latest price.
@ -1688,9 +1683,6 @@
<div class="lg:sticky lg:top-20"></div> <div class="lg:sticky lg:top-20"></div>
</div> </div>
<div class="w-full"> <div class="w-full">
<div class="w-full mt-14 sm:mt-0 m-auto sm:pl-6 sm:pb-6 sm:pt-6">
<CommunitySentiment {communitySentiment} />
</div>
<div class="w-full mt-10 m-auto sm:p-6 lg:hidden"> <div class="w-full mt-10 m-auto sm:p-6 lg:hidden">
<Lazy> <Lazy>
<h3 <h3
@ -1705,7 +1697,7 @@
</div> </div>
<div <div
class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 sm:pt-6 {Object?.keys( class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 {Object?.keys(
data?.getEarningsSurprise || {}, data?.getEarningsSurprise || {},
)?.length !== 0 )?.length !== 0
? '' ? ''
@ -1715,7 +1707,7 @@
</div> </div>
<div <div
class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 sm:pt-6 {Object?.keys( class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 {Object?.keys(
data?.getNextEarnings || {}, data?.getNextEarnings || {},
)?.length !== 0 )?.length !== 0
? '' ? ''
@ -1725,7 +1717,7 @@
</div> </div>
<div <div
class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 sm:pt-6 {Object?.keys( class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 {Object?.keys(
data?.getDividendAnnouncement || {}, data?.getDividendAnnouncement || {},
)?.length !== 0 )?.length !== 0
? '' ? ''
@ -1735,7 +1727,7 @@
</div> </div>
<div <div
class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 sm:pt-6 {Object?.keys( class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 {Object?.keys(
data?.getBullBearSay || {}, data?.getBullBearSay || {},
)?.length !== 0 )?.length !== 0
? '' ? ''
@ -1746,7 +1738,7 @@
<Lazy> <Lazy>
<div <div
class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 sm:pt-6 {data class="w-full mt-10 sm:mt-0 m-auto sm:pl-6 sm:pb-6 {data
?.getWhyPriceMoved?.length !== 0 ?.getWhyPriceMoved?.length !== 0
? '' ? ''
: 'hidden'}" : 'hidden'}"