FlotillasGPS - Sistema completo de monitoreo de flotillas GPS
Sistema completo para monitoreo y gestion de flotas de vehiculos con: - Backend FastAPI con PostgreSQL/TimescaleDB - Frontend React con TypeScript y TailwindCSS - App movil React Native con Expo - Soporte para dispositivos GPS, Meshtastic y celulares - Video streaming en vivo con MediaMTX - Geocercas, alertas, viajes y reportes - Autenticacion JWT y WebSockets en tiempo real Documentacion completa y guias de usuario incluidas.
This commit is contained in:
112
frontend/src/components/mapa/GeocercaLayer.tsx
Normal file
112
frontend/src/components/mapa/GeocercaLayer.tsx
Normal file
@@ -0,0 +1,112 @@
|
||||
import { Circle, Polygon, Polyline, Popup, Tooltip } from 'react-leaflet'
|
||||
import { Geocerca } from '@/types'
|
||||
|
||||
interface GeocercaLayerProps {
|
||||
geocerca: Geocerca
|
||||
editable?: boolean
|
||||
onClick?: () => void
|
||||
}
|
||||
|
||||
export default function GeocercaLayer({
|
||||
geocerca,
|
||||
editable = false,
|
||||
onClick,
|
||||
}: GeocercaLayerProps) {
|
||||
const pathOptions = {
|
||||
color: geocerca.color,
|
||||
fillColor: geocerca.color,
|
||||
fillOpacity: 0.2,
|
||||
weight: 2,
|
||||
}
|
||||
|
||||
const eventHandlers = {
|
||||
click: () => onClick?.(),
|
||||
}
|
||||
|
||||
// Circle geocerca
|
||||
if (geocerca.tipo === 'circulo' && geocerca.centroLat && geocerca.centroLng && geocerca.radio) {
|
||||
return (
|
||||
<Circle
|
||||
center={[geocerca.centroLat, geocerca.centroLng]}
|
||||
radius={geocerca.radio}
|
||||
pathOptions={pathOptions}
|
||||
eventHandlers={eventHandlers}
|
||||
>
|
||||
<Tooltip permanent={false} direction="top">
|
||||
<span className="text-sm font-medium">{geocerca.nombre}</span>
|
||||
</Tooltip>
|
||||
<Popup>
|
||||
<GeocercaPopup geocerca={geocerca} />
|
||||
</Popup>
|
||||
</Circle>
|
||||
)
|
||||
}
|
||||
|
||||
// Polygon geocerca
|
||||
if (geocerca.tipo === 'poligono' && geocerca.vertices && geocerca.vertices.length > 2) {
|
||||
const positions = geocerca.vertices.map((v) => [v.lat, v.lng] as [number, number])
|
||||
|
||||
return (
|
||||
<Polygon positions={positions} pathOptions={pathOptions} eventHandlers={eventHandlers}>
|
||||
<Tooltip permanent={false} direction="top">
|
||||
<span className="text-sm font-medium">{geocerca.nombre}</span>
|
||||
</Tooltip>
|
||||
<Popup>
|
||||
<GeocercaPopup geocerca={geocerca} />
|
||||
</Popup>
|
||||
</Polygon>
|
||||
)
|
||||
}
|
||||
|
||||
// Route geocerca
|
||||
if (geocerca.tipo === 'ruta' && geocerca.vertices && geocerca.vertices.length > 1) {
|
||||
const positions = geocerca.vertices.map((v) => [v.lat, v.lng] as [number, number])
|
||||
|
||||
return (
|
||||
<Polyline positions={positions} pathOptions={{ ...pathOptions, fillOpacity: 0 }} eventHandlers={eventHandlers}>
|
||||
<Tooltip permanent={false} direction="top">
|
||||
<span className="text-sm font-medium">{geocerca.nombre}</span>
|
||||
</Tooltip>
|
||||
<Popup>
|
||||
<GeocercaPopup geocerca={geocerca} />
|
||||
</Popup>
|
||||
</Polyline>
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
// Popup content
|
||||
function GeocercaPopup({ geocerca }: { geocerca: Geocerca }) {
|
||||
return (
|
||||
<div className="p-1">
|
||||
<h3 className="text-sm font-semibold text-white mb-1">{geocerca.nombre}</h3>
|
||||
{geocerca.descripcion && (
|
||||
<p className="text-xs text-slate-400 mb-2">{geocerca.descripcion}</p>
|
||||
)}
|
||||
<div className="space-y-1 text-xs">
|
||||
<div className="flex justify-between">
|
||||
<span className="text-slate-500">Tipo:</span>
|
||||
<span className="text-slate-300 capitalize">{geocerca.tipo}</span>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<span className="text-slate-500">Accion:</span>
|
||||
<span className="text-slate-300 capitalize">{geocerca.accion}</span>
|
||||
</div>
|
||||
{geocerca.velocidadMaxima && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-slate-500">Vel. max:</span>
|
||||
<span className="text-slate-300">{geocerca.velocidadMaxima} km/h</span>
|
||||
</div>
|
||||
)}
|
||||
{geocerca.tipo === 'circulo' && geocerca.radio && (
|
||||
<div className="flex justify-between">
|
||||
<span className="text-slate-500">Radio:</span>
|
||||
<span className="text-slate-300">{geocerca.radio} m</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user