diff --git a/extra/lib/plausible_web/live/customer_support/team.ex b/extra/lib/plausible_web/live/customer_support/team.ex
index d2ca34d1353e..bdcb8d505cb1 100644
--- a/extra/lib/plausible_web/live/customer_support/team.ex
+++ b/extra/lib/plausible_web/live/customer_support/team.ex
@@ -277,7 +277,9 @@ defmodule PlausibleWeb.Live.CustomerSupport.Team do
cond do
team && team.subscription ->
status_str =
- PlausibleWeb.SettingsView.present_subscription_status(team.subscription.status)
+ PlausibleWeb.Components.Billing.Helpers.present_subscription_status(
+ team.subscription.status
+ )
if team.subscription.paddle_subscription_id do
assigns = %{status_str: status_str, subscription: team.subscription}
diff --git a/lib/plausible_web/components/billing/billing.ex b/lib/plausible_web/components/billing/billing.ex
index e60cb2fb77de..41489d57047a 100644
--- a/lib/plausible_web/components/billing/billing.ex
+++ b/lib/plausible_web/components/billing/billing.ex
@@ -6,7 +6,6 @@ defmodule PlausibleWeb.Components.Billing do
import PlausibleWeb.Components.Icons
- require Plausible.Billing.Subscription.Status
alias Plausible.Billing.{Plan, Plans, EnterprisePlan}
attr :site, Plausible.Site, required: false, default: nil
diff --git a/lib/plausible_web/components/billing/helpers.ex b/lib/plausible_web/components/billing/helpers.ex
new file mode 100644
index 000000000000..f2b2028fe2aa
--- /dev/null
+++ b/lib/plausible_web/components/billing/helpers.ex
@@ -0,0 +1,63 @@
+defmodule PlausibleWeb.Components.Billing.Helpers do
+ @moduledoc false
+
+ require Plausible.Billing.Subscription.Status
+ alias Plausible.Billing.{Plan, Plans, EnterprisePlan, Subscription, Subscriptions}
+
+ def present_plan_name(%Plan{kind: kind}),
+ do: kind |> to_string() |> String.capitalize()
+
+ def present_plan_name(%EnterprisePlan{}), do: "Enterprise"
+ def present_plan_name(:free_10k), do: "Free"
+ def present_plan_name(_), do: "Plan"
+
+ def present_subscription_interval(subscription) do
+ case Plans.subscription_interval(subscription) do
+ "monthly" -> "month"
+ "yearly" -> "year"
+ interval -> interval
+ end
+ end
+
+ @spec present_subscription_status(Subscription.Status.status()) :: String.t()
+ def present_subscription_status(Subscription.Status.active()), do: "Active"
+ def present_subscription_status(Subscription.Status.past_due()), do: "Past due"
+ def present_subscription_status(Subscription.Status.deleted()), do: "Cancelled"
+ def present_subscription_status(Subscription.Status.paused()), do: "Paused"
+ def present_subscription_status(status), do: status
+
+ def subscription_pill_color(Subscription.Status.active()), do: :green
+ def subscription_pill_color(Subscription.Status.past_due()), do: :yellow
+ def subscription_pill_color(Subscription.Status.paused()), do: :red
+ def subscription_pill_color(Subscription.Status.deleted()), do: :red
+ def subscription_pill_color(_), do: :gray
+
+ def trial_button_label(team) do
+ if Plausible.Teams.Billing.enterprise_configured?(team) do
+ "Upgrade"
+ else
+ "Choose a plan →"
+ end
+ end
+
+ def change_plan_button_label(nil), do: "Upgrade"
+
+ def change_plan_button_label(subscription) do
+ if Subscriptions.resumable?(subscription) && subscription.cancel_url do
+ "Change plan"
+ else
+ "Upgrade"
+ end
+ end
+
+ def format_invoices(invoice_list) do
+ Enum.map(invoice_list, fn invoice ->
+ %{
+ date: invoice["payout_date"] |> Date.from_iso8601!() |> Calendar.strftime("%b %-d, %Y"),
+ amount: (invoice["amount"] / 1) |> :erlang.float_to_binary(decimals: 2),
+ currency: invoice["currency"] |> PlausibleWeb.BillingView.present_currency(),
+ url: invoice["receipt_url"]
+ }
+ end)
+ end
+end
diff --git a/lib/plausible_web/controllers/settings_controller.ex b/lib/plausible_web/controllers/settings_controller.ex
index aa39e396ad04..8877e31da398 100644
--- a/lib/plausible_web/controllers/settings_controller.ex
+++ b/lib/plausible_web/controllers/settings_controller.ex
@@ -134,47 +134,6 @@ defmodule PlausibleWeb.SettingsController do
render_security(conn)
end
- def subscription(conn, _params) do
- team = conn.assigns.current_team
- subscription = Teams.Billing.get_subscription(team)
-
- invoices = Plausible.Billing.paddle_api().get_invoices(subscription)
-
- pageview_usage = Teams.Billing.monthly_pageview_usage(team)
- site_usage = Teams.Billing.site_usage(team)
- team_member_usage = Teams.Billing.team_member_usage(team)
-
- usage = %{
- monthly_pageviews: pageview_usage,
- sites: site_usage,
- team_members: team_member_usage
- }
-
- notification_type = Plausible.Billing.Quota.usage_notification_type(team, usage)
-
- total_pageview_usage_domain =
- if site_usage == 1 do
- [site] = Plausible.Teams.owned_sites(team)
- site.domain
- else
- on_ee(do: team && get_consolidated_view_domain(team), else: nil)
- end
-
- render(conn, :subscription,
- layout: {PlausibleWeb.LayoutView, :settings},
- subscription: subscription,
- invoices: invoices,
- pageview_limit: Teams.Billing.monthly_pageview_limit(subscription),
- pageview_usage: pageview_usage,
- site_usage: site_usage,
- site_limit: Teams.Billing.site_limit(team),
- team_member_limit: Teams.Billing.team_member_limit(team),
- team_member_usage: team_member_usage,
- notification_type: notification_type,
- total_pageview_usage_domain: total_pageview_usage_domain
- )
- end
-
def redirect_invoices(conn, _params) do
redirect(conn, to: Routes.settings_path(conn, :subscription))
end
@@ -470,15 +429,6 @@ defmodule PlausibleWeb.SettingsController do
end
end
- on_ee do
- defp get_consolidated_view_domain(team) do
- case Plausible.ConsolidatedView.get(team) do
- nil -> nil
- view -> if Plausible.ConsolidatedView.ok_to_display?(team), do: view.domain
- end
- end
- end
-
defp handle_email_updated(conn) do
conn
|> put_flash(:success, "Email updated")
diff --git a/lib/plausible_web/live/components/form.ex b/lib/plausible_web/live/components/form.ex
index 0a637312d0e0..c49689be154f 100644
--- a/lib/plausible_web/live/components/form.ex
+++ b/lib/plausible_web/live/components/form.ex
@@ -428,7 +428,7 @@ defmodule PlausibleWeb.Live.Components.Form do
end)
end
- attr :conn, Plug.Conn, required: true
+ attr :conn, :map, default: %{}
attr :name, :string, required: true
attr :options, :list, required: true
attr :value, :any, default: nil
diff --git a/lib/plausible_web/live/settings_context.ex b/lib/plausible_web/live/settings_context.ex
new file mode 100644
index 000000000000..4284f3286439
--- /dev/null
+++ b/lib/plausible_web/live/settings_context.ex
@@ -0,0 +1,16 @@
+defmodule PlausibleWeb.Live.SettingsContext do
+ @moduledoc false
+
+ import Phoenix.LiveView
+ import Phoenix.Component
+
+ def on_mount(_arg, _params, _session, socket) do
+ socket = attach_hook(socket, :get_current_path, :handle_params, &get_current_path/3)
+ {:cont, socket, layout: {PlausibleWeb.LayoutView, :settings}}
+ end
+
+ defp get_current_path(_params, url, socket) do
+ %{path: current_path} = URI.parse(url)
+ {:cont, assign(socket, :current_path, current_path)}
+ end
+end
diff --git a/lib/plausible_web/live/subscription_settings.ex b/lib/plausible_web/live/subscription_settings.ex
new file mode 100644
index 000000000000..470c1cd4adf1
--- /dev/null
+++ b/lib/plausible_web/live/subscription_settings.ex
@@ -0,0 +1,309 @@
+defmodule PlausibleWeb.Live.SubscriptionSettings do
+ @moduledoc """
+ LiveView for the subscription settings page.
+ """
+ use PlausibleWeb, :live_view
+ use Plausible
+
+ import PlausibleWeb.Components.Billing.Helpers
+
+ alias Plausible.Teams
+ alias PlausibleWeb.Router.Helpers, as: Routes
+
+ def mount(_params, _session, socket) do
+ team = socket.assigns.current_team
+ subscription = Teams.Billing.get_subscription(team)
+ invoices = Plausible.Billing.paddle_api().get_invoices(subscription)
+ pageview_usage = Teams.Billing.monthly_pageview_usage(team)
+ site_usage = Teams.Billing.site_usage(team)
+ team_member_usage = Teams.Billing.team_member_usage(team)
+
+ usage = %{
+ monthly_pageviews: pageview_usage,
+ sites: site_usage,
+ team_members: team_member_usage
+ }
+
+ notification_type = Plausible.Billing.Quota.usage_notification_type(team, usage)
+
+ total_pageview_usage_domain =
+ if site_usage == 1 do
+ [site] = Plausible.Teams.owned_sites(team)
+ site.domain
+ else
+ on_ee(do: team && consolidated_view_domain(team), else: nil)
+ end
+
+ socket =
+ socket
+ |> assign(:subscription, subscription)
+ |> assign(:invoices, invoices)
+ |> assign(:pageview_limit, Teams.Billing.monthly_pageview_limit(subscription))
+ |> assign(:pageview_usage, pageview_usage)
+ |> assign(:site_usage, site_usage)
+ |> assign(:site_limit, Teams.Billing.site_limit(team))
+ |> assign(:team_member_limit, Teams.Billing.team_member_limit(team))
+ |> assign(:team_member_usage, team_member_usage)
+ |> assign(:notification_type, notification_type)
+ |> assign(:total_pageview_usage_domain, total_pageview_usage_domain)
+
+ {:ok, socket}
+ end
+
+ def render(assigns) do
+ ~H"""
+ <.settings_tiles>
+ <%= if is_nil(@current_team) || Plausible.Teams.on_trial?(@current_team) do %>
+ <.tile docs="trial-to-paid">
+ <:title>Current plan
+
+
+
+ Free trial
+ <.pill :if={@current_team} color={:yellow}>
+ {Plausible.Teams.trial_days_left(@current_team)} days left
+
+
+
+ Your 30-day trial will start when you add your first site
+
+
+ <.button_link
+ href={Routes.billing_path(PlausibleWeb.Endpoint, :choose_plan)}
+ mt?={false}
+ id="upgrade-or-change-plan-link"
+ >
+ {trial_button_label(@current_team)}
+
+
+
+ <% else %>
+ <.tile docs="billing">
+ <:title>Current plan
+ <%= if @subscription do %>
+
+
+
+
+
+
+ {present_plan_name(Plausible.Billing.Plans.get_subscription_plan(@subscription))}
+
+ <.pill color={subscription_pill_color(@subscription.status)}>
+ {present_subscription_status(@subscription.status)}
+
+
+
+ Up to {PlausibleWeb.AuthView.subscription_quota(@subscription)} monthly pageviews
+
+ <%= if @subscription.next_bill_amount && @subscription.next_bill_date do %>
+
+ {PlausibleWeb.BillingView.present_currency(@subscription.currency_code)}{@subscription.next_bill_amount} / {present_subscription_interval(
+ @subscription
+ )} • Renews on {Calendar.strftime(@subscription.next_bill_date, "%b %-d, %Y")}
+
+ <% end %>
+
+
+ <.button_link
+ :if={
+ @subscription &&
+ Plausible.Billing.Subscriptions.resumable?(@subscription) &&
+ @subscription.update_url
+ }
+ theme="secondary"
+ href={@subscription.update_url}
+ mt?={false}
+ id="billing-details-link"
+ >
+ Billing details
+
+ <.button_link
+ :if={
+ not (Plausible.Teams.Billing.enterprise_configured?(@current_team) &&
+ Plausible.Billing.Subscriptions.halted?(@subscription))
+ }
+ href={Routes.billing_path(PlausibleWeb.Endpoint, :choose_plan)}
+ mt?={false}
+ id="upgrade-or-change-plan-link"
+ >
+ {change_plan_button_label(@subscription)}
+
+
+
+
+ <% else %>
+
+ <% end %>
+
+ <% end %>
+
+ <.tile docs="subscription-plans">
+ <:title>
+ Monthly usage
+
+
+
+
+
+ <.tile docs="subscription-plans">
+ <:title>Site and team usage
+
+
+
+
+
+
+
+ Owned sites
+
+ {PlausibleWeb.TextHelpers.number_format(@site_usage)}
+ {if is_number(@site_limit),
+ do: "/ #{PlausibleWeb.TextHelpers.number_format(@site_limit)}"}
+ {if @site_limit == :unlimited, do: "/ Unlimited"}
+
+
+
+
+
+
+ Team members
+
+ {PlausibleWeb.TextHelpers.number_format(@team_member_usage)}
+ {if is_number(@team_member_limit),
+ do: "/ #{PlausibleWeb.TextHelpers.number_format(@team_member_limit)}"}
+ {if @team_member_limit == :unlimited, do: "/ Unlimited"}
+
+
+
+
+
+
+
+ <.tile :if={@subscription} docs="download-invoices">
+ <:title>
+ Invoices
+
+ <%= case @invoices do %>
+ <% {:error, :no_invoices} -> %>
+
+ You don't have any invoices yet.
+
+ <% {:error, :request_failed} -> %>
+ <.notice theme={:gray} title="We couldn't retrieve your invoices">
+ Please refresh the page or try again later
+
+ <% {:ok, invoice_list} when is_list(invoice_list) -> %>
+
+ <.table
+ rows={Enum.with_index(format_invoices(invoice_list))}
+ row_attrs={
+ fn {_invoice, idx} ->
+ %{
+ "x-show" => "showAll || #{idx} < 3"
+ }
+ end
+ }
+ >
+ <:tbody :let={{invoice, _idx}}>
+ <.td>{invoice.date}
+ <.td>{invoice.currency <> invoice.amount}
+ <.td class="flex justify-end">
+ <.styled_link href={invoice.url} new_tab={true}>
+
+
+
3}>
+ |
+ <.button
+ theme="secondary"
+ x-on:click="showAll = true"
+ x-show="!showAll"
+ >
+ Show more
+
+ |
+
+
+
+ <% end %>
+
+
+
+ <%= if Plausible.Billing.Subscriptions.resumable?(@subscription) && @subscription.cancel_url do %>
+
+ <.button_link theme="danger" href={@subscription.cancel_url} mt?={false}>
+ Cancel plan
+
+ <%= if Application.get_env(:plausible, :environment) == "dev" do %>
+ <.button_link
+ href={@subscription.update_url}
+ theme="secondary"
+ class="text-yellow-600 dark:text-yellow-400"
+ mt?={false}
+ >
+ [DEV ONLY] Change status
+
+ <% end %>
+
+ <% end %>
+ """
+ end
+
+ on_ee do
+ defp consolidated_view_domain(team) do
+ view = Plausible.ConsolidatedView.get(team)
+
+ if not is_nil(view) and Plausible.ConsolidatedView.ok_to_display?(team) do
+ view.domain
+ end
+ end
+ end
+end
diff --git a/lib/plausible_web/plugs/current_path.ex b/lib/plausible_web/plugs/current_path.ex
new file mode 100644
index 000000000000..fecc537e6caf
--- /dev/null
+++ b/lib/plausible_web/plugs/current_path.ex
@@ -0,0 +1,6 @@
+defmodule PlausibleWeb.Plugs.CurrentPath do
+ @moduledoc false
+
+ def init(_), do: []
+ def call(conn, _), do: Plug.Conn.assign(conn, :current_path, conn.request_path)
+end
diff --git a/lib/plausible_web/router.ex b/lib/plausible_web/router.ex
index d864985e87c1..9f5265bd0163 100644
--- a/lib/plausible_web/router.ex
+++ b/lib/plausible_web/router.ex
@@ -481,7 +481,12 @@ defmodule PlausibleWeb.Router do
end
scope "/settings", PlausibleWeb do
- pipe_through [:browser, :csrf, PlausibleWeb.RequireAccountPlug]
+ pipe_through [
+ :browser,
+ :csrf,
+ PlausibleWeb.RequireAccountPlug,
+ PlausibleWeb.Plugs.CurrentPath
+ ]
get "/", SettingsController, :index
get "/preferences", SettingsController, :preferences
@@ -496,7 +501,12 @@ defmodule PlausibleWeb.Router do
post "/security/email", SettingsController, :update_email
post "/security/password", SettingsController, :update_password
- get "/billing/subscription", SettingsController, :subscription
+ live_session :settings, on_mount: PlausibleWeb.Live.SettingsContext do
+ scope alias: Live, assigns: %{connect_live_socket: true} do
+ live "/billing/subscription", SubscriptionSettings, :subscription, as: :settings
+ end
+ end
+
get "/billing/invoices", SettingsController, :redirect_invoices
get "/api-keys", SettingsController, :api_keys
diff --git a/lib/plausible_web/templates/layout/settings.html.heex b/lib/plausible_web/templates/layout/settings.html.heex
index 791478790180..b7e3f4d34f1e 100644
--- a/lib/plausible_web/templates/layout/settings.html.heex
+++ b/lib/plausible_web/templates/layout/settings.html.heex
@@ -1,4 +1,4 @@
-<% options = account_settings_sidebar(@conn) %>
+<% options = account_settings_sidebar(assigns) %>
<.styled_link class="font-semibold text-sm" href="/sites">
← Back to sites
@@ -13,8 +13,7 @@
<.mobile_nav_dropdown
name="settings"
options={options}
- selected_fn={&is_current_tab(@conn, &1)}
- conn={@conn}
+ selected_fn={&is_current_tab(@current_path, &1)}
href_base="/settings/"
/>
@@ -27,7 +26,7 @@
@@ -40,7 +39,7 @@
diff --git a/lib/plausible_web/templates/settings/subscription.html.heex b/lib/plausible_web/templates/settings/subscription.html.heex
deleted file mode 100644
index b7a3e563e7e5..000000000000
--- a/lib/plausible_web/templates/settings/subscription.html.heex
+++ /dev/null
@@ -1,242 +0,0 @@
-<.settings_tiles>
- <%= if is_nil(@current_team) || Plausible.Teams.on_trial?(@current_team) do %>
- <.tile docs="trial-to-paid">
- <:title>Current plan
-
-
-
- Free trial
- <.pill :if={@current_team} color={:yellow}>
- {Plausible.Teams.trial_days_left(@current_team)} days left
-
-
-
- Your 30-day trial will start when you add your first site
-
-
- <.button_link
- href={Routes.billing_path(@conn, :choose_plan)}
- mt?={false}
- id="upgrade-or-change-plan-link"
- >
- {trial_button_label(@current_team)}
-
-
-
- <% else %>
- <.tile docs="billing">
- <:title>Current plan
- <%= if @subscription do %>
-
-
-
-
-
-
- {present_plan_name(Plausible.Billing.Plans.get_subscription_plan(@subscription))}
-
- <.pill color={subscription_pill_color(@subscription.status)}>
- {present_subscription_status(@subscription.status)}
-
-
-
- Up to {PlausibleWeb.AuthView.subscription_quota(@subscription)} monthly pageviews
-
- <%= if @subscription.next_bill_amount && @subscription.next_bill_date do %>
-
- {PlausibleWeb.BillingView.present_currency(@subscription.currency_code)}{@subscription.next_bill_amount} / {present_subscription_interval(
- @subscription
- )} • Renews on {Calendar.strftime(@subscription.next_bill_date, "%b %-d, %Y")}
-
- <% end %>
-
-
- <.button_link
- :if={
- @subscription &&
- Plausible.Billing.Subscriptions.resumable?(@subscription) &&
- @subscription.update_url
- }
- theme="secondary"
- href={@subscription.update_url}
- mt?={false}
- id="billing-details-link"
- >
- Billing details
-
- <.button_link
- :if={
- not (Plausible.Teams.Billing.enterprise_configured?(@current_team) &&
- Plausible.Billing.Subscriptions.halted?(@subscription))
- }
- href={Routes.billing_path(@conn, :choose_plan)}
- mt?={false}
- id="upgrade-or-change-plan-link"
- >
- {change_plan_button_label(@subscription)}
-
-
-
-
- <% else %>
-
- <% end %>
-
- <% end %>
-
- <.tile docs="subscription-plans">
- <:title>
- Monthly usage
-
-
-
-
-
- <.tile docs="subscription-plans">
- <:title>Site and team usage
-
-
-
-
-
-
-
- Owned sites
-
- {PlausibleWeb.TextHelpers.number_format(@site_usage)}
- {if is_number(@site_limit),
- do: "/ #{PlausibleWeb.TextHelpers.number_format(@site_limit)}"}
- {if @site_limit == :unlimited, do: "/ Unlimited"}
-
-
-
-
-
-
- Team members
-
- {PlausibleWeb.TextHelpers.number_format(@team_member_usage)}
- {if is_number(@team_member_limit),
- do: "/ #{PlausibleWeb.TextHelpers.number_format(@team_member_limit)}"}
- {if @team_member_limit == :unlimited, do: "/ Unlimited"}
-
-
-
-
-
-
-
- <.tile :if={@subscription} docs="download-invoices">
- <:title>
- Invoices
-
- <%= case @invoices do %>
- <% {:error, :no_invoices} -> %>
-
- You don't have any invoices yet.
-
- <% {:error, :request_failed} -> %>
- <.notice theme={:gray} title="We couldn't retrieve your invoices">
- Please refresh the page or try again later
-
- <% {:ok, invoice_list} when is_list(invoice_list) -> %>
-
- <.table
- rows={Enum.with_index(format_invoices(invoice_list))}
- row_attrs={
- fn {_invoice, idx} ->
- %{
- "x-show" => "showAll || #{idx} < 3"
- }
- end
- }
- >
- <:tbody :let={{invoice, _idx}}>
- <.td>{invoice.date}
- <.td>{invoice.currency <> invoice.amount}
- <.td class="flex justify-end">
- <.styled_link href={invoice.url} new_tab={true}>
-
-
-
3}>
- |
- <.button
- theme="secondary"
- x-on:click="showAll = true"
- x-show="!showAll"
- >
- Show more
-
- |
-
-
-
- <% end %>
-
-
-
-<%= if Plausible.Billing.Subscriptions.resumable?(@subscription) && @subscription.cancel_url do %>
-
- <.button_link theme="danger" href={@subscription.cancel_url} mt?={false}>
- Cancel plan
-
- <%= if Application.get_env(:plausible, :environment) == "dev" do %>
- <.button_link
- href={@subscription.update_url}
- theme="secondary"
- class="text-yellow-600 dark:text-yellow-400"
- mt?={false}
- >
- [DEV ONLY] Change status
-
- <% end %>
-
-<% end %>
diff --git a/lib/plausible_web/views/layout_view.ex b/lib/plausible_web/views/layout_view.ex
index f224da978726..aee6bd45c126 100644
--- a/lib/plausible_web/views/layout_view.ex
+++ b/lib/plausible_web/views/layout_view.ex
@@ -95,9 +95,9 @@ defmodule PlausibleWeb.LayoutView do
|> Enum.reject(&is_nil/1)
end
- def account_settings_sidebar(conn) do
- current_team = conn.assigns[:current_team]
- current_team_role = conn.assigns[:current_team_role]
+ def account_settings_sidebar(assigns) do
+ current_team = assigns.current_team
+ current_team_role = assigns.current_team_role
options = %{
"Account" =>
@@ -110,7 +110,7 @@ defmodule PlausibleWeb.LayoutView do
if(not Teams.setup?(current_team),
do: %{key: "API keys", value: "api-keys", icon: :api_keys}
),
- if(Plausible.Users.type(conn.assigns.current_user) == :standard,
+ if(Plausible.Users.type(assigns.current_user) == :standard,
do: %{key: "Danger zone", value: "danger-zone", icon: :exclamation_triangle}
)
]
@@ -248,6 +248,10 @@ defmodule PlausibleWeb.LayoutView do
false
end
+ def is_current_tab(path, tab) when is_binary(path) do
+ String.ends_with?(path, tab)
+ end
+
def is_current_tab(conn, tab) do
full_path = Path.join(conn.path_info)
diff --git a/lib/plausible_web/views/settings_view.ex b/lib/plausible_web/views/settings_view.ex
index 167115a35969..e4e217de465e 100644
--- a/lib/plausible_web/views/settings_view.ex
+++ b/lib/plausible_web/views/settings_view.ex
@@ -2,68 +2,4 @@ defmodule PlausibleWeb.SettingsView do
use PlausibleWeb, :view
use Phoenix.Component, global_prefixes: ~w(x-)
use Plausible
-
- require Plausible.Billing.Subscription.Status
- alias Plausible.Billing.{Plans, Subscription, Subscriptions}
-
- def present_plan_name(%Plausible.Billing.Plan{kind: kind}),
- do: kind |> to_string() |> String.capitalize()
-
- def present_plan_name(%Plausible.Billing.EnterprisePlan{}), do: "Enterprise"
- def present_plan_name(:free_10k), do: "Free"
- def present_plan_name(_), do: "Plan"
-
- def subscription_interval(subscription) do
- Plans.subscription_interval(subscription)
- end
-
- def present_subscription_interval(subscription) do
- case subscription_interval(subscription) do
- "monthly" -> "month"
- "yearly" -> "year"
- interval -> interval
- end
- end
-
- @spec present_subscription_status(Subscription.Status.status()) :: String.t()
- def present_subscription_status(Subscription.Status.active()), do: "Active"
- def present_subscription_status(Subscription.Status.past_due()), do: "Past due"
- def present_subscription_status(Subscription.Status.deleted()), do: "Cancelled"
- def present_subscription_status(Subscription.Status.paused()), do: "Paused"
- def present_subscription_status(status), do: status
-
- def subscription_pill_color(Subscription.Status.active()), do: :green
- def subscription_pill_color(Subscription.Status.past_due()), do: :yellow
- def subscription_pill_color(Subscription.Status.paused()), do: :red
- def subscription_pill_color(Subscription.Status.deleted()), do: :red
- def subscription_pill_color(_), do: :gray
-
- def trial_button_label(team) do
- if Plausible.Teams.Billing.enterprise_configured?(team) do
- "Upgrade"
- else
- "Choose a plan →"
- end
- end
-
- def change_plan_button_label(nil), do: "Upgrade"
-
- def change_plan_button_label(subscription) do
- if Subscriptions.resumable?(subscription) && subscription.cancel_url do
- "Change plan"
- else
- "Upgrade"
- end
- end
-
- def format_invoices(invoice_list) do
- Enum.map(invoice_list, fn invoice ->
- %{
- date: invoice["payout_date"] |> Date.from_iso8601!() |> Calendar.strftime("%b %-d, %Y"),
- amount: (invoice["amount"] / 1) |> :erlang.float_to_binary(decimals: 2),
- currency: invoice["currency"] |> PlausibleWeb.BillingView.present_currency(),
- url: invoice["receipt_url"]
- }
- end)
- end
end