Files
Sankofa/src/components/infrastructure/ComplianceMapView.tsx
defiQUG 9daf1fd378 Apply Composer changes: comprehensive API updates, migrations, middleware, and infrastructure improvements
- Add comprehensive database migrations (001-024) for schema evolution
- Enhance API schema with expanded type definitions and resolvers
- Add new middleware: audit logging, rate limiting, MFA enforcement, security, tenant auth
- Implement new services: AI optimization, billing, blockchain, compliance, marketplace
- Add adapter layer for cloud integrations (Cloudflare, Kubernetes, Proxmox, storage)
- Update Crossplane provider with enhanced VM management capabilities
- Add comprehensive test suite for API endpoints and services
- Update frontend components with improved GraphQL subscriptions and real-time updates
- Enhance security configurations and headers (CSP, CORS, etc.)
- Update documentation and configuration files
- Add new CI/CD workflows and validation scripts
- Implement design system improvements and UI enhancements
2025-12-12 18:01:35 -08:00

117 lines
3.7 KiB
TypeScript

'use client'
import { useState, useCallback } from 'react'
import Map, { Marker, Popup, Layer, Source } from 'react-map-gl'
import 'mapbox-gl/dist/mapbox-gl.css'
import type { ComplianceRequirement } from '@/lib/types/infrastructure'
import { Card, CardContent } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
interface ComplianceMapViewProps {
requirements: ComplianceRequirement[]
onCountryClick?: (country: string) => void
}
const statusColors: Record<string, string> = {
Compliant: '#10b981',
Partial: '#f59e0b',
Pending: '#3b82f6',
'Non-Compliant': '#ef4444',
}
// Basic country coordinates (in production, use a proper geocoding service)
const countryCoordinates: Record<string, { lat: number; lng: number }> = {
Italy: { lat: 41.9028, lng: 12.4964 },
Germany: { lat: 51.1657, lng: 10.4515 },
France: { lat: 46.2276, lng: 2.2137 },
Spain: { lat: 40.4637, lng: -3.7492 },
// Add more as needed
}
export function ComplianceMapView({ requirements, onCountryClick }: ComplianceMapViewProps) {
const [popupInfo, setPopupInfo] = useState<ComplianceRequirement | null>(null)
const [viewState, setViewState] = useState({
longitude: 12.4964,
latitude: 41.9028,
zoom: 3,
})
const handleMarkerClick = useCallback(
(requirement: ComplianceRequirement) => {
setPopupInfo(requirement)
onCountryClick?.(requirement.country)
},
[onCountryClick]
)
const mapboxToken = process.env.NEXT_PUBLIC_MAPBOX_TOKEN || ''
if (!mapboxToken) {
return (
<Card>
<CardContent className="p-8 text-center">
<p className="text-studio-medium">
Mapbox token not configured. Please set NEXT_PUBLIC_MAPBOX_TOKEN in your environment
variables.
</p>
</CardContent>
</Card>
)
}
return (
<div className="w-full h-96 rounded-lg overflow-hidden border border-studio-medium">
<Map
{...viewState}
onMove={(evt) => setViewState(evt.viewState)}
mapboxAccessToken={mapboxToken}
style={{ width: '100%', height: '100%' }}
mapStyle="mapbox://styles/mapbox/dark-v10"
>
{requirements.map((req) => {
const coords = countryCoordinates[req.country]
if (!coords) return null
return (
<Marker
key={req.country}
longitude={coords.lng}
latitude={coords.lat}
anchor="bottom"
onClick={() => handleMarkerClick(req)}
>
<div
className="w-4 h-4 rounded-full border-2 border-white cursor-pointer"
style={{ backgroundColor: statusColors[req.status] || '#6b7280' }}
/>
</Marker>
)
})}
{popupInfo && (
<Popup
longitude={countryCoordinates[popupInfo.country]?.lng || 0}
latitude={countryCoordinates[popupInfo.country]?.lat || 0}
anchor="top"
onClose={() => setPopupInfo(null)}
closeButton
closeOnClick={false}
>
<div className="p-2 min-w-[200px]">
<h3 className="font-semibold text-sm mb-2">{popupInfo.country}</h3>
<Badge className={statusColors[popupInfo.status] ? `bg-${statusColors[popupInfo.status]}/20 text-${statusColors[popupInfo.status]}` : ''}>
{popupInfo.status}
</Badge>
<div className="mt-2 text-xs">
<div>Frameworks: {popupInfo.frameworks.join(', ')}</div>
<div>Requirements: {popupInfo.requirements.length}</div>
</div>
</div>
</Popup>
)}
</Map>
</div>
)
}