11import React , { useEffect , useState } from "react" ;
2- import { useState , useEffect } from "react" ;
3- import { Activity , ShieldCheck , TrendingUp , Wallet as WalletIcon } from "./icons" ;
2+ import { Activity , ShieldCheck , TrendingUp , Wallet as WalletIcon , AlertTriangle , Info } from "./icons" ;
43import { hasCustomRpcConfig , networkConfig } from "../config/network" ;
54import { useVault } from "../context/VaultContext" ;
65import ApiStatusBanner from "./ApiStatusBanner" ;
@@ -11,14 +10,43 @@ import { FormField, SubmitButton } from "../forms";
1110import CopyButton from "./CopyButton" ;
1211import { useDepositMutation , useWithdrawMutation } from "../hooks/useVaultMutations" ;
1312import TransactionStatus , { type ActionStatus } from "./TransactionStatus" ;
14- import { useDepositMutation , useWithdrawMutation } from "../hooks/useVaultMutations" ;
15- import CopyButton from "./CopyButton" ;
1613
1714interface VaultDashboardProps {
1815 walletAddress : string | null ;
1916 usdcBalance ?: number ;
2017}
2118
19+ const VaultCapWarning : React . FC < { utilization : number ; isReached : boolean } > = ( { utilization, isReached } ) => {
20+ const percent = ( utilization * 100 ) . toFixed ( 1 ) ;
21+
22+ return (
23+ < div
24+ className = "glass-panel"
25+ style = { {
26+ padding : "16px" ,
27+ marginBottom : "24px" ,
28+ border : `1px solid ${ isReached ? 'var(--text-error)' : 'var(--text-warning)' } ` ,
29+ background : isReached ? 'rgba(255, 69, 58, 0.1)' : 'rgba(255, 159, 10, 0.1)' ,
30+ display : "flex" ,
31+ alignItems : "flex-start" ,
32+ gap : "12px"
33+ } }
34+ >
35+ { isReached ? < AlertTriangle color = "var(--text-error)" size = { 20 } /> : < Info color = "var(--text-warning)" size = { 20 } /> }
36+ < div >
37+ < div style = { { fontWeight : 600 , color : isReached ? 'var(--text-error)' : 'var(--text-warning)' , marginBottom : "4px" } } >
38+ { isReached ? 'Vault Capacity Reached' : 'Vault Near Capacity' }
39+ </ div >
40+ < div style = { { fontSize : "0.85rem" , color : "var(--text-secondary)" , lineHeight : "1.4" } } >
41+ { isReached
42+ ? `This vault has reached its maximum deposit cap of ${ percent } %. Deposits are temporarily disabled.`
43+ : `This vault is at ${ percent } % capacity. New deposits may be restricted soon.` }
44+ </ div >
45+ </ div >
46+ </ div >
47+ ) ;
48+ } ;
49+
2250function buildFakeTxHash ( walletAddress : string , action : "deposit" | "withdraw" , amount : number ) : string {
2351 const seed = `${ walletAddress } -${ action } -${ amount . toFixed ( 2 ) } -${ Date . now ( ) } ` ;
2452 let hash = "" ;
@@ -304,72 +332,58 @@ const VaultDashboard: React.FC<VaultDashboardProps> = ({
304332
305333 { ( [ "deposit" , "withdraw" ] as const ) . map ( ( tab ) => (
306334 < TabsContent key = { tab } value = { tab } >
335+ { ( isCapReached || isCapWarning ) && tab === "deposit" && (
336+ < VaultCapWarning utilization = { utilization } isReached = { isCapReached } />
337+ ) }
307338 < form
308339 onSubmit = { ( event ) => {
309340 event . preventDefault ( ) ;
310341 void handleTransaction ( tab ) ;
311342 } }
312343 >
313- < div style = { { marginBottom : "24px" } } >
314- < div className = "flex justify-between items-center" style = { { marginBottom : "16px" } } >
315- < div style = { { color : "var(--text-secondary)" , fontSize : "0.9rem" } } >
316- { tab === "deposit" ? "Amount to deposit" : "Amount to withdraw" }
317- </ div >
318- < div style = { { color : "var(--text-secondary)" , fontSize : "0.85rem" } } >
319- Balance:{ " " }
320- < span style = { { color : "var(--text-primary)" , fontWeight : 600 } } >
321- { walletAddress ? availableBalance . toFixed ( 2 ) : "0.00" }
322- </ span >
344+ < div style = { { marginBottom : "24px" } } >
345+ < div className = "flex justify-between items-center" style = { { marginBottom : "16px" } } >
346+ < div style = { { color : "var(--text-secondary)" , fontSize : "0.9rem" } } >
347+ { tab === "deposit" ? "Amount to deposit" : "Amount to withdraw" }
348+ </ div >
349+ < div style = { { color : "var(--text-secondary)" , fontSize : "0.85rem" } } >
350+ Balance:{ " " }
351+ < span style = { { color : "var(--text-primary)" , fontWeight : 600 } } >
352+ { walletAddress ? availableBalance . toFixed ( 2 ) : "0.00" }
353+ </ span >
354+ </ div >
323355 </ div >
324- </ div >
325356
326- < FormField
327- label = { tab === "deposit" ? "Deposit amount" : "Withdrawal amount" }
328- name = { `${ tab } -amount` }
329- type = "number"
330- placeholder = "0.00"
331- value = { amount }
332- onChange = { ( event ) => setAmount ( event . target . value ) }
333- disabled = { isBusy }
334- />
357+ < FormField
358+ label = { tab === "deposit" ? "Deposit amount" : "Withdrawal amount" }
359+ name = { `${ tab } -amount` }
360+ type = "number"
361+ placeholder = "0.00"
362+ value = { amount }
363+ onChange = { ( event ) => setAmount ( event . target . value ) }
364+ disabled = { isBusy || ( tab === "deposit" && isCapReached ) }
365+ />
335366
336- < div className = "flex justify-between items-center" style = { { margin : "16px 0 24px" } } >
337- < span style = { { color : "var(--text-secondary)" , fontSize : "0.85rem" } } > Asset: USDC</ span >
338- < button
339- type = "button"
340- className = "btn btn-outline"
341- onClick = { ( ) => setAmount ( availableBalance . toFixed ( 2 ) ) }
342- disabled = { ! walletAddress || availableBalance <= 0 || isBusy }
343- >
344- MAX
345- </ button >
367+ < div className = "flex justify-between items-center" style = { { margin : "16px 0 24px" } } >
368+ < span style = { { color : "var(--text-secondary)" , fontSize : "0.85rem" } } > Asset: USDC</ span >
369+ < button
370+ type = "button"
371+ className = "btn btn-outline"
372+ onClick = { ( ) => setAmount ( availableBalance . toFixed ( 2 ) ) }
373+ disabled = { ! walletAddress || availableBalance <= 0 || isBusy || ( tab === "deposit" && isCapReached ) }
374+ >
375+ MAX
376+ </ button >
377+ </ div >
346378 </ div >
347379
348380 < SubmitButton
349381 loading = { isBusy && activeTab === tab }
350- disabled = { ! walletAddress || isBusy || ! amount || Number ( amount ) <= 0 }
351- label = { tab === "deposit" ? " Approve & Deposit" : "Withdraw Funds" }
382+ disabled = { ! walletAddress || isBusy || ! amount || Number ( amount ) <= 0 || ( tab === "deposit" && isCapReached ) }
383+ label = { tab === "deposit" ? ( isCapReached ? "Vault is full" : " Approve & Deposit") : "Withdraw Funds" }
352384 loadingLabel = "Waiting for confirmation..."
353385 />
354386 </ form >
355- Balance: < span style = { { color : "var(--text-primary)" , fontWeight : 600 } } > { availableBalance . toFixed ( 2 ) } </ span >
356- </ div >
357- </ div >
358-
359- < div className = "input-group" >
360- < div className = "input-wrapper" >
361- < span style = { { color : "var(--text-secondary)" , paddingRight : "12px" , borderRight : "1px solid var(--border-glass)" , marginRight : "16px" } } > USDC</ span >
362- < input className = "input-field" type = "number" placeholder = "0.00" value = { amount } onChange = { ( e ) => setAmount ( e . target . value ) } disabled = { isProcessing !== null } />
363- < button className = "btn-max" onClick = { ( ) => setAmount ( availableBalance . toFixed ( 2 ) ) } disabled = { ! walletAddress || availableBalance <= 0 || isProcessing !== null } >
364- MAX
365- </ button >
366- </ div >
367- < / d i v >
368- </div >
369-
370- < button className = "btn btn-primary" style = { { width : "100%" , padding : "16px" } } onClick = { ( ) => handleTransaction ( tab ) } disabled = { isProcessing !== null || ! amount || Number ( amount ) <= 0 } >
371- { isProcessing === tab ? "Processing..." : tab === "deposit" ? "Approve & Deposit" : "Withdraw Funds" }
372- </ button >
373387 </ TabsContent >
374388 ) ) }
375389 </ Tabs >
0 commit comments