Packages
phoenix_kit
1.7.29
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/modules/billing/web/orders.ex
defmodule PhoenixKit.Modules.Billing.Web.Orders do
@moduledoc """
Orders list LiveView for the billing module.
Provides order management interface with filtering, searching, and pagination.
"""
use PhoenixKitWeb, :live_view
alias PhoenixKit.Modules.Billing
alias PhoenixKit.Modules.Billing.Events
alias PhoenixKit.Settings
alias PhoenixKit.Utils.Routes
@default_per_page 25
@impl true
def mount(_params, _session, socket) do
if Billing.enabled?() do
# Subscribe to order events for real-time updates
if connected?(socket), do: Events.subscribe_orders()
project_title = Settings.get_project_title()
socket =
socket
|> assign(:page_title, "Orders")
|> assign(:project_title, project_title)
|> assign(:url_path, Routes.path("/admin/billing/orders"))
|> assign(:orders, [])
|> assign(:total_count, 0)
|> assign(:loading, true)
|> assign_filter_defaults()
|> assign_pagination_defaults()
{:ok, socket}
else
{:ok,
socket
|> put_flash(:error, "Billing module is not enabled")
|> push_navigate(to: Routes.path("/admin"))}
end
end
@impl true
def handle_params(params, _url, socket) do
socket =
socket
|> apply_params(params)
|> load_orders()
{:noreply, socket}
end
defp assign_filter_defaults(socket) do
socket
|> assign(:search, "")
|> assign(:status_filter, "all")
|> assign(:date_from, nil)
|> assign(:date_to, nil)
end
defp assign_pagination_defaults(socket) do
socket
|> assign(:page, 1)
|> assign(:per_page, @default_per_page)
|> assign(:total_pages, 1)
end
defp apply_params(socket, params) do
page = parse_page(params["page"])
per_page = parse_per_page(params["per_page"])
search = params["search"] || ""
status = params["status"] || "all"
socket
|> assign(:page, page)
|> assign(:per_page, per_page)
|> assign(:search, search)
|> assign(:status_filter, status)
end
defp parse_page(nil), do: 1
defp parse_page(page) when is_binary(page), do: max(1, String.to_integer(page))
defp parse_page(page) when is_integer(page), do: max(1, page)
defp parse_per_page(nil), do: @default_per_page
defp parse_per_page(per_page) when is_binary(per_page),
do: min(100, max(10, String.to_integer(per_page)))
defp parse_per_page(per_page) when is_integer(per_page), do: min(100, max(10, per_page))
defp load_orders(socket) do
%{
page: page,
per_page: per_page,
search: search,
status_filter: status
} = socket.assigns
opts = [
page: page,
per_page: per_page,
search: search,
status: if(status == "all", do: nil, else: status),
preload: [:user]
]
{orders, total_count} = Billing.list_orders_with_count(opts)
total_pages = ceil(total_count / per_page)
socket
|> assign(:orders, orders)
|> assign(:total_count, total_count)
|> assign(:total_pages, max(1, total_pages))
|> assign(:loading, false)
end
@impl true
def handle_event("filter", params, socket) do
new_params = build_url_params(socket.assigns, params)
{:noreply, push_patch(socket, to: Routes.path("/admin/billing/orders?#{new_params}"))}
end
@impl true
def handle_event("clear_filters", _params, socket) do
{:noreply, push_patch(socket, to: Routes.path("/admin/billing/orders"))}
end
@impl true
def handle_event("view_order", %{"id" => id}, socket) do
{:noreply, push_navigate(socket, to: Routes.path("/admin/billing/orders/#{id}"))}
end
@impl true
def handle_event("page_change", %{"page" => page}, socket) do
new_params = build_url_params(socket.assigns, %{"page" => page})
{:noreply, push_patch(socket, to: Routes.path("/admin/billing/orders?#{new_params}"))}
end
@impl true
def handle_event("refresh", _params, socket) do
{:noreply, socket |> assign(:loading, true) |> load_orders()}
end
# PubSub event handlers for real-time updates
@impl true
def handle_info({event, _order}, socket)
when event in [
:order_created,
:order_updated,
:order_confirmed,
:order_paid,
:order_cancelled
] do
{:noreply, load_orders(socket)}
end
# Catch-all for any other messages (ignore them)
@impl true
def handle_info(_msg, socket) do
{:noreply, socket}
end
defp build_url_params(assigns, new_params) do
params = %{
"page" => Map.get(new_params, "page", assigns.page),
"per_page" => assigns.per_page,
"search" => Map.get(new_params, "search", assigns.search),
"status" => Map.get(new_params, "status", assigns.status_filter)
}
params
|> Enum.reject(fn
{_k, v} when v in ["", "all", nil] -> true
{"page", 1} -> true
{"per_page", @default_per_page} -> true
_ -> false
end)
|> URI.encode_query()
end
end