From: charleswrayjr Date: Tue, 9 Sep 2025 18:34:24 +0000 (-0500) Subject: Adding a server status dialog. X-Git-Url: https://git.phasecustomsoft.com/static/git-favicon.png?a=commitdiff_plain;h=e33c96e429f55b8a4e7efdc4d6df27c280add5d4;p=phs-admin.git Adding a server status dialog. --- diff --git a/src/app/components/VPN/VPN.helpers.js b/src/app/components/VPN/VPN.helpers.js new file mode 100644 index 0000000..e69de29 diff --git a/src/app/components/VPN/VPNContext.jsx b/src/app/components/VPN/VPNContext.jsx index 66a246f..266f25f 100644 --- a/src/app/components/VPN/VPNContext.jsx +++ b/src/app/components/VPN/VPNContext.jsx @@ -1,6 +1,6 @@ -import React, { createContext, useState, useContext, useEffect } from 'react'; +import React, { createContext, useContext, useEffect, useState } from 'react'; import { VPNService } from '../../services'; -import { CreateVPNClientDialog, ConfirmRevoke } from '../index'; +import { ConfirmRevoke, CreateVPNClientDialog, VPNStatusDialog } from '../index'; const VPNContext = createContext( undefined ); @@ -13,6 +13,14 @@ export const VPNProvider = ( { children } ) => { const [availableClients, setAvailableClients] = useState( [] ); const [message, setMessage] = useState( '' ); const [createOpen, setCreateOpen] = useState( false ); + const [statusOpen, setStatusOpen] = useState( false ); + const [serverStatus, setServerStatus] = useState( {} ); + + const fetchServerStatus = async () => { + await VPNService.getServerStatus() + .then( res => setServerStatus( res ) ) + .catch( err => setMessage( err ) ); + }; const fetchClients = async () => { await VPNService.fetchClients() @@ -43,10 +51,12 @@ export const VPNProvider = ( { children } ) => { useEffect( () => { fetchClients().catch( e => setMessage( e ) ); fetchAvailableClients().catch( e => setMessage( e ) ); + fetchServerStatus().catch( e => setMessage( e ) ); const interval = setInterval( () => { fetchClients().catch( e => setMessage( e ) ); fetchAvailableClients().catch( e => setMessage( e ) ); + fetchServerStatus().catch( e => setMessage( e ) ); }, 10000 * 120 ); return () => clearInterval( interval ); @@ -64,11 +74,22 @@ export const VPNProvider = ( { children } ) => { createOpen, setCreateOpen, handleCreateClientSubmit, - handleRevokeClientSubmit + handleRevokeClientSubmit, + statusOpen, + setStatusOpen, + serverStatus, + setServerStatus }; return - {revokeOpen && setRevokeOpen(false)} onConfirm={handleRevokeClientSubmit}/>} - {createOpen && setCreateOpen(false)} onCreate={handleCreateClientSubmit}/>} + { revokeOpen && setRevokeOpen( false ) } + onConfirm={ handleRevokeClientSubmit }/> } + { createOpen && setCreateOpen( false ) } + onCreate={ handleCreateClientSubmit }/> } + { statusOpen && setStatusOpen( false ) } + status={ serverStatus }/> } { children }; }; diff --git a/src/app/components/VPN/VPNStatusDialog.jsx b/src/app/components/VPN/VPNStatusDialog.jsx new file mode 100644 index 0000000..3a25266 --- /dev/null +++ b/src/app/components/VPN/VPNStatusDialog.jsx @@ -0,0 +1,13 @@ +import { Dialog, DialogTitle, DialogContent, DialogActions, Button} from '@mui/material'; + +export default function VPNStatusDialog( { open, onClose, status } ) { + return ( + + VPN Status + { status } + + + + + ); +}; \ No newline at end of file diff --git a/src/app/components/index.js b/src/app/components/index.js index 9467176..7e4e52e 100644 --- a/src/app/components/index.js +++ b/src/app/components/index.js @@ -1,4 +1,6 @@ import ConfirmRevoke from './VPN/ConfirmRevoke'; import CreateVPNClientDialog from './VPN/CreateVPNClientDialog'; +import VPNStatusDialog from './VPN/VPNStatusDialog'; +export * from './VPN/VPNContext'; -export { ConfirmRevoke, CreateVPNClientDialog }; \ No newline at end of file +export { ConfirmRevoke, CreateVPNClientDialog, VPNStatusDialog }; \ No newline at end of file diff --git a/src/app/routes.js b/src/app/routes.js index c18771c..f31818d 100755 --- a/src/app/routes.js +++ b/src/app/routes.js @@ -1,16 +1,16 @@ import { Route, Routes } from 'react-router-dom'; import { Login, NotFound, Dashboard, Git, VPN, Docker } from './views'; -import { VPNProvider } from './components/VPN/VPNContext'; +import { VPNProvider } from './components/'; export default function AppRoutes() { return ( - } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> ); }; diff --git a/src/app/services/VPN/VPNConfig.js b/src/app/services/VPN/VPNConfig.js index b398f39..17b8750 100644 --- a/src/app/services/VPN/VPNConfig.js +++ b/src/app/services/VPN/VPNConfig.js @@ -3,7 +3,10 @@ const VPNConfig = { create: `${base}create-client/`, delete: `${base}revoke-client/`, index: `${base}clients/`, - availableClients: `${base}available-clients/` + availableClients: `${base}available-clients/`, + getStatus: `${base}status/`, + disconnect: `${base}disconnect/`, + restart: `${base}restart/` }; export default VPNConfig; \ No newline at end of file diff --git a/src/app/services/VPN/VPNService.js b/src/app/services/VPN/VPNService.js index 6b2ffdf..11feb3f 100644 --- a/src/app/services/VPN/VPNService.js +++ b/src/app/services/VPN/VPNService.js @@ -6,63 +6,96 @@ class VPNService { fetchClients = () => { return new Promise( async ( resolve ) => { try { - const response = await axios.get(`${base_url}${VPNConfig.index}`); - resolve(response.data.clients); + const response = await axios.get( `${ base_url }${ VPNConfig.index }` ); + resolve( response.data.clients ); } catch (error) { - resolve(`Error: ${error.response?.data?.error || 'Failed to fetch clients'}`); + resolve( `Error: ${ error.response?.data?.error || 'Failed to fetch clients' }` ); } - }); + } ); }; fetchAvailableClients = () => { return new Promise( async ( resolve ) => { try { - const response = await axios.get(`${base_url}${VPNConfig.availableClients}`); - resolve(response.data.clients); + const response = await axios.get( `${ base_url }${ VPNConfig.availableClients }` ); + resolve( response.data.clients ); } catch (error) { - resolve(`Error: ${error.response?.data?.error || 'Failed to fetch available clients'}`); + resolve( `Error: ${ error.response?.data?.error || 'Failed to fetch available clients' }` ); } - }); + } ); }; createClient = ( data, fetchClients ) => { return new Promise( async ( resolve ) => { const { clientName, useStaticIp, staticIp } = data; try { - const response = await axios.post(`${base_url}${VPNConfig.create}`, { + const response = await axios.post( `${ base_url }${ VPNConfig.create }`, { clientName, - staticIp: useStaticIp ? staticIp : undefined, - }); + staticIp:useStaticIp ? staticIp : undefined, + } ); fetchClients(); if (response.data.ovpn) { - const element = document.createElement('a'); - const file = new Blob([response.data.ovpn], { type: 'text/plain' }); - element.href = URL.createObjectURL(file); - element.download = `${clientName}.ovpn`; - document.body.appendChild(element); + const element = document.createElement( 'a' ); + const file = new Blob( [response.data.ovpn], { type:'text/plain' } ); + element.href = URL.createObjectURL( file ); + element.download = `${ clientName }.ovpn`; + document.body.appendChild( element ); element.click(); - document.body.removeChild(element); + document.body.removeChild( element ); } - resolve(response.data.message); + resolve( response.data.message ); } catch (error) { - resolve(`Error: ${error.response?.data?.error || 'Failed to create client'}`); + resolve( `Error: ${ error.response?.data?.error || 'Failed to create client' }` ); } - }) + } ); }; revokeClient = ( data, fetchClients ) => { return new Promise( async ( resolve ) => { const { revokeClientName } = data; try { - const response = await axios.put(`${base_url}${VPNConfig.delete}`, { - clientName: revokeClientName, - }); + const response = await axios.put( `${ base_url }${ VPNConfig.delete }`, { + clientName:revokeClientName, + } ); fetchClients(); - resolve(response.data.message); + resolve( response.data.message ); } catch (error) { - resolve(`Error: ${error.response?.data?.error || 'Failed to revoke client'}`); + resolve( `Error: ${ error.response?.data?.error || 'Failed to revoke client' }` ); } - }); + } ); + }; + + getServerStatus = () => { + return new Promise( async ( resolve ) => { + try { + const response = await axios.get( `${ base_url }${ VPNConfig.getStatus }` ); + resolve( response.data ); + } catch (error) { + resolve( `Error: ${ error.response?.data?.error || 'Failed to fetch server status' }` ); + } + } ); + }; + + disconnect = () => { + return new Promise( async ( resolve ) => { + try { + const response = await axios.put( `${ base_url }${ VPNConfig.disconnect }` ); + resolve( response.data.message ); + } catch (error) { + resolve( `Error: ${ error.response?.data?.error || 'Failed to disconnect' }` ); + } + } ); + }; + + restart = () => { + return new Promise( async ( resolve ) => { + try { + const response = await axios.put( `${ base_url }${ VPNConfig.restart }` ); + resolve( response.data.message ); + } catch (error) { + resolve( `Error: ${ error.response?.data?.error || 'Failed to restart' }` ); + } + } ); }; } diff --git a/src/app/views/VPN/VPN.jsx b/src/app/views/VPN/VPN.jsx index 959a2ea..6fdfefb 100644 --- a/src/app/views/VPN/VPN.jsx +++ b/src/app/views/VPN/VPN.jsx @@ -1,6 +1,6 @@ import { Container, Typography, Button, Grid } from '@mui/material'; import { MaterialReactTable, useMaterialReactTable } from 'material-react-table'; -import { useVPN } from '../../components/VPN/VPNContext'; +import { useVPN } from '../../components'; const VPN = () => { const { setRevokeOpen, @@ -8,7 +8,8 @@ const VPN = () => { clients, availableClients, message, - setCreateOpen } = useVPN(); + setCreateOpen, + setStatusOpen } = useVPN(); const clientTable = useMaterialReactTable( { columns: [ { accessorKey: 'name', header: 'Name' }, @@ -62,11 +63,18 @@ const VPN = () => { data: availableClients, renderTopToolbarCustomActions: () => ( <> - + ) }); diff --git a/src/app/views/VPN/index.js b/src/app/views/VPN/index.js deleted file mode 100644 index e69de29..0000000