Packages
phoenix_kit
1.7.39
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/billing/web/subscription_plans.html.heex
<PhoenixKitWeb.Components.LayoutWrapper.app_layout
flash={@flash}
phoenix_kit_current_scope={assigns[:phoenix_kit_current_scope]}
page_title="{@project_title} Subscription Plans"
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">Subscription Plans</h1>
<p class="text-base-content/60 mt-1">Manage pricing and features for subscriptions</p>
</div>
</div>
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/billing/plans/new")}
class="btn btn-primary btn-sm"
>
<.icon name="hero-plus" class="w-4 h-4" /> Create Plan
</.link>
</div>
<%!-- Navigation Tabs --%>
<div class="tabs tabs-boxed bg-base-200 p-1 mb-6">
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/settings/billing")}
class="tab"
>
<.icon name="hero-cog-6-tooth" class="w-4 h-4 mr-2" /> General
</.link>
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/settings/billing/providers")}
class="tab"
>
<.icon name="hero-credit-card" class="w-4 h-4 mr-2" /> Payment Providers
</.link>
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/billing/currencies")}
class="tab"
>
<.icon name="hero-currency-dollar" class="w-4 h-4 mr-2" /> Currencies
</.link>
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/billing/plans")}
class="tab tab-active"
>
<.icon name="hero-clipboard-document-list" class="w-4 h-4 mr-2" /> Plans
</.link>
</div>
<%!-- Plans Grid --%>
<%= if Enum.empty?(@plans) do %>
<div class="card bg-base-100 shadow-xl">
<div class="card-body text-center py-12">
<.icon name="hero-squares-2x2" class="w-12 h-12 mx-auto mb-4 opacity-50" />
<h3 class="text-lg font-medium">No Plans Created</h3>
<p class="text-base-content/60 mt-2">
Create your first subscription plan to start accepting recurring payments.
</p>
<div class="mt-6">
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/billing/plans/new")}
class="btn btn-primary"
>
<.icon name="hero-plus" class="w-4 h-4" /> Create First Plan
</.link>
</div>
</div>
</div>
<% else %>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<%= for plan <- @plans do %>
<div class={[
"card bg-base-100 shadow-xl",
!plan.active && "opacity-60"
]}>
<div class="card-body">
<div class="flex items-start justify-between">
<div>
<h2 class="card-title">
{plan.name}
<%= if !plan.active do %>
<span class="badge badge-neutral badge-sm">Inactive</span>
<% end %>
</h2>
<p class="text-sm text-base-content/60">{plan.description}</p>
</div>
<div class="flex gap-1">
<.link
navigate={
PhoenixKit.Utils.Routes.path("/admin/billing/plans/#{plan.uuid}/edit")
}
class="btn btn-xs btn-ghost"
title="Edit plan"
>
<.icon name="hero-pencil" class="w-4 h-4" />
</.link>
<button
phx-click="toggle_active"
phx-value-uuid={plan.uuid}
class="btn btn-xs btn-ghost"
title={if plan.active, do: "Deactivate plan", else: "Activate plan"}
>
<%= if plan.active do %>
<.icon name="hero-pause" class="w-4 h-4" />
<% else %>
<.icon name="hero-play" class="w-4 h-4" />
<% end %>
</button>
<button
phx-click="delete_plan"
phx-value-uuid={plan.uuid}
data-confirm="Delete this plan? This cannot be undone."
class="btn btn-xs btn-ghost text-error"
title="Delete plan"
>
<.icon name="hero-trash" class="w-4 h-4" />
</button>
</div>
</div>
<div class="mt-4">
<div class="text-3xl font-bold">
<.currency_amount amount={plan.price} currency={plan.currency} />
</div>
<div class="text-sm text-base-content/60">
{format_interval(plan.interval, plan.interval_count)}
</div>
</div>
<%= if plan.trial_days && plan.trial_days > 0 do %>
<div class="badge badge-info badge-outline mt-2">
{plan.trial_days} day trial
</div>
<% end %>
<%!-- Features --%>
<%= if plan.features && is_list(plan.features) && length(plan.features) > 0 do %>
<div class="divider my-2"></div>
<ul class="space-y-1">
<%= for feature <- plan.features do %>
<li class="flex items-center gap-2 text-sm">
<.icon name="hero-check" class="w-4 h-4 text-success flex-shrink-0" />
<span>{feature}</span>
</li>
<% end %>
</ul>
<% end %>
<%!-- Meta Info --%>
<div class="mt-auto pt-4 border-t border-base-200 text-xs text-base-content/50">
<div class="flex justify-between">
<span>Slug:</span>
<span class="font-mono">{plan.slug}</span>
</div>
<%= if plan.sort_order do %>
<div class="flex justify-between mt-1">
<span>Sort Order:</span>
<span>{plan.sort_order}</span>
</div>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
<% end %>
</div>
</PhoenixKitWeb.Components.LayoutWrapper.app_layout>