Packages
phoenix_kit
1.7.80
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
Current section
Files
lib/modules/shop/web/shipping_methods.ex
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.uuid == updated.uuid, 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.uuid == method.uuid))
{: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"""
<PhoenixKitWeb.Components.LayoutWrapper.app_layout
flash={@flash}
phoenix_kit_current_scope={@phoenix_kit_current_scope}
current_path={@url_path}
current_locale={@current_locale}
page_title={@page_title}
>
<div class="p-6 max-w-6xl mx-auto">
<.admin_page_header back={Routes.path("/admin/shop")}>
<h1 class="text-xl sm:text-2xl lg:text-3xl font-bold text-base-content">
Shipping Methods
</h1>
<p class="text-sm sm:text-base text-base-content/60 mt-0.5">
{length(@methods)} methods configured
</p>
<: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
</.link>
</:actions>
</.admin_page_header>
<div class="card bg-base-100 shadow-lg">
<div class="overflow-x-auto">
<table class="table">
<thead>
<tr>
<th>Method</th>
<th>Price</th>
<th>Constraints</th>
<th>Delivery</th>
<th>Status</th>
<th class="text-right">Actions</th>
</tr>
</thead>
<tbody>
<%= if @methods == [] do %>
<tr>
<td colspan="6" class="text-center py-12 text-base-content/50">
<.icon name="hero-truck" class="w-12 h-12 mx-auto mb-3 opacity-50" />
<p class="text-lg">No shipping methods</p>
<p class="text-sm">Create your first shipping method to get started</p>
</td>
</tr>
<% else %>
<%= for method <- @methods do %>
<tr class="hover">
<td>
<div class="font-bold">{method.name}</div>
<%= if method.description do %>
<div class="text-sm text-base-content/60 max-w-xs truncate">
{method.description}
</div>
<% end %>
</td>
<td>
<div class="font-semibold">{format_price(method.price, @currency)}</div>
<%= if method.free_above_amount do %>
<div class="text-xs text-success">
Free above {format_price(method.free_above_amount, @currency)}
</div>
<% end %>
</td>
<td>
<div class="flex flex-wrap gap-1">
<%= if method.max_weight_grams do %>
<span class="badge badge-outline badge-sm">
Max {format_weight(method.max_weight_grams)}
</span>
<% end %>
<%= if method.countries != [] do %>
<span class="badge badge-outline badge-sm">
{length(method.countries)} countries
</span>
<% end %>
<%= if method.countries == [] && is_nil(method.max_weight_grams) do %>
<span class="text-base-content/50 text-sm">No limits</span>
<% end %>
</div>
</td>
<td>
<%= if estimate = PhoenixKit.Modules.Shop.ShippingMethod.delivery_estimate(method) do %>
<span class="text-sm">{estimate}</span>
<% else %>
<span class="text-base-content/50 text-sm">-</span>
<% end %>
</td>
<td>
<input
type="checkbox"
class="toggle toggle-success toggle-sm"
checked={method.active}
phx-click="toggle_active"
phx-value-uuid={method.uuid}
/>
</td>
<td class="text-right">
<div class="flex justify-end gap-2">
<.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" />
</.link>
<button
phx-click="delete"
phx-value-uuid={method.uuid}
data-confirm="Delete this shipping method?"
class="btn btn-ghost btn-sm text-error"
>
<.icon name="hero-trash" class="w-4 h-4" />
</button>
</div>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
</div>
</div>
</div>
</PhoenixKitWeb.Components.LayoutWrapper.app_layout>
"""
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