]> PHS Git Server - phs-admin.git/commitdiff
Separating the revoke client functionality from the main vpn lists.
authorcharleswrayjr <charleswrayjr@gmail.com>
Tue, 9 Sep 2025 15:58:53 +0000 (10:58 -0500)
committercharleswrayjr <charleswrayjr@gmail.com>
Tue, 9 Sep 2025 15:58:53 +0000 (10:58 -0500)
src/app/views/VPN/VPN.jsx

index db1761217a87eb26d186d89876226e96fa4001bb..dcc866386fb7c068b6849e5999ac3d1d17ec53be 100644 (file)
@@ -1,24 +1,52 @@
 import React, { useState, useEffect } from 'react';
 import { Container, Typography, Button } from '@mui/material';
-import { MaterialReactTable } from 'material-react-table';
-/*import axios from 'axios';*/
-import 'tailwindcss/tailwind.css';
+import { MaterialReactTable, useMaterialReactTable } from 'material-react-table';
 import { VPNService } from '../../services';
 import { ConfirmRevoke, CreateVPNClientDialog } from '../../components';
 
 const VPN = () => {
-  /*const [token, setToken] = useState('');
-  const [username, setUsername] = useState('');
-  const [password, setPassword] = useState('');*/
-  /*const [clientName, setClientName] = useState('');
-  const [staticIp, setStaticIp] = useState('');
-  const [useStaticIp, setUseStaticIp] = useState(false);*/
   const [revokeOpen, setRevokeOpen] = useState( false );
   const [revokeClientName, setRevokeClientName] = useState('');
   const [clients, setClients] = useState([]);
   const [availableClients, setAvailableClients] = useState( [] );
   const [message, setMessage] = useState('');
   const [createOpen, setCreateOpen] = useState( false );
+  const clientTable = useMaterialReactTable( {
+    columns: [
+      { accessorKey: 'name', header: 'Name' },
+      { accessorKey: 'ip', header: 'IP' },
+      { accessorFn: row => row.virtual_ip, header: 'Virtual IP' },
+      { accessorFn: row => row.connectedSince, header: 'Connected Since' },
+    ],
+    data: clients,
+  } );
+  const availableTable = useMaterialReactTable({
+    columns:[
+      { accessorKey: 'clientName', header: 'Name' },
+      { accessorKey: 'staticIp', header: 'IP' },
+      { accessorFn: row => row.hasCertificate ? 'Yes' : 'No', header: 'Active Certificate' },
+      { accessorFn: row => clients.find( c => c.name === row.clientName ) ? 'Yes' : 'No', header: 'Connected' },
+      { accessorFn: row => row.hasOvpn ? 'Yes' : 'No', header: 'Has Profile' },
+      {
+        header: 'Actions',
+        Cell: ({ row }) => (
+          <Button
+            variant="contained"
+            color="secondary"
+            onClick={() => {
+              setRevokeClientName( row.original.clientName );
+              setRevokeOpen( true );
+            }}
+          >
+            Revoke
+          </Button>
+        ),
+      },
+    ],
+    data: availableClients,
+    createDisplayMode: 'modal',
+    renderCreateRowDialogContent: () => (<CreateVPNClientDialog open={createOpen} onClose={() => setCreateOpen(false)} onCreate={handleCreateClientSubmit} />)
+  });
 
   const fetchClients = async () => {
     await VPNService.fetchClients().then( res => setClients( res ) ).catch( err => setMessage( err ) );
@@ -33,17 +61,6 @@ const VPN = () => {
     fetchAvailableClients().catch( e => setMessage( e ) );
   }, [] );
 
-  /*const handleLogin = async (e) => {
-    e.preventDefault();
-    try {
-      const response = await axios.post('http://localhost:3000/login', { username, password });
-      setToken(response.data.token);
-      setMessage('Logged in successfully');
-    } catch (error) {
-      setMessage(`Error: ${error.response?.data?.error || 'Login failed'}`);
-    }
-  };*/
-
   const handleCreateClientSubmit = async (e, data) => {
     const { clientName, useStaticIp, staticIp } = data;
     e.preventDefault();
@@ -58,6 +75,11 @@ const VPN = () => {
     setRevokeOpen( false );
   };
 
+  setTimeout( () => {
+    fetchClients().catch( e => setMessage( e ) );
+    fetchAvailableClients().catch( e => setMessage( e ) );
+  }, 10000 * 120 );
+
   return (
     <Container>
       { revokeOpen &&
@@ -66,118 +88,18 @@ const VPN = () => {
           onClose={() => setRevokeOpen(false)}
           onConfirm={handleRevokeClientSubmit}
         />}
-      <Button variant="contained" color="primary" onClick={() => setCreateOpen(true)}>Create Client</Button>
-      {createOpen && <CreateVPNClientDialog open={createOpen} onClose={() => setCreateOpen(false)} onCreate={handleCreateClientSubmit}/>}
-      {/*<Typography variant="h5" className="mt-6">Create OpenVPN Client</Typography>
-      <form onSubmit={handleCreateClientSubmit} className="space-y-4">
-        <TextField
-          label="Client Name"
-          value={clientName}
-          onChange={(e) => setClientName(e.target.value)}
-          fullWidth
-        />
-        <Select
-          value={useStaticIp}
-          onChange={(e) => setUseStaticIp(e.target.value)}
-          fullWidth
-        >
-          <MenuItem value={false}>Dynamic IP</MenuItem>
-          <MenuItem value={true}>Static IP</MenuItem>
-        </Select>
-        {useStaticIp && (
-          <TextField
-            label="Static IP"
-            value={staticIp}
-            onChange={(e) => setStaticIp(e.target.value)}
-            fullWidth
-            placeholder="e.g., 10.8.0.x"
-          />
-        )}
-        <Button type="submit" variant="contained" color="primary">Create Client</Button>
-      </form>*/}
-
-      {/*<Typography variant="h5" className="mt-6">Revoke OpenVPN Client</Typography>
-      <form onSubmit={handleRevokeClientSubmit} className="space-y-4">
-        <TextField
-          label="Client Name"
-          value={revokeClientName}
-          onChange={(e) => setRevokeClientName(e.target.value)}
-          fullWidth
-        />
-        <Button type="submit" variant="contained" color="secondary">Revoke Client</Button>
-      </form>*/}
+      {/*<Button variant="contained" color="primary" onClick={() => setCreateOpen(true)}>Create Client</Button>
+      {createOpen && <CreateVPNClientDialog open={createOpen} onClose={() => setCreateOpen(false)} onCreate={handleCreateClientSubmit}/>}*/}
 
       <Typography variant="h5" className="mt-6">Available OpenVPN Clients</Typography>
-      <MaterialReactTable
-        columns={[
-          { accessorKey: 'clientName', header: 'Name' },
-          { accessorKey: 'staticIp', header: 'IP' },
-          { accessorFn: row => {
-            console.log(row.hasCertificate);
-              return row.hasCertificate ? 'Yes' : 'No';
-            }, header: 'Active Certificate' },
-          { accessorFn: row => clients.find( c => c.name === row.clientName ) ? 'Yes' : 'No', header: 'Connected' },
-          { accessorFn: row => row.hasOvpn ? 'Yes' : 'No', header: 'Has Profile' },
-          {
-            header: 'Actions',
-            Cell: ({ row }) => (
-              <Button
-                variant="contained"
-                color="secondary"
-                onClick={() => {
-                  setRevokeClientName( row.original.clientName );
-                  setRevokeOpen( true );
-                }}
-              >
-                Revoke
-              </Button>
-            ),
-          },
-        ]}
-        data={availableClients}
-      />
+      <MaterialReactTable table={ availableTable } />
 
       <Typography variant="h5" className="mt-6">Connected OpenVPN Clients</Typography>
-      <MaterialReactTable
-        columns={[
-          { accessorKey: 'name', header: 'Name' },
-          { accessorKey: 'ip', header: 'IP' },
-          { accessorKey: 'virtual_ip', header: 'Virtual IP' },
-          { accessorKey: 'connectedSince', header: 'Connected Since' },
-        ]}
-        data={clients}
-      />
+      <MaterialReactTable table={ clientTable } />
 
       {message && <Typography color={message.startsWith('Error') ? 'error' : 'success'}>{message}</Typography>}
     </Container>
   );
-
-  /*return (
-    <Container>
-      <Typography variant="h4" gutterBottom>PHS Admin Dashboard</Typography>
-      {!token ? (
-        <form onSubmit={handleLogin} className="space-y-4">
-          <TextField
-            label="Username"
-            value={username}
-            onChange={(e) => setUsername(e.target.value)}
-            fullWidth
-          />
-          <TextField
-            label="Password"
-            type="password"
-            value={password}
-            onChange={(e) => setPassword(e.target.value)}
-            fullWidth
-          />
-          <Button type="submit" variant="contained" color="primary">Login</Button>
-        </form>
-      ) : (
-        <>
-        </>
-      )}
-    </Container>
-  );*/
 };
 
 export default VPN;
\ No newline at end of file