Files
asm-dashboard/resources/js/Components/SecurityScoresOverviewBarChart.tsx
2024-11-10 19:06:42 +01:00

126 lines
4.6 KiB
TypeScript

"use client"
import React, { useMemo } from 'react';
import { TrendingUp, TrendingDown } from "lucide-react";
import { Bar, BarChart, CartesianGrid, LabelList, XAxis, YAxis } from "recharts";
import {
Card,
CardContent,
CardDescription,
CardFooter,
CardHeader,
CardTitle,
} from "@/Components/ui/card";
import {
ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from "@/Components/ui/chart";
import { SecuritySummaryReportResultType } from "@/types/security-summary";
export default function SecurityScoresOverviewBarChart({ reportData }: { reportData: SecuritySummaryReportResultType }) {
const chartData = useMemo(() => [
{ metric: 'Services Exposure', score: reportData.servizi_esposti_score },
{ metric: 'Data Leak', score: reportData.dataleak_score },
{ metric: 'Email Leak', score: reportData.rapporto_leak_email_score },
{ metric: 'Spoofing', score: reportData.spoofing_score },
{ metric: 'Open Port', score: reportData.open_ports_score },
{ metric: 'Blacklist', score: reportData.blacklist_score },
{ metric: 'Certificate', score: reportData.certificate_score }
], [reportData]);
const chartConfig = {
score: {
label: "Score",
color: "hsl(var(--chart-1))",
},
label: {
color: "hsl(var(--background))",
},
} satisfies ChartConfig;
const averageScore = useMemo(() => {
const sum = chartData.reduce((acc, curr) => acc + curr.score, 0);
return Math.round(sum / chartData.length);
}, [chartData]);
const isHighRisk = averageScore > 75;
return (
<Card>
<CardHeader>
<CardTitle>Security Scores Overview</CardTitle>
<CardDescription>Security metrics analysis</CardDescription>
</CardHeader>
<CardContent>
<ChartContainer config={chartConfig} className="max-h-[250px] w-full">
<BarChart
data={chartData}
layout="vertical"
margin={{
right: 16,
left: 16,
top: 16,
bottom: 16,
}}
height={250}
>
<CartesianGrid horizontal={false} />
<YAxis
dataKey="metric"
type="category"
tickLine={false}
tickMargin={10}
axisLine={false}
width={100}
/>
<XAxis
type="number"
domain={[0, 100]}
tickFormatter={(value) => `${value}%`}
/>
<ChartTooltip
cursor={false}
content={<ChartTooltipContent />}
/>
<Bar
dataKey="score"
fill="var(--color-score)"
radius={4}
>
<LabelList
dataKey="score"
position="right"
offset={8}
className="fill-foreground"
fontSize={12}
formatter={(value: number) => `${value}%`}
/>
</Bar>
</BarChart>
</ChartContainer>
</CardContent>
<CardFooter className="flex-col items-start gap-2 text-sm">
<div className="flex gap-2 font-medium leading-none">
{isHighRisk ? (
<>
High risk level detected
<TrendingUp className="h-4 w-4 text-destructive" />
</>
) : (
<>
Moderate risk level
<TrendingDown className="h-4 w-4 text-success" />
</>
)}
</div>
<div className="leading-none text-muted-foreground">
Average security score: {averageScore}%
</div>
</CardFooter>
</Card>
);
}