@@ -10,27 +10,34 @@ import { useIntl } from "react-intl";
1010import { Uptime } from "./uptime" ;
1111
1212export default function ProvidersCard ( { provider } : any ) {
13- const activeCPU = provider . isOnline ? provider . activeStats . cpu / 1000 : 0 ;
14- const pendingCPU = provider . isOnline ? provider . pendingStats . cpu / 1000 : 0 ;
15- const totalCPU = provider . isOnline
16- ? ( provider . availableStats . cpu +
17- provider . pendingStats . cpu +
18- provider . activeStats . cpu ) /
13+ // Safely access stats with defaults
14+ const activeStats = provider . activeStats || { cpu : 0 , memory : 0 , gpu : 0 , storage : 0 } ;
15+ const pendingStats = provider . pendingStats || { cpu : 0 , memory : 0 , gpu : 0 , storage : 0 } ;
16+ const availableStats = provider . availableStats || { cpu : 0 , memory : 0 , gpu : 0 , storage : 0 } ;
17+
18+ const isOnline = provider . isOnline ?? false ;
19+
20+ const activeCPU = isOnline ? ( activeStats . cpu || 0 ) / 1000 : 0 ;
21+ const pendingCPU = isOnline ? ( pendingStats . cpu || 0 ) / 1000 : 0 ;
22+ const totalCPU = isOnline
23+ ? ( ( availableStats . cpu || 0 ) +
24+ ( pendingStats . cpu || 0 ) +
25+ ( activeStats . cpu || 0 ) ) /
1926 1000
2027 : 0 ;
2128
22- const gpuModels = provider . hardwareGpuModels . map ( ( gpu : any ) =>
29+ const gpuModels = ( provider . hardwareGpuModels || [ ] ) . map ( ( gpu : any ) =>
2330 gpu . substring ( gpu . lastIndexOf ( " " ) + 1 , gpu . length ) ,
2431 ) ;
2532
26- const _activeMemory = provider . isOnline
27- ? bytesToShrink ( provider . activeStats . memory + provider . pendingStats . memory )
33+ const _activeMemory = isOnline && ( activeStats . memory || pendingStats . memory )
34+ ? bytesToShrink ( ( activeStats . memory || 0 ) + ( pendingStats . memory || 0 ) )
2835 : null ;
29- const _totalMemory = provider . isOnline
36+ const _totalMemory = isOnline && ( availableStats . memory || pendingStats . memory || activeStats . memory )
3037 ? bytesToShrink (
31- provider . availableStats . memory +
32- provider . pendingStats . memory +
33- provider . activeStats . memory ,
38+ ( availableStats . memory || 0 ) +
39+ ( pendingStats . memory || 0 ) +
40+ ( activeStats . memory || 0 ) ,
3441 )
3542 : null ;
3643
@@ -42,23 +49,23 @@ export default function ProvidersCard({ provider }: any) {
4249 < div className = "flex w-full flex-col overflow-hidden rounded-lg border bg-background2 p-4" >
4350 < div className = "flex gap-x-[10px]" >
4451 < div className = "flex h-12 w-12 items-center justify-center rounded border bg-background text-xl font-extrabold uppercase" >
45- { name ?. [ 0 ] }
46- { name ?. [ 1 ] }
52+ { name ?. [ 0 ] || provider . owner ?. [ 5 ] || "?" }
53+ { name ?. [ 1 ] || provider . owner ?. [ 6 ] || "" }
4754 </ div >
4855
4956 < div >
5057 < p className = "break-words text-base font-semibold text-foreground" >
51- { provider . name ? .length > 20 ? (
58+ { provider . name && provider . name . length > 20 ? (
5259 < span > { getSplitText ( provider . name , 4 , 13 ) } </ span >
5360 ) : (
54- < span > { provider . name } </ span >
61+ < span > { provider . name || provider . owner || "Unknown Provider" } </ span >
5562 ) }
5663 </ p >
5764 < p className = "break-words text-xs text-cardGray" >
58- { provider . hostUri ? .length > 20 ? (
65+ { provider . hostUri && provider . hostUri . length > 20 ? (
5966 < span > { getSplitText ( provider . hostUri , 4 , 13 ) } </ span >
6067 ) : (
61- < span > { provider . hostUri } </ span >
68+ < span > { provider . hostUri || provider . owner || "" } </ span >
6269 ) }
6370 </ p >
6471 </ div >
@@ -76,89 +83,99 @@ export default function ProvidersCard({ provider }: any) {
7683 </ p >
7784 </ div >
7885
79- < div className = "mt-3 flex flex-col items-center justify-between " >
80- < div className = "flex w-full items-center justify-between" >
81- < p className = "text-xs font-medium" > { `Uptime: ${ intl . formatNumber (
82- provider . uptime7d ,
83- {
84- style : "percent" ,
85- maximumFractionDigits : 0 ,
86- } ,
87- ) } `} </ p >
88- < p className = "text-xs font-medium text-foreground" > 7 D</ p >
89- </ div >
86+ { provider . uptime7d !== undefined && (
87+ < div className = "mt-3 flex flex-col items-center justify-between " >
88+ < div className = "flex w-full items-center justify-between" >
89+ < p className = "text-xs font-medium" > { `Uptime: ${ intl . formatNumber (
90+ provider . uptime7d || 0 ,
91+ {
92+ style : "percent" ,
93+ maximumFractionDigits : 0 ,
94+ } ,
95+ ) } `} </ p >
96+ < p className = "text-xs font-medium text-foreground" > 7 D</ p >
97+ </ div >
9098
91- < div className = " mt-3 w-full" >
92- < Uptime value = { provider . uptime7d } />
99+ < div className = " mt-3 w-full" >
100+ < Uptime value = { provider . uptime7d || 0 } />
101+ </ div >
93102 </ div >
94- </ div >
103+ ) }
95104
96105 < div className = " mt-3 flex flex-col gap-y-[6px]" >
97- < Stats
98- componentName = "CPU:"
99- isOver60Percent = {
100- Math . round ( ( ( activeCPU + pendingCPU ) / totalCPU ) * 100 ) > 60
101- }
102- value = { `${ Math . round ( activeCPU + pendingCPU ) } / ${ Math . round (
103- totalCPU ,
104- ) } `}
105- />
106+ { totalCPU > 0 && (
107+ < Stats
108+ componentName = "CPU:"
109+ isOver60Percent = {
110+ totalCPU > 0 && Math . round ( ( ( activeCPU + pendingCPU ) / totalCPU ) * 100 ) > 60
111+ }
112+ value = { `${ Math . round ( activeCPU + pendingCPU ) } / ${ Math . round (
113+ totalCPU ,
114+ ) } `}
115+ />
116+ ) }
106117
107- < div className = "flex w-full items-center justify-between rounded-sm border p-2" >
108- < p className = " text-xs font-medium" > GPU:</ p >
118+ { gpuModels . length > 0 && (
119+ < div className = "flex w-full items-center justify-between rounded-sm border p-2" >
120+ < p className = " text-xs font-medium" > GPU:</ p >
109121
110- < div className = "flex items-center justify-center gap-x-1" >
111- { gpuModels . slice ( 0 , 1 ) . map ( ( gpu : any , i : any ) => (
112- < p
113- key = { i }
114- className = "rounded-full border bg-[#F4F4F4] px-2 text-2xs font-bold text-cardGray dark:bg-darkGray dark:text-para"
115- >
116- { gpu }
117- </ p >
118- ) ) }
122+ < div className = "flex items-center justify-center gap-x-1" >
123+ { gpuModels . slice ( 0 , 1 ) . map ( ( gpu : any , i : any ) => (
124+ < p
125+ key = { i }
126+ className = "rounded-full border bg-[#F4F4F4] px-2 text-2xs font-bold text-cardGray dark:bg-darkGray dark:text-para"
127+ >
128+ { gpu }
129+ </ p >
130+ ) ) }
119131
120- { gpuModels . length > 2 && (
121- < HoverCard >
122- < HoverCardTrigger >
123- < p className = "rounded-full border bg-[#F4F4F4] px-2 text-xs font-bold text-cardGray dark:bg-darkGray dark:text-para" >
124- { `+${ gpuModels . length - 1 } ` }
125- </ p >
126- </ HoverCardTrigger >
127- < HoverCardContent >
128- < div className = "flex w-52 flex-wrap gap-x-2 gap-y-2 rounded-lg bg-background2 p-2" >
129- { gpuModels . slice ( 1 ) . map ( ( gpu : any , i : any ) => (
130- < p
131- key = { i }
132- className = "rounded-full border bg-[#F4F4F4] px-2 text-xs font-bold text-cardGray"
133- >
134- { gpu }
135- </ p >
136- ) ) }
137- </ div >
138- </ HoverCardContent >
139- </ HoverCard >
140- ) }
132+ { gpuModels . length > 2 && (
133+ < HoverCard >
134+ < HoverCardTrigger >
135+ < p className = "rounded-full border bg-[#F4F4F4] px-2 text-xs font-bold text-cardGray dark:bg-darkGray dark:text-para" >
136+ { `+${ gpuModels . length - 1 } ` }
137+ </ p >
138+ </ HoverCardTrigger >
139+ < HoverCardContent >
140+ < div className = "flex w-52 flex-wrap gap-x-2 gap-y-2 rounded-lg bg-background2 p-2" >
141+ { gpuModels . slice ( 1 ) . map ( ( gpu : any , i : any ) => (
142+ < p
143+ key = { i }
144+ className = "rounded-full border bg-[#F4F4F4] px-2 text-xs font-bold text-cardGray"
145+ >
146+ { gpu }
147+ </ p >
148+ ) ) }
149+ </ div >
150+ </ HoverCardContent >
151+ </ HoverCard >
152+ ) }
153+ </ div >
141154 </ div >
142- </ div >
155+ ) }
143156
144- < Stats
145- componentName = "Memory:"
146- value = { `${ roundDecimal (
147- _activeMemory ?. value as number ,
148- 0 ,
149- ) } ${ _activeMemory ?. unit } / ${ roundDecimal (
150- _totalMemory ?. value as number ,
151- 0 ,
152- ) } ${ _totalMemory ?. unit } `}
153- isOver60Percent = {
154- ( provider . activeStats . memory + provider . pendingStats . memory ) /
155- ( provider . availableStats . memory +
156- provider . pendingStats . memory +
157- provider . activeStats . memory ) >
158- 0.64
159- }
160- />
161- < Stats componentName = "Active Leases:" value = { provider . leaseCount } />
157+ { _activeMemory && _totalMemory && (
158+ < Stats
159+ componentName = "Memory:"
160+ value = { `${ roundDecimal (
161+ _activeMemory ?. value as number ,
162+ 0 ,
163+ ) } ${ _activeMemory ?. unit } / ${ roundDecimal (
164+ _totalMemory ?. value as number ,
165+ 0 ,
166+ ) } ${ _totalMemory ?. unit } `}
167+ isOver60Percent = {
168+ ( ( activeStats . memory || 0 ) + ( pendingStats . memory || 0 ) ) /
169+ ( ( availableStats . memory || 0 ) +
170+ ( pendingStats . memory || 0 ) +
171+ ( activeStats . memory || 0 ) ) >
172+ 0.64
173+ }
174+ />
175+ ) }
176+ { provider . leaseCount !== undefined && (
177+ < Stats componentName = "Active Leases:" value = { provider . leaseCount || 0 } />
178+ ) }
162179
163180 { provider . ipRegion && provider . ipCountry && (
164181 < Stats
0 commit comments