Packages

phoenix_kit

1.7.43
1.7.208 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
phoenix_kit lib modules shop web user_orders.ex
Raw

lib/modules/shop/web/user_orders.ex

defmodule PhoenixKit.Modules.Shop.Web.UserOrders do
@moduledoc """
LiveView for displaying user's shop orders.
Users can view only their own orders with status filtering and pagination.
This is the user-facing order portal, using the dashboard layout.
"""
use PhoenixKitWeb, :live_view
alias PhoenixKit.Modules.Billing
alias PhoenixKit.Modules.Billing.Currency
alias PhoenixKit.Modules.Shop
alias PhoenixKit.Utils.Routes
@impl true
def mount(_params, _session, socket) do
if Billing.enabled?() do
current_user = socket.assigns[:phoenix_kit_current_user]
socket =
socket
|> assign(:page_title, gettext("My Orders"))
|> assign(:current_user, current_user)
|> assign(:orders, [])
|> assign(:total_count, 0)
|> assign(:loading, true)
|> assign_filter_defaults()
|> assign_pagination_defaults()
{:ok, socket}
else
{:ok,
socket
|> put_flash(:error, gettext("Billing module is not enabled"))
|> push_navigate(to: Routes.path("/dashboard"))}
end
end
@impl true
def handle_params(params, uri, socket) do
socket =
socket
|> assign(:url_path, URI.parse(uri).path)
|> apply_params(params)
|> load_user_orders()
{:noreply, assign(socket, :loading, false)}
end
@impl true
def handle_event("filter", params, socket) do
filter_params = %{}
filter_params =
case Map.get(params, "filters") do
%{"status" => status} when status != "" ->
Map.put(filter_params, "status", status)
_ ->
filter_params
end
{:noreply,
push_patch(socket, to: Routes.path("/dashboard/orders", map_to_keyword(filter_params)))}
end
@impl true
def handle_event("clear_filters", _params, socket) do
{:noreply, push_patch(socket, to: Routes.path("/dashboard/orders"))}
end
@impl true
def handle_event("change_page", %{"page" => page}, socket) do
page = String.to_integer(page)
current_params = build_current_params(socket)
params = Map.put(current_params, "page", page)
{:noreply, push_patch(socket, to: Routes.path("/dashboard/orders", map_to_keyword(params)))}
end
# Private functions
defp assign_filter_defaults(socket) do
assign(socket, :status_filter, nil)
end
defp assign_pagination_defaults(socket) do
socket
|> assign(:page, 1)
|> assign(:per_page, 20)
|> assign(:total_pages, 1)
end
defp apply_params(socket, params) do
page = params |> Map.get("page", "1") |> String.to_integer() |> max(1)
status = Map.get(params, "status")
socket
|> assign(:page, page)
|> assign(:status_filter, status)
end
defp load_user_orders(socket) do
user_id = socket.assigns.current_user.id
currency = Shop.get_default_currency()
# Build filters for Billing.list_user_orders
filters = build_query_filters(socket)
all_orders = Billing.list_user_orders(user_id, filters)
total_count = length(all_orders)
# Apply pagination manually
per_page = socket.assigns.per_page
page = socket.assigns.page
orders = all_orders |> Enum.drop((page - 1) * per_page) |> Enum.take(per_page)
total_pages = max(1, ceil(total_count / per_page))
socket
|> assign(:orders, orders)
|> assign(:total_count, total_count)
|> assign(:total_pages, total_pages)
|> assign(:currency, currency)
end
defp build_query_filters(socket) do
filters = %{}
case socket.assigns.status_filter do
nil -> filters
status -> Map.put(filters, :status, status)
end
end
defp build_current_params(socket) do
params = %{}
if socket.assigns.status_filter,
do: Map.put(params, "status", socket.assigns.status_filter),
else: params
end
defp map_to_keyword(map) when is_map(map) do
Enum.map(map, fn {k, v} -> {String.to_existing_atom(k), v} end)
end
# View helpers
defp status_badge_class("pending"), do: "badge-warning"
defp status_badge_class("processing"), do: "badge-info"
defp status_badge_class("completed"), do: "badge-success"
defp status_badge_class("shipped"), do: "badge-info"
defp status_badge_class("delivered"), do: "badge-success"
defp status_badge_class("cancelled"), do: "badge-error"
defp status_badge_class("refunded"), do: "badge-neutral"
defp status_badge_class(_), do: "badge-ghost"
defp format_date(nil), do: "-"
defp format_date(%DateTime{} = dt) do
Calendar.strftime(dt, "%B %d, %Y")
end
defp format_date(%NaiveDateTime{} = dt) do
Calendar.strftime(dt, "%B %d, %Y")
end
defp format_price(nil, _currency), do: "-"
defp format_price(amount, %Currency{} = currency) do
Currency.format_amount(amount, currency)
end
defp format_price(amount, nil) do
"$#{Decimal.round(amount, 2)}"
end
defp items_count(nil), do: 0
defp items_count([]), do: 0
defp items_count(items) do
items
|> Enum.filter(&(&1["type"] != "shipping"))
|> length()
end
end