defmodule PhoenixKit.Modules.Shop.Web.ShippingMethods do @moduledoc """ Shipping methods list LiveView for E-Commerce module admin. """ use PhoenixKitWeb, :live_view alias PhoenixKit.Modules.Billing.Currency alias PhoenixKit.Modules.Shop alias PhoenixKit.Utils.Routes @impl true def mount(_params, _session, socket) do methods = Shop.list_shipping_methods() currency = Shop.get_default_currency() socket = socket |> assign(:page_title, "Shipping Methods") |> assign(:methods, methods) |> assign(:currency, currency) {:ok, socket} end @impl true def handle_event("toggle_active", %{"uuid" => uuid}, socket) do method = Shop.get_shipping_method!(uuid) {:ok, updated} = Shop.update_shipping_method(method, %{active: !method.active}) methods = Enum.map(socket.assigns.methods, fn m -> if m.id == updated.id, do: updated, else: m end) {:noreply, assign(socket, :methods, methods)} end @impl true def handle_event("delete", %{"uuid" => uuid}, socket) do method = Shop.get_shipping_method!(uuid) case Shop.delete_shipping_method(method) do {:ok, _} -> methods = Enum.reject(socket.assigns.methods, &(&1.id == method.id)) {:noreply, socket |> assign(:methods, methods) |> put_flash(:info, "Shipping method deleted")} {:error, _} -> {:noreply, put_flash(socket, :error, "Failed to delete shipping method")} end end @impl true def render(assigns) do ~H"""
<.admin_page_header back={Routes.path("/admin/shop")}>

Shipping Methods

{length(@methods)} methods configured

<:actions> <.link navigate={Routes.path("/admin/shop/shipping/new")} class="btn btn-primary btn-sm"> <.icon name="hero-plus" class="w-4 h-4 mr-2" /> Add Method
<%= if @methods == [] do %> <% else %> <%= for method <- @methods do %> <% end %> <% end %>
Method Price Constraints Delivery Status Actions
<.icon name="hero-truck" class="w-12 h-12 mx-auto mb-3 opacity-50" />

No shipping methods

Create your first shipping method to get started

{method.name}
<%= if method.description do %>
{method.description}
<% end %>
{format_price(method.price, @currency)}
<%= if method.free_above_amount do %>
Free above {format_price(method.free_above_amount, @currency)}
<% end %>
<%= if method.max_weight_grams do %> Max {format_weight(method.max_weight_grams)} <% end %> <%= if method.countries != [] do %> {length(method.countries)} countries <% end %> <%= if method.countries == [] && is_nil(method.max_weight_grams) do %> No limits <% end %>
<%= if estimate = PhoenixKit.Modules.Shop.ShippingMethod.delivery_estimate(method) do %> {estimate} <% else %> - <% end %>
<.link navigate={Routes.path("/admin/shop/shipping/#{method.uuid}/edit")} class="btn btn-ghost btn-sm" > <.icon name="hero-pencil" class="w-4 h-4" />
""" 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 || Decimal.new("0"), 2)}" end defp format_weight(grams) when grams >= 1000, do: "#{div(grams, 1000)} kg" defp format_weight(grams), do: "#{grams} g" end