Spaces:
Running on CPU Upgrade
Running on CPU Upgrade
Update frontend/src/pages/Dashboard.jsx
Browse files- frontend/src/pages/Dashboard.jsx +27 -15
frontend/src/pages/Dashboard.jsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
|
| 2 |
import { Link, useNavigate } from 'react-router-dom';
|
| 3 |
import { useAuth } from '../components/AuthContext';
|
| 4 |
import { LabelList, ComposedChart, RadialBarChart, RadialBar, RadarChart, Radar, PolarGrid, PolarAngleAxis, PolarRadiusAxis, AreaChart, Area, LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip as RechartsTooltip, ResponsiveContainer, PieChart, Pie, Cell, Legend, BarChart, Bar } from 'recharts';
|
|
@@ -268,13 +268,23 @@ export const Dashboard = () => {
|
|
| 268 |
const counts = summary?.vulnerabilities_count || { critical: 0, high: 0, medium: 0, low: 0, total: 0 };
|
| 269 |
|
| 270 |
// Real-time dynamic security score calculation
|
| 271 |
-
const
|
| 272 |
-
const
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
|
| 279 |
const getRatingGrade = (s) => {
|
| 280 |
if (s === null || s === undefined) return '--';
|
|
@@ -625,7 +635,7 @@ export const Dashboard = () => {
|
|
| 625 |
<circle
|
| 626 |
className="transition-all duration-1000 ease-out"
|
| 627 |
cx="50" cy="50" fill="none" r="45"
|
| 628 |
-
stroke={score < 50 ? '#ba1a1a' : score < 80 ? '#bc4800' : '#004ac6'}
|
| 629 |
strokeDasharray="283"
|
| 630 |
strokeDashoffset={dashOffset}
|
| 631 |
strokeLinecap="round"
|
|
@@ -633,12 +643,14 @@ export const Dashboard = () => {
|
|
| 633 |
/>
|
| 634 |
</svg>
|
| 635 |
<div className="text-center flex flex-col items-center z-10">
|
| 636 |
-
<span className=
|
| 637 |
-
|
|
|
|
|
|
|
| 638 |
{scoreLabel}
|
| 639 |
</span>
|
| 640 |
<span className="font-label-sm text-label-sm text-on-surface-variant/70 mt-base">
|
| 641 |
-
{
|
| 642 |
</span>
|
| 643 |
</div>
|
| 644 |
</div>
|
|
@@ -646,12 +658,12 @@ export const Dashboard = () => {
|
|
| 646 |
<div className="flex items-center justify-between text-body-sm font-body-sm border-t border-outline-variant pt-sm mt-sm">
|
| 647 |
<span className="text-on-surface-variant">Live security posture</span>
|
| 648 |
<span className={`font-medium flex items-center ${
|
| 649 |
-
score >= 80 ? 'text-green-600' : score >= 50 ? 'text-orange-600' : 'text-error'
|
| 650 |
}`}>
|
| 651 |
<span className="material-symbols-outlined text-[16px] mr-[2px]">
|
| 652 |
-
{score >= 80 ? 'trending_up' : score >= 50 ? 'trending_flat' : 'trending_down'}
|
| 653 |
</span>
|
| 654 |
-
{score >= 80 ? 'Stable' : score >= 50 ? 'Needs Attention' : 'Critical Risk'}
|
| 655 |
</span>
|
| 656 |
</div>
|
| 657 |
</div>
|
|
|
|
| 1 |
+
import { useState, useEffect, useRef, useCallback } from 'react';
|
| 2 |
import { Link, useNavigate } from 'react-router-dom';
|
| 3 |
import { useAuth } from '../components/AuthContext';
|
| 4 |
import { LabelList, ComposedChart, RadialBarChart, RadialBar, RadarChart, Radar, PolarGrid, PolarAngleAxis, PolarRadiusAxis, AreaChart, Area, LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip as RechartsTooltip, ResponsiveContainer, PieChart, Pie, Cell, Legend, BarChart, Bar } from 'recharts';
|
|
|
|
| 268 |
const counts = summary?.vulnerabilities_count || { critical: 0, high: 0, medium: 0, low: 0, total: 0 };
|
| 269 |
|
| 270 |
// Real-time dynamic security score calculation
|
| 271 |
+
const rawScore = summary?.average_security_score;
|
| 272 |
+
const hasCompletedScans = (summary?.scans_count > 0 || recentScans.some(s => s.status === 'completed')) && rawScore !== null && rawScore !== undefined;
|
| 273 |
+
|
| 274 |
+
const score = hasCompletedScans ? Math.round(rawScore) : null;
|
| 275 |
+
const dashOffset = hasCompletedScans ? (283 - (283 * score) / 100) : 283;
|
| 276 |
+
|
| 277 |
+
let scoreDisplay = hasCompletedScans ? score : 'N/A';
|
| 278 |
+
let scoreLabel = hasCompletedScans ? 'Excellent' : 'Not Tested Yet';
|
| 279 |
+
let scoreColorClass = hasCompletedScans ? 'text-primary bg-primary/10' : 'text-slate-400 bg-slate-500/10 border border-slate-500/20';
|
| 280 |
+
let scoreSubtext = hasCompletedScans
|
| 281 |
+
? (score >= 80 ? 'System Protected' : 'Remediation Required')
|
| 282 |
+
: 'No Scans Performed Yet';
|
| 283 |
+
|
| 284 |
+
if (hasCompletedScans) {
|
| 285 |
+
if (score < 50) { scoreLabel = 'Critical'; scoreColorClass = 'text-error bg-error/10'; }
|
| 286 |
+
else if (score < 80) { scoreLabel = 'Warning'; scoreColorClass = 'text-tertiary bg-tertiary/10'; }
|
| 287 |
+
}
|
| 288 |
|
| 289 |
const getRatingGrade = (s) => {
|
| 290 |
if (s === null || s === undefined) return '--';
|
|
|
|
| 635 |
<circle
|
| 636 |
className="transition-all duration-1000 ease-out"
|
| 637 |
cx="50" cy="50" fill="none" r="45"
|
| 638 |
+
stroke={!hasCompletedScans ? '#94a3b8' : score < 50 ? '#ba1a1a' : score < 80 ? '#bc4800' : '#004ac6'}
|
| 639 |
strokeDasharray="283"
|
| 640 |
strokeDashoffset={dashOffset}
|
| 641 |
strokeLinecap="round"
|
|
|
|
| 643 |
/>
|
| 644 |
</svg>
|
| 645 |
<div className="text-center flex flex-col items-center z-10">
|
| 646 |
+
<span className={`font-display-lg text-display-lg tracking-tighter ${hasCompletedScans ? 'text-primary' : 'text-slate-400'}`}>
|
| 647 |
+
{scoreDisplay}
|
| 648 |
+
</span>
|
| 649 |
+
<span className={`font-label-sm text-label-sm uppercase tracking-widest px-xs py-[2px] rounded-sm mt-xs ${scoreColorClass}`}>
|
| 650 |
{scoreLabel}
|
| 651 |
</span>
|
| 652 |
<span className="font-label-sm text-label-sm text-on-surface-variant/70 mt-base">
|
| 653 |
+
{scoreSubtext}
|
| 654 |
</span>
|
| 655 |
</div>
|
| 656 |
</div>
|
|
|
|
| 658 |
<div className="flex items-center justify-between text-body-sm font-body-sm border-t border-outline-variant pt-sm mt-sm">
|
| 659 |
<span className="text-on-surface-variant">Live security posture</span>
|
| 660 |
<span className={`font-medium flex items-center ${
|
| 661 |
+
!hasCompletedScans ? 'text-slate-500' : score >= 80 ? 'text-green-600' : score >= 50 ? 'text-orange-600' : 'text-error'
|
| 662 |
}`}>
|
| 663 |
<span className="material-symbols-outlined text-[16px] mr-[2px]">
|
| 664 |
+
{!hasCompletedScans ? 'sensors_off' : score >= 80 ? 'trending_up' : score >= 50 ? 'trending_flat' : 'trending_down'}
|
| 665 |
</span>
|
| 666 |
+
{!hasCompletedScans ? 'Pending Initial Scan' : score >= 80 ? 'Stable' : score >= 50 ? 'Needs Attention' : 'Critical Risk'}
|
| 667 |
</span>
|
| 668 |
</div>
|
| 669 |
</div>
|