Add Jinja2 web UI with Bootstrap 5 dark theme
- app/templates/: base layout with sidebar nav + 6 pages (dashboard, printers, jobs, filaments, todos, pricing) - app/routers/ui.py: HTML routes querying the DB live - API routes moved to /api/* prefix - requirements: jinja2, python-multipart Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
76
app/routers/ui.py
Normal file
76
app/routers/ui.py
Normal file
@@ -0,0 +1,76 @@
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db import get_db
|
||||
from app.models.filament import Filament
|
||||
from app.models.print_job import JobStatus, PrintJob
|
||||
from app.models.printer import Printer, PrinterStatus
|
||||
from app.models.pricing import PricingConfig
|
||||
from app.models.todo import Todo
|
||||
|
||||
router = APIRouter()
|
||||
templates = Jinja2Templates(directory="app/templates")
|
||||
|
||||
|
||||
@router.get("/", response_class=HTMLResponse)
|
||||
def dashboard(request: Request, db: Session = Depends(get_db)):
|
||||
printers = db.query(Printer).order_by(Printer.name).all()
|
||||
return templates.TemplateResponse("dashboard.html", {
|
||||
"request": request,
|
||||
"active": "dashboard",
|
||||
"printers": printers,
|
||||
"total_printers": len(printers),
|
||||
"printing_count": sum(1 for p in printers if p.status == PrinterStatus.printing),
|
||||
"active_jobs": db.query(PrintJob).filter(
|
||||
PrintJob.status.in_([JobStatus.queued, JobStatus.printing])
|
||||
).count(),
|
||||
"total_filaments": db.query(Filament).count(),
|
||||
"recent_jobs": db.query(PrintJob).order_by(PrintJob.created_at.desc()).limit(5).all(),
|
||||
})
|
||||
|
||||
|
||||
@router.get("/printers", response_class=HTMLResponse)
|
||||
def printers_page(request: Request, db: Session = Depends(get_db)):
|
||||
return templates.TemplateResponse("printers.html", {
|
||||
"request": request,
|
||||
"active": "printers",
|
||||
"printers": db.query(Printer).order_by(Printer.name).all(),
|
||||
})
|
||||
|
||||
|
||||
@router.get("/jobs", response_class=HTMLResponse)
|
||||
def jobs_page(request: Request, db: Session = Depends(get_db)):
|
||||
return templates.TemplateResponse("jobs.html", {
|
||||
"request": request,
|
||||
"active": "jobs",
|
||||
"jobs": db.query(PrintJob).order_by(PrintJob.created_at.desc()).all(),
|
||||
})
|
||||
|
||||
|
||||
@router.get("/filaments", response_class=HTMLResponse)
|
||||
def filaments_page(request: Request, db: Session = Depends(get_db)):
|
||||
return templates.TemplateResponse("filaments.html", {
|
||||
"request": request,
|
||||
"active": "filaments",
|
||||
"filaments": db.query(Filament).order_by(Filament.brand, Filament.material).all(),
|
||||
})
|
||||
|
||||
|
||||
@router.get("/todos", response_class=HTMLResponse)
|
||||
def todos_page(request: Request, db: Session = Depends(get_db)):
|
||||
return templates.TemplateResponse("todos.html", {
|
||||
"request": request,
|
||||
"active": "todos",
|
||||
"todos": db.query(Todo).order_by(Todo.done, Todo.created_at.desc()).all(),
|
||||
})
|
||||
|
||||
|
||||
@router.get("/pricing", response_class=HTMLResponse)
|
||||
def pricing_page(request: Request, db: Session = Depends(get_db)):
|
||||
return templates.TemplateResponse("pricing.html", {
|
||||
"request": request,
|
||||
"active": "pricing",
|
||||
"configs": db.query(PricingConfig).order_by(PricingConfig.valid_from.desc()).all(),
|
||||
})
|
||||
Reference in New Issue
Block a user