"""Account pages blueprint. Moved from federation/bp/auth — newsletters, fragment pages (tickets, bookings). Mounted at root /. GET page handlers replaced by defpage. """ from __future__ import annotations from quart import ( Blueprint, request, redirect, g, ) from sqlalchemy import select from shared.models import UserNewsletter from shared.models.ghost_membership_entities import GhostNewsletter from shared.infrastructure.urls import login_url from shared.infrastructure.fragments import fetch_fragment, fetch_fragments from shared.sx.helpers import sx_response def register(url_prefix="/"): account_bp = Blueprint("account", __name__, url_prefix=url_prefix) @account_bp.before_request async def _prepare_page_data(): """Fetch account_nav fragments and load data for defpage routes.""" # Fetch account nav items for layout (was in context_processor) events_nav, cart_nav, artdag_nav = await fetch_fragments([ ("events", "account-nav-item", {}), ("cart", "account-nav-item", {}), ("artdag", "nav-item", {}), ], required=False) g.account_nav = events_nav + cart_nav + artdag_nav if request.method != "GET": return endpoint = request.endpoint or "" # Newsletters page — load newsletter data if endpoint.endswith("defpage_newsletters"): result = await g.s.execute( select(GhostNewsletter).order_by(GhostNewsletter.name) ) all_newsletters = result.scalars().all() sub_result = await g.s.execute( select(UserNewsletter).where( UserNewsletter.user_id == g.user.id, ) ) user_subs = {un.newsletter_id: un for un in sub_result.scalars().all()} newsletter_list = [] for nl in all_newsletters: un = user_subs.get(nl.id) newsletter_list.append({ "newsletter": nl, "un": un, "subscribed": un.subscribed if un else False, }) g.newsletters_data = newsletter_list # Fragment page — load fragment from events service elif endpoint.endswith("defpage_fragment_page"): slug = request.view_args.get("slug") if slug and g.get("user"): fragment_html = await fetch_fragment( "events", "account-page", params={"slug": slug, "user_id": str(g.user.id)}, ) if not fragment_html: from quart import abort abort(404) g.fragment_page_data = fragment_html @account_bp.post("/newsletter//toggle/") async def toggle_newsletter(newsletter_id: int): if not g.get("user"): return "", 401 result = await g.s.execute( select(UserNewsletter).where( UserNewsletter.user_id == g.user.id, UserNewsletter.newsletter_id == newsletter_id, ) ) un = result.scalar_one_or_none() if un: un.subscribed = not un.subscribed else: un = UserNewsletter( user_id=g.user.id, newsletter_id=newsletter_id, subscribed=True, ) g.s.add(un) await g.s.flush() from sx.sx_components import render_newsletter_toggle return sx_response(render_newsletter_toggle(un)) return account_bp