66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
'use client'
|
|
|
|
import { useRouter } from 'next/navigation'
|
|
import type { MappedQuote } from '@/lib/stockApi'
|
|
import { SwipeableRow } from './SwipeableRow'
|
|
|
|
interface StockWatchlistRowProps {
|
|
stock: MappedQuote & { id: string }
|
|
onDelete: () => Promise<void>
|
|
isOpen: boolean
|
|
onOpenChange: (open: boolean) => void
|
|
}
|
|
|
|
export function StockWatchlistRow({ stock, onDelete, isOpen, onOpenChange }: StockWatchlistRowProps) {
|
|
const router = useRouter()
|
|
|
|
const changeColor =
|
|
stock.priceChange > 0
|
|
? 'text-positive'
|
|
: stock.priceChange < 0
|
|
? 'text-negative'
|
|
: 'text-foreground'
|
|
|
|
const changeSign = stock.priceChange > 0 ? '+' : ''
|
|
|
|
return (
|
|
<SwipeableRow
|
|
onDelete={onDelete}
|
|
onTap={() => router.push(`/symbol-details?symbol=${stock.symbol}`)}
|
|
isOpen={isOpen}
|
|
onOpenChange={onOpenChange}
|
|
>
|
|
<div className="border border-border bg-card p-4 cursor-pointer transition-colors space-y-3 hover:bg-secondary">
|
|
{/* Header Row */}
|
|
<div className="flex justify-between items-start">
|
|
<div>
|
|
<div className="font-bold text-foreground">{stock.symbol}</div>
|
|
</div>
|
|
<div className="text-right">
|
|
<div className="font-bold text-foreground">${stock.lastPrice.toFixed(2)}</div>
|
|
<div className={`text-sm font-semibold ${changeColor}`}>
|
|
{changeSign}${stock.priceChange.toFixed(2)} ({changeSign}{stock.percentChange.toFixed(2)}%)
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Key fields */}
|
|
<div className="grid grid-cols-2 gap-x-4 text-xs">
|
|
<div className="flex justify-between">
|
|
<span className="text-muted-foreground">Open</span>
|
|
<span>{stock.openPrice != null ? `$${stock.openPrice.toFixed(2)}` : '—'}</span>
|
|
</div>
|
|
<div className="flex justify-between">
|
|
<span className="text-muted-foreground">Prev Close</span>
|
|
<span>${stock.previousClose.toFixed(2)}</span>
|
|
</div>
|
|
<div className="flex justify-between col-span-2 mt-1">
|
|
<span className="text-muted-foreground">Volume</span>
|
|
<span>{stock.volume.toLocaleString()}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</SwipeableRow>
|
|
)
|
|
}
|