Add MVP frontend scaffold with FastAPI + HTMX + TailwindCSS

- Created complete frontend structure with Jinja2 templates
- Implemented three main pages: Dashboard, Fleet Roster, and Unit Detail
- Added HTMX auto-refresh for real-time updates (10s interval)
- Integrated dark/light mode toggle with localStorage persistence
- Built responsive card-based UI with sidebar navigation
- Created API endpoints for status snapshot, roster, unit details, and photos
- Added mock data service for development (emit_status_snapshot)
- Implemented tabbed interface on unit detail page (Photos, Map, History)
- Integrated Leaflet maps for unit location visualization
- Configured static file serving and photo management
- Updated requirements.txt with Jinja2 and aiofiles
- Reorganized backend structure into routers and services
- Added comprehensive FRONTEND_README.md documentation

Frontend features:
- Auto-refreshing dashboard with fleet summary and alerts
- Sortable fleet roster table (prioritizes Missing > Pending > OK)
- Unit detail view with status, deployment info, and notes
- Photo gallery with thumbnail navigation
- Interactive maps showing unit coordinates
- Consistent styling with brand colors (orange, navy, burgundy)

Ready for integration with real Series3 emitter data.
This commit is contained in:
Claude
2025-11-22 00:16:26 +00:00
parent e7e660a9c3
commit 247405c361
16 changed files with 1390 additions and 3 deletions

View File

@@ -0,0 +1,96 @@
"""
Mock implementation of emit_status_snapshot().
This will be replaced with real Series3 emitter logic by the user.
"""
from datetime import datetime, timedelta
import random
def emit_status_snapshot():
"""
Mock function that returns fleet status snapshot.
In production, this will call the real Series3 emitter logic.
Returns a dictionary with unit statuses, ages, deployment status, etc.
"""
# Mock data for demonstration
mock_units = {
"BE1234": {
"status": "OK",
"age": "1h 12m",
"last": "2025-11-22 12:32:10",
"fname": "evt_1234.mlg",
"deployed": True,
"note": "Bridge monitoring project - Golden Gate"
},
"BE5678": {
"status": "Pending",
"age": "2h 45m",
"last": "2025-11-22 11:05:33",
"fname": "evt_5678.mlg",
"deployed": True,
"note": "Dam structural analysis"
},
"BE9012": {
"status": "Missing",
"age": "5d 3h",
"last": "2025-11-17 09:15:00",
"fname": "evt_9012.mlg",
"deployed": True,
"note": "Tunnel excavation site"
},
"BE3456": {
"status": "OK",
"age": "30m",
"last": "2025-11-22 13:20:45",
"fname": "evt_3456.mlg",
"deployed": False,
"note": "Benched for maintenance"
},
"BE7890": {
"status": "OK",
"age": "15m",
"last": "2025-11-22 13:35:22",
"fname": "evt_7890.mlg",
"deployed": True,
"note": "Pipeline monitoring"
},
"BE2468": {
"status": "Pending",
"age": "4h 20m",
"last": "2025-11-22 09:30:15",
"fname": "evt_2468.mlg",
"deployed": True,
"note": "Building foundation survey"
},
"BE1357": {
"status": "OK",
"age": "45m",
"last": "2025-11-22 13:05:00",
"fname": "evt_1357.mlg",
"deployed": False,
"note": "Awaiting deployment"
},
"BE8642": {
"status": "Missing",
"age": "2d 12h",
"last": "2025-11-20 01:30:00",
"fname": "evt_8642.mlg",
"deployed": True,
"note": "Offshore platform - comms issue suspected"
}
}
return {
"units": mock_units,
"timestamp": datetime.now().isoformat(),
"total_units": len(mock_units),
"deployed_units": sum(1 for u in mock_units.values() if u["deployed"]),
"status_summary": {
"OK": sum(1 for u in mock_units.values() if u["status"] == "OK"),
"Pending": sum(1 for u in mock_units.values() if u["status"] == "Pending"),
"Missing": sum(1 for u in mock_units.values() if u["status"] == "Missing")
}
}