From dd799cea8e0b085c542910b73994578da9a8a343 Mon Sep 17 00:00:00 2001 From: caoimhinr Date: Mon, 25 May 2026 19:30:43 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20add=20standalone=20web=20UI=20=E2=80=94?= =?UTF-8?q?=20tickets=20page=20with=20same=20style=20as=20homelab-dashboar?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - corvid/templates/base.html: simplified nav (Corvid logo, Tickets link only), no user footer, no SSO — identical dark theme and component styles - corvid/templates/tickets.html: copied verbatim from homelab-dashboard (all API paths are relative, no user-specific references) - corvid/main.py: /tickets HTML route + / redirect; templates loaded from package dir so they work whether installed or run from source - corvid/router.py: allow open access when TICKETS_API_KEY is not set (local/dev mode) — set the key to require auth for external access - pyproject.toml: add jinja2>=3.1 dependency Co-Authored-By: Claude Sonnet 4.6 --- Dockerfile | 1 + corvid/main.py | 20 +- corvid/router.py | 3 + corvid/templates/base.html | 395 +++++++++++++ corvid/templates/tickets.html | 1001 +++++++++++++++++++++++++++++++++ pyproject.toml | 1 + 6 files changed, 1420 insertions(+), 1 deletion(-) create mode 100644 corvid/templates/base.html create mode 100644 corvid/templates/tickets.html diff --git a/Dockerfile b/Dockerfile index 5272f4a..b98eb56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,7 @@ COPY alembic.ini . COPY alembic/ alembic/ COPY corvid/ corvid/ COPY entrypoint.sh . +# templates are bundled inside corvid/ package dir — no extra COPY needed RUN chmod +x entrypoint.sh EXPOSE 8080 diff --git a/corvid/main.py b/corvid/main.py index 3b63ddd..64190e7 100644 --- a/corvid/main.py +++ b/corvid/main.py @@ -1,11 +1,17 @@ +import os from contextlib import asynccontextmanager -from fastapi import FastAPI +from fastapi import FastAPI, Request +from fastapi.responses import HTMLResponse, RedirectResponse +from fastapi.templating import Jinja2Templates from .config import TICKETS_API_KEY from .database import get_db from .router import make_router +_TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), "templates") +templates = Jinja2Templates(directory=_TEMPLATE_DIR) + @asynccontextmanager async def lifespan(app: FastAPI): @@ -17,6 +23,18 @@ app = FastAPI(title="Corvid", lifespan=lifespan) app.include_router(make_router(api_key=TICKETS_API_KEY, get_db=get_db)) +@app.get("/", include_in_schema=False) +async def root(): + return RedirectResponse("/tickets") + + +@app.get("/tickets", response_class=HTMLResponse, include_in_schema=False) +async def tickets_page(request: Request): + return templates.TemplateResponse( + "tickets.html", {"request": request, "active_page": "tickets"} + ) + + @app.get("/health") async def health(): return {"status": "ok"} diff --git a/corvid/router.py b/corvid/router.py index f467bf3..8443c91 100644 --- a/corvid/router.py +++ b/corvid/router.py @@ -111,6 +111,9 @@ def make_router(api_key: str, get_db, require_user=None) -> APIRouter: return {"username": "claude", "email": "claude@internal"} if require_user is not None: return require_user(request) + if not api_key: + # No key configured — open / local mode + return {"username": "local", "email": "local@localhost"} raise HTTPException(401, "unauthorized") # ── Ticket endpoints ────────────────────────────────────────────────────── diff --git a/corvid/templates/base.html b/corvid/templates/base.html new file mode 100644 index 0000000..07fd8ee --- /dev/null +++ b/corvid/templates/base.html @@ -0,0 +1,395 @@ + + + + + +{% block title %}Corvid{% endblock %} — Corvid + +{% block head %}{% endblock %} + + + + + + + +
+
+
+ + {% block page_title %}{% endblock %} +
+ {% block topbar_meta %}{% endblock %} +
+
+ {% block content %}{% endblock %} +
+
+ +
+ + + +{% block scripts %}{% endblock %} + + diff --git a/corvid/templates/tickets.html b/corvid/templates/tickets.html new file mode 100644 index 0000000..1675ca6 --- /dev/null +++ b/corvid/templates/tickets.html @@ -0,0 +1,1001 @@ +{% extends "base.html" %} +{% block title %}Tickets{% endblock %} +{% block page_title %}Tickets{% endblock %} +{% block topbar_meta %}{% endblock %} + +{% block head %} + + + +{% endblock %} + +{% block content %} + + +
+
+
+ + + + +
+
+ + + + +
+
+ Sort: + + + + +
+
+
+
+ +
+ +
+
+ + +
+
+
Loading…
+
+
+ + +
+
+
+
+

+
+
+ + + +
+
+
+ Status: + Type: + Effort: + By: + Submitted: + + + GUID: +
+
+
+
+ +
+ Attachments + +
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ +{% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/pyproject.toml b/pyproject.toml index 97bbca6..40e2409 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ "uvicorn[standard]>=0.32", "alembic>=1.14", "pydantic>=2.0", + "jinja2>=3.1", ] [project.optional-dependencies]