import { useState, useMemo } from "react"; import type { Order, OrderStatus, OrderPriority, OrderType } from "../../lib/api"; import { OrderContextMenu } from "./OrderContextMenu"; const STATUS_BADGE: Record = { open: { color: "text-[#75aafc] border-[rgba(117,170,252,0.4)]", label: "OPEN" }, in_progress: { color: "text-yellow-400 border-yellow-800", label: "IN PROGRESS" }, under_review: { color: "text-purple-400 border-purple-800", label: "REVIEW" }, done: { color: "text-emerald-400 border-emerald-800", label: "DONE" }, archived: { color: "text-[#556677] border-[#2a3a5a]", label: "ARCHIVED" }, }; const PRIORITY_COLOR: Record = { critical: "bg-red-400", high: "bg-orange-400", medium: "bg-yellow-400", low: "bg-[#75aafc]", none: "bg-[#556677]", }; const TYPE_BADGE: Record = { feature: { color: "text-[#75aafc] border-[rgba(117,170,252,0.3)]", label: "FEAT" }, bug: { color: "text-red-400 border-red-800", label: "BUG" }, spike: { color: "text-yellow-400 border-yellow-800", label: "SPIKE" }, chore: { color: "text-[#7788aa] border-[#2a3a5a]", label: "CHORE" }, improvement: { color: "text-emerald-400 border-emerald-800", label: "IMPROVE" }, }; interface OrderListProps { orders: Order[]; selectedId: string | null; onSelect: (id: string) => void; onCreate: () => void; statusFilter: OrderStatus | undefined; onStatusFilter: (s: OrderStatus | undefined) => void; typeFilter: OrderType | undefined; onTypeFilter: (t: OrderType | undefined) => void; onChangeStatus?: (order: Order, status: OrderStatus) => void; onDelete?: (order: Order) => void; onGoToDirective?: (order: Order) => void; } const STATUS_OPTIONS: (OrderStatus | "all")[] = ["all", "open", "in_progress", "under_review", "done", "archived"]; const TYPE_OPTIONS: (OrderType | "all")[] = ["all", "feature", "bug", "spike", "chore", "improvement"]; export function OrderList({ orders, selectedId, onSelect, onCreate, statusFilter, onStatusFilter, typeFilter, onTypeFilter, onChangeStatus, onDelete, onGoToDirective, }: OrderListProps) { const [search, setSearch] = useState(""); const [contextMenuPosition, setContextMenuPosition] = useState<{ x: number; y: number } | null>(null); const [contextMenuOrder, setContextMenuOrder] = useState(null); const handleContextMenu = (e: React.MouseEvent, order: Order) => { e.preventDefault(); setContextMenuPosition({ x: e.clientX, y: e.clientY }); setContextMenuOrder(order); }; const closeContextMenu = () => { setContextMenuPosition(null); setContextMenuOrder(null); }; const filtered = useMemo(() => { if (!search.trim()) return orders; const q = search.toLowerCase(); return orders.filter( (o) => o.title.toLowerCase().includes(q) || (o.description && o.description.toLowerCase().includes(q)) || o.labels.some((l) => l.toLowerCase().includes(q)) || (o.directiveName && o.directiveName.toLowerCase().includes(q)), ); }, [orders, search]); return (
{/* Header */}
Orders
{/* Search */}
setSearch(e.target.value)} placeholder="Search orders..." className="w-full bg-transparent border-none outline-none text-[11px] font-mono text-white placeholder:text-[#556677]" />
{/* Filters */}
Status {STATUS_OPTIONS.map((s) => ( ))}
Type {TYPE_OPTIONS.map((t) => ( ))}
{/* List */}
{filtered.length === 0 ? (
No orders found
) : ( filtered.map((o) => { const statusBadge = STATUS_BADGE[o.status] || STATUS_BADGE.open; const typeBadge = TYPE_BADGE[o.orderType] || TYPE_BADGE.feature; const priorityColor = PRIORITY_COLOR[o.priority] || PRIORITY_COLOR.none; return ( ); }) )}
{/* Context Menu */} {contextMenuPosition && contextMenuOrder && ( onChangeStatus?.(contextMenuOrder, status)} onDelete={() => onDelete?.(contextMenuOrder)} onGoToDirective={() => onGoToDirective?.(contextMenuOrder)} /> )}
); }