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:
303
FRONTEND_README.md
Normal file
303
FRONTEND_README.md
Normal file
@@ -0,0 +1,303 @@
|
||||
# Seismo Fleet Manager - Frontend Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
This is the MVP frontend scaffold for **Seismo Fleet Manager**, built with:
|
||||
- **FastAPI** (backend framework)
|
||||
- **HTMX** (dynamic updates without JavaScript frameworks)
|
||||
- **TailwindCSS** (utility-first styling)
|
||||
- **Jinja2** (server-side templating)
|
||||
- **Leaflet** (interactive maps)
|
||||
|
||||
No React, Vue, or other frontend frameworks are used.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
seismo-fleet-manager/
|
||||
├── backend/
|
||||
│ ├── main.py # FastAPI app entry point
|
||||
│ ├── routers/
|
||||
│ │ ├── roster.py # Fleet roster endpoints
|
||||
│ │ ├── units.py # Individual unit endpoints
|
||||
│ │ └── photos.py # Photo management endpoints
|
||||
│ ├── services/
|
||||
│ │ └── snapshot.py # Mock status snapshot (replace with real logic)
|
||||
│ ├── static/
|
||||
│ │ └── style.css # Custom CSS
|
||||
│ ├── database.py # SQLAlchemy database setup
|
||||
│ ├── models.py # Database models
|
||||
│ └── routes.py # Legacy API routes
|
||||
├── templates/
|
||||
│ ├── base.html # Base layout with sidebar & dark mode
|
||||
│ ├── dashboard.html # Main dashboard page
|
||||
│ ├── roster.html # Fleet roster page
|
||||
│ ├── unit_detail.html # Unit detail page
|
||||
│ └── partials/
|
||||
│ └── roster_table.html # HTMX partial for roster table
|
||||
├── data/
|
||||
│ └── photos/ # Photo storage (organized by unit_id)
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
## Running the Application
|
||||
|
||||
### Install Dependencies
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### Run the Server
|
||||
|
||||
```bash
|
||||
uvicorn backend.main:app --host 0.0.0.0 --port 8001 --reload
|
||||
```
|
||||
|
||||
The application will be available at:
|
||||
- **Web UI**: http://localhost:8001/
|
||||
- **API Docs**: http://localhost:8001/docs
|
||||
- **Health Check**: http://localhost:8001/health
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Dashboard (`/`)
|
||||
|
||||
The main dashboard provides an at-a-glance view of the fleet:
|
||||
|
||||
- **Fleet Summary Card**: Total units, deployed units, status breakdown
|
||||
- **Recent Alerts Card**: Shows units with Missing or Pending status
|
||||
- **Recent Photos Card**: Placeholder for photo gallery
|
||||
- **Fleet Status Preview**: Quick view of first 5 units
|
||||
|
||||
**Auto-refresh**: Dashboard updates every 10 seconds via HTMX
|
||||
|
||||
### 2. Fleet Roster (`/roster`)
|
||||
|
||||
A comprehensive table view of all seismograph units:
|
||||
|
||||
**Columns**:
|
||||
- Status indicator (colored dot: green=OK, yellow=Pending, red=Missing)
|
||||
- Deployment indicator (blue dot if deployed)
|
||||
- Unit ID
|
||||
- Last seen timestamp
|
||||
- Age since last contact
|
||||
- Notes
|
||||
- Actions (View detail button)
|
||||
|
||||
**Features**:
|
||||
- Auto-refresh every 10 seconds
|
||||
- Sorted by priority (Missing > Pending > OK)
|
||||
- Click any row to view unit details
|
||||
|
||||
### 3. Unit Detail Page (`/unit/{unit_id}`)
|
||||
|
||||
Split-screen layout with detailed information:
|
||||
|
||||
**Left Column**:
|
||||
- Status card with real-time updates
|
||||
- Deployment status
|
||||
- Last contact time and file
|
||||
- Notes section
|
||||
- Editable metadata (mock form)
|
||||
|
||||
**Right Column - Tabbed Interface**:
|
||||
- **Photos Tab**: Primary photo with thumbnail gallery
|
||||
- **Map Tab**: Interactive Leaflet map showing unit location
|
||||
- **History Tab**: Placeholder for event history
|
||||
|
||||
**Auto-refresh**: Unit data updates every 10 seconds
|
||||
|
||||
### 4. Dark/Light Mode
|
||||
|
||||
Toggle button in sidebar switches between themes:
|
||||
- Uses Tailwind's `dark:` classes
|
||||
- Preference saved to localStorage
|
||||
- Smooth transitions on theme change
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Status & Fleet Data
|
||||
|
||||
```http
|
||||
GET /api/status-snapshot
|
||||
```
|
||||
Returns complete fleet status snapshot with statistics.
|
||||
|
||||
```http
|
||||
GET /api/roster
|
||||
```
|
||||
Returns sorted list of all units for roster table.
|
||||
|
||||
```http
|
||||
GET /api/unit/{unit_id}
|
||||
```
|
||||
Returns detailed information for a single unit including coordinates.
|
||||
|
||||
### Photo Management
|
||||
|
||||
```http
|
||||
GET /api/unit/{unit_id}/photos
|
||||
```
|
||||
Returns list of photos for a unit, sorted by recency.
|
||||
|
||||
```http
|
||||
GET /api/unit/{unit_id}/photo/{filename}
|
||||
```
|
||||
Serves a specific photo file.
|
||||
|
||||
### Legacy Endpoints
|
||||
|
||||
```http
|
||||
POST /emitters/report
|
||||
```
|
||||
Endpoint for emitters to report status (from original backend).
|
||||
|
||||
```http
|
||||
GET /fleet/status
|
||||
```
|
||||
Returns database-backed fleet status (from original backend).
|
||||
|
||||
## Mock Data
|
||||
|
||||
### Location: `backend/services/snapshot.py`
|
||||
|
||||
The `emit_status_snapshot()` function currently returns mock data with 8 units:
|
||||
|
||||
- **BE1234**: OK, deployed (San Francisco)
|
||||
- **BE5678**: Pending, deployed (Los Angeles)
|
||||
- **BE9012**: Missing, deployed (New York)
|
||||
- **BE3456**: OK, benched (Chicago)
|
||||
- **BE7890**: OK, deployed (Houston)
|
||||
- **BE2468**: Pending, deployed
|
||||
- **BE1357**: OK, benched
|
||||
- **BE8642**: Missing, deployed
|
||||
|
||||
**To replace with real data**: Update the `emit_status_snapshot()` function to call your Series3 emitter logic.
|
||||
|
||||
## Styling
|
||||
|
||||
### Color Palette
|
||||
|
||||
The application uses your brand colors:
|
||||
|
||||
```css
|
||||
orange: #f48b1c
|
||||
navy: #142a66
|
||||
burgundy: #7d234d
|
||||
```
|
||||
|
||||
These are configured in the Tailwind config as `seismo-orange`, `seismo-navy`, `seismo-burgundy`.
|
||||
|
||||
### Cards
|
||||
|
||||
All cards use the consistent styling:
|
||||
```html
|
||||
<div class="rounded-xl shadow-lg bg-white dark:bg-slate-800 p-6">
|
||||
```
|
||||
|
||||
### Status Indicators
|
||||
|
||||
- Green dot: OK status
|
||||
- Yellow dot: Pending status
|
||||
- Red dot: Missing status
|
||||
- Blue dot: Deployed
|
||||
- Gray dot: Benched
|
||||
|
||||
## HTMX Usage
|
||||
|
||||
HTMX enables dynamic updates without writing JavaScript:
|
||||
|
||||
### Auto-refresh Example (Dashboard)
|
||||
|
||||
```html
|
||||
<div hx-get="/api/status-snapshot"
|
||||
hx-trigger="load, every 10s"
|
||||
hx-swap="none"
|
||||
hx-on::after-request="updateDashboard(event)">
|
||||
```
|
||||
|
||||
This fetches the snapshot on page load and every 10 seconds, then calls a JavaScript function to update the DOM.
|
||||
|
||||
### Partial Template Loading (Roster)
|
||||
|
||||
```html
|
||||
<div hx-get="/partials/roster-table"
|
||||
hx-trigger="load, every 10s"
|
||||
hx-swap="innerHTML">
|
||||
```
|
||||
|
||||
This replaces the entire inner HTML with the server-rendered roster table every 10 seconds.
|
||||
|
||||
## Adding Photos
|
||||
|
||||
To add photos for a unit:
|
||||
|
||||
1. Create a directory: `data/photos/{unit_id}/`
|
||||
2. Add image files (jpg, jpeg, png, gif, webp)
|
||||
3. Photos will automatically appear on the unit detail page
|
||||
4. Most recent file becomes the primary photo
|
||||
|
||||
Example:
|
||||
```bash
|
||||
mkdir -p data/photos/BE1234
|
||||
cp my-photo.jpg data/photos/BE1234/deployment-site.jpg
|
||||
```
|
||||
|
||||
## Customization
|
||||
|
||||
### Adding New Pages
|
||||
|
||||
1. Create a template in `templates/`
|
||||
2. Add a route in `backend/main.py`:
|
||||
|
||||
```python
|
||||
@app.get("/my-page", response_class=HTMLResponse)
|
||||
async def my_page(request: Request):
|
||||
return templates.TemplateResponse("my_page.html", {"request": request})
|
||||
```
|
||||
|
||||
3. Add a navigation link in `templates/base.html`
|
||||
|
||||
### Adding New API Endpoints
|
||||
|
||||
1. Create a router file in `backend/routers/`
|
||||
2. Include the router in `backend/main.py`:
|
||||
|
||||
```python
|
||||
from backend.routers import my_router
|
||||
app.include_router(my_router.router)
|
||||
```
|
||||
|
||||
## Docker Deployment
|
||||
|
||||
The project includes Docker configuration:
|
||||
|
||||
```bash
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
This will start the application on port 8001 (configured to avoid conflicts with port 8000).
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Replace Mock Data**: Update `backend/services/snapshot.py` with real Series3 emitter logic
|
||||
2. **Database Integration**: The existing SQLAlchemy models can store historical data
|
||||
3. **Photo Upload**: Add a form to upload photos from the UI
|
||||
4. **Projects Management**: Implement the "Projects" page
|
||||
5. **Settings**: Add user preferences and configuration
|
||||
6. **Event History**: Populate the History tab with real event data
|
||||
7. **Authentication**: Add user login/authentication if needed
|
||||
8. **Notifications**: Add real-time alerts for critical status changes
|
||||
|
||||
## Development Tips
|
||||
|
||||
- The `--reload` flag auto-reloads the server when code changes
|
||||
- Use browser DevTools to debug HTMX requests (look for `HX-Request` headers)
|
||||
- Check `/docs` for interactive API documentation (Swagger UI)
|
||||
- Dark mode state persists in browser localStorage
|
||||
- All timestamps are currently mock data - replace with real values
|
||||
|
||||
## License
|
||||
|
||||
See main README.md for license information.
|
||||
Reference in New Issue
Block a user