import { useLoaderData } from "react-router"; import TradingViewChart from "../components/TradingViewChart"; import Navbar from "../components/Navbar"; export const meta = () => [{ title: "Stock Detail - AITrader" }]; interface LoaderData { ticker: string; position: number | null; orders: any[]; } export async function loader({ params, request }: { params: { ticker: string }; request: Request }) { const ticker = params.ticker?.toUpperCase() || ""; // Build base URL from request for server-side fetches const url = new URL(request.url); const baseUrl = `${url.protocol}//${url.host}`; // Fetch position const posRes = await fetch(`${baseUrl}/api/alpaca/positions`); const positions = posRes.ok ? await posRes.json() : []; const position = positions.find((p: any) => p.ticker === ticker)?.qty ?? null; // Fetch orders const ordRes = await fetch(`${baseUrl}/api/alpaca/orders`); const ordersData = ordRes.ok ? await ordRes.json() : { orders: [] }; const orders = ordersData.orders?.filter((o: any) => o.symbol === ticker) || []; return Response.json({ ticker, position, orders }); } export default function StockDetail() { const { ticker, position, orders } = useLoaderData() as LoaderData; return (
{position ? `Quantity: ${position} shares` : "No position held"}
No orders found for {ticker}
) : (| Side | Qty | Status | Filled Price | Filled At |
|---|---|---|---|---|
| {order.side?.toUpperCase()} | {order.qty} | {order.status} | {order.filled_avg_price ? `$${parseFloat(order.filled_avg_price).toFixed(2)}` : "-"} | {order.filled_at ? new Date(order.filled_at).toLocaleDateString() : "-"} |