"""Page helpers for market defpage system.""" from __future__ import annotations from .cards import ( _market_cards_sx, _markets_grid, _no_markets_sx, _market_landing_content_sx, ) # --------------------------------------------------------------------------- # Page admin panel (used by _h_page_admin_content) # --------------------------------------------------------------------------- async def _markets_admin_panel_sx(ctx: dict) -> str: """Render the markets list + create form panel.""" from quart import g, url_for from shared.services.registry import services from shared.sx.helpers import sx_call from shared.sx.parser import SxExpr rights = ctx.get("rights") or {} is_admin = getattr(rights, "admin", False) if hasattr(rights, "admin") else rights.get("admin", False) has_access = ctx.get("has_access") can_create = has_access("page_admin.create_market") if callable(has_access) else is_admin csrf_token = ctx.get("csrf_token") csrf = csrf_token() if callable(csrf_token) else (csrf_token or "") post = ctx.get("post") or {} post_id = post.get("id") markets = await services.market.marketplaces_for_container(g.s, "page", post_id) if post_id else [] form_html = "" if can_create: create_url = url_for("page_admin.create_market") form_html = sx_call("crud-create-form", create_url=create_url, csrf=csrf, errors_id="market-create-errors", list_id="markets-list", placeholder="e.g. Suma, Craft Fair", btn_label="Add market") list_html = _markets_admin_list_sx(ctx, markets) return sx_call("crud-panel", form=SxExpr(form_html), list=SxExpr(list_html), list_id="markets-list") def _markets_admin_list_sx(ctx: dict, markets: list) -> str: """Render the markets list items.""" from quart import url_for from shared.utils import route_prefix from shared.sx.helpers import sx_call csrf_token = ctx.get("csrf_token") csrf = csrf_token() if callable(csrf_token) else (csrf_token or "") prefix = route_prefix() if not markets: return sx_call("empty-state", message="No markets yet. Create one above.", cls="text-gray-500 mt-4") parts = [] for m in markets: m_slug = getattr(m, "slug", "") or (m.get("slug", "") if isinstance(m, dict) else "") m_name = getattr(m, "name", "") or (m.get("name", "") if isinstance(m, dict) else "") post_slug = (ctx.get("post") or {}).get("slug", "") href = prefix + f"/{post_slug}/{m_slug}/" del_url = url_for("page_admin.delete_market", market_slug=m_slug) csrf_hdr = f'{{"X-CSRFToken":"{csrf}"}}' parts.append(sx_call("crud-item", href=href, name=m_name, slug=m_slug, del_url=del_url, csrf_hdr=csrf_hdr, list_id="markets-list", confirm_title="Delete market?", confirm_text="Products will be hidden (soft delete)")) return "".join(parts) # =========================================================================== # Page helpers # =========================================================================== def _register_market_helpers() -> None: from shared.sx.pages import register_page_helpers register_page_helpers("market", { "all-markets-content": _h_all_markets_content, "page-markets-content": _h_page_markets_content, "page-admin-content": _h_page_admin_content, "market-home-content": _h_market_home_content, "market-admin-content": _h_market_admin_content, }) async def _h_all_markets_content(**kw): from quart import g, url_for, request from shared.utils import route_prefix from shared.services.registry import services from shared.infrastructure.data_client import fetch_data from shared.contracts.dtos import PostDTO, dto_from_dict page = int(request.args.get("page", 1)) markets, has_more = await services.market.list_marketplaces( g.s, page=page, per_page=20, ) page_info = {} if markets: post_ids = list({m.container_id for m in markets if m.container_type == "page"}) if post_ids: raw_posts = await fetch_data("blog", "posts-by-ids", params={"ids": ",".join(str(i) for i in post_ids)}, required=False) or [] for raw_p in raw_posts: p = dto_from_dict(PostDTO, raw_p) page_info[p.id] = {"title": p.title, "slug": p.slug} if not markets: return _no_markets_sx() prefix = route_prefix() next_url = prefix + url_for("all_markets.markets_fragment", page=page + 1) cards = _market_cards_sx(markets, page_info, page, has_more, next_url) return _markets_grid(cards) async def _h_page_markets_content(slug=None, **kw): from quart import g, url_for, request from shared.utils import route_prefix from shared.services.registry import services post = g.post_data["post"] page = int(request.args.get("page", 1)) markets, has_more = await services.market.list_marketplaces( g.s, "page", post["id"], page=page, per_page=20, ) post_slug = post.get("slug", "") if not markets: return _no_markets_sx("No markets for this page") prefix = route_prefix() next_url = prefix + url_for("page_markets.markets_fragment", page=page + 1) cards = _market_cards_sx(markets, {}, page, has_more, next_url, show_page_badge=False, post_slug=post_slug) return _markets_grid(cards) async def _h_page_admin_content(slug=None, **kw): from shared.sx.page import get_template_context from shared.sx.helpers import sx_call ctx = await get_template_context() content = await _markets_admin_panel_sx(ctx) return sx_call("market-admin-content-wrap", inner=content) def _h_market_home_content(page_slug=None, market_slug=None, **kw): from quart import g post_data = getattr(g, "post_data", {}) post = post_data.get("post", {}) return _market_landing_content_sx(post) def _h_market_admin_content(page_slug=None, market_slug=None, **kw): return '"market admin"'