boyinfuture's picture
feat: Build complete application with all features
c3bf538
import React from 'react';
import { Bot, Newspaper, LineChart, Share2, TrendingUp, TrendingDown, ChevronsUp, ChevronsDown, Landmark, Building2, User, ArrowUp, ArrowDown, Minus } from 'lucide-react';
import ReactMarkdown from 'react-markdown';
import HistoricalChart from './HistoricalChart';
const SectionTitle = ({ icon, title, subtitle }) => (
<div className="mb-8">
<div className="flex items-center space-x-4 mb-2">
<div className="p-2 bg-gradient-to-r from-green-500/20 to-emerald-500/20 rounded-lg border border-green-500/30">
{icon}
</div>
<h2 className="text-3xl font-bold bg-gradient-to-r from-green-400 to-emerald-400 bg-clip-text text-transparent tracking-wide">
{title}
</h2>
</div>
{subtitle && (
<p className="text-gray-400 ml-16 text-sm leading-relaxed">{subtitle}</p>
)}
</div>
);
const MetricCard = ({ title, value, subtitle, trend }) => {
const getTrendIcon = () => {
if (trend > 0) return <ArrowUp className="w-4 h-4 text-green-400" />;
if (trend < 0) return <ArrowDown className="w-4 h-4 text-red-400" />;
return <Minus className="w-4 h-4 text-gray-400" />;
};
const getTrendColor = () => {
if (trend > 0) return 'text-green-400';
if (trend < 0) return 'text-red-400';
return 'text-gray-400';
};
return (
<div className="group relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-br from-green-500/5 to-emerald-500/5 opacity-0 group-hover:opacity-100 transition-opacity duration-300 rounded-xl"></div>
<div className="relative bg-gray-800/60 backdrop-blur-sm p-6 rounded-xl border border-gray-700/50 hover:border-green-500/30 transition-all duration-300 hover:shadow-lg hover:shadow-green-500/10 hover:-translate-y-1">
<div className="flex items-center justify-between mb-2">
<p className="text-sm font-medium text-gray-400 uppercase tracking-wide">{title}</p>
{trend !== undefined && getTrendIcon()}
</div>
<p className="text-2xl font-bold text-white mb-1 leading-tight">{value}</p>
{subtitle && (
<p className={`text-xs font-medium ${getTrendColor()} flex items-center space-x-1`}>
<span>{subtitle}</span>
</p>
)}
</div>
</div>
);
};
const NewsCard = ({ item, index }) => (
<a
href={item.url}
target="_blank"
rel="noopener noreferrer"
className="group block relative overflow-hidden bg-gradient-to-br from-gray-800/80 to-gray-900/80 backdrop-blur-sm rounded-xl border border-gray-700/50 hover:border-green-500/30 transition-all duration-300 hover:shadow-xl hover:shadow-green-500/10 hover:-translate-y-2"
>
<div className="absolute inset-0 bg-gradient-to-br from-green-500/5 to-emerald-500/5 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
<div className="relative p-6">
<div className="flex items-start justify-between mb-4">
<span className={`inline-flex items-center px-3 py-1 rounded-full text-xs font-bold ${
item.sentiment === 'Positive'
? 'bg-green-900/60 text-green-300 border border-green-500/30'
: item.sentiment === 'Negative'
? 'bg-red-900/60 text-red-300 border border-red-500/30'
: 'bg-yellow-900/60 text-yellow-300 border border-yellow-500/30'
}`}>
{item.sentiment}
</span>
<div className="flex items-center space-x-1">
<div className="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
<span className="text-xs text-gray-500">Live</span>
</div>
</div>
<h3 className="font-bold text-gray-100 mb-3 line-clamp-3 leading-snug text-base group-hover:text-green-300 transition-colors">
{item.title}
</h3>
<div className="flex justify-between items-center text-xs text-gray-400 pt-4 border-t border-gray-700/50">
<span className="font-semibold bg-gray-700/50 px-2 py-1 rounded-md">{item.source}</span>
<span className="opacity-70">Click to read</span>
</div>
</div>
</a>
);
function ResultsDisplay({ result }) {
if (!result) return null;
const {
company_name,
current_price,
previous_close,
day_high,
day_low,
fifty_two_week_high,
fifty_two_week_low,
market_cap,
pe_ratio,
sector,
industry,
ceo,
intelligence_briefing,
llm_analysis
} = result;
const price_change = current_price - previous_close;
const price_change_percent = ((price_change / previous_close) * 100);
const advisorReportText = llm_analysis?.llm_report;
const handleShare = () => {
if (navigator.share) {
navigator.share({
title: `${company_name} Analysis`,
text: `Check out this comprehensive analysis of ${company_name}`,
url: window.location.href,
});
} else {
navigator.clipboard.writeText(window.location.href);
alert('Analysis link copied to clipboard!');
}
};
return (
<div className="mt-12 animate-fade-in">
<div className="relative overflow-hidden bg-gradient-to-br from-gray-800/60 to-gray-900/60 backdrop-blur-sm p-8 rounded-2xl border border-gray-700/50 mb-12">
<div className="absolute inset-0 bg-gradient-to-br from-green-500/5 to-emerald-500/5"></div>
<div className="relative flex flex-col lg:flex-row justify-between items-start">
<div className="flex-1">
<div className="flex items-center space-x-4 mb-4">
<div className="w-3 h-3 bg-green-400 rounded-full animate-pulse"></div>
<span className="text-sm font-medium text-green-400 uppercase tracking-wider">Live Analysis</span>
</div>
<h1 className="text-5xl lg:text-6xl font-extrabold bg-gradient-to-r from-white to-gray-300 bg-clip-text text-transparent mb-4 leading-tight">
{company_name}
</h1>
<div className="flex flex-wrap items-center gap-6 text-gray-400">
<span className="flex items-center space-x-2 bg-gray-700/50 px-3 py-2 rounded-lg">
<Building2 className="w-4 h-4 text-green-400" />
<span className="font-medium">{sector}</span>
</span>
<span className="flex items-center space-x-2 bg-gray-700/50 px-3 py-2 rounded-lg">
<Landmark className="w-4 h-4 text-green-400" />
<span className="font-medium">{industry}</span>
</span>
<span className="flex items-center space-x-2 bg-gray-700/50 px-3 py-2 rounded-lg">
<User className="w-4 h-4 text-green-400" />
<span className="font-medium">CEO: {ceo}</span>
</span>
</div>
</div>
<button
onClick={handleShare}
className="mt-6 lg:mt-0 flex-shrink-0 group relative overflow-hidden bg-gradient-to-r from-green-600 to-emerald-600 hover:from-green-500 hover:to-emerald-500 text-white font-semibold py-3 px-6 rounded-xl transition-all duration-300 hover:shadow-lg hover:shadow-green-500/25 hover:-translate-y-1"
>
<div className="absolute inset-0 bg-white/20 opacity-0 group-hover:opacity-100 transition-opacity duration-300"></div>
<div className="relative flex items-center space-x-2">
<Share2 className="w-5 h-5" />
<span>Share Analysis</span>
</div>
</button>
</div>
</div>
<div className="mb-16">
<SectionTitle
icon={<TrendingUp className="w-8 h-8 text-green-400" />}
title="Key Metrics"
subtitle="Real-time financial indicators and performance metrics"
/>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-6">
<MetricCard
title="Current Price"
value={`₹${current_price?.toFixed(2)}`}
subtitle={`${price_change >= 0 ? '+' : ''}₹${price_change.toFixed(2)} (${price_change_percent >= 0 ? '+' : ''}${price_change_percent.toFixed(2)}%)`}
trend={price_change}
/>
<MetricCard
title="Market Cap"
value={`₹${(market_cap / 10000000).toFixed(2)} Cr`}
/>
<MetricCard
title="P/E Ratio"
value={pe_ratio?.toFixed(2)}
subtitle="Price to Earnings"
/>
<MetricCard
title="Today's Range"
value={`₹${day_low?.toFixed(2)}`}
subtitle={`High: ₹${day_high?.toFixed(2)}`}
/>
<MetricCard
title="52W Range"
value={`₹${fifty_two_week_low?.toFixed(2)}`}
subtitle={`High: ₹${fifty_two_week_high?.toFixed(2)}`}
/>
</div>
</div>
<div className="mb-16">
<SectionTitle
icon={<LineChart className="w-8 h-8 text-green-400" />}
title="Price Movement"
subtitle="Historical price action over the last 100 trading days"
/>
<div className="relative overflow-hidden bg-gradient-to-br from-gray-800/40 to-gray-900/40 backdrop-blur-sm p-8 rounded-2xl border border-gray-700/50">
<div className="absolute inset-0 bg-gradient-to-br from-green-500/3 to-emerald-500/3"></div>
<div className="relative">
<HistoricalChart ticker={result.ticker} />
</div>
</div>
</div>
{advisorReportText && (
<div className="mb-16">
<SectionTitle
icon={<Bot className="w-8 h-8 text-green-400" />}
title="AI Analyst Report"
subtitle="Comprehensive analysis powered by advanced AI models and real-time market data"
/>
<div className="relative overflow-hidden bg-gradient-to-br from-gray-800/40 to-gray-900/40 backdrop-blur-sm rounded-2xl border border-gray-700/50">
<div className="absolute inset-0 bg-gradient-to-br from-green-500/3 to-emerald-500/3"></div>
<div className="relative p-8">
<div className="flex items-center space-x-3 mb-6 pb-4 border-b border-gray-700/50">
<div className="w-3 h-3 bg-green-400 rounded-full animate-pulse"></div>
<span className="text-sm font-medium text-green-400 uppercase tracking-wider">AI Generated</span>
<span className="text-xs text-gray-500"></span>
<span className="text-xs text-gray-500">Powered by AI</span>
</div>
<div className="prose prose-invert prose-lg max-w-none text-gray-300 prose-headings:text-green-400 prose-strong:text-white prose-p:leading-relaxed prose-li:leading-relaxed">
<ReactMarkdown
components={{
h1: ({node, ...props}) => <h2 className="text-2xl font-bold mt-8 mb-4 text-green-400" {...props} />,
h2: ({node, ...props}) => <h3 className="text-xl font-bold mt-6 mb-3 text-green-300" {...props} />,
h3: ({node, ...props}) => <h4 className="text-lg font-semibold mt-4 mb-2 text-green-200" {...props} />,
ul: ({node, ...props}) => <ul className="list-disc pl-6 space-y-2 my-4" {...props} />,
ol: ({node, ...props}) => <ol className="list-decimal pl-6 space-y-2 my-4" {...props} />,
li: ({node, ...props}) => <li className="leading-relaxed text-gray-300" {...props} />,
p: ({node, ...props}) => <p className="mb-4 leading-relaxed text-gray-300" {...props} />,
strong: ({node, ...props}) => <strong className="font-semibold text-white" {...props} />,
blockquote: ({node, ...props}) => (
<blockquote className="border-l-4 border-green-500/50 pl-4 italic text-gray-400 my-4" {...props} />
),
}}
>
{advisorReportText}
</ReactMarkdown>
</div>
</div>
</div>
</div>
)}
<div className="mb-16">
<SectionTitle
icon={<Newspaper className="w-8 h-8 text-green-400" />}
title="Market Intelligence"
subtitle="Latest news and sentiment analysis from multiple sources"
/>
{intelligence_briefing?.articles?.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-8">
{intelligence_briefing.articles.slice(0, 9).map((item, index) => (
<NewsCard key={index} item={item} index={index} />
))}
</div>
) : (
<div className="text-center py-16 bg-gray-800/30 rounded-2xl border border-gray-700/50">
<Newspaper className="w-16 h-16 text-gray-600 mx-auto mb-4" />
<p className="text-gray-400 text-lg">No news articles found for this symbol.</p>
<p className="text-gray-500 text-sm mt-2">Try checking back later or verify the ticker symbol.</p>
</div>
)}
</div>
</div>
);
}
export default ResultsDisplay;