defmodule PlausibleWeb.Live.SubscriptionSettings do @moduledoc """ LiveView for the subscription settings page. """ use PlausibleWeb, :live_view use Plausible require Plausible.Billing 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 if Teams.setup?(team) && socket.assigns.current_team_role not in Plausible.Billing.allowed_roles() do {:ok, redirect(socket, to: Routes.site_path(socket, :index))} else 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 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={ 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