137 lines
5.5 KiB
TypeScript
137 lines
5.5 KiB
TypeScript
"use client"
|
|
|
|
import { Badge } from "@/components/ui/badge"
|
|
import { Button } from "@/components/ui/button"
|
|
import { TrendingUp, TrendingDown, Star } from "lucide-react"
|
|
|
|
interface StockHeaderProps {
|
|
symbol: string
|
|
activeTab: string
|
|
onTabChange: (tab: string) => void
|
|
}
|
|
|
|
export function StockHeader({ symbol, activeTab, onTabChange }: StockHeaderProps) {
|
|
// Mock data - in real app this would come from an API
|
|
const stockData = {
|
|
TSLA: {
|
|
name: "Tesla, Inc.",
|
|
symbol: "TSLA",
|
|
exchange: "NASDAQ",
|
|
price: 423.39,
|
|
afterHoursPrice: 417.13,
|
|
change: 18.4,
|
|
changePercent: 4.38,
|
|
afterHoursChange: -6.26,
|
|
afterHoursChangePercent: -1.48,
|
|
lastUpdate: "At close: Sep 25, 4:00 PM EDT",
|
|
afterHoursUpdate: "After hours: Sep 26, 6:08 AM EDT",
|
|
},
|
|
}
|
|
|
|
const stock = stockData[symbol as keyof typeof stockData] || stockData.TSLA
|
|
const isPositive = stock.change > 0
|
|
const isAfterHoursPositive = stock.afterHoursChange > 0
|
|
|
|
const tabs = [
|
|
{ id: "overview", label: "Overview" },
|
|
{ id: "historical", label: "Historical Data" },
|
|
{ id: "financials", label: "Financials" },
|
|
{ id: "earnings", label: "Earnings" },
|
|
{ id: "research", label: "Research" },
|
|
]
|
|
|
|
return (
|
|
<div className="bg-card border border-border rounded-lg">
|
|
<div className="p-3 sm:p-4 md:p-6">
|
|
<div className="flex items-start justify-between mb-3 sm:mb-4 md:mb-6">
|
|
<div className="flex items-center space-x-2 sm:space-x-3">
|
|
<div className="w-8 h-8 sm:w-10 sm:h-10 bg-destructive rounded-sm flex items-center justify-center">
|
|
<span className="text-destructive-foreground font-bold text-sm sm:text-base">T</span>
|
|
</div>
|
|
<div>
|
|
<h1 className="text-lg sm:text-xl md:text-2xl font-bold text-foreground leading-tight">{stock.name}</h1>
|
|
<div className="flex items-center space-x-1 sm:space-x-2 text-muted-foreground">
|
|
<span className="text-xs sm:text-sm">{stock.symbol}</span>
|
|
<span className="text-xs sm:text-sm">•</span>
|
|
<span className="text-xs sm:text-sm">{stock.exchange}</span>
|
|
<Badge variant="secondary" className="ml-1 sm:ml-2 text-xs">
|
|
🇺🇸
|
|
</Badge>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<Button variant="outline" size="sm" className="text-xs sm:text-sm bg-transparent">
|
|
<Star className="w-3 h-3 sm:w-4 sm:h-4 mr-1 sm:mr-2" />
|
|
Add to Watchlist
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 sm:gap-6 md:gap-8">
|
|
{/* Regular Hours */}
|
|
<div>
|
|
<div className="flex items-baseline space-x-2 sm:space-x-3 md:space-x-4 mb-1 sm:mb-2">
|
|
<span className="text-2xl font-bold text-foreground leading-tight">US${stock.price.toFixed(2)}</span>
|
|
<div className={`flex items-center space-x-1 ${isPositive ? "text-success" : "text-destructive"}`}>
|
|
{isPositive ? (
|
|
<TrendingUp className="w-3 h-3 sm:w-4 sm:h-4" />
|
|
) : (
|
|
<TrendingDown className="w-3 h-3 sm:w-4 sm:h-4" />
|
|
)}
|
|
<span className="font-medium text-sm sm:text-base">US${Math.abs(stock.change).toFixed(2)}</span>
|
|
<span className="font-medium text-sm sm:text-base">
|
|
{isPositive ? "+" : ""}
|
|
{stock.changePercent.toFixed(2)}%
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<p className="text-xs sm:text-sm text-muted-foreground leading-tight">{stock.lastUpdate}</p>
|
|
</div>
|
|
|
|
{/* After Hours */}
|
|
<div>
|
|
<div className="flex items-baseline space-x-2 sm:space-x-3 md:space-x-4 mb-1 sm:mb-2">
|
|
<span className="text-2xl font-bold text-foreground leading-tight">
|
|
US${stock.afterHoursPrice.toFixed(2)}
|
|
</span>
|
|
<div
|
|
className={`flex items-center space-x-1 ${isAfterHoursPositive ? "text-success" : "text-destructive"}`}
|
|
>
|
|
{isAfterHoursPositive ? (
|
|
<TrendingUp className="w-3 h-3 sm:w-4 sm:h-4" />
|
|
) : (
|
|
<TrendingDown className="w-3 h-3 sm:w-4 sm:h-4" />
|
|
)}
|
|
<span className="font-medium text-sm sm:text-base">
|
|
US${Math.abs(stock.afterHoursChange).toFixed(2)}
|
|
</span>
|
|
<span className="font-medium text-sm sm:text-base">
|
|
{isAfterHoursPositive ? "+" : ""}
|
|
{stock.afterHoursChangePercent.toFixed(2)}%
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<p className="text-xs sm:text-sm text-muted-foreground leading-tight">{stock.afterHoursUpdate}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center space-x-3 sm:space-x-4 md:space-x-6 border-t border-border px-3 sm:px-4 md:px-6 py-2 sm:py-3">
|
|
{tabs.map((tab) => (
|
|
<Button
|
|
key={tab.id}
|
|
variant="ghost"
|
|
onClick={() => onTabChange(tab.id)}
|
|
className={`rounded-none pb-2 sm:pb-3 text-xs sm:text-sm ${
|
|
activeTab === tab.id
|
|
? "text-foreground border-b-2 border-primary"
|
|
: "text-muted-foreground hover:text-foreground"
|
|
}`}
|
|
>
|
|
{tab.label}
|
|
</Button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|