From 38a6f9439cad6b8860aa085a8cfeaae9c161e3d3 Mon Sep 17 00:00:00 2001 From: Parneet Kaur Date: Sat, 30 May 2026 00:18:46 +0530 Subject: [PATCH 1/3] feat(analytics): add security analytics dashboard --- frontend/src/App.tsx | 2 + frontend/src/components/AppShell.tsx | 34 ++--- frontend/src/pages/Analytics.tsx | 187 +++++++++++++++++++++++++++ frontend/src/routes.ts | 1 + 4 files changed, 208 insertions(+), 16 deletions(-) create mode 100644 frontend/src/pages/Analytics.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index f4f6b39f..1218b6da 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -6,6 +6,7 @@ import Toolkit from './pages/Toolkit' import ToolConfig from './pages/ToolConfig' import Findings from './pages/Findings' import Reports from './pages/Reports' +import Analytics from './pages/Analytics' import Settings from './pages/Settings' import Scans from './pages/Scans' import TaskDetails from './pages/TaskDetails' @@ -25,6 +26,7 @@ export function AppRoutes() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/frontend/src/components/AppShell.tsx b/frontend/src/components/AppShell.tsx index 1c73e91b..b6827ade 100644 --- a/frontend/src/components/AppShell.tsx +++ b/frontend/src/components/AppShell.tsx @@ -46,6 +46,7 @@ export default function AppShell({ children }: AppShellProps) { { to: routes.reports, icon: 'summarize', label: 'Reports' }, { to: routes.workflows, icon: 'account_tree', label: 'Workflows' }, { to: routes.toolkit, icon: 'add_circle', label: 'Toolkit' }, + { to: routes.analytics, icon: 'analytics', label: 'Analytics' }, ] const mobileDrawerNav = [ { to: routes.dashboard, label: 'Dashboard' }, @@ -55,6 +56,7 @@ export default function AppShell({ children }: AppShellProps) { { to: routes.workflows, label: 'Workflows' }, { to: routes.toolkit, label: 'Toolkit' }, { to: routes.settings, label: 'Settings' }, + { to: routes.analytics, label: 'Analytics' }, ] @@ -111,22 +113,22 @@ export default function AppShell({ children }: AppShellProps) { {children} - + ) diff --git a/frontend/src/pages/Analytics.tsx b/frontend/src/pages/Analytics.tsx new file mode 100644 index 00000000..67799660 --- /dev/null +++ b/frontend/src/pages/Analytics.tsx @@ -0,0 +1,187 @@ +import { + Bar, + BarChart, + CartesianGrid, + Cell, + Line, + LineChart, + Pie, + PieChart, + ResponsiveContainer, + Tooltip, + XAxis, + YAxis, +} from 'recharts' +import { useEffect, useMemo, useState } from 'react' + +const vulnerabilityTrend = [ + { day: 'Mon', critical: 4, high: 9, medium: 18 }, + { day: 'Tue', critical: 6, high: 12, medium: 21 }, + { day: 'Wed', critical: 3, high: 10, medium: 16 }, + { day: 'Thu', critical: 8, high: 14, medium: 24 }, + { day: 'Fri', critical: 5, high: 11, medium: 19 }, + { day: 'Sat', critical: 7, high: 13, medium: 22 }, + { day: 'Sun', critical: 4, high: 8, medium: 15 }, +] + +const severityData = [ + { name: 'Critical', value: 18 }, + { name: 'High', value: 42 }, + { name: 'Medium', value: 76 }, + { name: 'Low', value: 55 }, +] + +const targetRisk = [ + { target: 'api.secuscan.local', risk: 94 }, + { target: 'admin.panel', risk: 87 }, + { target: 'auth.gateway', risk: 72 }, + { target: 'cdn.edge', risk: 51 }, +] + +const scanStats = [ + { name: 'Success', value: 72 }, + { name: 'Failed', value: 18 }, + { name: 'Aborted', value: 10 }, +] + +const COLORS = ['#ef4444', '#f97316', '#eab308', '#22c55e'] + +function MetricCard({ label, value, detail }: { label: string; value: string; detail: string }) { + return ( +
+

{label}

+

{value}

+

{detail}

+
+ ) +} + +function ChartCard({ title, children }: { title: string; children: React.ReactNode }) { + return ( +
+

+ {title} +

+
{children}
+
+ ) +} +export default function Analytics() { + + const [timeRange, setTimeRange] = useState<'7d' | '30d' | '90d'>('7d') + const [lastUpdated, setLastUpdated] = useState(new Date()) + + useEffect(() => { + const interval = window.setInterval(() => { + setLastUpdated(new Date()) + }, 30000) + + return () => window.clearInterval(interval) + }, []) + + const filteredTrend = useMemo(() => { + if (timeRange === '7d') return vulnerabilityTrend.slice(-7) + if (timeRange === '30d') return vulnerabilityTrend + return vulnerabilityTrend + }, [timeRange]) + + return ( +
+
+
+ Analytics_Core v1.0 +
+ +

+ Security Analytics +

+ +

+ Vulnerability trends // scan statistics // target risk analysis +

+ +
+ {(['7d', '30d', '90d'] as const).map((range) => ( + + ))} +
+ +

+ Auto refresh enabled // Last updated: {lastUpdated.toLocaleTimeString()} +

+ +
+ +
+ + + + +
+ +
+ + + + + + + + + + + + + + + + + + + {severityData.map((_, index) => ( + + ))} + + + + + + + + + + + + + + + + + + + + + + + {scanStats.map((_, index) => ( + + ))} + + + + + +
+
+ ) +} \ No newline at end of file diff --git a/frontend/src/routes.ts b/frontend/src/routes.ts index 38caa98f..c929e937 100644 --- a/frontend/src/routes.ts +++ b/frontend/src/routes.ts @@ -4,6 +4,7 @@ export const routes = { scanTool: '/toolkit/:toolId', findings: '/findings', scans: '/scans', + analytics: '/analytics', reports: '/reports', workflows: '/workflows', settings: '/settings', From 63671ce9f1e795f8549b3583f47e4000c879187f Mon Sep 17 00:00:00 2001 From: Parneet Kaur Date: Sun, 31 May 2026 10:19:25 +0530 Subject: [PATCH 2/3] fix(ui): keep analytics dashboard out of production --- frontend/src/App.tsx | 2 -- frontend/src/components/AppShell.tsx | 5 +---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 1218b6da..f4f6b39f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -6,7 +6,6 @@ import Toolkit from './pages/Toolkit' import ToolConfig from './pages/ToolConfig' import Findings from './pages/Findings' import Reports from './pages/Reports' -import Analytics from './pages/Analytics' import Settings from './pages/Settings' import Scans from './pages/Scans' import TaskDetails from './pages/TaskDetails' @@ -26,7 +25,6 @@ export function AppRoutes() { } /> } /> } /> - } /> } /> } /> } /> diff --git a/frontend/src/components/AppShell.tsx b/frontend/src/components/AppShell.tsx index b6827ade..d998d147 100644 --- a/frontend/src/components/AppShell.tsx +++ b/frontend/src/components/AppShell.tsx @@ -46,9 +46,7 @@ export default function AppShell({ children }: AppShellProps) { { to: routes.reports, icon: 'summarize', label: 'Reports' }, { to: routes.workflows, icon: 'account_tree', label: 'Workflows' }, { to: routes.toolkit, icon: 'add_circle', label: 'Toolkit' }, - { to: routes.analytics, icon: 'analytics', label: 'Analytics' }, - ] - const mobileDrawerNav = [ + ]; const mobileDrawerNav = [ { to: routes.dashboard, label: 'Dashboard' }, { to: routes.scans, label: 'Scans' }, { to: routes.findings, label: 'Findings' }, @@ -56,7 +54,6 @@ export default function AppShell({ children }: AppShellProps) { { to: routes.workflows, label: 'Workflows' }, { to: routes.toolkit, label: 'Toolkit' }, { to: routes.settings, label: 'Settings' }, - { to: routes.analytics, label: 'Analytics' }, ] From 8dd9c23c6baf8ac7e392b433e240a9d1e0051a1b Mon Sep 17 00:00:00 2001 From: Parneet Kaur Date: Sun, 31 May 2026 11:44:06 +0530 Subject: [PATCH 3/3] fix(ui): keep analytics dashboard out of production --- frontend/src/App.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index f4f6b39f..72b7f982 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -27,8 +27,7 @@ export function AppRoutes() { } /> } /> } /> - } /> - + } /> -0 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 9 } /> )