All checks were successful
deploy / deploy (push) Successful in 3m20s
Three-layer pipeline: Plug for all HTTP requests (no JS needed), LiveView hook for SPA navigations, JS hook for screen width. ETS-backed buffer batches writes to SQLite every 10s. Daily-rotating salt for visitor hashing. Includes admin dashboard with date ranges, visitor trends, top pages, sources, devices, and e-commerce conversion funnel. Oban cron for 12-month data retention. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
56 lines
1.4 KiB
Elixir
56 lines
1.4 KiB
Elixir
defmodule BerrypodWeb.Shop.CheckoutSuccess do
|
|
use BerrypodWeb, :live_view
|
|
|
|
alias Berrypod.{Analytics, Orders}
|
|
|
|
@impl true
|
|
def mount(%{"session_id" => session_id}, _session, socket) do
|
|
order = Orders.get_order_by_stripe_session(session_id)
|
|
|
|
# Subscribe to order status updates (webhook may arrive after redirect)
|
|
if order && connected?(socket) do
|
|
Phoenix.PubSub.subscribe(Berrypod.PubSub, "order:#{order.id}:status")
|
|
end
|
|
|
|
# Track purchase event
|
|
if order && connected?(socket) && socket.assigns[:analytics_visitor_hash] do
|
|
Analytics.track_event("purchase", %{
|
|
pathname: "/checkout/success",
|
|
visitor_hash: socket.assigns.analytics_visitor_hash,
|
|
revenue: order.total
|
|
})
|
|
end
|
|
|
|
# Clear the cart after successful checkout
|
|
socket =
|
|
if order && connected?(socket) do
|
|
BerrypodWeb.CartHook.broadcast_and_update(socket, [])
|
|
else
|
|
socket
|
|
end
|
|
|
|
socket =
|
|
socket
|
|
|> assign(:page_title, "Order confirmed")
|
|
|> assign(:order, order)
|
|
|
|
{:ok, socket}
|
|
end
|
|
|
|
def mount(_params, _session, socket) do
|
|
{:ok, redirect(socket, to: ~p"/")}
|
|
end
|
|
|
|
@impl true
|
|
def handle_info({:order_paid, order}, socket) do
|
|
{:noreply, assign(socket, :order, order)}
|
|
end
|
|
|
|
@impl true
|
|
def render(assigns) do
|
|
~H"""
|
|
<BerrypodWeb.PageTemplates.checkout_success {assigns} />
|
|
"""
|
|
end
|
|
end
|