100 lines
4.0 KiB
TypeScript
100 lines
4.0 KiB
TypeScript
import TradingViewWidget from "@/components/TradingViewWidget";
|
|
import WatchlistButton from "@/components/WatchlistButton";
|
|
import StockAIAnalysisCard from "@/components/stocks/StockAIAnalysisCard";
|
|
import StockSentimentCard from "@/components/stocks/StockSentimentCard";
|
|
import {
|
|
SYMBOL_INFO_WIDGET_CONFIG,
|
|
CANDLE_CHART_WIDGET_CONFIG,
|
|
BASELINE_WIDGET_CONFIG,
|
|
TECHNICAL_ANALYSIS_WIDGET_CONFIG,
|
|
COMPANY_PROFILE_WIDGET_CONFIG,
|
|
COMPANY_FINANCIALS_WIDGET_CONFIG,
|
|
} from "@/lib/constants";
|
|
|
|
import { auth } from '@/lib/better-auth/auth';
|
|
import { headers } from 'next/headers';
|
|
import { isStockInWatchlist } from '@/lib/actions/watchlist.actions';
|
|
import { getStockDetailInsights } from '@/lib/actions/stock-analysis.actions';
|
|
import { formatSymbolForTradingView } from '@/lib/utils';
|
|
|
|
export default async function StockDetails({ params }: StockDetailsPageProps) {
|
|
const { symbol } = await params;
|
|
const tvSymbol = formatSymbolForTradingView(symbol);
|
|
const scriptUrl = `https://s3.tradingview.com/external-embedding/embed-widget-`;
|
|
|
|
const session = await auth.api.getSession({
|
|
headers: await headers()
|
|
});
|
|
const userId = session?.user?.id;
|
|
const [isInWatchlist, stockInsights] = await Promise.all([
|
|
userId ? isStockInWatchlist(userId, symbol) : Promise.resolve(false),
|
|
getStockDetailInsights(symbol),
|
|
]);
|
|
const { sentimentInsights, aiAnalysis } = stockInsights;
|
|
|
|
return (
|
|
<div className="flex min-h-screen p-4 md:p-6 lg:p-8">
|
|
<section className="grid grid-cols-1 md:grid-cols-2 gap-8 w-full">
|
|
{/* Left column */}
|
|
<div className="flex flex-col gap-6">
|
|
<TradingViewWidget
|
|
scriptUrl={`${scriptUrl}symbol-info.js`}
|
|
config={SYMBOL_INFO_WIDGET_CONFIG(tvSymbol)}
|
|
height={170}
|
|
/>
|
|
|
|
<TradingViewWidget
|
|
scriptUrl={`${scriptUrl}advanced-chart.js`}
|
|
config={CANDLE_CHART_WIDGET_CONFIG(tvSymbol)}
|
|
className="custom-chart"
|
|
height={600}
|
|
allowExpand={true}
|
|
/>
|
|
|
|
<TradingViewWidget
|
|
scriptUrl={`${scriptUrl}advanced-chart.js`}
|
|
config={BASELINE_WIDGET_CONFIG(tvSymbol)}
|
|
className="custom-chart"
|
|
height={600}
|
|
allowExpand={true}
|
|
/>
|
|
</div>
|
|
|
|
{/* Right column */}
|
|
<div className="flex flex-col gap-6">
|
|
<div className="flex items-center justify-between">
|
|
<WatchlistButton
|
|
symbol={symbol.toUpperCase()}
|
|
company={aiAnalysis?.companyName ?? sentimentInsights?.companyName ?? symbol.toUpperCase()}
|
|
isInWatchlist={isInWatchlist}
|
|
userId={userId}
|
|
/>
|
|
</div>
|
|
|
|
<StockAIAnalysisCard analysis={aiAnalysis} />
|
|
|
|
<StockSentimentCard insight={sentimentInsights} />
|
|
|
|
<TradingViewWidget
|
|
scriptUrl={`${scriptUrl}technical-analysis.js`}
|
|
config={TECHNICAL_ANALYSIS_WIDGET_CONFIG(tvSymbol)}
|
|
height={400}
|
|
/>
|
|
|
|
<TradingViewWidget
|
|
scriptUrl={`${scriptUrl}company-profile.js`}
|
|
config={COMPANY_PROFILE_WIDGET_CONFIG(tvSymbol)}
|
|
height={440}
|
|
/>
|
|
|
|
<TradingViewWidget
|
|
scriptUrl={`${scriptUrl}financials.js`}
|
|
config={COMPANY_FINANCIALS_WIDGET_CONFIG(tvSymbol)}
|
|
height={800}
|
|
/>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|