defmodule BerrypodWeb.Admin.Orders do
use BerrypodWeb, :live_view
alias Berrypod.Orders
alias Berrypod.Cart
@impl true
def mount(_params, _session, socket) do
counts = Orders.count_orders_by_status()
orders = Orders.list_orders()
socket =
socket
|> assign(:page_title, "Orders")
|> assign(:status_filter, "all")
|> assign(:status_counts, counts)
|> assign(:order_count, length(orders))
|> stream(:orders, orders)
{:ok, socket}
end
@impl true
def handle_event("filter", %{"status" => status}, socket) do
orders = Orders.list_orders(status: status)
socket =
socket
|> assign(:status_filter, status)
|> assign(:order_count, length(orders))
|> stream(:orders, orders, reset: true)
{:noreply, socket}
end
@impl true
def render(assigns) do
~H"""
<.header>
Orders
<.filter_tab
status="all"
label="All"
count={total_count(@status_counts)}
active={@status_filter}
/>
<.filter_tab
status="paid"
label="Paid"
count={@status_counts["paid"]}
active={@status_filter}
/>
<.filter_tab
status="pending"
label="Pending"
count={@status_counts["pending"]}
active={@status_filter}
/>
<.filter_tab
status="failed"
label="Failed"
count={@status_counts["failed"]}
active={@status_filter}
/>
<.filter_tab
status="refunded"
label="Refunded"
count={@status_counts["refunded"]}
active={@status_filter}
/>
<.table
:if={@order_count > 0}
id="orders"
rows={@streams.orders}
row_item={fn {_id, order} -> order end}
row_click={fn {_id, order} -> JS.navigate(~p"/admin/orders/#{order}") end}
>
<:col :let={order} label="Order">{order.order_number}
<:col :let={order} label="Date">{format_date(order.inserted_at)}
<:col :let={order} label="Customer">{order.customer_email || "—"}
<:col :let={order} label="Total">{Cart.format_price(order.total)}
<:col :let={order} label="Status"><.status_badge status={order.payment_status} />
<:col :let={order} label="Fulfilment">
<.fulfilment_badge status={order.fulfilment_status} />
<.icon name="hero-inbox" class="size-12 mx-auto mb-4" />
No orders yet
Orders will appear here once customers check out.
"""
end
defp filter_tab(assigns) do
count = assigns[:count] || 0
active = assigns.active == assigns.status
assigns = assign(assigns, count: count, active: active)
~H"""