@@ -4,11 +4,43 @@ import {
4
4
ActivityList ,
5
5
type ActivityCardData ,
6
6
type ActivityCardDetailItem ,
7
+ type ActivityCardActionButton ,
7
8
ProviderItem ,
8
9
} from "@babylonlabs-io/core-ui" ;
10
+ import { useCallback , useState } from "react" ;
11
+ import type { VaultActivity } from "../../mockData/vaultActivities" ;
9
12
import { BorrowFlow } from "../BorrowFlow" ;
13
+ import { RepayFlow } from "../RepayFlow" ;
10
14
import { useActivitiesState } from "./useActivitiesState" ;
11
15
16
+ function getPrimaryAction (
17
+ activity : VaultActivity ,
18
+ hasBorrowed : boolean ,
19
+ isActive : boolean ,
20
+ onBorrow : ( activity : VaultActivity ) => void ,
21
+ onRepay : ( activity : VaultActivity ) => void
22
+ ) : ActivityCardActionButton | undefined {
23
+ if ( hasBorrowed ) {
24
+ return {
25
+ label : "Repay and Withdraw BTC" ,
26
+ onClick : ( ) => onRepay ( activity ) ,
27
+ variant : "outlined" ,
28
+ fullWidth : true ,
29
+ } ;
30
+ }
31
+
32
+ if ( isActive && ! hasBorrowed ) {
33
+ return {
34
+ label : "Borrow USDC" ,
35
+ onClick : ( ) => onBorrow ( activity ) ,
36
+ variant : "outlined" ,
37
+ fullWidth : true ,
38
+ } ;
39
+ }
40
+
41
+ return undefined ;
42
+ }
43
+
12
44
export function Activities ( ) {
13
45
const {
14
46
activities,
@@ -21,6 +53,21 @@ export function Activities() {
21
53
refetchActivities,
22
54
} = useActivitiesState ( ) ;
23
55
56
+ // Repay flow state
57
+ const [ repayFlowOpen , setRepayFlowOpen ] = useState ( false ) ;
58
+ const [ selectedRepayActivity , setSelectedRepayActivity ] = useState < VaultActivity | null > ( null ) ;
59
+
60
+ const handleRepayAndWithdraw = useCallback ( ( activity : VaultActivity ) => {
61
+ console . log ( '[Activities] Repay and withdraw for:' , activity . id ) ;
62
+ setSelectedRepayActivity ( activity ) ;
63
+ setRepayFlowOpen ( true ) ;
64
+ } , [ ] ) ;
65
+
66
+ const handleRepayFlowClose = useCallback ( ( ) => {
67
+ setRepayFlowOpen ( false ) ;
68
+ setSelectedRepayActivity ( null ) ;
69
+ } , [ ] ) ;
70
+
24
71
console . log ( '[Activities] activities:' , activities ) ;
25
72
console . log ( '[Activities] activities.length:' , activities . length ) ;
26
73
@@ -66,30 +113,46 @@ export function Activities() {
66
113
} ;
67
114
68
115
// Check if user has already borrowed (has borrow shares > 0)
69
- const hasBorrowed = activity . morphoPosition && activity . morphoPosition . borrowShares > 0n ;
116
+ const hasBorrowed = ! ! ( activity . morphoPosition && activity . morphoPosition . borrowShares > 0n ) ;
70
117
71
118
// Only active vaults can borrow
72
119
const isActive = activity . status . variant === 'active' ;
73
120
74
- // Build details array, adding borrowing data if available
121
+ // Build main details array
75
122
const details : ActivityCardDetailItem [ ] = [ statusDetail , providersDetail ] ;
76
123
77
- // Add borrowing details if user has borrowed
124
+ // Build optional details array for loan information (shown in separate section)
125
+ const optionalDetails : ActivityCardDetailItem [ ] = [ ] ;
126
+
78
127
if ( activity . borrowingData ) {
79
- details . push ( {
80
- label : "Borrowed" ,
128
+ // Add loan details section header
129
+ optionalDetails . push ( {
130
+ label : (
131
+ < div className = "space-y-1" >
132
+ < div className = "text-base font-semibold text-accent-primary" > Loan Details</ div >
133
+ < div className = "text-xs text-accent-secondary" > Your current loan</ div >
134
+ </ div >
135
+ ) ,
136
+ value : "" ,
137
+ } ) ;
138
+
139
+ // Add loan amount
140
+ optionalDetails . push ( {
141
+ label : "Loan" ,
81
142
value : `${ activity . borrowingData . borrowedAmount } ${ activity . borrowingData . borrowedSymbol } ` ,
82
143
} ) ;
83
- // Only show LTV if it's calculated (non-zero)
84
- // TODO: Implement BTC price oracle to calculate accurate current LTV
144
+
145
+ // Add LTV (only if calculated)
85
146
if ( activity . borrowingData . currentLTV > 0 ) {
86
- details . push ( {
87
- label : "Current LTV" ,
147
+ optionalDetails . push ( {
148
+ label : "LTV" ,
88
149
value : `${ activity . borrowingData . currentLTV } %` ,
89
150
} ) ;
90
151
}
91
- details . push ( {
92
- label : "Max LTV (LLTV)" ,
152
+
153
+ // Add liquidation LTV
154
+ optionalDetails . push ( {
155
+ label : "Liquidation LTV" ,
93
156
value : `${ activity . borrowingData . maxLTV } %` ,
94
157
} ) ;
95
158
}
@@ -99,11 +162,15 @@ export function Activities() {
99
162
icon : activity . collateral . icon ,
100
163
iconAlt : activity . collateral . symbol ,
101
164
details,
102
- // Show borrow button if vault is active and user hasn't borrowed yet
103
- primaryAction : ( isActive && ! hasBorrowed ) ? {
104
- label : activity . action . label ,
105
- onClick : ( ) => handleActivityBorrow ( activity ) ,
106
- } : undefined ,
165
+ optionalDetails : optionalDetails . length > 0 ? optionalDetails : undefined ,
166
+ // Use helper function for cleaner conditional button logic
167
+ primaryAction : getPrimaryAction (
168
+ activity ,
169
+ hasBorrowed ,
170
+ isActive ,
171
+ handleActivityBorrow ,
172
+ handleRepayAndWithdraw
173
+ ) ,
107
174
} ;
108
175
} ) ;
109
176
@@ -123,6 +190,13 @@ export function Activities() {
123
190
onClose = { handleBorrowFlowClose }
124
191
onBorrowSuccess = { refetchActivities }
125
192
/>
193
+
194
+ < RepayFlow
195
+ activity = { selectedRepayActivity }
196
+ isOpen = { repayFlowOpen }
197
+ onClose = { handleRepayFlowClose }
198
+ onRepaySuccess = { refetchActivities }
199
+ />
126
200
</ >
127
201
) ;
128
202
}
0 commit comments