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 subscription_plans.html.heex
Raw

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="dropdown dropdown-end">
<label tabindex="0" class="btn btn-ghost btn-sm btn-circle">
<.icon name="hero-ellipsis-vertical" class="w-4 h-4" />
</label>
<ul
tabindex="0"
class="dropdown-content menu p-2 shadow bg-base-200 rounded-box w-52 z-10"
>
<li>
<.link navigate={
PhoenixKit.Utils.Routes.path("/admin/billing/plans/#{plan.id}/edit")
}>
<.icon name="hero-pencil" class="w-4 h-4" /> Edit
</.link>
</li>
<li>
<button phx-click="toggle_active" phx-value-id={plan.id}>
<%= if plan.active do %>
<.icon name="hero-pause" class="w-4 h-4" /> Deactivate
<% else %>
<.icon name="hero-play" class="w-4 h-4" /> Activate
<% end %>
</button>
</li>
<li>
<button
phx-click="delete_plan"
phx-value-id={plan.id}
class="text-error"
data-confirm="Delete this plan? This cannot be undone."
>
<.icon name="hero-trash" class="w-4 h-4" /> Delete
</button>
</li>
</ul>
</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>