From dba356c4136b8e5d0439ba48617312a171fd8233 Mon Sep 17 00:00:00 2001 From: MuslemRahimi Date: Sat, 1 Jun 2024 16:18:35 +0200 Subject: [PATCH] Add new feature: community sentiment --- src/lib/components/CommunitySentiment.svelte | 109 ++++++++++++++++++ src/routes/api/community-sentiment/+server.ts | 69 +++++++++++ .../stocks/[tickerID]/+layout.server.ts | 39 ++++++- src/routes/stocks/[tickerID]/+page.server.ts | 3 +- src/routes/stocks/[tickerID]/+page.svelte | 20 +++- 5 files changed, 230 insertions(+), 10 deletions(-) create mode 100644 src/lib/components/CommunitySentiment.svelte create mode 100644 src/routes/api/community-sentiment/+server.ts diff --git a/src/lib/components/CommunitySentiment.svelte b/src/lib/components/CommunitySentiment.svelte new file mode 100644 index 00000000..208088be --- /dev/null +++ b/src/lib/components/CommunitySentiment.svelte @@ -0,0 +1,109 @@ + + + + + + +
+ +
+
+ +
+ + + The community is bullish about {$displayCompanyName} today. + +
+ +
+
+ +
+ + +
+
diff --git a/src/routes/api/community-sentiment/+server.ts b/src/routes/api/community-sentiment/+server.ts new file mode 100644 index 00000000..02914d00 --- /dev/null +++ b/src/routes/api/community-sentiment/+server.ts @@ -0,0 +1,69 @@ +import type { RequestHandler } from './$types'; + +function secondsUntilEndOfDay() { + const now = new Date(); + const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1); + const secondsUntilEndOfDay = (endOfDay - now) / 1000; + return secondsUntilEndOfDay; +} + + + +export const POST = (async ( {request, cookies, locals} ) => { + + let output = 'error'; + const data = await request.json() + const sentiment = data?.sentiment; + const ticker = data?.ticker + const sentimentId = data?.sentimentId; + const maxAge = secondsUntilEndOfDay(); + + let newData; + + if (cookies?.get('community-sentiment-'+ticker)) { + //console.log('already voted') + return new Response(JSON.stringify(output)) + } + else { + try { + if (sentimentId) { + if (sentiment === 'upvote') { + await locals?.pb?.collection('sentiment').update( sentimentId, {'upvote+': 1}) + } + else if (sentiment === 'downvote') { + await locals?.pb?.collection('sentiment').update( sentimentId, {'downvote+': 1}) + } + } + + else { + + if (sentiment === 'upvote') { + newData = await locals?.pb?.collection('sentiment').create({'ticker': ticker, 'upvote': 1}) + } + else if (sentiment === 'downvote') { + newData = await locals?.pb?.collection('sentiment').create({'ticker': ticker, 'downvote': 1}) + } + } + + + + output = 'success'; + + cookies.set('community-sentiment-'+ticker, sentiment, {httpOnly: true, + sameSite: 'lax', + secure: true, + path: '/', + maxAge: maxAge // End of day expiry + }); + + + } catch(e) { + console.log(e); + } + } + + + + return new Response(JSON.stringify(output)) +}) satisfies RequestHandler; + diff --git a/src/routes/stocks/[tickerID]/+layout.server.ts b/src/routes/stocks/[tickerID]/+layout.server.ts index 68891f7f..e2a2d226 100644 --- a/src/routes/stocks/[tickerID]/+layout.server.ts +++ b/src/routes/stocks/[tickerID]/+layout.server.ts @@ -85,7 +85,37 @@ async function fetchPortfolio(fastifyURL, userId) return output } -export const load = async ({ params, locals}) => { +async function fetchCommunitySentiment(pb, ticker, cookies) +{ + let alreadyVoted; + const cookieVote = cookies?.get('community-sentiment-'+ticker); + + const today = new Date(); + const tomorrow = new Date(today); + tomorrow.setDate(today.getDate() + 1); + + const startDate = today.toISOString().split('T')[0]; + const endDate = tomorrow.toISOString().split('T')[0]; + + const output = await pb.collection("sentiment").getFullList({ + filter: `ticker="${ticker}" && created >= "${startDate}" && created < "${endDate}"` + }); + + if (cookieVote) { + alreadyVoted = cookieVote; + } + + if(output?.length !== 0) { + + return {'alreadyVoted': alreadyVoted, 'sentimentData': output?.at(0)} + } + else { + return {'alreadyVoted': alreadyVoted, 'sentimentData': {} } + } + +} + +export const load = async ({ params, locals, cookies}) => { const userRegion = locals?.region?.split("::")[0]; @@ -102,7 +132,7 @@ export const load = async ({ params, locals}) => { }; - + const promises = [ fetchData(apiURL,'/fair-price',params.tickerID), @@ -130,7 +160,8 @@ export const load = async ({ params, locals}) => { fetchData(apiURL,'/historical-price',params.tickerID), fetchData(apiURL,'/one-day-price',params.tickerID), fetchWatchlist(fastifyURL, locals?.user?.id), - fetchPortfolio(fastifyURL, locals?.user?.id) + fetchPortfolio(fastifyURL, locals?.user?.id), + fetchCommunitySentiment(locals?.pb, params.tickerID, cookies) ]; const [ @@ -160,6 +191,7 @@ export const load = async ({ params, locals}) => { getOneDayPrice, getUserWatchlist, getUserPortfolio, + getCommunitySentiment, ] = await Promise.all(promises); /* @@ -195,6 +227,7 @@ export const load = async ({ params, locals}) => { getOneDayPrice, getUserWatchlist, getUserPortfolio, + getCommunitySentiment, companyName, }; diff --git a/src/routes/stocks/[tickerID]/+page.server.ts b/src/routes/stocks/[tickerID]/+page.server.ts index 7f115527..5f61acee 100644 --- a/src/routes/stocks/[tickerID]/+page.server.ts +++ b/src/routes/stocks/[tickerID]/+page.server.ts @@ -136,6 +136,7 @@ export const actions = { redirect(302,authProviderRedirect); - } + }, + }; diff --git a/src/routes/stocks/[tickerID]/+page.svelte b/src/routes/stocks/[tickerID]/+page.svelte index 2cf41ade..7e8a5185 100644 --- a/src/routes/stocks/[tickerID]/+page.svelte +++ b/src/routes/stocks/[tickerID]/+page.svelte @@ -8,7 +8,7 @@ import AnalystEstimate from '$lib/components/AnalystEstimate.svelte'; import StockKeyInformation from '$lib/components/StockKeyInformation.svelte'; import BullBearSay from '$lib/components/BullBearSay.svelte'; - + import CommunitySentiment from '$lib/components/CommunitySentiment.svelte'; const usRegion = ['cle1','iad1','pdx1','sfo1']; @@ -49,6 +49,7 @@ let trendList = []; let priceAnalysisDict = {}; let fundamentalAnalysisDict = {}; + let communitySentiment = {}; //============================================// @@ -653,6 +654,7 @@ function changeChartType() { trendList = []; priceAnalysisDict = {}; fundamentalAnalysisDict = {}; + communitySentiment = {} output = null; @@ -673,7 +675,7 @@ function changeChartType() { enterpriseValues = data?.getEnterPriseValues; priceAnalysisDict = data?.getPriceAnalysis; fundamentalAnalysisDict = data?.getFundamentalAnalysis; - + communitySentiment = data?.getCommunitySentiment; similarstock = data?.getSimilarStock; topETFHolder = data?.getTopETFHolder; @@ -1197,9 +1199,13 @@ function changeChartType() { - - {#if $screenWidth <= 1022} -
+
+ +
+ + + {#if $screenWidth <= 1022} +

Key Information

@@ -1214,7 +1220,9 @@ function changeChartType() { {/if} -
+ + +