"use client"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { COUNTRY_NAMES } from "../../lib/constants/countries"; interface GeographicThreatMapProps { geoDistribution: Record; title?: string; } // Threat level configuration with colors const THREAT_LEVELS = { high: { color: "destructive", bgColor: "bg-red-500" }, medium: { color: "secondary", bgColor: "bg-yellow-500" }, low: { color: "outline", bgColor: "bg-blue-500" }, minimal: { color: "outline", bgColor: "bg-gray-400" }, } as const; type ThreatLevel = keyof typeof THREAT_LEVELS; export function GeographicThreatMap({ geoDistribution, title = "Geographic Threat Distribution", }: GeographicThreatMapProps) { // Calculate values once for efficiency const totalEvents = Object.values(geoDistribution).reduce( (sum, count) => sum + count, 0 ); const maxEventCount = Math.max(...Object.values(geoDistribution)); const sortedCountries = Object.entries(geoDistribution) .sort(([, a], [, b]) => b - a) .slice(0, 12); const getThreatLevel = (count: number, total: number): ThreatLevel => { const percentage = (count / total) * 100; if (percentage > 50) return "high"; if (percentage > 20) return "medium"; if (percentage > 5) return "low"; return "minimal"; }; const getCountryName = (code: string) => { return COUNTRY_NAMES[code] || code; }; return ( {title} Security events by country ({totalEvents} total events) {sortedCountries.length === 0 ? (

No geographic data available

) : (
{sortedCountries.map(([countryCode, count]) => { const threatLevel = getThreatLevel(count, totalEvents); const percentage = ((count / totalEvents) * 100).toFixed(1); return (
{getCountryName(countryCode)} {threatLevel}

{count} events ({percentage}%)

{count}
); })}
{Object.keys(geoDistribution).length > 12 && (

And {Object.keys(geoDistribution).length - 12} more countries...

)}
)} ); }