1- import React from 'react' ;
2- import Console from '@/components/server/Console' ;
1+ import React , { lazy , useEffect , useState } from 'react' ;
32import { ServerContext } from '@/state/server' ;
43import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
54import { faServer } from '@fortawesome/free-solid-svg-icons/faServer' ;
65import { faCircle } from '@fortawesome/free-solid-svg-icons/faCircle' ;
76import classNames from 'classnames' ;
7+ import styled from 'styled-components' ;
8+ import { faMemory } from '@fortawesome/free-solid-svg-icons/faMemory' ;
9+ import { faMicrochip } from '@fortawesome/free-solid-svg-icons/faMicrochip' ;
10+ import { bytesToHuman } from '@/helpers' ;
11+ import Spinner from '@/components/elements/Spinner' ;
12+
13+ const GreyBox = styled . div `
14+ ${ tw `mt-4 shadow-md bg-neutral-700 rounded p-3 flex text-xs` }
15+ ` ;
16+
17+ const ChunkedConsole = lazy ( ( ) => import ( '@/components/server/Console' ) ) ;
818
919export default ( ) => {
20+ const [ memory , setMemory ] = useState ( 0 ) ;
21+ const [ cpu , setCpu ] = useState ( 0 ) ;
22+
1023 const server = ServerContext . useStoreState ( state => state . server . data ! ) ;
1124 const status = ServerContext . useStoreState ( state => state . status . value ) ;
1225
26+ const { connected, instance } = ServerContext . useStoreState ( state => state . socket ) ;
27+
28+ const statsListener = ( data : string ) => {
29+ let stats : any = { } ;
30+ try {
31+ stats = JSON . parse ( data ) ;
32+ } catch ( e ) {
33+ return ;
34+ }
35+
36+ setMemory ( stats . memory_bytes ) ;
37+ setCpu ( stats . cpu_absolute ) ;
38+ } ;
39+
40+ useEffect ( ( ) => {
41+ if ( ! connected || ! instance ) {
42+ return ;
43+ }
44+
45+ instance . addListener ( 'stats' , statsListener ) ;
46+
47+ return ( ) => {
48+ instance . removeListener ( 'stats' , statsListener ) ;
49+ } ;
50+ } , [ connected ] ) ;
51+
1352 return (
1453 < div className = { 'my-10 flex' } >
1554 < div className = { 'flex-1 ml-4' } >
@@ -23,20 +62,51 @@ export default () => {
2362 < p className = { 'text-xs uppercase' } >
2463 < FontAwesomeIcon
2564 icon = { faCircle }
65+ fixedWidth = { true }
2666 className = { classNames ( 'mr-1' , {
2767 'text-red-500' : status === 'offline' ,
28- 'text-yellow-500' : [ 'running' , 'offline' ] . indexOf ( status ) < 0 ,
68+ 'text-yellow-500' : [ 'running' , 'offline' ] . indexOf ( status ) < 0 ,
2969 'text-green-500' : status === 'running' ,
3070 } ) }
3171 />
3272 { status }
3373 </ p >
74+ < p className = { 'text-xs mt-2' } >
75+ < FontAwesomeIcon
76+ icon = { faMemory }
77+ fixedWidth = { true }
78+ className = { 'mr-1' }
79+ />
80+ { bytesToHuman ( memory ) }
81+ < span className = { 'text-neutral-500' } > / { server . limits . memory } MB</ span >
82+ </ p >
83+ < p className = { 'text-xs mt-2' } >
84+ < FontAwesomeIcon
85+ icon = { faMicrochip }
86+ fixedWidth = { true }
87+ className = { 'mr-1' }
88+ />
89+ { cpu . toFixed ( 2 ) } %
90+ </ p >
3491 </ div >
3592 </ div >
93+ < GreyBox className = { 'justify-center' } >
94+ < button className = { 'btn btn-secondary btn-xs mr-2' } > Start</ button >
95+ < button className = { 'btn btn-secondary btn-xs mr-2' } > Restart</ button >
96+ < button className = { 'btn btn-red btn-xs' } > Stop</ button >
97+ </ GreyBox >
3698 </ div >
37- < div className = { 'mx-4 w-3/4 mr-4' } >
38- < Console />
39- </ div >
99+ < React . Suspense
100+ fallback = {
101+ < div className = { 'mx-4 w-3/4 mr-4 flex items-center justify-center' } >
102+ < Spinner centered = { true } size = { 'normal' } />
103+ </ div >
104+ }
105+ >
106+ < div className = { 'mx-4 w-3/4 mr-4' } >
107+ < ChunkedConsole />
108+ </ div >
109+ </ React . Suspense >
40110 </ div >
41111 ) ;
42112} ;
0 commit comments