refactor(ui): rename graph components to kebab-case naming convention

- Rename threat-map.tsx to map-chart.tsx
- Add map-region-filter component
- Update component exports in graphs and ui indices
This commit is contained in:
Alan Buscaglia
2025-10-22 15:11:25 +02:00
parent 6fb6bebe59
commit 124d2db9f1
5 changed files with 79 additions and 53 deletions
+1 -1
View File
@@ -1,9 +1,9 @@
export { DonutChart } from "./donut-chart";
export { HorizontalBarChart } from "./horizontal-bar-chart";
export { LineChart } from "./line-chart";
export { MapChart, type MapChartData, type MapChartProps } from "./map-chart";
export { RadarChart } from "./radar-chart";
export { RadialChart } from "./radial-chart";
export { SankeyChart } from "./sankey-chart";
export { ScatterPlot } from "./scatter-plot";
export { ChartLegend, type ChartLegendItem } from "./shared/chart-legend";
export { ThreatMap } from "./threat-map";
@@ -16,14 +16,6 @@ import type {
Topology,
} from "topojson-specification";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { HorizontalBarChart } from "./horizontal-bar-chart";
import { BarDataPoint } from "./types";
@@ -63,13 +55,13 @@ interface LocationPoint {
change?: number;
}
interface ThreatMapData {
export interface MapChartData {
locations: LocationPoint[];
regions: string[];
}
interface ThreatMapProps {
data: ThreatMapData;
export interface MapChartProps {
data: MapChartData;
height?: number;
onLocationSelect?: (location: LocationPoint | null) => void;
}
@@ -220,10 +212,10 @@ function LoadingState({ height }: { height: number }) {
);
}
export function ThreatMap({
export function MapChart({
data,
height = MAP_CONFIG.defaultHeight,
}: ThreatMapProps) {
}: MapChartProps) {
const svgRef = useRef<SVGSVGElement>(null);
const containerRef = useRef<HTMLDivElement>(null);
const [selectedLocation, setSelectedLocation] =
@@ -235,7 +227,6 @@ export function ThreatMap({
x: number;
y: number;
} | null>(null);
const [selectedRegion, setSelectedRegion] = useState<string>("All Regions");
const [worldData, setWorldData] = useState<FeatureCollection | null>(null);
const [isLoadingMap, setIsLoadingMap] = useState(true);
const [dimensions, setDimensions] = useState<{
@@ -246,11 +237,6 @@ export function ThreatMap({
height,
});
const filteredLocations =
selectedRegion === "All Regions"
? data.locations
: data.locations.filter((loc) => loc.region === selectedRegion);
// Fetch world data once on mount
useEffect(() => {
let isMounted = true;
@@ -367,7 +353,7 @@ export function ThreatMap({
});
// Unselected points first
filteredLocations.forEach((location) => {
data.locations.forEach((location) => {
if (selectedLocation?.id !== location.id) {
const circle = createCircle(location);
if (circle) pointsGroup.appendChild(circle);
@@ -376,7 +362,7 @@ export function ThreatMap({
// Selected point last (on top)
if (selectedLocation) {
const selectedData = filteredLocations.find(
const selectedData = data.locations.find(
(loc) => loc.id === selectedLocation.id,
);
if (selectedData) {
@@ -387,8 +373,8 @@ export function ThreatMap({
svg.appendChild(pointsGroup);
}, [
data.locations,
dimensions,
filteredLocations,
selectedLocation,
hoveredLocation,
worldData,
@@ -406,34 +392,12 @@ export function ThreatMap({
<div className="flex w-full flex-col gap-6 lg:flex-row lg:items-start">
{/* Map Section */}
<div className="flex-1">
<div className="mb-4 flex items-center justify-between">
<h3
className="text-lg font-semibold"
style={{ color: CHART_COLORS.textPrimary }}
>
Threat Map
</h3>
<Select value={selectedRegion} onValueChange={setSelectedRegion}>
<SelectTrigger
className="w-full rounded-lg"
style={{
borderColor: CHART_COLORS.tooltipBorder,
backgroundColor: CHART_COLORS.tooltipBackground,
color: CHART_COLORS.textPrimary,
}}
>
<SelectValue placeholder="All Regions" />
</SelectTrigger>
<SelectContent>
<SelectItem value="All Regions">All Regions</SelectItem>
{data.regions.map((region) => (
<SelectItem key={region} value={region}>
{region}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<h3
className="mb-4 text-lg font-semibold"
style={{ color: CHART_COLORS.textPrimary }}
>
Threat Map
</h3>
<div
ref={containerRef}
@@ -468,7 +432,7 @@ export function ThreatMap({
className="text-sm"
style={{ color: CHART_COLORS.textSecondary }}
>
{filteredLocations.length} Locations
{data.locations.length} Locations
</span>
</div>
</>
@@ -0,0 +1,50 @@
"use client";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
interface MapRegionFilterProps {
regions: string[];
selectedRegion: string;
onRegionChange: (region: string) => void;
chartColors: {
tooltipBorder: string;
tooltipBackground: string;
textPrimary: string;
};
}
export function MapRegionFilter({
regions,
selectedRegion,
onRegionChange,
chartColors,
}: MapRegionFilterProps) {
return (
<Select value={selectedRegion} onValueChange={onRegionChange}>
<SelectTrigger
className="w-full rounded-lg"
style={{
borderColor: chartColors.tooltipBorder,
backgroundColor: chartColors.tooltipBackground,
color: chartColors.textPrimary,
}}
>
<SelectValue placeholder="All Regions" />
</SelectTrigger>
<SelectContent>
<SelectItem value="All Regions">All Regions</SelectItem>
{regions.map((region) => (
<SelectItem key={region} value={region}>
{region}
</SelectItem>
))}
</SelectContent>
</Select>
);
}
+1 -1
View File
@@ -12,6 +12,6 @@ export * from "./feedback-banner/feedback-banner";
export * from "./headers/navigation-header";
export * from "./label/Label";
export * from "./main-layout/main-layout";
export * from "./select/Select";
export * from "./select";
export * from "./sidebar";
export * from "./toast";
+12
View File
@@ -0,0 +1,12 @@
export {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectScrollDownButton,
SelectScrollUpButton,
SelectSeparator,
SelectTrigger,
SelectValue,
} from "./Select";