This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
RPDB (Roadway Pavement Database) Frontend is a Next.js 16 application for visualizing and managing Texas highway pavement data. The application features interactive maps (ArcGIS and Leaflet), data visualization charts, mobile-responsive layouts, and admin tools for managing pavement sections and survey data.
Tech Stack:
- Next.js 16 (App Router, Static Export)
- TypeScript
- TailwindCSS + Radix UI components
- ArcGIS Maps SDK + Leaflet for mapping
- Chart.js, Plotly, D3 for visualizations
- React Context for state management
# Development (LOCAL deployment)
npm run dev
# Production build and preview
npm run build
npm start
# Local build and preview
npm run build-dev
npm run start-dev
# Linting
npm run lint
# Deploy to GitHub Pages
npm run deployThe scripts/ directory contains Python utilities for processing pavement data:
# Install dependencies first
pip install -r scripts/requirements.txt
# Convert Excel to JSON
python scripts/convert_excel_to_json.py
# Generate highway/county averages
python scripts/hw_cnty_avg.py
python scripts/hw_dist_avg.py
# Convert PMIS data to GeoJSON
python scripts/pmis_to_geo_line.py
python scripts/pmis_to_geo_line_by_year.pysrc/app/
├── (app)/ # Protected routes requiring auth
│ ├── ProtectedLayout.tsx # Auth wrapper with JWT refresh
│ ├── page.tsx # Main map page (ArcGIS)
│ ├── admin/ # Admin tools
│ ├── level_one_sections/ # Section management
│ ├── special_sections/[category] # Dynamic category routes
│ ├── experimental_sections/[category]
│ ├── forensic-evaluations/
│ ├── general/
│ │ ├── lane-miles/
│ │ ├── pmis/
│ │ │ ├── condition-analysis/
│ │ │ └── highway-heatmaps
│ │ └── traffic-data/
│ └── specifications/ # TxDOT standards/manuals
└── (auth)/ # Public auth routes
├── login/
├── register/
└── activate/
src/
├──components/
│ ├── chart/ # Chart components (Chart.js, custom)
│ │ ├── HighwaySegmentChart.tsx
│ │ ├── MiniSegmentChart.tsx
│ │ ├── ScoreGauge.tsx
│ │ └── ...
│ ├── map/ # Leaflet map components
│ ├── map-arcgis/ # ArcGIS map components
│ │ └── MapExplorerModal.tsx
│ ├── mobile/ # Mobile-specific layouts
│ ├── nav/ # Navigation components
│ ├── section/ # Section data management
│ ├── highway-heatmaps/ # PMIS heat map visualizations
│ └── ui/ # Radix UI component wrappers
├── constants
├── lib
└── hooks
React Context providers in src/context/:
GlobalLoadingContext- Global loading stateMapContext- Shared map state (selected highway, county)ModalContext- Modal visibility stateSectionContext- Section data managementThemeContext- Theme preferences
- Backend URL:
https://txrpdb-backend.azurewebsites.net - Proxy Routes: Defined in
src/config.ts(route,routeDownload,routeUploadContent) - API Service:
src/services/rpdbApiService.ts(currently in mock mode - setmockMode = falsewhen backend is ready) - Data Fetching: Uses
src/lib/fetchJsonData.tsfor static JSON files from Azure blob storage
- JWT-based auth with automatic token refresh (60s before expiry)
- Guest mode available via localStorage
- Protected routes wrapped in
ProtectedLayout.tsx - Auth utilities:
src/lib/auth.ts(isLoggedIn(),isGuest(),clearAuth()) - Role-based menu access via
SIDENAV_ITEMSinsrc/components/nav/constants.ts
The application features a specialized mobile layout (src/components/mobile/) activated at breakpoints < 768px:
- Swipeable metric cards with touch gesture support
- Horizontal metric selector header
- Mini chart previews (MiniSegmentChart)
- Full-screen chart views with overlay modals
- See
MOBILE_ARCHITECTURE.mdfor detailed mobile layout flow
Key Mobile Components:
MobileLayout.tsx- Main mobile container with swipe logicCard.tsx- Highway/county metric cardsMiniSegmentChart.tsx- Deferred rendering chart previews
- PMIS Data: Highway pavement metrics loaded from CSV files (
hw_cnty_avg.csv) - GeoJSON: Highway geometry loaded from Azure blob storage
- Caching: PMIS year data cached via
src/lib/pmisYearCache.ts - Helpers:
src/lib/data-helpers.tsfor data transformations
- Static export (
output: 'export') - Dynamic
basePathandassetPrefixbased onNEXT_PUBLIC_DEPLOYMENTenv var - GitHub Pages deployment support with version-based paths
- Turbopack enabled (Next.js 16 default)
Environment-aware configuration:
NEXT_PUBLIC_DEPLOYMENT: "LOCAL" or "PRODUCTION"routePublic: Base path for static assets (GitHub Pages compatible)
Path alias configured: @/* → ./src/*
ArcGIS components must be client-side only ('use client'). Import ArcGIS modules carefully:
import MapView from '@arcgis/core/views/MapView'
import FeatureLayer from '@arcgis/core/layers/FeatureLayer'Pages use consistent loading pattern with GlobalLoadingContext:
const { setLoading } = useGlobalLoading()
useEffect(() => {
setLoading(true)
// Load data...
setLoading(false)
}, [setLoading])Highway data flows: CSV → processedData → segmentDataByHighway → Components
- Process in parent component
- Pass via callbacks (
onDataProcessed,onSegmentDataReady) - Cache segment maps for performance
Modals use controlled state pattern:
const [modalOpen, setModalOpen] = useState(false)
const [modalInfo, setModalInfo] = useState({ highway, county, viewType })# Start dev server
npm run dev
# In browser DevTools:
# 1. Toggle device toolbar (Ctrl+Shift+M / Cmd+Shift+M)
# 2. Select mobile device (iPhone 12 Pro, etc.)
# 3. Enable touch simulation
# 4. Test swipe gestures on metric selectorThe app is configured for static export to GitHub Pages:
- Build:
npm run build(setsNEXT_PUBLIC_DEPLOYMENT=PRODUCTION) - Deploy:
npm run deploy(pushesout/directory to gh-pages branch) - Access via:
https://{username}.github.io/{repo-name}/
Base path is automatically prefixed in production mode.
-
Always use client-side rendering for:
- ArcGIS components
- Components accessing
windoworlocalStorage - Interactive map features
-
Performance optimizations in place:
- React.memo on Card/TableRow components
- useMemo for expensive data transformations
- useCallback for stable event handlers
- Dynamic imports for heavy components (maps, charts)
- Deferred rendering in MiniSegmentChart
-
TypeScript strict mode enabled - all components must be properly typed
-
Path Resolution:
- Use
@/alias for imports (e.g.,@/components,@/lib) - Static assets use
routePublicprefix from@/config
- Use
-
Backend API Service is in mock mode. To enable real API:
- Set
mockMode = falseinsrc/services/rpdbApiService.ts - Ensure Azure backend is running and accessible
- Set