"""Cart app fragment endpoints. Exposes HTML fragments at ``/internal/fragments/`` for consumption by other coop apps via the fragment client. Fragments: cart-mini Cart icon with badge (or logo when empty) account-nav-item "orders" link for account dashboard """ from __future__ import annotations from quart import Blueprint, Response, request, g from shared.infrastructure.fragments import FRAGMENT_HEADER def register(): bp = Blueprint("fragments", __name__, url_prefix="/internal/fragments") # --------------------------------------------------------------- # Fragment handlers # --------------------------------------------------------------- async def _cart_mini(): from shared.services.registry import services from shared.infrastructure.urls import blog_url, cart_url from shared.sexp.jinja_bridge import sexp as render_sexp user_id = request.args.get("user_id", type=int) session_id = request.args.get("session_id") summary = await services.cart.cart_summary( g.s, user_id=user_id, session_id=session_id, ) count = summary.count + summary.calendar_count + summary.ticket_count oob = request.args.get("oob", "") return render_sexp( '(~cart-mini :cart-count cart-count :blog-url blog-url :cart-url cart-url :oob oob)', **{"cart-count": count, "blog-url": blog_url(""), "cart-url": cart_url(""), "oob": oob or None}, ) async def _account_nav_item(): from shared.infrastructure.urls import cart_url from shared.sexp.jinja_bridge import sexp as render_sexp return render_sexp( '(~account-nav-item :href href :label "orders")', href=cart_url("/orders/"), ) _handlers = { "cart-mini": _cart_mini, "account-nav-item": _account_nav_item, } # --------------------------------------------------------------- # Routing # --------------------------------------------------------------- @bp.before_request async def _require_fragment_header(): if not request.headers.get(FRAGMENT_HEADER): return Response("", status=403) @bp.get("/") async def get_fragment(fragment_type: str): handler = _handlers.get(fragment_type) if handler is None: return Response("", status=200, content_type="text/html") html = await handler() return Response(html, status=200, content_type="text/html") return bp