'use client'; import React, { useEffect, useState } from 'react'; import { Box, Typography, Paper, Grid, Card, CardContent, Button, CircularProgress, Divider, Chip, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Alert } from '@mui/material'; import { PictureAsPdf as PdfIcon, Assessment as AssessmentIcon, Security as SecurityIcon, Devices as DevicesIcon, Apps as AppsIcon } from '@mui/icons-material'; import api from '@/lib/axios'; import jsPDF from 'jspdf'; import { format } from 'date-fns'; interface ComplianceSummary { totalDevices: number; vulnerableDevices: number; totalVulnerabilities: number; criticalVulns: number; highVulns: number; mediumVulns: number; lowVulns: number; totalSoftware: number; vulnerableSoftware: number; lastUpdated: string; } interface TopVulnerability { cveId: string; title: string; severity: string; score: number; affectedDevices: number; } interface TopVulnerableSoftware { softwareName: string; totalInstances: number; vulnerableInstances: number; totalCves: number; } export default function ReportingPage() { const [summary, setSummary] = useState(null); const [topVulns, setTopVulns] = useState([]); const [topSoftware, setTopSoftware] = useState([]); const [loading, setLoading] = useState(true); const [exporting, setExporting] = useState(false); const reportRef = React.useRef(null); const fetchReportingData = async () => { try { setLoading(true); // Fetch compliance summary data (you'll need to create these endpoints) const [summaryRes, vulnsRes, softwareRes] = await Promise.all([ api.get('/reporting/compliance-summary'), api.get('/reporting/top-vulnerabilities'), api.get('/reporting/vulnerable-software') ]); setSummary(summaryRes.data); setTopVulns(vulnsRes.data); setTopSoftware(softwareRes.data); } catch (error) { console.error('Failed to fetch reporting data:', error); // Create mock data for now since endpoints don't exist yet createMockData(); } finally { setLoading(false); } }; useEffect(() => { fetchReportingData(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const createMockData = () => { setSummary({ totalDevices: 127, vulnerableDevices: 89, totalVulnerabilities: 342, criticalVulns: 23, highVulns: 67, mediumVulns: 156, lowVulns: 96, totalSoftware: 1247, vulnerableSoftware: 89, lastUpdated: new Date().toISOString() }); setTopVulns([ { cveId: 'CVE-2024-12345', title: 'Critical Remote Code Execution', severity: 'CRITICAL', score: 9.8, affectedDevices: 34 }, { cveId: 'CVE-2024-12346', title: 'Privilege Escalation Vulnerability', severity: 'HIGH', score: 8.4, affectedDevices: 28 }, { cveId: 'CVE-2024-12347', title: 'Information Disclosure', severity: 'HIGH', score: 7.9, affectedDevices: 22 }, { cveId: 'CVE-2024-12348', title: 'Cross-Site Scripting', severity: 'MEDIUM', score: 6.1, affectedDevices: 19 }, { cveId: 'CVE-2024-12349', title: 'Denial of Service', severity: 'MEDIUM', score: 5.8, affectedDevices: 15 } ]); setTopSoftware([ { softwareName: 'Apache HTTP Server', totalInstances: 45, vulnerableInstances: 23, totalCves: 12 }, { softwareName: 'OpenSSL', totalInstances: 89, vulnerableInstances: 34, totalCves: 8 }, { softwareName: 'Microsoft Office', totalInstances: 127, vulnerableInstances: 67, totalCves: 15 }, { softwareName: 'Adobe Reader', totalInstances: 98, vulnerableInstances: 45, totalCves: 9 }, { softwareName: 'Java Runtime Environment', totalInstances: 76, vulnerableInstances: 28, totalCves: 6 } ]); }; const exportToPDF = async () => { if (!reportRef.current || !summary) return; try { setExporting(true); // Create a new jsPDF instance const pdf = new jsPDF('p', 'mm', 'a4'); const pageWidth = pdf.internal.pageSize.getWidth(); const pageHeight = pdf.internal.pageSize.getHeight(); // Add header pdf.setFontSize(20); pdf.setFont('helvetica', 'bold'); pdf.text('Compliance Security Report', pageWidth / 2, 20, { align: 'center' }); pdf.setFontSize(12); pdf.setFont('helvetica', 'normal'); pdf.text(`Generated: ${format(new Date(), 'PPP')}`, pageWidth / 2, 30, { align: 'center' }); let yPosition = 45; // Executive Summary pdf.setFontSize(16); pdf.setFont('helvetica', 'bold'); pdf.text('Executive Summary', 20, yPosition); yPosition += 10; pdf.setFontSize(10); pdf.setFont('helvetica', 'normal'); const summaryText = [ `Total Devices: ${summary.totalDevices}`, `Vulnerable Devices: ${summary.vulnerableDevices} (${((summary.vulnerableDevices / summary.totalDevices) * 100).toFixed(1)}%)`, `Total Vulnerabilities: ${summary.totalVulnerabilities}`, `Critical: ${summary.criticalVulns} | High: ${summary.highVulns} | Medium: ${summary.mediumVulns} | Low: ${summary.lowVulns}`, `Software Applications: ${summary.totalSoftware}`, `Vulnerable Software: ${summary.vulnerableSoftware}` ]; summaryText.forEach(text => { pdf.text(text, 20, yPosition); yPosition += 6; }); yPosition += 10; // Top Vulnerabilities pdf.setFontSize(16); pdf.setFont('helvetica', 'bold'); pdf.text('Top Critical Vulnerabilities', 20, yPosition); yPosition += 10; pdf.setFontSize(9); pdf.setFont('helvetica', 'normal'); topVulns.slice(0, 10).forEach((vuln, index) => { if (yPosition > pageHeight - 30) { pdf.addPage(); yPosition = 20; } pdf.text(`${index + 1}. ${vuln.cveId} - ${vuln.title}`, 20, yPosition); yPosition += 5; pdf.text(` Severity: ${vuln.severity} | Score: ${vuln.score} | Affected: ${vuln.affectedDevices} devices`, 20, yPosition); yPosition += 8; }); // Add page break if needed if (yPosition > pageHeight - 80) { pdf.addPage(); yPosition = 20; } else { yPosition += 10; } // Top Vulnerable Software pdf.setFontSize(16); pdf.setFont('helvetica', 'bold'); pdf.text('Most Vulnerable Software', 20, yPosition); yPosition += 10; pdf.setFontSize(9); pdf.setFont('helvetica', 'normal'); topSoftware.slice(0, 10).forEach((software, index) => { if (yPosition > pageHeight - 30) { pdf.addPage(); yPosition = 20; } pdf.text(`${index + 1}. ${software.softwareName}`, 20, yPosition); yPosition += 5; pdf.text(` ${software.vulnerableInstances}/${software.totalInstances} instances vulnerable | ${software.totalCves} CVEs`, 20, yPosition); yPosition += 8; }); // Footer const totalPages = pdf.internal.pages.length - 1; for (let i = 1; i <= totalPages; i++) { pdf.setPage(i); pdf.setFontSize(8); pdf.text(`Page ${i} of ${totalPages}`, pageWidth - 30, pageHeight - 10); pdf.text('Confidential - Internal Use Only', 20, pageHeight - 10); } // Save the PDF const filename = `compliance-report-${format(new Date(), 'yyyy-MM-dd')}.pdf`; pdf.save(filename); } catch (error) { console.error('Failed to export PDF:', error); } finally { setExporting(false); } }; const getSeverityColor = (severity: string) => { switch (severity?.toLowerCase()) { case 'critical': return 'error'; case 'high': return 'warning'; case 'medium': return 'info'; case 'low': return 'success'; default: return 'default'; } }; if (loading) { return ( ); } if (!summary) { return ( Failed to load reporting data. Please try again later. ); } return ( Compliance Reporting Comprehensive security compliance overview and vulnerability reporting {/* Executive Summary Cards */} Devices {summary.totalDevices} {summary.vulnerableDevices} vulnerable ({((summary.vulnerableDevices / summary.totalDevices) * 100).toFixed(1)}%) Vulnerabilities {summary.totalVulnerabilities} Software {summary.totalSoftware} {summary.vulnerableSoftware} with vulnerabilities Risk Level 0 ? "error" : summary.highVulns > 10 ? "warning" : "success"} > {summary.criticalVulns > 0 ? "HIGH" : summary.highVulns > 10 ? "MEDIUM" : "LOW"} Last updated: {format(new Date(summary.lastUpdated), 'PPp')} {/* Detailed Reports */} Top Critical Vulnerabilities CVE ID Severity Score Devices {topVulns.slice(0, 8).map((vuln) => ( {vuln.cveId} {vuln.title.length > 40 ? `${vuln.title.substring(0, 40)}...` : vuln.title} {vuln.score} {vuln.affectedDevices} ))}
Most Vulnerable Software Software Vulnerable CVEs Risk {topSoftware.slice(0, 8).map((software) => { const riskLevel = software.vulnerableInstances / software.totalInstances; return ( {software.softwareName} {software.vulnerableInstances}/{software.totalInstances} ({((riskLevel) * 100).toFixed(0)}%) {software.totalCves} 0.5 ? "HIGH" : riskLevel > 0.2 ? "MEDIUM" : "LOW"} color={riskLevel > 0.5 ? "error" : riskLevel > 0.2 ? "warning" : "success"} size="small" /> ); })}
This report contains confidential security information. Distribution should be limited to authorized personnel only. Report generated on {format(new Date(), 'PPP')} from data last updated {format(new Date(summary.lastUpdated), 'PPp')}.
); }