@@ -86,13 +86,13 @@ export default function TradeHistoryTable() {
8686 const navigateDate = ( direction : 'prev' | 'next' ) => {
8787 const [ year , month , day ] = selectedDate . split ( '-' ) . map ( Number ) ;
8888 const currentDate = new Date ( year , month - 1 , day ) ;
89-
89+
9090 if ( direction === 'prev' ) {
9191 currentDate . setDate ( currentDate . getDate ( ) - 1 ) ;
9292 } else {
9393 currentDate . setDate ( currentDate . getDate ( ) + 1 ) ;
9494 }
95-
95+
9696 const newDateString = `${ currentDate . getFullYear ( ) } -${ String ( currentDate . getMonth ( ) + 1 ) . padStart ( 2 , '0' ) } -${ String ( currentDate . getDate ( ) ) . padStart ( 2 , '0' ) } ` ;
9797 setSelectedDate ( newDateString ) ;
9898 } ;
@@ -140,7 +140,7 @@ export default function TradeHistoryTable() {
140140 totalValue : item . dollar_amount ? Number ( item . dollar_amount ) : Number ( item . shares ) * Number ( item . price ) ,
141141 status : item . status ,
142142 executedAt : item . executed_at ? formatTimestamp ( item . executed_at ) : null ,
143- sourceType : item . source_type ,
143+ sourceType : item . source_type == 'rebalance' ? item . source_type : 'analysis' ,
144144 analysisId : item . analysis_id ,
145145 rebalanceRequestId : item . rebalance_request_id ,
146146 alpacaOrderId : item . metadata ?. alpaca_order ?. id ,
@@ -194,7 +194,7 @@ export default function TradeHistoryTable() {
194194 // Extract all Alpaca order IDs
195195 const alpacaOrderIds = ordersWithAlpacaIds . map ( o => o . metadata . alpaca_order . id ) ;
196196 console . log ( `Fetching status for ${ alpacaOrderIds . length } Alpaca orders:` , alpacaOrderIds ) ;
197-
197+
198198 // Fetch all orders from Alpaca using batch API
199199 const session = await getCachedSession ( ) ;
200200 if ( ! session ?. access_token ) {
@@ -233,33 +233,33 @@ export default function TradeHistoryTable() {
233233
234234 if ( alpacaOrder ) {
235235 console . log ( `Found Alpaca order ${ alpacaOrderId } with status: ${ alpacaOrder . status } ` ) ;
236-
236+
237237 // Check if status has changed or if there's new fill information
238238 const currentAlpacaStatus = order . metadata ?. alpaca_order ?. status ;
239239 const currentFilledQty = order . metadata ?. alpaca_order ?. filled_qty ;
240240 const hasStatusChanged = currentAlpacaStatus !== alpacaOrder . status ;
241241 const hasNewFillData = alpacaOrder . filled_qty && alpacaOrder . filled_qty !== currentFilledQty ;
242-
242+
243243 // Always update if we don't have a status yet, or if something changed
244244 if ( ! currentAlpacaStatus || hasStatusChanged || hasNewFillData ) {
245245 console . log ( `Order ${ alpacaOrderId } updating: current status "${ currentAlpacaStatus } " -> new status "${ alpacaOrder . status } "` ) ;
246246 hasUpdates = true ;
247-
247+
248248 // Build the alpaca_order object, only including defined values
249249 const alpacaOrderUpdate : any = {
250250 ...( order . metadata ?. alpaca_order || { } ) ,
251251 status : alpacaOrder . status ,
252252 updated_at : new Date ( ) . toISOString ( )
253253 } ;
254-
254+
255255 // Only add filled_qty and filled_avg_price if they exist
256256 if ( alpacaOrder . filled_qty ) {
257257 alpacaOrderUpdate . filled_qty = parseFloat ( alpacaOrder . filled_qty ) ;
258258 }
259259 if ( alpacaOrder . filled_avg_price ) {
260260 alpacaOrderUpdate . filled_avg_price = parseFloat ( alpacaOrder . filled_avg_price ) ;
261261 }
262-
262+
263263 // Update metadata with latest Alpaca order info
264264 const updatedMetadata = {
265265 ...( order . metadata || { } ) ,
@@ -287,7 +287,7 @@ export default function TradeHistoryTable() {
287287 . update ( updates )
288288 . eq ( 'id' , order . id )
289289 . select ( ) ;
290-
290+
291291 if ( updateError ) {
292292 console . error ( `Failed to update order ${ order . id } :` , updateError ) ;
293293 console . error ( 'Update payload was:' , updates ) ;
@@ -441,15 +441,15 @@ export default function TradeHistoryTable() {
441441 // Filter trades by status
442442 const getFilteredTrades = ( status ?: string ) => {
443443 if ( ! status || status === 'all' ) return allTrades ;
444-
444+
445445 // Special handling for executed - look at Alpaca order status
446446 if ( status === 'executed' ) {
447- return allTrades . filter ( trade =>
448- trade . alpacaOrderStatus === 'filled' ||
447+ return allTrades . filter ( trade =>
448+ trade . alpacaOrderStatus === 'filled' ||
449449 trade . alpacaOrderStatus === 'partially_filled'
450450 ) ;
451451 }
452-
452+
453453 return allTrades . filter ( trade => trade . status === status ) ;
454454 } ;
455455
@@ -475,16 +475,16 @@ export default function TradeHistoryTable() {
475475 } ) ;
476476
477477 // Convert to array and sort chronologically (mixing both types)
478-
478+
479479 // Sort trades within each rebalance group
480480 Array . from ( rebalanceGroups . values ( ) ) . forEach ( group => {
481481 group . trades . sort ( ( a , b ) => new Date ( b . createdAt ) . getTime ( ) - new Date ( a . createdAt ) . getTime ( ) ) ;
482482 } ) ;
483-
483+
484484 // Combine rebalance groups and standalone trades, then sort by creation time
485485 const rebalanceGroupsArray = Array . from ( rebalanceGroups . values ( ) ) ;
486486 const allItems : ( TradeDecision | RebalanceGroup ) [ ] = [ ...rebalanceGroupsArray , ...standaloneTradesList ] ;
487-
487+
488488 // Sort all items by their creation time (newest first)
489489 allItems . sort ( ( a , b ) => {
490490 const timeA = new Date ( a . createdAt ) . getTime ( ) ;
@@ -527,9 +527,8 @@ export default function TradeHistoryTable() {
527527 return (
528528 < div
529529 key = { decision . id }
530- className = { `p-3 rounded-lg border transition-colors flex flex-col gap-3 ${
531- isInGroup ? 'border-l-2 border-l-border ml-4' : ''
532- } ${ getCardClasses ( ) } `}
530+ className = { `p-3 rounded-lg border transition-colors flex flex-col gap-3 ${ isInGroup ? 'border-l-2 border-l-border ml-4' : ''
531+ } ${ getCardClasses ( ) } `}
533532 >
534533 < div className = "flex items-start justify-between gap-3" >
535534 < div className = "flex gap-3 flex-1" >
@@ -544,8 +543,8 @@ export default function TradeHistoryTable() {
544543 < div className = "space-y-1 flex-1" >
545544 < div className = "flex items-center gap-2 flex-wrap" >
546545 < span className = "font-semibold text-sm" > { decision . symbol } </ span >
547- < Badge
548- variant = { decision . action === 'BUY' ? 'buy' : decision . action === 'SELL' ? 'sell' : 'hold' }
546+ < Badge
547+ variant = { decision . action === 'BUY' ? 'buy' : decision . action === 'SELL' ? 'sell' : 'hold' }
549548 className = "text-xs"
550549 >
551550 { decision . action }
@@ -717,7 +716,7 @@ export default function TradeHistoryTable() {
717716 ) }
718717 </ div >
719718 </ div >
720-
719+
721720 { /* Metadata - at bottom of card */ }
722721 < div className = "flex items-center gap-2 text-xs text-muted-foreground border-t border-slate-800 pt-2" >
723722 { decision . agent && ! decision . agent . toLowerCase ( ) . includes ( 'portfolio' ) && (
@@ -729,10 +728,10 @@ export default function TradeHistoryTable() {
729728 { decision . sourceType && (
730729 < >
731730 < span className = "capitalize" > { decision . sourceType . replace ( '_' , ' ' ) } </ span >
732- < span > •</ span >
731+ { ! isApproved && < span > •</ span > }
733732 </ >
734733 ) }
735- < span > { decision . timestamp } </ span >
734+ { ! isApproved && < span > { decision . timestamp } </ span > }
736735 { decision . executedAt && (
737736 < >
738737 < span > •</ span >
@@ -795,7 +794,7 @@ export default function TradeHistoryTable() {
795794 { formatFullDate ( group . createdAt ) }
796795 </ div >
797796 </ div >
798-
797+
799798 { /* Rebalance Trades */ }
800799 < div className = "space-y-3" >
801800 { group . trades . map ( trade => renderTradeCard ( trade , true ) ) }
@@ -820,7 +819,7 @@ export default function TradeHistoryTable() {
820819 < TrendingUp className = "h-5 w-5 text-primary" />
821820 Trade History
822821 </ CardTitle >
823-
822+
824823 < div className = "flex items-center gap-1" >
825824 < Button
826825 variant = "ghost"
@@ -830,7 +829,7 @@ export default function TradeHistoryTable() {
830829 >
831830 < ChevronLeft className = "h-4 w-4" />
832831 </ Button >
833-
832+
834833 < Button
835834 variant = "outline"
836835 size = "sm"
@@ -840,7 +839,7 @@ export default function TradeHistoryTable() {
840839 < CalendarIcon className = "h-4 w-4 mr-2" />
841840 { getDateDisplay ( ) }
842841 </ Button >
843-
842+
844843 < Button
845844 variant = "ghost"
846845 size = "sm"
@@ -850,7 +849,7 @@ export default function TradeHistoryTable() {
850849 >
851850 < ChevronRight className = "h-4 w-4" />
852851 </ Button >
853-
852+
854853 < div className = "ml-2" >
855854 < Button
856855 variant = "ghost"
@@ -874,7 +873,7 @@ export default function TradeHistoryTable() {
874873 </ div >
875874 </ div >
876875 </ CardHeader >
877-
876+
878877 < CardContent >
879878 < Tabs value = { activeTab } onValueChange = { setActiveTab } className = "w-full" >
880879 < TabsList className = "grid w-full grid-cols-5" >
@@ -899,23 +898,23 @@ export default function TradeHistoryTable() {
899898 < span className = "hidden sm:inline" > Rejected ({ getFilteredTrades ( 'rejected' ) . length } )</ span >
900899 </ TabsTrigger >
901900 </ TabsList >
902-
901+
903902 < TabsContent value = "all" className = "mt-6" >
904903 { renderContent ( getFilteredTrades ( 'all' ) ) }
905904 </ TabsContent >
906-
905+
907906 < TabsContent value = "pending" className = "mt-6" >
908907 { renderContent ( getFilteredTrades ( 'pending' ) ) }
909908 </ TabsContent >
910-
909+
911910 < TabsContent value = "approved" className = "mt-6" >
912911 { renderContent ( getFilteredTrades ( 'approved' ) ) }
913912 </ TabsContent >
914-
913+
915914 < TabsContent value = "executed" className = "mt-6" >
916915 { renderContent ( getFilteredTrades ( 'executed' ) ) }
917916 </ TabsContent >
918-
917+
919918 < TabsContent value = "rejected" className = "mt-6" >
920919 { renderContent ( getFilteredTrades ( 'rejected' ) ) }
921920 </ TabsContent >
0 commit comments