"""Cart layout registration and header builders.""" from __future__ import annotations from typing import Any from shared.sx.parser import SxExpr def _register_cart_layouts() -> None: from shared.sx.layouts import register_custom_layout register_custom_layout("cart-page", _cart_page_full, _cart_page_oob) register_custom_layout("cart-admin", _cart_admin_full, _cart_admin_oob) # --------------------------------------------------------------------------- # Header helpers # --------------------------------------------------------------------------- def _ensure_post_ctx(ctx: dict, page_post: Any) -> dict: """Ensure ctx has a 'post' dict from page_post DTO.""" if ctx.get("post") or not page_post: return ctx return {**ctx, "post": { "id": getattr(page_post, "id", None), "slug": getattr(page_post, "slug", ""), "title": getattr(page_post, "title", ""), "feature_image": getattr(page_post, "feature_image", None), }} async def _ensure_container_nav(ctx: dict) -> dict: """Fetch container_nav if not already present.""" if ctx.get("container_nav"): return ctx post = ctx.get("post") or {} post_id = post.get("id") if not post_id: return ctx slug = post.get("slug", "") from shared.infrastructure.fragments import fetch_fragments nav_params = { "container_type": "page", "container_id": str(post_id), "post_slug": slug, } events_nav, market_nav = await fetch_fragments([ ("events", "container-nav", nav_params), ("market", "container-nav", nav_params), ], required=False) return {**ctx, "container_nav": events_nav + market_nav} async def _post_header_sx(ctx: dict, page_post: Any, *, oob: bool = False) -> str: from shared.sx.helpers import post_header_sx as _shared_post_header_sx ctx = _ensure_post_ctx(ctx, page_post) ctx = await _ensure_container_nav(ctx) return await _shared_post_header_sx(ctx, oob=oob) def _cart_header_sx(ctx: dict, *, oob: bool = False) -> str: from shared.sx.helpers import sx_call, call_url return sx_call( "menu-row-sx", id="cart-row", level=1, colour="sky", link_href=call_url(ctx, "cart_url", "/"), link_label="cart", icon="fa fa-shopping-cart", child_id="cart-header-child", oob=oob, ) def _page_cart_header_sx(ctx: dict, page_post: Any, *, oob: bool = False) -> str: from shared.sx.helpers import sx_call, call_url slug = page_post.slug if page_post else "" title = ((page_post.title if page_post else None) or "")[:160] label_sx = sx_call("cart-page-label", feature_image=page_post.feature_image if page_post else None, title=title) nav_sx = sx_call("cart-all-carts-link", href=call_url(ctx, "cart_url", "/")) return sx_call( "menu-row-sx", id="page-cart-row", level=2, colour="sky", link_href=call_url(ctx, "cart_url", f"/{slug}/"), link_label_content=SxExpr(label_sx), nav=SxExpr(nav_sx), oob=oob, ) async def _cart_page_admin_header_sx(ctx: dict, page_post: Any, *, oob: bool = False, selected: str = "") -> str: from shared.sx.helpers import post_admin_header_sx slug = page_post.slug if page_post else "" ctx = _ensure_post_ctx(ctx, page_post) return await post_admin_header_sx(ctx, slug, oob=oob, selected=selected) # --------------------------------------------------------------------------- # Layout functions # --------------------------------------------------------------------------- async def _cart_page_full(ctx: dict, **kw: Any) -> str: from shared.sx.helpers import render_to_sx_with_env page_post = ctx.get("page_post") env = {} return await render_to_sx_with_env("cart-page-layout-full", env, cart_row=SxExpr(_cart_header_sx(ctx)), page_cart_row=SxExpr(_page_cart_header_sx(ctx, page_post)), ) async def _cart_page_oob(ctx: dict, **kw: Any) -> str: from shared.sx.helpers import render_to_sx_with_env, root_header_sx page_post = ctx.get("page_post") env = {} return await render_to_sx_with_env("cart-page-layout-oob", env, root_header_oob=SxExpr(await root_header_sx(ctx, oob=True)), cart_row_oob=SxExpr(_cart_header_sx(ctx, oob=True)), page_cart_row=SxExpr(_page_cart_header_sx(ctx, page_post)), ) async def _cart_admin_full(ctx: dict, **kw: Any) -> str: from shared.sx.helpers import render_to_sx_with_env page_post = ctx.get("page_post") selected = kw.get("selected", "") env = {} return await render_to_sx_with_env("cart-admin-layout-full", env, post_header=SxExpr(await _post_header_sx(ctx, page_post)), admin_header=SxExpr(await _cart_page_admin_header_sx(ctx, page_post, selected=selected)), ) async def _cart_admin_oob(ctx: dict, **kw: Any) -> str: page_post = ctx.get("page_post") selected = kw.get("selected", "") return await _cart_page_admin_header_sx(ctx, page_post, oob=True, selected=selected)