"""The per-frame HTML pages: Photos (/frames/{id}), Configuration, and Stats tabs, all inside the sidebar app shell. Data loading happens client-side against /api/frames/{id}/... (routers/api_frames.py); these routes just authorize and render the scaffold.""" from __future__ import annotations from fastapi import APIRouter, Depends, HTTPException, Request from fastapi.responses import HTMLResponse, RedirectResponse from fastapi.templating import Jinja2Templates from sqlalchemy.orm import Session from ..auth import can_view_frame, current_user from ..db import get_db from ..image_pipeline import ( DEFAULT_PALETTE_RGB, DISPLAY_MODE_LABELS, PALETTE_LABELS, palette_to_hex, ) from ..models import Frame from ..quiet_hours import ALL_TIMEZONES from .common import shell_context router = APIRouter() templates = Jinja2Templates(directory="app/templates") def _frame_page(request: Request, db: Session, frame_id: int, template: str, tab: str, **extra): user = current_user(request, db) if user is None: return RedirectResponse(f"/login?next=/frames/{frame_id}", status_code=303) frame = db.get(Frame, frame_id) if frame is None or not can_view_frame(db, user, frame): raise HTTPException(404, "No such frame") ctx = shell_context(request, db, user, active_frame=frame) ctx.update({"frame": frame, "active_tab": tab, **extra}) return templates.TemplateResponse(template, ctx) @router.get("/frames/{frame_id}", response_class=HTMLResponse) def frame_photos_page(frame_id: int, request: Request, db: Session = Depends(get_db)): return _frame_page(request, db, frame_id, "frame_photos.html", "photos") @router.get("/frames/{frame_id}/config", response_class=HTMLResponse) def frame_config_page(frame_id: int, request: Request, db: Session = Depends(get_db)): return _frame_page( request, db, frame_id, "frame_config.html", "config", timezones=ALL_TIMEZONES, palette_labels=PALETTE_LABELS, default_palette_rgb=DEFAULT_PALETTE_RGB, palette_to_hex=palette_to_hex, display_mode_labels=DISPLAY_MODE_LABELS, ) @router.get("/frames/{frame_id}/stats", response_class=HTMLResponse) def frame_stats_page(frame_id: int, request: Request, db: Session = Depends(get_db)): return _frame_page(request, db, frame_id, "frame_stats.html", "stats")