← Back to Portfolio

dotstreamTM UI

React/TypeScript Frontend for Traffic Management Systems

Project Overview

dotstreamTM UI is a modular React/Next.js application serving as the frontend for multiple traffic management and surveillance systems. I developed key features including the OHVD (Over-Height Vehicle Detection) module, interactive map viewer with GIS integration, real-time dashboard with KPI analytics, and WebSocket-based video streaming components.

React TypeScript Next.js PostgREST PostgreSQL WebSocket MQTT Docker Swarm AWS ECR Tailwind CSS GeoServer
1700+
Cameras Supported
<500ms
PTZ Feedback Latency
24/7
Production Uptime

Map Viewer & Station Management

Interactive GIS Map

Full-featured map viewer with dynamic popup system, station markers, and real-time status updates. Integrated with GeoServer for geographic data layers.

  • Custom popup components per station type (OHVD, traffic cameras, sensors)
  • Real-time station status via WebSocket connections
  • Multi-layer GIS integration with GeoServer
  • Station panel with live video feeds, relay controls, and event history

Station Control Panel

Comprehensive station management interface with PTZ camera controls, relay toggles, and VMS (Variable Message Sign) messaging.

Key Components

  • OHVDStationPanel.tsx - Main panel container
  • StationDetailsPanel.tsx - Station info and video feeds
  • CommandsPanel.tsx - Relay controls, system commands
  • OHVDStationEvents.tsx - Event list with filtering

Dashboard & KPI Analytics

Real-Time KPI Dashboard

Dashboard with live metrics, filtering by station/date range/alert type, and database-level aggregations via PostgREST.

KPI Cards Implemented

  • Total OHVD Triggers with trend analysis
  • Bridge Hits - critical infrastructure events
  • Stalled Vehicles - traffic incident detection
  • False Alert Rate - system accuracy metrics

Technical Implementation

  • PostgREST API layer with custom PostgreSQL views
  • Station filtering using UUID (not names) for data integrity
  • Date range filtering with proper timezone handling
  • Pagination handling for large datasets (16,000+ events)

Video Streaming Integration

Live PTZ & VCA Camera Feeds

WebSocket-based frame streaming from the backend dVS (dotstream Video Service), with offline detection, retry logic, and graceful degradation.

// OHVDStream.tsx - Key state management
const [isOffline, setIsOffline] = useState(false);
const [cooldownMessage, setCooldownMessage] = useState<string | null>(null);
const [retryCount, setRetryCount] = useState(0);
const startupTimeoutRef = useRef<NodeJS.Timeout | null>(null);

// Flow: Check offline status -> Initialize stream -> Wait for first frame
// 30-second timeout with automatic offline recheck

Features Implemented

  • WebSocket frame streaming with CSRF token authentication
  • Camera offline detection with retry mechanism (5-min cooldown)
  • 30-second initialization timeout with graceful fallback
  • Spinner shows until first frame received (not on socket connect)
  • Video file playback for recorded alerts

MQTT Real-Time Updates

Event Notification System

Client-side MQTT integration for real-time alert notifications and station status updates.

src/projects/ohvd/MQTT/
├── MQTTContext.tsx   # React context provider
├── MQTTManager.ts    # Connection lifecycle management
└── MQTTFunctions.ts  # Message parsing and handlers

Technical Challenges Solved

Dashboard KPI Count Issue

Problem: Total OHVD Triggers showed only 1 instead of hundreds.

Root Cause: Status filter was excluding "Unacknowledged" events; PostgREST default limit (1000 records) was being hit.

Solution: Removed restrictive status filter, used UUID-based station filtering, configured proper pagination.

Video Stream Lifecycle

Problem: Backend changed to non-blocking stream initialization - HTTP 200 no longer meant "stream ready."

Solution: Added offline detection endpoint, 30-second timeout with recheck, retry mechanism with cooldown, spinner tied to first frame (not socket connect).

React DOM Boolean Attribute Warnings

Problem: SVG components receiving entire feature objects with boolean props (is_armed, is_active).

Solution: Refactored titleIconComponent to pass only required props instead of spreading full feature object.

Architecture

src/
├── app/
│   └── dashboards/ohvd/ohvd/     # Dashboard route
├── projects/ohvd/
│   ├── dashboard/              # OhvdDashboard.tsx
│   ├── MQTT/                   # Real-time messaging
│   ├── ohvd-map-panels/        # Event & Station panels
│   ├── OhvdConfig.ts
│   ├── OHVDInterfaces.tsx
│   ├── OHVDStream.tsx          # Video streaming component
│   └── OhvdTable.tsx
├── components/map-viewer/
│   ├── map-panels/OHVD/        # Station control components
│   └── popup-system/           # Dynamic popup instances
└── app/api/ohvd/
    └── video/route.ts           # Next.js API route for video

Deployment

Production deployment via Docker Swarm with AWS ECR for container registry and AWS Secrets Manager for configuration.

  • Services: Next.js app (port 3000), PostgREST API (port 4001), GeoServer (port 8601)
  • CI/CD: GitHub Actions with trunk-based deployment
  • Image tagging: 2.57.6-ohvd_dev_branch-YYYYMMDDHHMMSS