initial commit
This commit is contained in:
90
components/StockRow.tsx
Normal file
90
components/StockRow.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
import React from 'react';
|
||||
import { Zap, ShoppingCart, Star } from 'lucide-react';
|
||||
import { StockItem, MarketType, OrderType } from '../types';
|
||||
|
||||
interface StockRowProps {
|
||||
stock: StockItem;
|
||||
rank?: number;
|
||||
showRank?: boolean;
|
||||
showActions?: boolean;
|
||||
showRatioBar?: boolean;
|
||||
showPL?: { pl: number; percent: number };
|
||||
isWatchlisted?: boolean;
|
||||
onClick?: () => void;
|
||||
onTrade?: (type: OrderType) => void;
|
||||
onToggleWatchlist?: () => void;
|
||||
}
|
||||
|
||||
export const StockRow: React.FC<StockRowProps> = ({
|
||||
stock, rank, showRank, showActions, showRatioBar, showPL, isWatchlisted, onClick, onTrade, onToggleWatchlist
|
||||
}) => {
|
||||
return (
|
||||
<tr
|
||||
onClick={onClick}
|
||||
className="group cursor-pointer transition-colors hover:bg-slate-50/70"
|
||||
>
|
||||
{showRank && (
|
||||
<td className="pl-6 py-3 font-mono font-black text-slate-400 group-hover:text-blue-600 transition-colors">
|
||||
{rank}
|
||||
</td>
|
||||
)}
|
||||
<td className="px-4 py-3">
|
||||
<div className="flex items-center gap-3">
|
||||
{onToggleWatchlist && (
|
||||
<button
|
||||
onClick={(e) => { e.stopPropagation(); onToggleWatchlist(); }}
|
||||
className="text-slate-300 hover:text-amber-500 transition-colors"
|
||||
>
|
||||
<Star size={16} fill={isWatchlisted ? "currentColor" : "none"} className={isWatchlisted ? "text-amber-500" : ""} />
|
||||
</button>
|
||||
)}
|
||||
<div className="w-8 h-8 rounded-lg bg-slate-900 flex items-center justify-center text-white text-[10px] font-black shadow-sm overflow-hidden">
|
||||
{stock.name[0]}
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-black text-slate-900 text-[13px] tracking-tight group-hover:text-blue-600">{stock.name}</span>
|
||||
<span className="text-[9px] text-slate-400 font-mono font-bold">{stock.code}</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-4 py-3 text-right font-mono font-black text-slate-800 text-[13px]">
|
||||
{stock.market === MarketType.DOMESTIC ? stock.price.toLocaleString() + '원' : '$' + stock.price}
|
||||
</td>
|
||||
<td className="px-4 py-3 text-right">
|
||||
{showPL ? (
|
||||
<div className={showPL.pl >= 0 ? 'text-rose-500' : 'text-blue-600'}>
|
||||
<p className="font-black text-[13px]">{showPL.pl.toLocaleString()}</p>
|
||||
<p className="text-[10px] font-bold">({showPL.percent.toFixed(2)}%)</p>
|
||||
</div>
|
||||
) : (
|
||||
<span className={`font-black text-[13px] ${stock.changePercent >= 0 ? 'text-rose-500' : 'text-blue-600'}`}>
|
||||
{stock.changePercent >= 0 ? '+' : ''}{stock.changePercent}%
|
||||
</span>
|
||||
)}
|
||||
</td>
|
||||
{showRatioBar && (
|
||||
<td className="px-4 py-3">
|
||||
<div className="flex flex-col items-end gap-0.5">
|
||||
<div className="w-full h-1 rounded-full bg-slate-100 overflow-hidden flex">
|
||||
<div className="h-full bg-rose-400" style={{ width: `${stock.buyRatio || 50}%` }} />
|
||||
<div className="h-full bg-blue-400" style={{ width: `${stock.sellRatio || 50}%` }} />
|
||||
</div>
|
||||
<div className="flex justify-between w-full text-[8px] font-black font-mono">
|
||||
<span className="text-rose-500">{stock.buyRatio || 50}</span>
|
||||
<span className="text-blue-500">{stock.sellRatio || 50}</span>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
)}
|
||||
{showActions && onTrade && (
|
||||
<td className="px-4 py-3 text-right">
|
||||
<div className="flex gap-1.5 justify-end opacity-0 group-hover:opacity-100 transition-opacity">
|
||||
<button onClick={(e) => { e.stopPropagation(); onTrade(OrderType.BUY); }} className="p-1.5 bg-rose-50 text-rose-500 rounded-lg hover:bg-rose-500 hover:text-white transition-all"><Zap size={12} fill="currentColor" /></button>
|
||||
<button onClick={(e) => { e.stopPropagation(); onTrade(OrderType.SELL); }} className="p-1.5 bg-blue-50 text-blue-500 rounded-lg hover:bg-blue-500 hover:text-white transition-all"><ShoppingCart size={12} /></button>
|
||||
</div>
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user