From 21d134df1d69c28c4d244e4be3b8704304559397 Mon Sep 17 00:00:00 2001 From: Jason Feibelman Date: Mon, 24 Mar 2025 16:44:04 -0400 Subject: [PATCH 1/3] Add initial news --- src/app/news/page.tsx | 93 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/app/news/page.tsx diff --git a/src/app/news/page.tsx b/src/app/news/page.tsx new file mode 100644 index 0000000..49191f7 --- /dev/null +++ b/src/app/news/page.tsx @@ -0,0 +1,93 @@ +'use client'; + +import { Search } from 'lucide-react'; +import { useState } from 'react'; +import Image from 'next/image'; +import Link from 'next/link'; + +// TODO: add source with little profile pic of cnbc, bloomberg, etc. + +export interface News { + id: string; + title: string; + summary: string; +} + +const mockNewsData: News[] = [ + { + "id": "_TSLA2025OUTLOOK", + "title": "Tesla faces market challenges but bets on AI and autonomy", + "summary": "Tesla's stock has been volatile, currently at $279.17, after a 40% decline from recent highs. Revenue growth remains stagnant, and U.S. EV market share has dropped to 44%. Elon Musk's political engagements may be affecting brand perception, with Tesla registrations in Germany falling 76%. Despite challenges, Tesla is investing in AI, robotics, and autonomous driving, aiming to launch Full Self-Driving in Austin by June 2025 and the Cybercab ride-hailing vehicle by 2026. Analysts are divided—Morgan Stanley sees growth potential, while Bank of America has lowered its price target." + } + , + { id: '_4dn88SBPLM1', title: 'Tech giants announce a new AI breakthrough', summary: 'Tech giants announce a new AI breakthrough.' }, + { id: '_4dn88SBPLM2', title: 'Sports update: Local team secures championship win.', summary: 'Sports update: Local team secures championship win.' }, + { id: '_4dn88SBPLM3', title: 'Market trends: Stocks surge after latest reports.', summary: 'Market trends: Stocks surge after latest reports.' }, + { id: '_4dn88SBPLM4', title: 'Entertainment: Upcoming movies and releases for this year.', summary: 'Entertainment: Upcoming movies and releases for this year.' }, +]; + +const NewsPage = () => { + const [news] = useState(mockNewsData); + const [expanded, setExpanded] = useState<{ [key: string]: boolean }>({}); + + const toggleSummary = (id: string) => { + setExpanded((prev) => ({ ...prev, [id]: !prev[id] })); + }; + + return ( +
+
+
+ +

Latest News

+
+
+
+ +
+ {news.map((item) => ( +
+ {/* Construct YouTube URL dynamically */} + +
+ {/* Thumbnail on the Left */} +
+ + placeholder + +
+ + {/* Text on the Right */} +
+

{item.title}

+ + {/* Sliced Summary */} +

+ {expanded[item.id] ? item.summary : `${item.summary.slice(0, 100)}...`} +

+ + {/* Toggle Button */} + +
+
+
+ ))} +
+
+ ); +}; + +export default NewsPage; \ No newline at end of file From 075d949accd1f83068213a7ee4b26fc8468a8d4d Mon Sep 17 00:00:00 2001 From: Jason Feibelman Date: Mon, 24 Mar 2025 16:46:52 -0400 Subject: [PATCH 2/3] Add initial news --- src/app/news/page.tsx | 117 +++++++++++++++++++++++++++++------------- 1 file changed, 80 insertions(+), 37 deletions(-) diff --git a/src/app/news/page.tsx b/src/app/news/page.tsx index 49191f7..665db18 100644 --- a/src/app/news/page.tsx +++ b/src/app/news/page.tsx @@ -1,41 +1,74 @@ 'use client'; import { Search } from 'lucide-react'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import Image from 'next/image'; import Link from 'next/link'; -// TODO: add source with little profile pic of cnbc, bloomberg, etc. - export interface News { id: string; title: string; summary: string; + description: string; } -const mockNewsData: News[] = [ - { - "id": "_TSLA2025OUTLOOK", - "title": "Tesla faces market challenges but bets on AI and autonomy", - "summary": "Tesla's stock has been volatile, currently at $279.17, after a 40% decline from recent highs. Revenue growth remains stagnant, and U.S. EV market share has dropped to 44%. Elon Musk's political engagements may be affecting brand perception, with Tesla registrations in Germany falling 76%. Despite challenges, Tesla is investing in AI, robotics, and autonomous driving, aiming to launch Full Self-Driving in Austin by June 2025 and the Cybercab ride-hailing vehicle by 2026. Analysts are divided—Morgan Stanley sees growth potential, while Bank of America has lowered its price target." - } - , - { id: '_4dn88SBPLM1', title: 'Tech giants announce a new AI breakthrough', summary: 'Tech giants announce a new AI breakthrough.' }, - { id: '_4dn88SBPLM2', title: 'Sports update: Local team secures championship win.', summary: 'Sports update: Local team secures championship win.' }, - { id: '_4dn88SBPLM3', title: 'Market trends: Stocks surge after latest reports.', summary: 'Market trends: Stocks surge after latest reports.' }, - { id: '_4dn88SBPLM4', title: 'Entertainment: Upcoming movies and releases for this year.', summary: 'Entertainment: Upcoming movies and releases for this year.' }, -]; +const API_BASE_URL = process.env.NEXT_PUBLIC_AWS_DB_API_URL || ''; +const API_URL = `${API_BASE_URL}?queryType=joint&num_results=20`; +const API_KEY = process.env.NEXT_PUBLIC_AWS_DB_API_KEY || ''; -const NewsPage = () => { - const [news] = useState(mockNewsData); +const NewsPageContent = () => { + const [news, setNews] = useState([]); const [expanded, setExpanded] = useState<{ [key: string]: boolean }>({}); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchNews = async () => { + try { + const response = await fetch(API_URL, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'x-api-key': API_KEY, + }, + }); + + if (!response.ok) { + throw new Error(`Failed to fetch news: ${response.statusText}`); + } + + const data = await response.json(); + + console.log("API Response:", data); // Debugging: Log the API response + + // Convert API response into News format + const formattedNews = data.result.map((item: any) => ({ + id: item[0], // Video ID (used in YouTube links) + title: item[1], // News title + description: item[3], // Short description + summary: item[4], // Full summary (for Show More) + })); + + setNews(formattedNews); + } catch (err) { + setError(err instanceof Error ? err.message : 'An unknown error occurred'); + } finally { + setLoading(false); + } + }; + + fetchNews(); + }, []); const toggleSummary = (id: string) => { setExpanded((prev) => ({ ...prev, [id]: !prev[id] })); }; + if (loading) return

Loading news...

; + if (error) return

Error: {error}

; + return ( -
+
@@ -48,33 +81,31 @@ const NewsPage = () => { {news.map((item) => (
- {/* Construct YouTube URL dynamically */} - -
+
{/* Thumbnail on the Left */} -
- - placeholder - +
+
{/* Text on the Right */}

{item.title}

- - {/* Sliced Summary */} -

- {expanded[item.id] ? item.summary : `${item.summary.slice(0, 100)}...`} +

+ {expanded[item.id] ? item.description : `${item.description.slice(0, 120)}...`}

- - {/* Toggle Button */}
+ + {expanded[item.id] && ( +

{item.summary}

+ )}
))}
@@ -90,4 +125,12 @@ const NewsPage = () => { ); }; +const NewsPage = () => { + return ( + <> + + + ); +}; + export default NewsPage; \ No newline at end of file From eeb585c7df032f9830524d546cad319a0429f4b6 Mon Sep 17 00:00:00 2001 From: Jason Feibelman Date: Mon, 24 Mar 2025 16:51:52 -0400 Subject: [PATCH 3/3] latest news code --- app.dockerfile | 3 +++ src/components/Sidebar.tsx | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app.dockerfile b/app.dockerfile index 3433288..11503fe 100644 --- a/app.dockerfile +++ b/app.dockerfile @@ -1,5 +1,8 @@ FROM node:20.18.0-slim AS builder +ENV NEXT_PUBLIC_AWS_DB_API_URL=https://lyxeetk4w1.execute-api.us-east-1.amazonaws.com/default/getFromStockalyzerDB +ENV NEXT_PUBLIC_AWS_DB_API_KEY=0KcuAyP5zT8kk2vW4MXAU9lMi52Yorti4vRwLwia + WORKDIR /home/perplexica COPY package.json yarn.lock ./ diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 5829c60..76b9e52 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -1,7 +1,7 @@ 'use client'; import { cn } from '@/lib/utils'; -import { BookOpenText, Home, Search, SquarePen, Settings } from 'lucide-react'; +import { BookOpenText, Home, Search, SquarePen, Settings, VideoIcon } from 'lucide-react'; import Link from 'next/link'; import { useSelectedLayoutSegments } from 'next/navigation'; import React, { useState, type ReactNode } from 'react'; @@ -35,6 +35,12 @@ const Sidebar = ({ children }: { children: React.ReactNode }) => { active: segments.includes('library'), label: 'Library', }, + { + icon: VideoIcon, + href: '/news', + active: segments.includes('news'), + label: 'News', + }, ]; return (