from fastapi import APIRouter, Depends, Form, Request from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.templating import Jinja2Templates from sqlalchemy.orm import Session from starlette.status import HTTP_303_SEE_OTHER 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.printer_log import PrinterLog from app.models.printer_type import PrinterType 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(), "printer_types": db.query(PrinterType).order_by(PrinterType.name).all(), }) @router.post("/printers") def create_printer( name: str = Form(...), location: str = Form(""), type_id: str = Form(""), bought_at: str = Form(""), db: Session = Depends(get_db), ): from datetime import date printer = Printer( name=name.strip(), location=location.strip() or None, type_id=int(type_id) if type_id else None, bought_at=date.fromisoformat(bought_at) if bought_at else None, ) db.add(printer) db.commit() return RedirectResponse(url="/printers", status_code=HTTP_303_SEE_OTHER) @router.get("/printers/{printer_id}", response_class=HTMLResponse) def printer_detail(printer_id: int, request: Request, db: Session = Depends(get_db)): printer = db.query(Printer).filter(Printer.id == printer_id).first() if not printer: from fastapi import HTTPException raise HTTPException(status_code=404, detail="Printer not found") return templates.TemplateResponse("printer_detail.html", { "request": request, "active": "printers", "printer": printer, }) @router.post("/printers/{printer_id}/log") def add_printer_log(printer_id: int, message: str = Form(...), db: Session = Depends(get_db)): entry = PrinterLog(printer_id=printer_id, message=message.strip()) db.add(entry) db.commit() return RedirectResponse(url=f"/printers/{printer_id}", status_code=HTTP_303_SEE_OTHER) @router.get("/printer-types", response_class=HTMLResponse) def printer_types_page(request: Request, db: Session = Depends(get_db)): return templates.TemplateResponse("printer_types.html", { "request": request, "active": "printers", "printer_types": db.query(PrinterType).order_by(PrinterType.name).all(), }) @router.post("/printer-types") def create_printer_type( name: str = Form(...), bed_x_mm: int = Form(...), bed_y_mm: int = Form(...), bed_z_mm: int = Form(...), db: Session = Depends(get_db), ): pt = PrinterType(name=name.strip(), bed_x_mm=bed_x_mm, bed_y_mm=bed_y_mm, bed_z_mm=bed_z_mm) db.add(pt) db.commit() return RedirectResponse(url="/printer-types", status_code=HTTP_303_SEE_OTHER) @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(), })