1
1
"use client" ;
2
2
import React , { useCallback , useState } from "react" ;
3
- import { Button , Input , Separator } from "@akashnetwork/ui/components" ;
3
+ import { Button , Input , Popup , Separator } from "@akashnetwork/ui/components" ;
4
4
5
+ import { useWallet } from "@src/context/WalletProvider" ;
5
6
import { ServerForm } from "./ServerForm" ;
6
7
7
8
interface ServerAccessProps {
8
9
onComplete : ( ) => void ;
9
10
}
10
11
12
+ interface NodeCounts {
13
+ controlPlane : number ;
14
+ workerNodes : number ;
15
+ }
16
+
17
+ interface ServerTypeInfo {
18
+ isControlPlane : boolean ;
19
+ nodeNumber : number ;
20
+ }
21
+
11
22
export const ServerAccess : React . FC < ServerAccessProps > = ( { onComplete } ) => {
12
23
const [ numberOfServers , setNumberOfServers ] = useState ( 1 ) ;
13
24
const [ activateServerForm , setActivateServerForm ] = useState ( false ) ;
14
25
const [ currentServer , setCurrentServer ] = useState ( 0 ) ;
26
+ const [ showBalancePopup , setShowBalancePopup ] = useState ( false ) ;
27
+ const [ showNodeDistribution , setShowNodeDistribution ] = useState ( false ) ;
28
+
29
+ const { walletBalances } = useWallet ( ) ;
30
+ const MIN_BALANCE = 5_000_000 ;
31
+ const hasEnoughBalance = ( walletBalances ?. uakt || 0 ) >= MIN_BALANCE ;
32
+
33
+ React . useEffect ( ( ) => {
34
+ if ( ! hasEnoughBalance ) {
35
+ setShowBalancePopup ( true ) ;
36
+ }
37
+ } , [ hasEnoughBalance ] ) ;
15
38
16
39
const handleServerFormSubmit = useCallback ( ( ) => {
17
40
if ( currentServer + 1 >= numberOfServers ) {
@@ -25,9 +48,59 @@ export const ServerAccess: React.FC<ServerAccessProps> = ({ onComplete }) => {
25
48
setNumberOfServers ( value ) ;
26
49
} , [ ] ) ;
27
50
51
+ const calculateNodeDistribution = useCallback ( ( totalNodes : number ) : NodeCounts => {
52
+ if ( totalNodes <= 3 ) {
53
+ return { controlPlane : 1 , workerNodes : totalNodes - 1 } ;
54
+ }
55
+ if ( totalNodes <= 5 ) {
56
+ return { controlPlane : 3 , workerNodes : totalNodes - 3 } ;
57
+ }
58
+
59
+ const baseControlPlane = 3 ;
60
+ const additionalPairs = Math . floor ( ( totalNodes - 1 ) / 50 ) ;
61
+ const controlPlane = Math . min ( baseControlPlane + additionalPairs * 2 , 11 ) ; // Cap at 11 control plane nodes
62
+ return { controlPlane, workerNodes : totalNodes - controlPlane } ;
63
+ } , [ ] ) ;
64
+
65
+ const handleNextClick = useCallback ( ( ) => {
66
+ if ( ! hasEnoughBalance ) {
67
+ setShowBalancePopup ( true ) ;
68
+ return ;
69
+ }
70
+ setShowNodeDistribution ( true ) ;
71
+ } , [ hasEnoughBalance ] ) ;
72
+
73
+ const handleDistributionNext = useCallback ( ( ) => {
74
+ setShowNodeDistribution ( false ) ;
75
+ setActivateServerForm ( true ) ;
76
+ } , [ ] ) ;
77
+
78
+ const handleClosePopup = useCallback ( ( ) => {
79
+ setShowBalancePopup ( false ) ;
80
+ } , [ ] ) ;
81
+
82
+ const getCurrentServerType = useCallback (
83
+ ( serverIndex : number ) : ServerTypeInfo => {
84
+ const { controlPlane } = calculateNodeDistribution ( numberOfServers ) ;
85
+
86
+ if ( serverIndex < controlPlane ) {
87
+ return {
88
+ isControlPlane : true ,
89
+ nodeNumber : serverIndex + 1
90
+ } ;
91
+ }
92
+
93
+ return {
94
+ isControlPlane : false ,
95
+ nodeNumber : serverIndex - controlPlane + 1
96
+ } ;
97
+ } ,
98
+ [ calculateNodeDistribution , numberOfServers ]
99
+ ) ;
100
+
28
101
return (
29
102
< div className = "flex flex-col items-center pt-10" >
30
- { ! activateServerForm ? (
103
+ { ! activateServerForm && ! showNodeDistribution ? (
31
104
< div className = "space-y-6" >
32
105
< div className = "flex items-center space-x-4" >
33
106
< h3 className = "text-xl font-bold" > Server Count</ h3 >
@@ -50,13 +123,71 @@ export const ServerAccess: React.FC<ServerAccessProps> = ({ onComplete }) => {
50
123
< div className = "flex w-full justify-between" >
51
124
< div className = "flex justify-start" > </ div >
52
125
< div className = "flex justify-end" >
53
- < Button onClick = { ( ) => setActivateServerForm ( true ) } > Next</ Button >
126
+ < Button onClick = { handleNextClick } > Next</ Button >
127
+ </ div >
128
+ </ div >
129
+ </ div >
130
+ ) : showNodeDistribution ? (
131
+ < div className = "space-y-6" >
132
+ < div className = "flex gap-6" >
133
+ < div className = "rounded-lg border p-6 text-center" >
134
+ < p className = "mb-4 text-3xl font-bold" > { calculateNodeDistribution ( numberOfServers ) . controlPlane } </ p >
135
+ < h3 className = "mb-2 text-xl font-bold" > Control Plane Nodes</ h3 >
136
+ < p className = "text-sm" > Manages the cluster operations & run your workloads </ p >
137
+ </ div >
138
+ < div className = "rounded-lg border p-6 text-center" >
139
+ < p className = "mb-4 text-3xl font-bold" > { calculateNodeDistribution ( numberOfServers ) . workerNodes } </ p >
140
+ < h3 className = "mb-2 text-xl font-bold" > Worker Nodes</ h3 >
141
+ < p className = "text-sm" > Runs your workloads</ p >
54
142
</ div >
55
143
</ div >
144
+ < div className = "flex w-full justify-between" >
145
+ < Button variant = "ghost" onClick = { ( ) => setShowNodeDistribution ( false ) } >
146
+ Back
147
+ </ Button >
148
+ < Button onClick = { handleDistributionNext } > Next</ Button >
149
+ </ div >
56
150
</ div >
57
151
) : (
58
- < ServerForm key = { currentServer } currentServerNumber = { currentServer } onComplete = { handleServerFormSubmit } />
152
+ < ServerForm key = { currentServer } currentServerNumber = { currentServer } onComplete = { handleServerFormSubmit } { ... getCurrentServerType ( currentServer ) } />
59
153
) }
154
+
155
+ < Popup
156
+ fullWidth
157
+ open = { showBalancePopup }
158
+ variant = "custom"
159
+ actions = { [
160
+ {
161
+ label : "Close" ,
162
+ color : "primary" ,
163
+ variant : "ghost" ,
164
+ side : "left" ,
165
+ onClick : handleClosePopup
166
+ }
167
+ ] }
168
+ onClose = { handleClosePopup }
169
+ maxWidth = "xs"
170
+ enableCloseOnBackdropClick
171
+ title = "Insufficient Balance"
172
+ >
173
+ < div >
174
+ < div className = "pb-2" >
175
+ < p >
176
+ You need at least < strong > 5 AKT</ strong > to become a provider.
177
+ < br />
178
+ Every lease created on the Akash network requires < strong > 0.5 AKT</ strong > to be locked in escrow.
179
+ < br />
180
+ Please ensure you have enough funds to cover your resources.
181
+ </ p >
182
+ </ div >
183
+ < Separator />
184
+ < div >
185
+ < p className = "pt-2" >
186
+ You currently have < strong > { ( walletBalances ?. uakt || 0 ) / 1000000 } AKT</ strong > .
187
+ </ p >
188
+ </ div >
189
+ </ div >
190
+ </ Popup >
60
191
</ div >
61
192
) ;
62
193
} ;
0 commit comments