@@ -3,7 +3,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
33import { Badge } from "@/components/ui/badge" ;
44import { Button } from "@/components/ui/button" ;
55import { Tabs , TabsContent , TabsList , TabsTrigger } from "@/components/ui/tabs" ;
6- import { ArrowUpRight , ArrowDownRight , Clock , CheckCircle , XCircle , TrendingUp , RefreshCw , Loader2 , ExternalLink , FileText , BarChart3 , Calendar , Package } from "lucide-react" ;
6+ import { ArrowUpRight , ArrowDownRight , Clock , CheckCircle , XCircle , TrendingUp , RefreshCw , Loader2 , ExternalLink , FileText , BarChart3 , Calendar , Package , ChevronLeft , ChevronRight , CalendarIcon } from "lucide-react" ;
77import { useAuth } from "@/lib/auth" ;
88import { supabase } from "@/lib/supabase" ;
99import { getCachedSession } from "@/lib/cachedAuth" ;
@@ -51,17 +51,73 @@ export default function TradeHistoryTable() {
5151 const { apiSettings, user } = useAuth ( ) ;
5252 const { toast } = useToast ( ) ;
5353
54+ // Date filter states - default to today (using local date to avoid timezone issues)
55+ const today = new Date ( ) ;
56+ const todayString = `${ today . getFullYear ( ) } -${ String ( today . getMonth ( ) + 1 ) . padStart ( 2 , '0' ) } -${ String ( today . getDate ( ) ) . padStart ( 2 , '0' ) } ` ;
57+ const [ selectedDate , setSelectedDate ] = useState < string > ( todayString ) ;
58+
59+ // Helper to format date display
60+ const getDateDisplay = ( ) => {
61+ const today = new Date ( ) ;
62+ const todayString = `${ today . getFullYear ( ) } -${ String ( today . getMonth ( ) + 1 ) . padStart ( 2 , '0' ) } -${ String ( today . getDate ( ) ) . padStart ( 2 , '0' ) } ` ;
63+
64+ const yesterday = new Date ( ) ;
65+ yesterday . setDate ( yesterday . getDate ( ) - 1 ) ;
66+ const yesterdayString = `${ yesterday . getFullYear ( ) } -${ String ( yesterday . getMonth ( ) + 1 ) . padStart ( 2 , '0' ) } -${ String ( yesterday . getDate ( ) ) . padStart ( 2 , '0' ) } ` ;
67+
68+ if ( selectedDate === todayString ) return "Today" ;
69+ if ( selectedDate === yesterdayString ) return "Yesterday" ;
70+
71+ // Parse the date parts to avoid timezone issues
72+ const [ year , month , day ] = selectedDate . split ( '-' ) . map ( Number ) ;
73+ const date = new Date ( year , month - 1 , day ) ;
74+
75+ return date . toLocaleDateString ( 'en-US' , {
76+ month : 'short' ,
77+ day : 'numeric' ,
78+ year : 'numeric'
79+ } ) ;
80+ } ;
81+
82+ // Navigate date helper functions
83+ const navigateDate = ( direction : 'prev' | 'next' ) => {
84+ const [ year , month , day ] = selectedDate . split ( '-' ) . map ( Number ) ;
85+ const currentDate = new Date ( year , month - 1 , day ) ;
86+
87+ if ( direction === 'prev' ) {
88+ currentDate . setDate ( currentDate . getDate ( ) - 1 ) ;
89+ } else {
90+ currentDate . setDate ( currentDate . getDate ( ) + 1 ) ;
91+ }
92+
93+ const newDateString = `${ currentDate . getFullYear ( ) } -${ String ( currentDate . getMonth ( ) + 1 ) . padStart ( 2 , '0' ) } -${ String ( currentDate . getDate ( ) ) . padStart ( 2 , '0' ) } ` ;
94+ setSelectedDate ( newDateString ) ;
95+ } ;
96+
97+ const jumpToToday = ( ) => {
98+ const today = new Date ( ) ;
99+ const todayString = `${ today . getFullYear ( ) } -${ String ( today . getMonth ( ) + 1 ) . padStart ( 2 , '0' ) } -${ String ( today . getDate ( ) ) . padStart ( 2 , '0' ) } ` ;
100+ setSelectedDate ( todayString ) ;
101+ } ;
102+
54103 // Fetch all trades from trading_actions table
55104 const fetchAllTrades = async ( ) => {
56105 if ( ! user ?. id ) return ;
57106
58107 setLoading ( true ) ;
59108 try {
60- // Get all trading actions for this user
109+ // Build date range for the selected date using local date parsing
110+ const [ year , month , day ] = selectedDate . split ( '-' ) . map ( Number ) ;
111+ const startOfDay = new Date ( year , month - 1 , day , 0 , 0 , 0 , 0 ) ;
112+ const endOfDay = new Date ( year , month - 1 , day , 23 , 59 , 59 , 999 ) ;
113+
114+ // Get trading actions for this user within the selected date
61115 const { data, error } = await supabase
62116 . from ( 'trading_actions' )
63117 . select ( '*' )
64118 . eq ( 'user_id' , user . id )
119+ . gte ( 'created_at' , startOfDay . toISOString ( ) )
120+ . lte ( 'created_at' , endOfDay . toISOString ( ) )
65121 . order ( 'created_at' , { ascending : false } ) ;
66122
67123 if ( error ) throw error ;
@@ -262,7 +318,7 @@ export default function TradeHistoryTable() {
262318 } else {
263319 console . log ( 'No Alpaca credentials found, skipping order status update' ) ;
264320 }
265- } , [ apiSettings , user ] ) ;
321+ } , [ apiSettings , user , selectedDate ] ) ; // Added selectedDate dependency
266322
267323 // Periodically update Alpaca order status
268324 useEffect ( ( ) => {
@@ -757,27 +813,61 @@ export default function TradeHistoryTable() {
757813 < div className = "flex items-center justify-between" >
758814 < CardTitle className = "text-foreground flex items-center gap-2" >
759815 < TrendingUp className = "h-5 w-5 text-primary" />
760- Complete Trade History
816+ Trade History
761817 </ CardTitle >
762- < Button
763- variant = "ghost"
764- size = "icon"
765- className = "h-7 w-7"
766- onClick = { ( ) => {
767- fetchAllTrades ( ) ;
768- const hasCredentials = apiSettings ?. alpaca_paper_api_key || apiSettings ?. alpaca_live_api_key ;
769- if ( hasCredentials ) {
770- updateAlpacaOrderStatus ( ) ;
771- }
772- } }
773- disabled = { loading }
774- >
775- { loading ? (
776- < Loader2 className = "h-4 w-4 animate-spin" />
777- ) : (
778- < RefreshCw className = "h-4 w-4" />
779- ) }
780- </ Button >
818+
819+ < div className = "flex items-center gap-1" >
820+ < Button
821+ variant = "ghost"
822+ size = "sm"
823+ onClick = { ( ) => navigateDate ( 'prev' ) }
824+ className = "h-8 w-8 p-0 hover:bg-[#fc0]/10 hover:text-[#fc0]"
825+ >
826+ < ChevronLeft className = "h-4 w-4" />
827+ </ Button >
828+
829+ < Button
830+ variant = "outline"
831+ size = "sm"
832+ className = "px-3 min-w-[140px] hover:border-[#fc0] hover:bg-[#fc0]/10 hover:text-[#fc0] transition-all duration-200"
833+ onClick = { jumpToToday }
834+ >
835+ < CalendarIcon className = "h-4 w-4 mr-2" />
836+ { getDateDisplay ( ) }
837+ </ Button >
838+
839+ < Button
840+ variant = "ghost"
841+ size = "sm"
842+ onClick = { ( ) => navigateDate ( 'next' ) }
843+ disabled = { selectedDate === todayString }
844+ className = "h-8 w-8 p-0 hover:bg-[#fc0]/10 hover:text-[#fc0] disabled:opacity-50 disabled:hover:bg-transparent disabled:hover:text-muted-foreground"
845+ >
846+ < ChevronRight className = "h-4 w-4" />
847+ </ Button >
848+
849+ < div className = "ml-2" >
850+ < Button
851+ variant = "ghost"
852+ size = "icon"
853+ className = "h-8 w-8"
854+ onClick = { ( ) => {
855+ fetchAllTrades ( ) ;
856+ const hasCredentials = apiSettings ?. alpaca_paper_api_key || apiSettings ?. alpaca_live_api_key ;
857+ if ( hasCredentials ) {
858+ updateAlpacaOrderStatus ( ) ;
859+ }
860+ } }
861+ disabled = { loading }
862+ >
863+ { loading ? (
864+ < Loader2 className = "h-4 w-4 animate-spin" />
865+ ) : (
866+ < RefreshCw className = "h-4 w-4" />
867+ ) }
868+ </ Button >
869+ </ div >
870+ </ div >
781871 </ div >
782872 </ CardHeader >
783873
0 commit comments