Complete Frontend Components Reference
Overview
Comprehensive documentation for all 40+ React components in the HCMC Traffic Management System frontend, built with React 18.2, TypeScript, MapLibre GL, and modern web technologies.
Table of Contents
Map Components
- TrafficMap
- CameraMarkers
- AccidentMarkers
- CongestionZones
- WeatherOverlay
- AQIHeatmap
- VehicleHeatmap
- SpeedZones
- PatternZones
- RouteOverlay
UI Components
Feature Components
- CitizenReportForm
- CitizenReportMap
- RoutePlanner
- TimeMachine
- AnalyticsDashboard
- RealTimeMonitor
- AlertPanel
- NotificationCenter
Chart Components
Form Components
Utility Components
Map Components
TrafficMap
Overview
Core interactive map component displaying real-time traffic conditions, camera feeds, accidents, congestion zones, and weather overlays using MapLibre GL.
Props
interface TrafficMapProps {
center?: [number, number]; // Map center [lat, lon]
zoom?: number; // Initial zoom level (1-18)
height?: string; // Map container height
showCameras?: boolean; // Show camera markers
showAccidents?: boolean; // Show accident markers
showCongestion?: boolean; // Show congestion zones
showWeather?: boolean; // Show weather overlay
showAQI?: boolean; // Show air quality heatmap
showVehicles?: boolean; // Show vehicle heatmap
enableClustering?: boolean; // Enable marker clustering
enableGeolocation?: boolean; // Show user location
onCameraClick?: (cameraId: string) => void;
onAccidentClick?: (accidentId: string) => void;
onZoneClick?: (zoneId: string) => void;
onMapClick?: (lat: number, lon: number) => void;
style?: React.CSSProperties;
}
Usage
import TrafficMap from '@/components/TrafficMap';
// Basic usage
<TrafficMap
center={[10.7769, 106.7009]}
zoom={13}
height="600px"
/>
// Full features
<TrafficMap
center={[10.7769, 106.7009]}
zoom={13}
height="100vh"
showCameras={true}
showAccidents={true}
showCongestion={true}
showWeather={true}
showAQI={true}
enableClustering={true}
enableGeolocation={true}
onCameraClick={(id) => console.log('Camera:', id)}
onAccidentClick={(id) => console.log('Accident:', id)}
style={{ borderRadius: '8px' }}
/>
// With state management
const [mapConfig, setMapConfig] = useState({
showCameras: true,
showAccidents: true,
showCongestion: false
});
<TrafficMap {...mapConfig} />
Features
- Real-time Updates: WebSocket-powered live data
- Multiple Layers: Toggle-able overlay layers
- Marker Clustering: Performance optimization for 100+ markers
- Responsive: Mobile-friendly with touch gestures
- Custom Controls: Zoom, fullscreen, layer controls
- Geolocation: User location tracking
Styling
.traffic-map {
width: 100%;
height: 600px;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.maplibregl-map {
font-family: 'Inter', sans-serif;
background: #f5f5f5;
}
CameraMarkers
Overview
Displays camera locations on map with clickable markers showing camera status and latest image preview.
Props
interface CameraMarkersProps {
cameras: Camera[];
onCameraClick?: (cameraId: string) => void;
clustering?: boolean;
showStatus?: boolean;
iconSize?: number;
}
interface Camera {
id: string;
name: string;
location: { lat: number; lon: number };
status: 'active' | 'inactive' | 'error';
last_update: string;
}
Usage
import CameraMarkers from '@/components/CameraMarkers';
const cameras = [
{
id: 'CAM_001',
name: 'District 1 - Nguyen Hue',
location: { lat: 10.7769, lon: 106.7009 },
status: 'active',
last_update: '2025-11-29T10:30:00Z'
}
];
<MapContainer>
<CameraMarkers
cameras={cameras}
onCameraClick={(id) => handleCameraClick(id)}
clustering={true}
showStatus={true}
iconSize={32}
/>
</MapContainer>
Features
- Status Indicators: Color-coded by camera status
- Clustering: Group nearby cameras at low zoom
- Popup Preview: Show camera info on hover
- Custom Icons: SVG camera icons
- Batch Updates: Efficient re-rendering
AccidentMarkers
Overview
Displays accident locations with severity-based styling and animated alerts for critical incidents.
Props
interface AccidentMarkersProps {
accidents: Accident[];
onAccidentClick?: (accidentId: string) => void;
showSeverity?: boolean;
animateCritical?: boolean;
}
interface Accident {
id: string;
location: { lat: number; lon: number };
severity: 'minor' | 'moderate' | 'severe' | 'critical';
timestamp: string;
vehicles_involved: number;
}
Usage
import AccidentMarkers from '@/components/AccidentMarkers';
<AccidentMarkers
accidents={accidents}
onAccidentClick={(id) => showAccidentDetails(id)}
showSeverity={true}
animateCritical={true}
/>
Styling
.accident-marker {
transition: transform 0.2s;
}
.accident-marker.critical {
animation: pulse 2s infinite;
color: #d32f2f;
}
@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.2); opacity: 0.7; }
}
CongestionZones
Overview
Renders congestion zones as colored polygons with opacity based on severity level.
Props
interface CongestionZonesProps {
zones: CongestionZone[];
onZoneClick?: (zoneId: string) => void;
showLabels?: boolean;
interactive?: boolean;
}
interface CongestionZone {
id: string;
name: string;
polygon: [number, number][];
level: 'free_flow' | 'light' | 'moderate' | 'heavy' | 'severe';
avg_speed: number;
}
Usage
import CongestionZones from '@/components/CongestionZones';
<CongestionZones
zones={congestionZones}
onZoneClick={(id) => console.log('Zone:', id)}
showLabels={true}
interactive={true}
/>
Color Scheme
const congestionColors = {
free_flow: '#4caf50', // Green
light: '#8bc34a', // Light green
moderate: '#ffeb3b', // Yellow
heavy: '#ff9800', // Orange
severe: '#f44336' // Red
};
WeatherOverlay
Overview
Displays weather information overlay with temperature, conditions, and precipitation data.
Props
interface WeatherOverlayProps {
weather: WeatherData;
showForecast?: boolean;
showRadar?: boolean;
opacity?: number;
}
interface WeatherData {
temperature: number;
conditions: string;
precipitation: number;
wind: { speed: number; direction: number };
}
Usage
import WeatherOverlay from '@/components/WeatherOverlay';
<WeatherOverlay
weather={currentWeather}
showForecast={true}
showRadar={true}
opacity={0.6}
/>
AQIHeatmap
Overview
Air quality index heatmap showing pollution levels across the city.
Props
interface AQIHeatmapProps {
data: AQIDataPoint[];
radius?: number;
blur?: number;
maxOpacity?: number;
gradient?: Record<number, string>;
}
interface AQIDataPoint {
lat: number;
lon: number;
aqi: number;
}
Usage
import AQIHeatmap from '@/components/AQIHeatmap';
const aqiGradient = {
0.0: '#00e400', // Good
0.2: '#ffff00', // Moderate
0.4: '#ff7e00', // Unhealthy for Sensitive
0.6: '#ff0000', // Unhealthy
0.8: '#8f3f97', // Very Unhealthy
1.0: '#7e0023' // Hazardous
};
<AQIHeatmap
data={aqiData}
radius={25}
blur={15}
maxOpacity={0.6}
gradient={aqiGradient}
/>
VehicleHeatmap
Overview
Real-time vehicle density heatmap based on traffic camera detections.
Props
interface VehicleHeatmapProps {
data: VehicleDensityPoint[];
radius?: number;
blur?: number;
updateInterval?: number;
}
Usage
<VehicleHeatmap
data={vehicleDensity}
radius={30}
blur={20}
updateInterval={30000}
/>
UI Components
MapLegend
Overview
Interactive legend showing all map layers with toggle controls.
Props
interface MapLegendProps {
position?: 'topright' | 'topleft' | 'bottomright' | 'bottomleft';
layers: LayerConfig[];
onLayerToggle?: (layerId: string, visible: boolean) => void;
collapsible?: boolean;
}
interface LayerConfig {
id: string;
name: string;
icon: React.ReactNode;
visible: boolean;
color?: string;
}
Usage
import MapLegend from '@/components/MapLegend';
const layers = [
{ id: 'cameras', name: 'Cameras', icon: <CameraIcon />, visible: true },
{ id: 'accidents', name: 'Accidents', icon: <AccidentIcon />, visible: true, color: '#d32f2f' },
{ id: 'congestion', name: 'Congestion', icon: <TrafficIcon />, visible: false }
];
<MapLegend
position="topright"
layers={layers}
onLayerToggle={(id, visible) => handleLayerToggle(id, visible)}
collapsible={true}
/>
Styling
.map-legend {
background: white;
padding: 16px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
padding: 8px;
cursor: pointer;
transition: background 0.2s;
}
.legend-item:hover {
background: #f5f5f5;
}
FilterPanel
Overview
Advanced filtering panel for map layers and data visualization.
Props
interface FilterPanelProps {
filters: FilterState;
onFilterChange: (filters: FilterState) => void;
categories: string[];
dateRange?: [Date, Date];
locations?: string[];
}
interface FilterState {
categories: string[];
severity?: string[];
dateRange?: [Date, Date];
locations?: string[];
timeOfDay?: string;
}
Usage
import FilterPanel from '@/components/FilterPanel';
const [filters, setFilters] = useState({
categories: ['accidents', 'congestion'],
severity: ['moderate', 'severe'],
dateRange: [new Date('2025-11-20'), new Date('2025-12-05')]
});
<FilterPanel
filters={filters}
onFilterChange={setFilters}
categories={['accidents', 'congestion', 'weather']}
locations={['District 1', 'District 3', 'District 5']}
/>
Sidebar
Overview
Collapsible sidebar with navigation and quick access to features.
Props
interface SidebarProps {
open?: boolean;
onToggle?: (open: boolean) => void;
width?: number;
position?: 'left' | 'right';
children: React.ReactNode;
}
Usage
import Sidebar from '@/components/Sidebar';
<Sidebar open={sidebarOpen} onToggle={setSidebarOpen} width={300}>
<nav>
<Link to="/dashboard">Dashboard</Link>
<Link to="/cameras">Cameras</Link>
<Link to="/analytics">Analytics</Link>
</nav>
</Sidebar>
CameraDetailModal
Overview
Modal displaying detailed camera information with live feed and statistics.
Props
interface CameraDetailModalProps {
camera: CameraDetail;
open: boolean;
onClose: () => void;
showLiveFeed?: boolean;
showStatistics?: boolean;
}
interface CameraDetail {
id: string;
name: string;
location: Location;
status: string;
stream_url?: string;
stats?: CameraStats;
}
Usage
import CameraDetailModal from '@/components/CameraDetailModal';
<CameraDetailModal
camera={selectedCamera}
open={modalOpen}
onClose={() => setModalOpen(false)}
showLiveFeed={true}
showStatistics={true}
/>
Feature Components
CitizenReportForm
Overview
Form for citizens to submit traffic reports with photo upload and location selection.