Files
zeekay e0ec477433 feat: full docs modernization — zero 404s, 585 pages, dep updates
- Enable all 15 finance component docs (from .disabled → .mdx)
- Create stock-market.mdx, 8 chart docs, 8 block docs, 2 framework docs
- Add direction.tsx component (RTL/LTR support from upstream shadcn)
- Add xs/icon-xs button sizes, data-variant/data-size attributes
- Fix build-registry.mts to handle default exports in namespace re-exports
- Add default props to order-entry, positions-list, orders-history, trading-panel
- Fix 18 navigation stubs → re-export from root implementations
- Add 44 orphaned MDX files to nav (installation, dark-mode, desktop, guides, etc)
- Migrate 6 framer-motion imports → motion/react
- Bump React 19.2.0→19.2.4, Next.js 16.0.1→16.1.6, motion→12.34.0
- Align lucide-react, sonner v2, tailwind-merge v3, postcss-selector-parser v7
- Remove framer-motion dep (superseded by motion)
- Fix @types/react-dom, TypeScript versions across workspaces
2026-03-03 07:34:51 -08:00

162 lines
5.0 KiB
TypeScript

"use client"
import { useState } from "react"
export interface OrderEntryProps {
symbol: string
accountBalance: number
onPlaceOrder: (order: {
symbol: string
side: "buy" | "sell"
orderType: "market" | "limit"
shares: number
limitPrice?: number
}) => void
disabled?: boolean
}
export function OrderEntry({
symbol = "NASDAQ:AAPL",
accountBalance = 10000,
onPlaceOrder = () => {},
disabled = false,
}: Partial<OrderEntryProps>) {
const [orderType, setOrderType] = useState<"market" | "limit">("market")
const [orderSide, setOrderSide] = useState<"buy" | "sell">("buy")
const [shares, setShares] = useState("")
const [limitPrice, setLimitPrice] = useState("")
const getTickerFromSymbol = (symbol: string) => {
return symbol.split(":")[1] || symbol
}
const handlePlaceOrder = () => {
if (!shares || (orderType === "limit" && !limitPrice)) return
onPlaceOrder({
symbol,
side: orderSide,
orderType,
shares: parseInt(shares),
limitPrice: orderType === "limit" ? parseFloat(limitPrice) : undefined,
})
// Reset form
setShares("")
setLimitPrice("")
}
return (
<div className="p-4 space-y-4">
{/* Account Balance */}
<div className="bg-white/5 rounded-lg p-3">
<div className="text-xs text-white/60 mb-1">Buying Power</div>
<div className="text-lg font-semibold text-white">
${accountBalance.toLocaleString()}
</div>
</div>
{/* Buy/Sell Toggle */}
<div className="grid grid-cols-2 gap-2">
<button
onClick={() => setOrderSide("buy")}
disabled={disabled}
className={`py-2.5 rounded-lg font-semibold transition-all ${
orderSide === "buy"
? "bg-success text-white"
: "bg-white/5 text-white/60 hover:bg-white/10"
} disabled:opacity-50 disabled:cursor-not-allowed`}
>
Buy
</button>
<button
onClick={() => setOrderSide("sell")}
disabled={disabled}
className={`py-2.5 rounded-lg font-semibold transition-all ${
orderSide === "sell"
? "bg-danger text-white"
: "bg-white/5 text-white/60 hover:bg-white/10"
} disabled:opacity-50 disabled:cursor-not-allowed`}
>
Sell
</button>
</div>
{/* Order Type */}
<div>
<label className="text-xs text-white/60 mb-2 block">Order Type</label>
<div className="grid grid-cols-2 gap-2">
<button
onClick={() => setOrderType("market")}
disabled={disabled}
className={`py-2 rounded-lg text-sm font-medium transition-all ${
orderType === "market"
? "bg-white/10 text-white"
: "bg-white/5 text-white/60 hover:bg-white/10"
} disabled:opacity-50 disabled:cursor-not-allowed`}
>
Market
</button>
<button
onClick={() => setOrderType("limit")}
disabled={disabled}
className={`py-2 rounded-lg text-sm font-medium transition-all ${
orderType === "limit"
? "bg-white/10 text-white"
: "bg-white/5 text-white/60 hover:bg-white/10"
} disabled:opacity-50 disabled:cursor-not-allowed`}
>
Limit
</button>
</div>
</div>
{/* Shares */}
<div>
<label className="text-xs text-white/60 mb-2 block">Shares</label>
<input
type="number"
value={shares}
onChange={(e) => setShares(e.target.value)}
disabled={disabled}
className="w-full bg-white/5 border border-white/10 rounded-lg px-4 py-2.5 text-white focus:outline-none focus:border-success disabled:opacity-50 disabled:cursor-not-allowed"
placeholder="0"
/>
</div>
{/* Limit Price */}
{orderType === "limit" && (
<div>
<label className="text-xs text-white/60 mb-2 block">
Limit Price
</label>
<input
type="number"
value={limitPrice}
onChange={(e) => setLimitPrice(e.target.value)}
disabled={disabled}
className="w-full bg-white/5 border border-white/10 rounded-lg px-4 py-2.5 text-white focus:outline-none focus:border-success disabled:opacity-50 disabled:cursor-not-allowed"
placeholder="0.00"
step="0.01"
/>
</div>
)}
{/* Place Order Button */}
<button
onClick={handlePlaceOrder}
disabled={disabled || !shares || (orderType === "limit" && !limitPrice)}
className={`w-full py-3 rounded-lg font-semibold transition-all ${
orderSide === "buy"
? "bg-success hover:bg-success/90 text-white"
: "bg-danger hover:bg-danger/90 text-white"
} disabled:opacity-50 disabled:cursor-not-allowed`}
>
{orderSide === "buy" ? "Buy" : "Sell"} {getTickerFromSymbol(symbol)}
</button>
</div>
)
}
export default OrderEntry