Packages

phoenix_kit

1.7.21
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 billing web transactions.html.heex
Raw

lib/modules/billing/web/transactions.html.heex

<PhoenixKitWeb.Components.LayoutWrapper.app_layout
flash={@flash}
phoenix_kit_current_scope={assigns[:phoenix_kit_current_scope]}
page_title="{@project_title} Transactions"
current_path={@url_path}
project_title={@project_title}
>
<div class="container mx-auto px-4 py-6">
<%!-- Header --%>
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-6 gap-4">
<div class="flex items-center gap-4">
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/billing")}
class="btn btn-ghost btn-sm"
>
<.icon name="hero-arrow-left" class="w-4 h-4" />
</.link>
<div>
<h1 class="text-3xl font-bold">Transactions</h1>
<p class="text-base-content/60 mt-1">{@total_count} total transactions</p>
</div>
</div>
<div class="flex gap-2">
<button phx-click="refresh" class="btn btn-ghost btn-sm">
<.icon name="hero-arrow-path" class="w-4 h-4" /> Refresh
</button>
</div>
</div>
<%!-- Filters --%>
<div class="card bg-base-100 shadow mb-6">
<div class="card-body py-4">
<form phx-change="filter" phx-submit="filter" class="flex flex-wrap gap-4 items-end">
<div class="form-control flex-1 min-w-[200px]">
<label class="label">
<span class="label-text">Search</span>
</label>
<input
type="text"
name="search"
value={@search}
placeholder="Transaction #, Invoice #..."
class="input input-bordered input-sm"
phx-debounce="300"
/>
</div>
<div class="form-control">
<label class="label">
<span class="label-text">Type</span>
</label>
<select name="type" class="select select-bordered select-sm">
<option value="all" selected={@type_filter == "all"}>All Types</option>
<option value="payment" selected={@type_filter == "payment"}>Payments</option>
<option value="refund" selected={@type_filter == "refund"}>Refunds</option>
</select>
</div>
<div class="form-control">
<label class="label">
<span class="label-text">Payment Method</span>
</label>
<select name="payment_method" class="select select-bordered select-sm">
<option value="all" selected={@payment_method_filter == "all"}>All Methods</option>
<option value="bank" selected={@payment_method_filter == "bank"}>
Bank Transfer
</option>
</select>
</div>
<button type="button" phx-click="clear_filters" class="btn btn-ghost btn-sm">
Clear Filters
</button>
</form>
</div>
</div>
<%!-- Transactions Table --%>
<div class="card bg-base-100 shadow-xl">
<div class="card-body p-0">
<%= if @loading do %>
<div class="flex justify-center items-center py-12">
<span class="loading loading-spinner loading-lg"></span>
</div>
<% else %>
<%= if Enum.empty?(@transactions) do %>
<div class="text-center py-12">
<.icon
name="hero-banknotes"
class="w-16 h-16 mx-auto mb-4 text-base-content/30"
/>
<h3 class="text-xl font-semibold mb-2">No transactions found</h3>
<p class="text-base-content/60 mb-4">
<%= if @search != "" or @type_filter != "all" or @payment_method_filter != "all" do %>
Try adjusting your filters or search terms
<% else %>
Transactions will appear here when payments or refunds are recorded
<% end %>
</p>
</div>
<% else %>
<div class="overflow-x-auto">
<table class="table">
<thead>
<tr>
<th>Transaction #</th>
<th>Invoice</th>
<th>Type</th>
<th>Amount</th>
<th>Method</th>
<th>Description</th>
<th>Date</th>
<th></th>
</tr>
</thead>
<tbody>
<%= for transaction <- @transactions do %>
<tr
class="hover cursor-pointer"
phx-click="view_invoice"
phx-value-id={transaction.invoice_id}
>
<td class="font-mono text-sm">{transaction.transaction_number}</td>
<td>
<%= if transaction.invoice do %>
<.link
navigate={
PhoenixKit.Utils.Routes.path(
"/admin/billing/invoices/#{transaction.invoice_id}"
)
}
class="link link-hover font-mono text-sm"
>
{transaction.invoice.invoice_number}
</.link>
<% else %>
<span class="text-base-content/50">-</span>
<% end %>
</td>
<td>
<.transaction_type_badge type={transaction_type(transaction)} />
</td>
<td>
<span class={[
"font-mono font-medium",
if(Decimal.positive?(transaction.amount),
do: "text-success",
else: "text-error"
)
]}>
<%= if Decimal.positive?(transaction.amount) do %>
+<.currency_compact
amount={transaction.amount}
currency={transaction.currency}
/>
<% else %>
<.currency_compact
amount={transaction.amount}
currency={transaction.currency}
/>
<% end %>
</span>
</td>
<td>
<span class="badge badge-outline badge-sm">
{String.upcase(transaction.payment_method || "bank")}
</span>
</td>
<td class="max-w-[200px] truncate text-sm text-base-content/70">
{transaction.description || "-"}
</td>
<td class="text-sm text-base-content/60">
<.time_ago datetime={transaction.inserted_at} />
</td>
<td>
<.link
navigate={
PhoenixKit.Utils.Routes.path(
"/admin/billing/invoices/#{transaction.invoice_id}"
)
}
class="btn btn-ghost btn-xs"
>
<.icon name="hero-eye" class="w-4 h-4" />
</.link>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<%!-- Pagination --%>
<%= if @total_pages > 1 do %>
<div class="flex justify-center py-4">
<.pagination
current_page={@page}
total_pages={@total_pages}
base_path={PhoenixKit.Utils.Routes.path("/admin/billing/transactions")}
params={
%{
"search" => @search,
"type" => @type_filter,
"payment_method" => @payment_method_filter
}
}
/>
</div>
<% end %>
<% end %>
<% end %>
</div>
</div>
</div>
</PhoenixKitWeb.Components.LayoutWrapper.app_layout>