From 295a8a13635de2fe11bcb2a2b44925f013d082e3 Mon Sep 17 00:00:00 2001 From: "Mr. Algorithm" <11aravipratapsingh@gmail.com> Date: Tue, 30 Sep 2025 10:13:08 +0530 Subject: [PATCH] Implemented home page with TradingView widgets --- app/(root)/page.tsx | 52 ++++- components/TradingViewWidget.tsx | 30 +++ hooks/useTradingViewWidget.tsx | 30 +++ lib/constants.ts | 342 ++++++++++++++++++++++++++++++- 4 files changed, 441 insertions(+), 13 deletions(-) create mode 100644 components/TradingViewWidget.tsx create mode 100644 hooks/useTradingViewWidget.tsx diff --git a/app/(root)/page.tsx b/app/(root)/page.tsx index 7bfb095..a8b060d 100644 --- a/app/(root)/page.tsx +++ b/app/(root)/page.tsx @@ -1,18 +1,52 @@ import React from 'react' -import {Button} from "../../components/ui/button"; +import TradingViewWidget from "@/components/TradingViewWidget"; +import {MARKET_DATA_WIDGET_CONFIG, MARKET_OVERVIEW_WIDGET_CONFIG, TOP_STORIES_WIDGET_CONFIG} from "@/lib/constants"; const Home = () => { + const scriptUrl = `https://s3.tradingview.com/external-embedding/embed-widget-`; return (
-
-

Welcome to OpenStock

-

- OpenStock is an open-source alternative to expensive market platforms. - Track real-time prices, set personalized alerts, and explore detailed company insights. -

- -
+
+
+ + +
+
+ +
+
+
+
+ +
+
+ + +
+ +
+ ) } export default Home diff --git a/components/TradingViewWidget.tsx b/components/TradingViewWidget.tsx new file mode 100644 index 0000000..64359aa --- /dev/null +++ b/components/TradingViewWidget.tsx @@ -0,0 +1,30 @@ +'use client'; + +import React, { memo } from 'react'; +import useTradingViewWidget from "@/hooks/useTradingViewWidget"; +import {cn} from "@/lib/utils"; + +interface TradingViewWidgetProps{ + title: string; + scriptUrl: string; + config: Record; + height?: number; + className?: string; +} + +const TradingViewWidget = ({title, scriptUrl, config, height = 600, className}: TradingViewWidgetProps) => { + const containerRef = useTradingViewWidget(scriptUrl, config, height); + + + return ( +
+ {title &&

{title}

} +
+
+
+
+ + ); +} + +export default memo(TradingViewWidget); diff --git a/hooks/useTradingViewWidget.tsx b/hooks/useTradingViewWidget.tsx new file mode 100644 index 0000000..9e62726 --- /dev/null +++ b/hooks/useTradingViewWidget.tsx @@ -0,0 +1,30 @@ +'use client'; +import { useEffect, useRef } from "react"; + +const useTradingViewWidget = (scriptUrl: string, config: Record, height = 600) => { + const containerRef = useRef(null); + + useEffect(() => { + if (!containerRef.current) return; + if (containerRef.current.dataset.loaded) return; + containerRef.current.innerHTML = `
`; + + const script = document.createElement("script"); + script.src = scriptUrl; + script.async = true; + script.innerHTML = JSON.stringify(config); + + containerRef.current.appendChild(script); + containerRef.current.dataset.loaded = 'true'; + + return () => { + if(containerRef.current) { + containerRef.current.innerHTML = ''; + delete containerRef.current.dataset.loaded; + } + } + }, [scriptUrl, config, height]) + + return containerRef; +} +export default useTradingViewWidget \ No newline at end of file diff --git a/lib/constants.ts b/lib/constants.ts index 98688c7..66e51f4 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -1,5 +1,339 @@ export const NAV_ITEMS = [ - {href: "/", label: 'Dashboard'}, - {href: "/search", label: 'Search'}, - {href: "/watchlist", label: 'Watchlist'}, -] \ No newline at end of file + { href: '/', label: 'Dashboard' }, + { href: '/search', label: 'Search' }, + { href: '/watchlist', label: 'Watchlist' }, +]; + +// Sign-up form select options +export const INVESTMENT_GOALS = [ + { value: 'Growth', label: 'Growth' }, + { value: 'Income', label: 'Income' }, + { value: 'Balanced', label: 'Balanced' }, + { value: 'Conservative', label: 'Conservative' }, +]; + +export const RISK_TOLERANCE_OPTIONS = [ + { value: 'Low', label: 'Low' }, + { value: 'Medium', label: 'Medium' }, + { value: 'High', label: 'High' }, +]; + +export const PREFERRED_INDUSTRIES = [ + { value: 'Technology', label: 'Technology' }, + { value: 'Healthcare', label: 'Healthcare' }, + { value: 'Finance', label: 'Finance' }, + { value: 'Energy', label: 'Energy' }, + { value: 'Consumer Goods', label: 'Consumer Goods' }, +]; + +export const ALERT_TYPE_OPTIONS = [ + { value: 'upper', label: 'Upper' }, + { value: 'lower', label: 'Lower' }, +]; + +export const CONDITION_OPTIONS = [ + { value: 'greater', label: 'Greater than (>)' }, + { value: 'less', label: 'Less than (<)' }, +]; + +// TradingView Charts +export const MARKET_OVERVIEW_WIDGET_CONFIG = { + colorTheme: 'dark', // dark mode + dateRange: '12M', // last 12 months + locale: 'en', // language + largeChartUrl: '', // link to a large chart if needed + isTransparent: true, // makes background transparent + showFloatingTooltip: true, // show tooltip on hover + plotLineColorGrowing: '#0FEDBE', // line color when price goes up + plotLineColorFalling: '#0FEDBE', // line color when price falls + gridLineColor: 'rgba(240, 243, 250, 0)', // grid line color + scaleFontColor: '#DBDBDB', // font color for scale + belowLineFillColorGrowing: 'rgba(41, 98, 255, 0.12)', // fill under line when growing + belowLineFillColorFalling: 'rgba(41, 98, 255, 0.12)', // fill under line when falling + belowLineFillColorGrowingBottom: 'rgba(41, 98, 255, 0)', + belowLineFillColorFallingBottom: 'rgba(41, 98, 255, 0)', + symbolActiveColor: 'rgba(15, 237, 190, 0.05)', // highlight color for active symbol + tabs: [ + { + title: 'Financial', + symbols: [ + { s: 'NYSE:JPM', d: 'JPMorgan Chase' }, + { s: 'NYSE:WFC', d: 'Wells Fargo Co New' }, + { s: 'NYSE:BAC', d: 'Bank Amer Corp' }, + { s: 'NYSE:HSBC', d: 'Hsbc Hldgs Plc' }, + { s: 'NYSE:C', d: 'Citigroup Inc' }, + { s: 'NYSE:MA', d: 'Mastercard Incorporated' }, + ], + }, + { + title: 'Technology', + symbols: [ + { s: 'NASDAQ:AAPL', d: 'Apple' }, + { s: 'NASDAQ:GOOGL', d: 'Alphabet' }, + { s: 'NASDAQ:MSFT', d: 'Microsoft' }, + { s: 'NASDAQ:FB', d: 'Meta Platforms' }, + { s: 'NYSE:ORCL', d: 'Oracle Corp' }, + { s: 'NASDAQ:INTC', d: 'Intel Corp' }, + ], + }, + { + title: 'Services', + symbols: [ + { s: 'NASDAQ:AMZN', d: 'Amazon' }, + { s: 'NYSE:BABA', d: 'Alibaba Group Hldg Ltd' }, + { s: 'NYSE:T', d: 'At&t Inc' }, + { s: 'NYSE:WMT', d: 'Walmart' }, + { s: 'NYSE:V', d: 'Visa' }, + ], + }, + ], + support_host: 'https://www.tradingview.com', // TradingView host + backgroundColor: '#141414', // background color + width: '100%', // full width + height: 600, // height in px + showSymbolLogo: true, // show logo next to symbols + showChart: true, // display mini chart +}; + +export const HEATMAP_WIDGET_CONFIG = { + dataSource: 'SPX500', + blockSize: 'market_cap_basic', + blockColor: 'change', + grouping: 'sector', + isTransparent: true, + locale: 'en', + symbolUrl: '', + colorTheme: 'dark', + exchanges: [], + hasTopBar: false, + isDataSetEnabled: false, + isZoomEnabled: true, + hasSymbolTooltip: true, + isMonoSize: false, + width: '100%', + height: '600', +}; + +export const TOP_STORIES_WIDGET_CONFIG = { + displayMode: 'regular', + feedMode: 'market', + colorTheme: 'dark', + isTransparent: true, + locale: 'en', + market: 'stock', + width: '100%', + height: '600', +}; + +export const MARKET_DATA_WIDGET_CONFIG = { + title: 'Stocks', + width: '100%', + height: 600, + locale: 'en', + showSymbolLogo: true, + colorTheme: 'dark', + isTransparent: false, + backgroundColor: '#0F0F0F', + symbolsGroups: [ + { + name: 'Financial', + symbols: [ + { name: 'NYSE:JPM', displayName: 'JPMorgan Chase' }, + { name: 'NYSE:WFC', displayName: 'Wells Fargo Co New' }, + { name: 'NYSE:BAC', displayName: 'Bank Amer Corp' }, + { name: 'NYSE:HSBC', displayName: 'Hsbc Hldgs Plc' }, + { name: 'NYSE:C', displayName: 'Citigroup Inc' }, + { name: 'NYSE:MA', displayName: 'Mastercard Incorporated' }, + ], + }, + { + name: 'Technology', + symbols: [ + { name: 'NASDAQ:AAPL', displayName: 'Apple' }, + { name: 'NASDAQ:GOOGL', displayName: 'Alphabet' }, + { name: 'NASDAQ:MSFT', displayName: 'Microsoft' }, + { name: 'NASDAQ:FB', displayName: 'Meta Platforms' }, + { name: 'NYSE:ORCL', displayName: 'Oracle Corp' }, + { name: 'NASDAQ:INTC', displayName: 'Intel Corp' }, + ], + }, + { + name: 'Services', + symbols: [ + { name: 'NASDAQ:AMZN', displayName: 'Amazon' }, + { name: 'NYSE:BABA', displayName: 'Alibaba Group Hldg Ltd' }, + { name: 'NYSE:T', displayName: 'At&t Inc' }, + { name: 'NYSE:WMT', displayName: 'Walmart' }, + { name: 'NYSE:V', displayName: 'Visa' }, + ], + }, + ], +}; + +export const SYMBOL_INFO_WIDGET_CONFIG = (symbol: string) => ({ + symbol: symbol.toUpperCase(), + colorTheme: 'dark', + isTransparent: true, + locale: 'en', + width: '100%', + height: 170, +}); + +export const CANDLE_CHART_WIDGET_CONFIG = (symbol: string) => ({ + allow_symbol_change: false, + calendar: false, + details: true, + hide_side_toolbar: true, + hide_top_toolbar: false, + hide_legend: false, + hide_volume: false, + hotlist: false, + interval: 'D', + locale: 'en', + save_image: false, + style: 1, + symbol: symbol.toUpperCase(), + theme: 'dark', + timezone: 'Etc/UTC', + backgroundColor: '#141414', + gridColor: '#141414', + watchlist: [], + withdateranges: false, + compareSymbols: [], + studies: [], + width: '100%', + height: 600, +}); + +export const BASELINE_WIDGET_CONFIG = (symbol: string) => ({ + allow_symbol_change: false, + calendar: false, + details: false, + hide_side_toolbar: true, + hide_top_toolbar: false, + hide_legend: false, + hide_volume: false, + hotlist: false, + interval: 'D', + locale: 'en', + save_image: false, + style: 10, + symbol: symbol.toUpperCase(), + theme: 'dark', + timezone: 'Etc/UTC', + backgroundColor: '#141414', + gridColor: '#141414', + watchlist: [], + withdateranges: false, + compareSymbols: [], + studies: [], + width: '100%', + height: 600, +}); + +export const TECHNICAL_ANALYSIS_WIDGET_CONFIG = (symbol: string) => ({ + symbol: symbol.toUpperCase(), + colorTheme: 'dark', + isTransparent: 'true', + locale: 'en', + width: '100%', + height: 400, + interval: '1h', + largeChartUrl: '', +}); + +export const COMPANY_PROFILE_WIDGET_CONFIG = (symbol: string) => ({ + symbol: symbol.toUpperCase(), + colorTheme: 'dark', + isTransparent: 'true', + locale: 'en', + width: '100%', + height: 440, +}); + +export const COMPANY_FINANCIALS_WIDGET_CONFIG = (symbol: string) => ({ + symbol: symbol.toUpperCase(), + colorTheme: 'dark', + isTransparent: 'true', + locale: 'en', + width: '100%', + height: 464, + displayMode: 'regular', + largeChartUrl: '', +}); + +export const POPULAR_STOCK_SYMBOLS = [ + // Tech Giants (the big technology companies) + 'AAPL', + 'MSFT', + 'GOOGL', + 'AMZN', + 'TSLA', + 'META', + 'NVDA', + 'NFLX', + 'ORCL', + 'CRM', + + // Growing Tech Companies + 'ADBE', + 'INTC', + 'AMD', + 'PYPL', + 'UBER', + 'ZOOM', + 'SPOT', + 'SQ', + 'SHOP', + 'ROKU', + + // Newer Tech Companies + 'SNOW', + 'PLTR', + 'COIN', + 'RBLX', + 'DDOG', + 'CRWD', + 'NET', + 'OKTA', + 'TWLO', + 'ZM', + + // Consumer & Delivery Apps + 'DOCU', + 'PTON', + 'PINS', + 'SNAP', + 'LYFT', + 'DASH', + 'ABNB', + 'RIVN', + 'LCID', + 'NIO', + + // International Companies + 'XPEV', + 'LI', + 'BABA', + 'JD', + 'PDD', + 'TME', + 'BILI', + 'DIDI', + 'GRAB', + 'SE', +]; + +export const NO_MARKET_NEWS = + '

No market news available today. Please check back tomorrow.

'; + +export const WATCHLIST_TABLE_HEADER = [ + 'Company', + 'Symbol', + 'Price', + 'Change', + 'Market Cap', + 'P/E Ratio', + 'Alert', + 'Action', +]; \ No newline at end of file