- Login page with JWT auth and role-based redirect - CS Dashboard: KPI cards, priority breakdown, recent tickets - FM Dashboard: tech workload, aging analysis, emergency alerts - CEO Dashboard: executive KPIs, charts, risk indicators - All Issues: filterable/sortable ticket table with pagination - Create Issue: form with category tree, property/unit selector, photo uploads - Issue Detail: full timeline, photo gallery, SLA status, action modals - Role-based nav bar: CS/FM/Executive links adapt to user role - Base template: shared Alpine.js app state, toast notifications, loading overlay
51 lines
1.6 KiB
Python
51 lines
1.6 KiB
Python
"""Frontend page routes — serve Jinja2 HTML templates for the SPA-like dashboard."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from fastapi import APIRouter, Request
|
|
from fastapi.responses import HTMLResponse
|
|
from fastapi.templating import Jinja2Templates
|
|
|
|
router = APIRouter(tags=["pages"])
|
|
|
|
templates = Jinja2Templates(directory=str(Path(__file__).resolve().parent.parent / "templates"))
|
|
|
|
|
|
@router.get("/login", response_class=HTMLResponse)
|
|
async def login_page(request: Request):
|
|
return templates.TemplateResponse(request, "login.html")
|
|
|
|
|
|
@router.get("/dashboard/cs", response_class=HTMLResponse)
|
|
async def cs_dashboard(request: Request):
|
|
return templates.TemplateResponse(request, "dashboard/cs.html")
|
|
|
|
|
|
@router.get("/dashboard/fm", response_class=HTMLResponse)
|
|
async def fm_dashboard(request: Request):
|
|
return templates.TemplateResponse(request, "dashboard/fm.html")
|
|
|
|
|
|
@router.get("/dashboard/ceo", response_class=HTMLResponse)
|
|
async def ceo_dashboard(request: Request):
|
|
return templates.TemplateResponse(request, "dashboard/ceo.html")
|
|
|
|
|
|
@router.get("/tickets", response_class=HTMLResponse)
|
|
async def ticket_list(request: Request):
|
|
return templates.TemplateResponse(request, "tickets/list.html")
|
|
|
|
|
|
@router.get("/tickets/new", response_class=HTMLResponse)
|
|
async def create_ticket_page(request: Request):
|
|
return templates.TemplateResponse(request, "tickets/new.html")
|
|
|
|
|
|
@router.get("/tickets/{ticket_id}", response_class=HTMLResponse)
|
|
async def ticket_detail_page(request: Request, ticket_id: int):
|
|
return templates.TemplateResponse(request, "tickets/detail.html", context={"ticket_id": ticket_id})
|