126 lines
4.6 KiB
TypeScript
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>
|
|
);
|
|
}
|