This commit is contained in:
2025-06-16 08:27:55 -04:00
parent 987cce1687
commit 14f95e3192
17 changed files with 4098 additions and 0 deletions

39
frontend/src/App.jsx Normal file
View File

@@ -0,0 +1,39 @@
import React, { Suspense, useMemo } from "react";
import { createTheme, ThemeProvider } from "@mui/material/styles";
import { CssBaseline } from "@mui/material";
import { BrowserRouter, Routes, Route } from "react-router";
import Sidebar from "./components/Sidebar";
import Baseline from "./components/Baseline";
function App() {
const theme = useMemo(
() =>
createTheme({
palette: {
mode: "dark",
},
}),
[]
);
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<div className="flex h-screen text-white">
<Sidebar />
<div className="flex-1 p-6 overflow-auto">
<BrowserRouter>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/baseline" element={<Baseline />} />
</Routes>
</Suspense>
</BrowserRouter>
</div>
</div>
</ThemeProvider>
);
}
export default App;

View File

@@ -0,0 +1,80 @@
import React, { useEffect, useState } from "react";
import axios from "axios";
const Baseline = () => {
const [data, setData] = useState([]);
useEffect(() => {
axios
.get("/uploaded/baseline.csv")
.then((res) => {
const csv = res.data;
const lines = csv.trim().split("\n");
const headers = lines[0].split(",");
const rows = lines.slice(1).map((line) => {
const values = line.split(",");
return headers.reduce((obj, h, i) => {
obj[h.trim()] = values[i].trim();
return obj;
}, {});
});
setData(rows);
})
.catch((err) => console.error("Error loading baseline CSV:", err));
}, []);
const countByType = (pattern) =>
data.filter((row) => row["Operating System"]?.toLowerCase().includes(pattern)).length;
return (
<div className="p-6 text-white">
<h1 className="text-3xl font-bold mb-4">Network Baseline</h1>
{/* Summary Cards */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
{[
{ label: "Windows", color: "bg-blue-600", pattern: "windows" },
{ label: "Linux", color: "bg-green-600", pattern: "ubuntu" },
{ label: "Servers", color: "bg-red-600", pattern: "server" },
{ label: "Workstations", color: "bg-yellow-500", pattern: "workstation" },
].map(({ label, color, pattern }) => (
<div
key={label}
className={`flex items-center justify-center ${color} rounded-full h-24 w-24 mx-auto shadow-lg`}
>
<div className="text-center">
<div className="text-xl font-bold">{countByType(pattern)}</div>
<div className="text-sm">{label}</div>
</div>
</div>
))}
</div>
{/* Table */}
<div className="overflow-x-auto rounded-lg border border-zinc-700">
<table className="min-w-full text-left text-sm">
<thead className="bg-zinc-800 text-zinc-300">
<tr>
<th className="p-3">Host Name</th>
<th className="p-3">Operating System</th>
<th className="p-3">IP Address</th>
<th className="p-3">FQDN</th>
</tr>
</thead>
<tbody className="divide-y divide-zinc-700">
{data.map((row, i) => (
<tr key={i} className="hover:bg-zinc-800">
<td className="p-3">{row["Host Name"]}</td>
<td className="p-3">{row["Operating System"]}</td>
<td className="p-3">{row["IP Address"]}</td>
<td className="p-3">{row["Fdqn"]}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
};
export default Baseline;

View File

@@ -0,0 +1,53 @@
import React, { useState } from 'react';
import {
ShieldCheck, Server, Bug, Lock, Globe, Settings,
ChevronDown, ChevronRight, Folder
} from 'lucide-react';
import AddIcon from '@mui/icons-material/Add';
const SidebarItem = ({ icon: Icon, label, children }) => {
const [open, setOpen] = useState(false);
const hasChildren = !!children;
return (
<div className="text-sm w-full">
<div
className="flex items-center justify-between px-4 py-2 cursor-pointer rounded hover:bg-zinc-800 text-white transition-all"
onClick={() => hasChildren && setOpen(!open)}
>
<div className="flex items-center space-x-3">
<Icon className="w-5 h-5 text-cyan-400" />
<span>{label}</span>
{hasChildren &&
(open ? <AddIcon className="w-4 h-4" /> : <ChevronRight className="w-4 h-4" />)}
</div>
</div>
{hasChildren && open && (
<div className="ml-8 mt-1 space-y-1 text-zinc-400">
{children}
</div>
)}
</div>
);
};
const Sidebar = () => (
<div className="h-screen w-64 shadow-lg p-4 flex flex-col space-y-2">
<h2 className="text-xl font-bold text-white mb-4">Velo Dashboard</h2>
<SidebarItem icon={ShieldCheck} label="HomePage" />
<SidebarItem icon={Server} label="Baseline" />
<SidebarItem icon={Bug} label="Networking" />
<SidebarItem icon={Folder} label="Applications" />
<SidebarItem icon={Globe} label="CSV Processing" />
<SidebarItem icon={Settings} label="Security Tools">
<div>Anti Virus</div>
<div>Endpoint Detection & Response</div>
<div>Virtual Private Networks</div>
</SidebarItem>
<SidebarItem icon={Globe} label="Virus Totals" />
<SidebarItem icon={Globe} label="Configuration & Settings" />
</div>
);
export default Sidebar;

1
frontend/src/index.css Normal file
View File

@@ -0,0 +1 @@
@import "tailwindcss";

10
frontend/src/main.jsx Normal file
View File

@@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './index.css';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>
);