Phase 7: Replace render_template() with s-expression rendering in all POST/PUT/DELETE routes
Eliminates all render_template() calls from POST/PUT/DELETE handlers across all 7 services. Moves sexp_components.py into sexp/ packages per service. - Blog: like toggle, snippets, cache clear, features/sumup/entry panels, create/delete market, WYSIWYG editor panel (render_editor_panel) - Federation: like/unlike/boost/unboost, follow/unfollow, actor card, interaction buttons - Events: ticket widget, checkin, confirm/decline/provisional, tickets config, posts CRUD, description edit/save, calendar/slot/ticket_type CRUD, payments, buy tickets, day main panel, entry page - Market: like toggle, cart add response - Account: newsletter toggle - Cart: checkout error pages (3 handlers) - Orders: checkout error page (1 handler) Remaining render_template() calls are exclusively in GET handlers and internal services (email templates, fragment endpoints). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import path_setup # noqa: F401 # adds shared/ to sys.path
|
||||
import sexp_components # noqa: F401 # ensure Hypercorn --reload watches this file
|
||||
import sexp.sexp_components as sexp_components # noqa: F401 # ensure Hypercorn --reload watches this file
|
||||
from pathlib import Path
|
||||
|
||||
from quart import g, abort, request
|
||||
|
||||
@@ -66,7 +66,7 @@ def register() -> Blueprint:
|
||||
entries, has_more, pending_tickets, page_info = await _load_entries(page)
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_all_events_page, render_all_events_oob
|
||||
from sexp.sexp_components import render_all_events_page, render_all_events_oob
|
||||
|
||||
ctx = await get_template_context()
|
||||
if is_htmx_request():
|
||||
@@ -83,7 +83,7 @@ def register() -> Blueprint:
|
||||
|
||||
entries, has_more, pending_tickets, page_info = await _load_entries(page)
|
||||
|
||||
from sexp_components import render_all_events_cards
|
||||
from sexp.sexp_components import render_all_events_cards
|
||||
html = await render_all_events_cards(entries, has_more, pending_tickets, page_info, page, view)
|
||||
return await make_response(html, 200)
|
||||
|
||||
@@ -124,12 +124,8 @@ def register() -> Blueprint:
|
||||
if ident["session_id"] is not None:
|
||||
frag_params["session_id"] = ident["session_id"]
|
||||
|
||||
widget_html = await render_template(
|
||||
"_types/page_summary/_ticket_widget.html",
|
||||
entry=entry,
|
||||
qty=qty,
|
||||
ticket_url="/all-tickets/adjust",
|
||||
)
|
||||
from sexp.sexp_components import render_ticket_widget
|
||||
widget_html = render_ticket_widget(entry, qty, "/all-tickets/adjust")
|
||||
mini_html = await fetch_fragment("cart", "cart-mini", params=frag_params, required=False)
|
||||
return await make_response(widget_html + mini_html, 200)
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ def register():
|
||||
from shared.browser.app.utils.htmx import is_htmx_request
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_calendar_admin_page, render_calendar_admin_oob
|
||||
from sexp.sexp_components import render_calendar_admin_page, render_calendar_admin_oob
|
||||
|
||||
tctx = await get_template_context()
|
||||
if not is_htmx_request():
|
||||
@@ -34,12 +34,8 @@ def register():
|
||||
@bp.get("/description/")
|
||||
@require_admin
|
||||
async def calendar_description_edit(calendar_slug: str, **kwargs):
|
||||
# g.post and g.calendar should already be set by the parent calendar bp
|
||||
html = await render_template(
|
||||
"_types/calendar/admin/_description_edit.html",
|
||||
post=g.post_data['post'],
|
||||
calendar=g.calendar,
|
||||
)
|
||||
from sexp.sexp_components import render_calendar_description_edit
|
||||
html = render_calendar_description_edit(g.calendar)
|
||||
return await make_response(html)
|
||||
|
||||
|
||||
@@ -54,24 +50,16 @@ def register():
|
||||
g.calendar.description = description
|
||||
await g.s.flush()
|
||||
|
||||
html = await render_template(
|
||||
"_types/calendar/admin/_description.html",
|
||||
post=g.post_data['post'],
|
||||
calendar=g.calendar,
|
||||
oob=True
|
||||
)
|
||||
from sexp.sexp_components import render_calendar_description
|
||||
html = render_calendar_description(g.calendar, oob=True)
|
||||
return await make_response(html)
|
||||
|
||||
|
||||
@bp.get("/description/view/")
|
||||
@require_admin
|
||||
async def calendar_description_view(calendar_slug: str, **kwargs):
|
||||
# just render the display version without touching the DB (used by Cancel)
|
||||
html = await render_template(
|
||||
"_types/calendar/admin/_description.html",
|
||||
post=g.post_data['post'],
|
||||
calendar=g.calendar,
|
||||
)
|
||||
from sexp.sexp_components import render_calendar_description
|
||||
html = render_calendar_description(g.calendar)
|
||||
return await make_response(html)
|
||||
|
||||
return bp
|
||||
|
||||
@@ -143,7 +143,7 @@ def register():
|
||||
confirmed_entries = visible.confirmed_entries
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_calendar_page, render_calendar_oob
|
||||
from sexp.sexp_components import render_calendar_page, render_calendar_oob
|
||||
|
||||
tctx = await get_template_context()
|
||||
tctx.update(dict(
|
||||
@@ -183,7 +183,10 @@ def register():
|
||||
description = (form.get("description") or "").strip()
|
||||
|
||||
await update_calendar_description(g.calendar, description)
|
||||
html = await render_template("_types/calendar/admin/index.html")
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import _calendar_admin_main_panel_html
|
||||
ctx = await get_template_context()
|
||||
html = _calendar_admin_main_panel_html(ctx)
|
||||
return await make_response(html, 200)
|
||||
|
||||
|
||||
@@ -199,10 +202,14 @@ def register():
|
||||
|
||||
# If we have post context (blog-embedded mode), update nav
|
||||
post_data = getattr(g, "post_data", None)
|
||||
html = await render_template("_types/calendars/index.html")
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_calendars_list_panel
|
||||
ctx = await get_template_context()
|
||||
html = render_calendars_list_panel(ctx)
|
||||
|
||||
if post_data:
|
||||
from shared.services.entry_associations import get_associated_entries
|
||||
from sexp.sexp_components import render_post_nav_entries_oob
|
||||
|
||||
post_id = (post_data.get("post") or {}).get("id")
|
||||
cals = (
|
||||
@@ -214,13 +221,7 @@ def register():
|
||||
).scalars().all()
|
||||
|
||||
associated_entries = await get_associated_entries(g.s, post_id)
|
||||
|
||||
nav_oob = await render_template(
|
||||
"_types/post/admin/_nav_entries_oob.html",
|
||||
associated_entries=associated_entries,
|
||||
calendars=cals,
|
||||
post=post_data["post"],
|
||||
)
|
||||
nav_oob = render_post_nav_entries_oob(associated_entries, cals, post_data["post"])
|
||||
html = html + nav_oob
|
||||
|
||||
return await make_response(html, 200)
|
||||
|
||||
@@ -216,7 +216,49 @@ def register():
|
||||
if ident["session_id"] is not None:
|
||||
frag_params["session_id"] = ident["session_id"]
|
||||
|
||||
html = await render_template("_types/day/_main_panel.html")
|
||||
# Re-query day entries for the sexp component
|
||||
from datetime import date as date_cls, timedelta
|
||||
from bp.calendar.services import get_visible_entries_for_period
|
||||
from quart import session as qsession
|
||||
|
||||
period_start = datetime(year, month, day, tzinfo=timezone.utc)
|
||||
period_end = period_start + timedelta(days=1)
|
||||
user = getattr(g, "user", None)
|
||||
session_id = qsession.get("calendar_sid")
|
||||
|
||||
visible = await get_visible_entries_for_period(
|
||||
sess=g.s,
|
||||
calendar_id=g.calendar.id,
|
||||
period_start=period_start,
|
||||
period_end=period_end,
|
||||
user=user,
|
||||
session_id=session_id,
|
||||
)
|
||||
|
||||
# Query day slots for this weekday
|
||||
day_date = date_cls(year, month, day)
|
||||
weekday_attr = ["mon","tue","wed","thu","fri","sat","sun"][day_date.weekday()]
|
||||
stmt = select(CalendarSlot).where(
|
||||
CalendarSlot.calendar_id == g.calendar.id,
|
||||
getattr(CalendarSlot, weekday_attr) == True,
|
||||
CalendarSlot.deleted_at.is_(None),
|
||||
).order_by(CalendarSlot.time_start.asc(), CalendarSlot.id.asc())
|
||||
result = await g.s.execute(stmt)
|
||||
day_slots = list(result.scalars())
|
||||
|
||||
styles = getattr(g, "styles", None) or {}
|
||||
ctx = {
|
||||
"calendar": g.calendar,
|
||||
"day_entries": visible.merged_entries,
|
||||
"day": day,
|
||||
"month": month,
|
||||
"year": year,
|
||||
"hx_select_search": "#main-panel",
|
||||
"styles": styles,
|
||||
}
|
||||
|
||||
from sexp.sexp_components import render_day_main_panel
|
||||
html = render_day_main_panel(ctx)
|
||||
mini_html = await fetch_fragment("cart", "cart-mini", params=frag_params, required=False)
|
||||
return await make_response(html + mini_html, 200)
|
||||
|
||||
|
||||
@@ -109,15 +109,9 @@ def register():
|
||||
session_id=session_id,
|
||||
)
|
||||
|
||||
# Render OOB template
|
||||
nav_oob = await render_template(
|
||||
"_types/day/admin/_nav_entries_oob.html",
|
||||
confirmed_entries=visible.confirmed_entries,
|
||||
post=g.post_data["post"],
|
||||
calendar=calendar,
|
||||
day_date=day_date,
|
||||
)
|
||||
return nav_oob
|
||||
# Render OOB nav
|
||||
from sexp.sexp_components import render_day_entries_nav_oob
|
||||
return render_day_entries_nav_oob(visible.confirmed_entries, calendar, day_date)
|
||||
|
||||
async def get_post_nav_oob(entry_id: int):
|
||||
"""Helper to generate OOB update for post entries nav when entry state changes"""
|
||||
@@ -152,13 +146,9 @@ def register():
|
||||
)
|
||||
).scalars().all()
|
||||
|
||||
# Render OOB template for this post's nav
|
||||
nav_oob = await render_template(
|
||||
"_types/post/admin/_nav_entries_oob.html",
|
||||
associated_entries=associated_entries,
|
||||
calendars=calendars,
|
||||
post=post,
|
||||
)
|
||||
# Render OOB nav for this post
|
||||
from sexp.sexp_components import render_post_nav_entries_oob
|
||||
nav_oob = render_post_nav_entries_oob(associated_entries, calendars, post)
|
||||
nav_oobs.append(nav_oob)
|
||||
|
||||
return "".join(nav_oobs)
|
||||
@@ -250,19 +240,15 @@ def register():
|
||||
@require_admin
|
||||
async def get(entry_id: int, **rest):
|
||||
from shared.browser.app.utils.htmx import is_htmx_request
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_entry_page, render_entry_oob
|
||||
|
||||
# Full template for both HTMX and normal requests
|
||||
tctx = await get_template_context()
|
||||
if not is_htmx_request():
|
||||
# Normal browser request: full page with layout
|
||||
html = await render_template(
|
||||
"_types/entry/index.html",
|
||||
)
|
||||
html = await render_entry_page(tctx)
|
||||
else:
|
||||
|
||||
html = await render_template(
|
||||
"_types/entry/_oob_elements.html",
|
||||
)
|
||||
|
||||
html = await render_entry_oob(tctx)
|
||||
|
||||
return await make_response(html, 200)
|
||||
|
||||
@bp.get("/edit/")
|
||||
@@ -431,10 +417,11 @@ def register():
|
||||
# Get nav OOB update
|
||||
nav_oob = await get_day_nav_oob(year, month, day)
|
||||
|
||||
html = await render_template(
|
||||
"_types/entry/index.html",
|
||||
#entry=entry,
|
||||
)
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_entry_page
|
||||
|
||||
tctx = await get_template_context()
|
||||
html = await render_entry_page(tctx)
|
||||
return await make_response(html + nav_oob, 200)
|
||||
|
||||
|
||||
@@ -457,8 +444,10 @@ def register():
|
||||
day_nav_oob = await get_day_nav_oob(year, month, day)
|
||||
post_nav_oob = await get_post_nav_oob(entry_id)
|
||||
|
||||
# redirect back to calendar admin or order page as you prefer
|
||||
html = await render_template("_types/entry/_optioned.html")
|
||||
# Re-read entry to get updated state
|
||||
await g.s.refresh(g.entry)
|
||||
from sexp.sexp_components import render_entry_optioned
|
||||
html = render_entry_optioned(g.entry, g.calendar, day, month, year)
|
||||
return await make_response(html + day_nav_oob + post_nav_oob, 200)
|
||||
|
||||
@bp.post("/decline/")
|
||||
@@ -480,8 +469,10 @@ def register():
|
||||
day_nav_oob = await get_day_nav_oob(year, month, day)
|
||||
post_nav_oob = await get_post_nav_oob(entry_id)
|
||||
|
||||
# redirect back to calendar admin or order page as you prefer
|
||||
html = await render_template("_types/entry/_optioned.html")
|
||||
# Re-read entry to get updated state
|
||||
await g.s.refresh(g.entry)
|
||||
from sexp.sexp_components import render_entry_optioned
|
||||
html = render_entry_optioned(g.entry, g.calendar, day, month, year)
|
||||
return await make_response(html + day_nav_oob + post_nav_oob, 200)
|
||||
|
||||
@bp.post("/provisional/")
|
||||
@@ -503,8 +494,10 @@ def register():
|
||||
day_nav_oob = await get_day_nav_oob(year, month, day)
|
||||
post_nav_oob = await get_post_nav_oob(entry_id)
|
||||
|
||||
# redirect back to calendar admin or order page as you prefer
|
||||
html = await render_template("_types/entry/_optioned.html")
|
||||
# Re-read entry to get updated state
|
||||
await g.s.refresh(g.entry)
|
||||
from sexp.sexp_components import render_entry_optioned
|
||||
html = render_entry_optioned(g.entry, g.calendar, day, month, year)
|
||||
return await make_response(html + day_nav_oob + post_nav_oob, 200)
|
||||
|
||||
@bp.post("/tickets/")
|
||||
@@ -546,7 +539,9 @@ def register():
|
||||
await g.s.flush()
|
||||
|
||||
# Return just the tickets fragment (targeted by hx-target="#entry-tickets-...")
|
||||
html = await render_template("_types/entry/_tickets.html")
|
||||
await g.s.refresh(g.entry)
|
||||
from sexp.sexp_components import render_entry_tickets_config
|
||||
html = render_entry_tickets_config(g.entry, g.calendar, request.view_args.get("day"), request.view_args.get("month"), request.view_args.get("year"))
|
||||
return await make_response(html, 200)
|
||||
|
||||
@bp.get("/posts/search/")
|
||||
@@ -596,11 +591,10 @@ def register():
|
||||
entry_posts = await get_entry_posts(g.s, entry_id)
|
||||
|
||||
# Return updated posts list + OOB nav update
|
||||
html = await render_template("_types/entry/_posts.html")
|
||||
nav_oob = await render_template(
|
||||
"_types/entry/admin/_nav_posts_oob.html",
|
||||
entry_posts=entry_posts,
|
||||
)
|
||||
from sexp.sexp_components import render_entry_posts_panel, render_entry_posts_nav_oob
|
||||
va = request.view_args or {}
|
||||
html = render_entry_posts_panel(entry_posts, g.entry, g.calendar, va.get("day"), va.get("month"), va.get("year"))
|
||||
nav_oob = render_entry_posts_nav_oob(entry_posts)
|
||||
return await make_response(html + nav_oob, 200)
|
||||
|
||||
@bp.delete("/posts/<int:post_id>/")
|
||||
@@ -619,11 +613,10 @@ def register():
|
||||
entry_posts = await get_entry_posts(g.s, entry_id)
|
||||
|
||||
# Return updated posts list + OOB nav update
|
||||
html = await render_template("_types/entry/_posts.html")
|
||||
nav_oob = await render_template(
|
||||
"_types/entry/admin/_nav_posts_oob.html",
|
||||
entry_posts=entry_posts,
|
||||
)
|
||||
from sexp.sexp_components import render_entry_posts_panel, render_entry_posts_nav_oob
|
||||
va = request.view_args or {}
|
||||
html = render_entry_posts_panel(entry_posts, g.entry, g.calendar, va.get("day"), va.get("month"), va.get("year"))
|
||||
nav_oob = render_entry_posts_nav_oob(entry_posts)
|
||||
return await make_response(html + nav_oob, 200)
|
||||
|
||||
return bp
|
||||
|
||||
@@ -36,7 +36,7 @@ def register():
|
||||
@cache_page(tag="calendars")
|
||||
async def home(**kwargs):
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_calendars_page, render_calendars_oob
|
||||
from sexp.sexp_components import render_calendars_page, render_calendars_oob
|
||||
|
||||
ctx = await get_template_context()
|
||||
if not is_htmx_request():
|
||||
@@ -68,13 +68,15 @@ def register():
|
||||
except Exception as e:
|
||||
return await make_response(f'<div class="text-red-600 text-sm">{e}</div>', 422)
|
||||
|
||||
html = await render_template(
|
||||
"_types/calendars/index.html",
|
||||
)
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_calendars_list_panel
|
||||
ctx = await get_template_context()
|
||||
html = render_calendars_list_panel(ctx)
|
||||
|
||||
# Blog-embedded mode: also update post nav
|
||||
if post_data:
|
||||
from shared.services.entry_associations import get_associated_entries
|
||||
from sexp.sexp_components import render_post_nav_entries_oob
|
||||
|
||||
cals = (
|
||||
await g.s.execute(
|
||||
@@ -85,14 +87,7 @@ def register():
|
||||
).scalars().all()
|
||||
|
||||
associated_entries = await get_associated_entries(g.s, post_id)
|
||||
|
||||
nav_oob = await render_template(
|
||||
"_types/post/admin/_nav_entries_oob.html",
|
||||
associated_entries=associated_entries,
|
||||
calendars=cals,
|
||||
post=post_data["post"],
|
||||
)
|
||||
|
||||
nav_oob = render_post_nav_entries_oob(associated_entries, cals, post_data["post"])
|
||||
html = html + nav_oob
|
||||
|
||||
return await make_response(html)
|
||||
|
||||
@@ -18,7 +18,7 @@ def register():
|
||||
from shared.browser.app.utils.htmx import is_htmx_request
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_day_admin_page, render_day_admin_oob
|
||||
from sexp.sexp_components import render_day_admin_page, render_day_admin_oob
|
||||
|
||||
tctx = await get_template_context()
|
||||
if not is_htmx_request():
|
||||
|
||||
@@ -121,7 +121,7 @@ def register():
|
||||
- pending only for current user/session
|
||||
"""
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_day_page, render_day_oob
|
||||
from sexp.sexp_components import render_day_page, render_day_oob
|
||||
|
||||
tctx = await get_template_context()
|
||||
if not is_htmx_request():
|
||||
|
||||
@@ -24,7 +24,7 @@ def register():
|
||||
@bp.get("/")
|
||||
async def home(**kwargs):
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_markets_page, render_markets_oob
|
||||
from sexp.sexp_components import render_markets_page, render_markets_oob
|
||||
|
||||
ctx = await get_template_context()
|
||||
if not is_htmx_request():
|
||||
@@ -52,7 +52,10 @@ def register():
|
||||
except Exception as e:
|
||||
return await make_response(f'<div class="text-red-600 text-sm">{e}</div>', 422)
|
||||
|
||||
html = await render_template("_types/markets/index.html")
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_markets_list_panel
|
||||
ctx = await get_template_context()
|
||||
html = render_markets_list_panel(ctx)
|
||||
return await make_response(html)
|
||||
|
||||
@bp.delete("/<market_slug>/")
|
||||
@@ -63,7 +66,10 @@ def register():
|
||||
if not deleted:
|
||||
return await make_response("Market not found", 404)
|
||||
|
||||
html = await render_template("_types/markets/index.html")
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_markets_list_panel
|
||||
ctx = await get_template_context()
|
||||
html = render_markets_list_panel(ctx)
|
||||
return await make_response(html)
|
||||
|
||||
return bp
|
||||
|
||||
@@ -46,7 +46,7 @@ def register() -> Blueprint:
|
||||
entries, has_more, pending_tickets = await _load_entries(post["id"], page)
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_page_summary_page, render_page_summary_oob
|
||||
from sexp.sexp_components import render_page_summary_page, render_page_summary_oob
|
||||
|
||||
ctx = await get_template_context()
|
||||
if is_htmx_request():
|
||||
@@ -64,7 +64,7 @@ def register() -> Blueprint:
|
||||
|
||||
entries, has_more, pending_tickets = await _load_entries(post["id"], page)
|
||||
|
||||
from sexp_components import render_page_summary_cards
|
||||
from sexp.sexp_components import render_page_summary_cards
|
||||
html = await render_page_summary_cards(entries, has_more, pending_tickets, {}, page, view, post)
|
||||
return await make_response(html, 200)
|
||||
|
||||
@@ -105,12 +105,8 @@ def register() -> Blueprint:
|
||||
if ident["session_id"] is not None:
|
||||
frag_params["session_id"] = ident["session_id"]
|
||||
|
||||
widget_html = await render_template(
|
||||
"_types/page_summary/_ticket_widget.html",
|
||||
entry=entry,
|
||||
qty=qty,
|
||||
ticket_url=f"/{g.post_slug}/tickets/adjust",
|
||||
)
|
||||
from sexp.sexp_components import render_ticket_widget
|
||||
widget_html = render_ticket_widget(entry, qty, f"/{g.post_slug}/tickets/adjust")
|
||||
mini_html = await fetch_fragment("cart", "cart-mini", params=frag_params, required=False)
|
||||
return await make_response(widget_html + mini_html, 200)
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ def register():
|
||||
pay_ctx = await _load_payment_ctx()
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_payments_page, render_payments_oob
|
||||
from sexp.sexp_components import render_payments_page, render_payments_oob
|
||||
|
||||
ctx = await get_template_context()
|
||||
ctx.update(pay_ctx)
|
||||
@@ -80,8 +80,11 @@ def register():
|
||||
|
||||
await call_action("blog", "update-page-config", payload=payload)
|
||||
|
||||
ctx = await _load_payment_ctx()
|
||||
html = await render_template("_types/payments/_main_panel.html", **ctx)
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp.sexp_components import render_payments_panel
|
||||
ctx = await get_template_context()
|
||||
ctx.update(await _load_payment_ctx())
|
||||
html = render_payments_panel(ctx)
|
||||
return await make_response(html)
|
||||
|
||||
return bp
|
||||
|
||||
@@ -74,12 +74,8 @@ def register():
|
||||
slot = await svc_get_slot(g.s, slot_id)
|
||||
if not slot:
|
||||
return await make_response("Not found", 404)
|
||||
html = await render_template(
|
||||
"_types/slot/_main_panel.html",
|
||||
slot=slot,
|
||||
#post=g.post_data['post'],
|
||||
#calendar=g.calendar,
|
||||
)
|
||||
from sexp.sexp_components import render_slot_main_panel
|
||||
html = render_slot_main_panel(slot, g.calendar)
|
||||
return await make_response(html)
|
||||
|
||||
@bp.delete("/")
|
||||
@@ -88,7 +84,8 @@ def register():
|
||||
async def slot_delete(slot_id: int, **kwargs):
|
||||
await svc_delete_slot(g.s, slot_id)
|
||||
slots = await svc_list_slots(g.s, g.calendar.id)
|
||||
html = await render_template("_types/slots/_man_panel.html", calendar=g.calendar, slots=slots)
|
||||
from sexp.sexp_components import render_slots_table
|
||||
html = render_slots_table(slots, g.calendar)
|
||||
return await make_response(html)
|
||||
|
||||
@bp.put("/")
|
||||
@@ -170,11 +167,8 @@ def register():
|
||||
}
|
||||
), 422
|
||||
|
||||
html = await render_template(
|
||||
"_types/slot/_main_panel.html",
|
||||
slot=slot,
|
||||
oob=True,
|
||||
)
|
||||
from sexp.sexp_components import render_slot_main_panel
|
||||
html = render_slot_main_panel(slot, g.calendar, oob=True)
|
||||
return await make_response(html)
|
||||
|
||||
|
||||
|
||||
@@ -128,7 +128,9 @@ def register():
|
||||
}), 422
|
||||
|
||||
# Success → re-render the slots table
|
||||
html = await render_template("_types/slots/_main_panel.html")
|
||||
slots = await svc_list_slots(g.s, g.calendar.id)
|
||||
from sexp.sexp_components import render_slots_table
|
||||
html = render_slots_table(slots, g.calendar)
|
||||
return await make_response(html)
|
||||
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ def register() -> Blueprint:
|
||||
}
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_ticket_admin_page, render_ticket_admin_oob
|
||||
from sexp.sexp_components import render_ticket_admin_page, render_ticket_admin_oob
|
||||
|
||||
ctx = await get_template_context()
|
||||
if not is_htmx_request():
|
||||
@@ -100,11 +100,8 @@ def register() -> Blueprint:
|
||||
|
||||
tickets = await get_tickets_for_entry(g.s, entry_id)
|
||||
|
||||
html = await render_template(
|
||||
"_types/ticket_admin/_entry_tickets.html",
|
||||
entry=entry,
|
||||
tickets=tickets,
|
||||
)
|
||||
from sexp.sexp_components import render_entry_tickets_admin
|
||||
html = render_entry_tickets_admin(entry, tickets)
|
||||
return await make_response(html, 200)
|
||||
|
||||
@bp.get("/lookup/")
|
||||
@@ -119,19 +116,12 @@ def register() -> Blueprint:
|
||||
)
|
||||
|
||||
ticket = await get_ticket_by_code(g.s, code)
|
||||
from sexp.sexp_components import render_lookup_result
|
||||
if not ticket:
|
||||
html = await render_template(
|
||||
"_types/ticket_admin/_lookup_result.html",
|
||||
ticket=None,
|
||||
error="Ticket not found",
|
||||
)
|
||||
html = render_lookup_result(None, "Ticket not found")
|
||||
return await make_response(html, 200)
|
||||
|
||||
html = await render_template(
|
||||
"_types/ticket_admin/_lookup_result.html",
|
||||
ticket=ticket,
|
||||
error=None,
|
||||
)
|
||||
html = render_lookup_result(ticket, None)
|
||||
return await make_response(html, 200)
|
||||
|
||||
@bp.post("/<code>/checkin/")
|
||||
@@ -141,22 +131,13 @@ def register() -> Blueprint:
|
||||
"""Check in a ticket by its code."""
|
||||
success, error = await checkin_ticket(g.s, code)
|
||||
|
||||
from sexp.sexp_components import render_checkin_result
|
||||
if not success:
|
||||
html = await render_template(
|
||||
"_types/ticket_admin/_checkin_result.html",
|
||||
success=False,
|
||||
error=error,
|
||||
ticket=None,
|
||||
)
|
||||
html = render_checkin_result(False, error, None)
|
||||
return await make_response(html, 200)
|
||||
|
||||
ticket = await get_ticket_by_code(g.s, code)
|
||||
html = await render_template(
|
||||
"_types/ticket_admin/_checkin_result.html",
|
||||
success=True,
|
||||
error=None,
|
||||
ticket=ticket,
|
||||
)
|
||||
html = render_checkin_result(True, None, ticket)
|
||||
return await make_response(html, 200)
|
||||
|
||||
return bp
|
||||
|
||||
@@ -66,9 +66,11 @@ def register():
|
||||
if not ticket_type:
|
||||
return await make_response("Not found", 404)
|
||||
|
||||
html = await render_template(
|
||||
"_types/ticket_type/_main_panel.html",
|
||||
ticket_type=ticket_type,
|
||||
from sexp.sexp_components import render_ticket_type_main_panel
|
||||
va = request.view_args or {}
|
||||
html = render_ticket_type_main_panel(
|
||||
ticket_type, g.entry, g.calendar,
|
||||
va.get("day"), va.get("month"), va.get("year"),
|
||||
)
|
||||
return await make_response(html)
|
||||
|
||||
@@ -132,9 +134,11 @@ def register():
|
||||
return await make_response("Not found", 404)
|
||||
|
||||
# Return updated view with OOB flag
|
||||
html = await render_template(
|
||||
"_types/ticket_type/_main_panel.html",
|
||||
ticket_type=ticket_type,
|
||||
from sexp.sexp_components import render_ticket_type_main_panel
|
||||
va = request.view_args or {}
|
||||
html = render_ticket_type_main_panel(
|
||||
ticket_type, g.entry, g.calendar,
|
||||
va.get("day"), va.get("month"), va.get("year"),
|
||||
oob=True,
|
||||
)
|
||||
return await make_response(html)
|
||||
@@ -150,9 +154,11 @@ def register():
|
||||
|
||||
# Re-render the ticket types list
|
||||
ticket_types = await svc_list_ticket_types(g.s, g.entry.id)
|
||||
html = await render_template(
|
||||
"_types/ticket_types/_main_panel.html",
|
||||
ticket_types=ticket_types
|
||||
from sexp.sexp_components import render_ticket_types_table
|
||||
va = request.view_args or {}
|
||||
html = render_ticket_types_table(
|
||||
ticket_types, g.entry, g.calendar,
|
||||
va.get("day"), va.get("month"), va.get("year"),
|
||||
)
|
||||
return await make_response(html)
|
||||
|
||||
|
||||
@@ -108,7 +108,13 @@ def register():
|
||||
)
|
||||
|
||||
# Success → re-render the ticket types table
|
||||
html = await render_template("_types/ticket_types/_main_panel.html")
|
||||
ticket_types = await svc_list_ticket_types(g.s, g.entry.id)
|
||||
from sexp.sexp_components import render_ticket_types_table
|
||||
va = request.view_args or {}
|
||||
html = render_ticket_types_table(
|
||||
ticket_types, g.entry, g.calendar,
|
||||
va.get("day"), va.get("month"), va.get("year"),
|
||||
)
|
||||
return await make_response(html)
|
||||
|
||||
@bp.get("/add")
|
||||
|
||||
@@ -51,7 +51,7 @@ def register() -> Blueprint:
|
||||
)
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_tickets_page, render_tickets_oob
|
||||
from sexp.sexp_components import render_tickets_page, render_tickets_oob
|
||||
|
||||
ctx = await get_template_context()
|
||||
if not is_htmx_request():
|
||||
@@ -82,7 +82,7 @@ def register() -> Blueprint:
|
||||
return await make_response("Ticket not found", 404)
|
||||
|
||||
from shared.sexp.page import get_template_context
|
||||
from sexp_components import render_ticket_detail_page, render_ticket_detail_oob
|
||||
from sexp.sexp_components import render_ticket_detail_page, render_ticket_detail_oob
|
||||
|
||||
ctx = await get_template_context()
|
||||
if not is_htmx_request():
|
||||
@@ -169,13 +169,20 @@ def register() -> Blueprint:
|
||||
remaining = await get_available_ticket_count(g.s, entry_id)
|
||||
all_tickets = await get_tickets_for_entry(g.s, entry_id)
|
||||
|
||||
html = await render_template(
|
||||
"_types/tickets/_buy_result.html",
|
||||
entry=entry,
|
||||
created_tickets=created,
|
||||
remaining=remaining,
|
||||
all_tickets=all_tickets,
|
||||
)
|
||||
# Compute cart count for OOB mini-cart update
|
||||
from shared.infrastructure.data_client import fetch_data
|
||||
from shared.contracts.dtos import CartSummaryDTO, dto_from_dict
|
||||
summary_params = {}
|
||||
if ident["user_id"] is not None:
|
||||
summary_params["user_id"] = ident["user_id"]
|
||||
if ident["session_id"] is not None:
|
||||
summary_params["session_id"] = ident["session_id"]
|
||||
raw_summary = await fetch_data("cart", "cart-summary", params=summary_params, required=False)
|
||||
summary = dto_from_dict(CartSummaryDTO, raw_summary) if raw_summary else CartSummaryDTO()
|
||||
cart_count = summary.count + summary.calendar_count + summary.ticket_count
|
||||
|
||||
from sexp.sexp_components import render_buy_result
|
||||
html = render_buy_result(entry, created, remaining, cart_count)
|
||||
return await make_response(html, 200)
|
||||
|
||||
@bp.post("/adjust/")
|
||||
@@ -298,14 +305,10 @@ def register() -> Blueprint:
|
||||
summary = dto_from_dict(CartSummaryDTO, raw_summary) if raw_summary else CartSummaryDTO()
|
||||
cart_count = summary.count + summary.calendar_count + summary.ticket_count
|
||||
|
||||
html = await render_template(
|
||||
"_types/tickets/_adjust_response.html",
|
||||
entry=entry,
|
||||
ticket_remaining=ticket_remaining,
|
||||
ticket_sold_count=ticket_sold_count,
|
||||
user_ticket_count=user_ticket_count,
|
||||
user_ticket_counts_by_type=user_ticket_counts_by_type,
|
||||
cart_count=cart_count,
|
||||
from sexp.sexp_components import render_adjust_response
|
||||
html = render_adjust_response(
|
||||
entry, ticket_remaining, ticket_sold_count,
|
||||
user_ticket_count, user_ticket_counts_by_type, cart_count,
|
||||
)
|
||||
|
||||
return await make_response(html, 200)
|
||||
|
||||
0
events/sexp/__init__.py
Normal file
0
events/sexp/__init__.py
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user