@@ -97,10 +97,15 @@ export function TransactionHistory({ publicKey }) {
9797 const [ loaded , setLoaded ] = useState ( false ) ;
9898 const [ selected , setSelected ] = useState ( null ) ;
9999 const [ filters , setFilters ] = useState ( { type : '' , dateFrom : '' , dateTo : '' } ) ;
100+ const [ cursors , setCursors ] = useState ( [ ] ) ; // ring-buffer for back-pagination (max 50)
101+ const [ error , setError ] = useState ( null ) ;
102+
103+ const MAX_CURSOR_HISTORY = 50 ;
100104 const [ cursors , setCursors ] = useState ( [ ] ) ;
101105
102106 const fetchPage = useCallback ( async ( cursor = null , isBack = false ) => {
103107 setLoading ( true ) ;
108+ setError ( null ) ;
104109 try {
105110 const params = { limit : PAGE_SIZE , ...( cursor ? { cursor } : { } ) } ;
106111 if ( filters . type ) params . type = filters . type ;
@@ -110,6 +115,18 @@ export function TransactionHistory({ publicKey }) {
110115 setTxs ( data . records ) ;
111116 setNextCursor ( data . nextCursor ) ;
112117 setLoaded ( true ) ;
118+
119+ if ( ! isBack && cursor ) {
120+ setCursors ( prev => {
121+ const next = [ ...prev , cursor ] ;
122+ return next . length > MAX_CURSOR_HISTORY ? next . slice ( next . length - MAX_CURSOR_HISTORY ) : next ;
123+ } ) ;
124+ }
125+ } catch ( e ) {
126+ setError ( e ?. response ?. data ?. error ?? e ?. message ?? 'Failed to load transactions.' ) ;
127+ } finally {
128+ setLoading ( false ) ;
129+ }
113130 if ( ! isBack && cursor ) setCursors ( prev => [ ...prev , cursor ] ) ;
114131 } catch { /* errors handled by parent */ }
115132 finally { setLoading ( false ) ; }
@@ -171,7 +188,13 @@ export function TransactionHistory({ publicKey }) {
171188 </ form >
172189
173190 < AnimatePresence mode = "wait" >
174- { loaded && (
191+ { error && (
192+ < motion . div key = "error" className = "tx-error" initial = { { opacity : 0 } } animate = { { opacity : 1 } } exit = { { opacity : 0 } } >
193+ < p > { error } </ p >
194+ < button className = "tx-page-btn" onClick = { ( ) => fetchPage ( cursors [ cursors . length - 1 ] ?? null ) } > ↺ Retry</ button >
195+ </ motion . div >
196+ ) }
197+ { ! error && loaded && (
175198 < motion . div key = "list" initial = { { opacity : 0 } } animate = { { opacity : 1 } } exit = { { opacity : 0 } } >
176199 { txs . length === 0 ? (
177200 < p className = "tx-empty" role = "status" > No transactions found.</ p >
0 commit comments