""" Page summary blueprint — shows upcoming events across all calendars for a container (e.g. the village hall). Routes: GET // — full page with first page of entries GET //entries — HTMX fragment for infinite scroll """ from __future__ import annotations from quart import Blueprint, g, request, render_template, make_response from shared.browser.app.utils.htmx import is_htmx_request from shared.infrastructure.cart_identity import current_cart_identity from shared.services.registry import services def register() -> Blueprint: bp = Blueprint("page_summary", __name__) async def _load_entries(post_id, page, per_page=20): """Load upcoming entries + pending ticket counts for current user.""" entries, has_more = await services.calendar.upcoming_entries_for_container( g.s, "page", post_id, page=page, per_page=per_page, ) # Pending ticket counts keyed by entry_id ident = current_cart_identity() pending_tickets = {} if entries: tickets = await services.calendar.pending_tickets( g.s, user_id=ident["user_id"], session_id=ident["session_id"], ) for t in tickets: if t.entry_id is not None: pending_tickets[t.entry_id] = pending_tickets.get(t.entry_id, 0) + 1 return entries, has_more, pending_tickets @bp.get("/") async def index(): post = g.post_data["post"] view = request.args.get("view", "list") page = int(request.args.get("page", 1)) entries, has_more, pending_tickets = await _load_entries(post["id"], page) ctx = dict( entries=entries, has_more=has_more, pending_tickets=pending_tickets, page=page, view=view, ) if is_htmx_request(): html = await render_template("_types/page_summary/_main_panel.html", **ctx) else: html = await render_template("_types/page_summary/index.html", **ctx) return await make_response(html, 200) @bp.get("/entries") async def entries_fragment(): post = g.post_data["post"] view = request.args.get("view", "list") page = int(request.args.get("page", 1)) entries, has_more, pending_tickets = await _load_entries(post["id"], page) html = await render_template( "_types/page_summary/_cards.html", entries=entries, has_more=has_more, pending_tickets=pending_tickets, page=page, view=view, ) return await make_response(html, 200) return bp