diff --git a/assets/css/app.css b/assets/css/app.css
index 59cabe882..b68003678 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -7,6 +7,8 @@
@import "tooltip.css";
@import "flatpickr.css";
+[x-cloak] { display: none; }
+
.button {
@apply inline-flex justify-center px-4 py-2 text-sm font-medium text-white bg-indigo-600 border border-transparent rounded-md leading-5 transition hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500;
}
diff --git a/lib/plausible/billing/plans.ex b/lib/plausible/billing/plans.ex
index e10b09d88..619c2a9a2 100644
--- a/lib/plausible/billing/plans.ex
+++ b/lib/plausible/billing/plans.ex
@@ -1,80 +1,93 @@
defmodule Plausible.Billing.Plans do
- @monthly_plans [
- %{product_id: "558018", cost: "$6", limit: 10_000, cycle: "monthly"},
- %{product_id: "558745", cost: "$12", limit: 100_000, cycle: "monthly"},
- %{product_id: "597485", cost: "$18", limit: 200_000, cycle: "monthly"},
- %{product_id: "597487", cost: "$27", limit: 500_000, cycle: "monthly"},
- %{product_id: "597642", cost: "$48", limit: 1_000_000, cycle: "monthly"},
- %{product_id: "597309", cost: "$69", limit: 2_000_000, cycle: "monthly"},
- %{product_id: "597311", cost: "$99", limit: 5_000_000, cycle: "monthly"},
- %{product_id: "642352", cost: "$150", limit: 10_000_000, cycle: "monthly"},
- %{product_id: "642355", cost: "$225", limit: 20_000_000, cycle: "monthly"},
- %{product_id: "650652", cost: "$330", limit: 50_000_000, cycle: "monthly"}
- ]
-
- @yearly_plans [
- %{product_id: "572810", cost: "$48", monthly_cost: "$4", limit: 10_000, cycle: "yearly"},
- %{product_id: "590752", cost: "$96", monthly_cost: "$8", limit: 100_000, cycle: "yearly"},
- %{product_id: "597486", cost: "$144", monthly_cost: "$12", limit: 200_000, cycle: "yearly"},
- %{product_id: "597488", cost: "$216", monthly_cost: "$18", limit: 500_000, cycle: "yearly"},
- %{product_id: "597643", cost: "$384", monthly_cost: "$32", limit: 1_000_000, cycle: "yearly"},
- %{product_id: "597310", cost: "$552", monthly_cost: "$46", limit: 2_000_000, cycle: "yearly"},
- %{product_id: "597312", cost: "$792", monthly_cost: "$66", limit: 5_000_000, cycle: "yearly"},
+ @plans_v1 [
+ %{
+ limit: 10_000,
+ monthly_product_id: "558018",
+ monthly_cost: "$6",
+ yearly_product_id: "572810",
+ yearly_cost: "$48"
+ },
+ %{
+ limit: 100_000,
+ monthly_product_id: "558745",
+ monthly_cost: "$12",
+ yearly_product_id: "590752",
+ yearly_cost: "$96"
+ },
+ %{
+ limit: 200_000,
+ monthly_product_id: "597485",
+ monthly_cost: "$18",
+ yearly_product_id: "597486",
+ yearly_cost: "$144"
+ },
+ %{
+ limit: 500_000,
+ monthly_product_id: "597487",
+ monthly_cost: "$27",
+ yearly_product_id: "597488",
+ yearly_cost: "$216"
+ },
+ %{
+ limit: 1_000_000,
+ monthly_product_id: "597642",
+ monthly_cost: "$48",
+ yearly_product_id: "597643",
+ yearly_cost: "$384"
+ },
+ %{
+ limit: 2_000_000,
+ monthly_product_id: "597309",
+ monthly_cost: "$69",
+ yearly_product_id: "597310",
+ yearly_cost: "$552"
+ },
+ %{
+ limit: 5_000_000,
+ monthly_product_id: "597311",
+ monthly_cost: "$99",
+ yearly_product_id: "597312",
+ yearly_cost: "$792"
+ },
%{
- product_id: "642354",
- cost: "$1200",
- monthly_cost: "$100",
limit: 10_000_000,
- cycle: "yearly"
- },
- %{
- product_id: "642356",
- cost: "$1800",
+ monthly_product_id: "642352",
monthly_cost: "$150",
+ yearly_product_id: "642354",
+ yearly_cost: "$1200"
+ },
+ %{
limit: 20_000_000,
- cycle: "yearly"
+ monthly_product_id: "642355",
+ monthly_cost: "$225",
+ yearly_product_id: "642356",
+ yearly_cost: "$1800"
},
%{
- product_id: "650653",
- cost: "$2640",
- monthly_cost: "$220",
limit: 50_000_000,
- cycle: "yearly"
- },
- %{
- product_id: "648089",
- cost: "$4800",
- monthly_cost: "$400",
- limit: 150_000_000,
- cycle: "yearly"
+ monthly_product_id: "650652",
+ monthly_cost: "$330",
+ yearly_product_id: "650653",
+ yearly_cost: "$2640"
}
]
- @all_plans @monthly_plans ++ @yearly_plans
+ @yearly_plans_v1 [
+ %{limit: 150_000_000, yearly_product_id: "648089", yearly_cost: "$4800"}
+ ]
- def plans do
- monthly =
- @monthly_plans
- |> Enum.map(fn plan -> {String.to_atom(number_format(plan[:limit])), plan} end)
- |> Enum.into(%{})
-
- yearly =
- @yearly_plans
- |> Enum.map(fn plan -> {String.to_atom(number_format(plan[:limit])), plan} end)
- |> Enum.into(%{})
-
- %{
- monthly: monthly,
- yearly: yearly
- }
+ def plans_for(user) do
+ @plans_v1 |> Enum.map(fn plan -> Map.put(plan, :volume, number_format(plan[:limit])) end)
end
- def yearly_plan_ids do
- Enum.map(@yearly_plans, fn plan -> plan[:product_id] end)
+ def all_yearly_plan_ids do
+ Enum.map(@plans_v1, fn plan -> plan[:yearly_product_id] end)
end
def for_product_id(product_id) do
- Enum.find(@all_plans, fn plan -> plan[:product_id] == product_id end)
+ Enum.find(@plans_v1, fn plan ->
+ product_id in [plan[:monthly_product_id], plan[:yearly_product_id]]
+ end)
end
def subscription_quota("free_10k"), do: "10k"
@@ -90,38 +103,32 @@ defmodule Plausible.Billing.Plans do
def subscription_interval(product_id) do
case for_product_id(product_id) do
- nil -> raise "Unknown interval for subscription #{product_id}"
- product -> product[:cycle]
+ nil ->
+ raise "Unknown interval for subscription #{product_id}"
+
+ plan ->
+ if product_id == plan[:monthly_product_id] do
+ "monthly"
+ else
+ "yearly"
+ end
end
end
- def suggested_plan_name(usage) do
- plan = suggested_plan(usage)
- number_format(plan[:limit]) <> "/mo"
- end
-
- def suggested_plan_cost(usage) do
- plan = suggested_plan(usage)
- plan[:cost] <> "/mo"
- end
-
- def suggested_plan_cost_yearly(usage) do
- plan = Enum.find(@yearly_plans, fn plan -> usage < plan[:limit] end)
- plan[:monthly_cost] <> "/mo"
- end
-
- defp suggested_plan(usage) do
- Enum.find(@monthly_plans, fn plan -> usage < plan[:limit] end)
- end
+ def allowance(%Plausible.Billing.Subscription{paddle_plan_id: "free_10k"}), do: 10_000
def allowance(subscription) do
- found = Enum.find(@all_plans, fn plan -> plan[:product_id] == subscription.paddle_plan_id end)
+ found = for_product_id(subscription.paddle_plan_id)
if found do
Map.fetch!(found, :limit)
end
end
+ def suggested_plan(user, usage) do
+ Enum.find(plans_for(user), fn plan -> usage < plan[:limit] end)
+ end
+
defp number_format(num) do
PlausibleWeb.StatsView.large_number_format(num)
end
diff --git a/lib/plausible_web/email.ex b/lib/plausible_web/email.ex
index 42ca64ba3..7d828a5d2 100644
--- a/lib/plausible_web/email.ex
+++ b/lib/plausible_web/email.ex
@@ -71,6 +71,8 @@ defmodule PlausibleWeb.Email do
end
def trial_upgrade_email(user, day, {pageviews, custom_events}) do
+ suggested_plan = Plausible.Billing.Plans.suggested_plan(user, pageviews + custom_events)
+
base_email()
|> to(user)
|> tag("trial-upgrade-email")
@@ -79,7 +81,8 @@ defmodule PlausibleWeb.Email do
user: user,
day: day,
custom_events: custom_events,
- usage: pageviews + custom_events
+ usage: pageviews + custom_events,
+ suggested_plan: suggested_plan
)
end
@@ -112,7 +115,7 @@ defmodule PlausibleWeb.Email do
})
end
- def over_limit_email(user, usage, last_cycle) do
+ def over_limit_email(user, usage, last_cycle, suggested_plan) do
base_email()
|> to(user)
|> tag("over-limit")
@@ -120,7 +123,8 @@ defmodule PlausibleWeb.Email do
|> render("over_limit.html", %{
user: user,
usage: usage,
- last_cycle: last_cycle
+ last_cycle: last_cycle,
+ suggested_plan: suggested_plan
})
end
diff --git a/lib/plausible_web/templates/billing/_plan_option.html.eex b/lib/plausible_web/templates/billing/_plan_option.html.eex
index c624b6be0..d1db3b7f9 100644
--- a/lib/plausible_web/templates/billing/_plan_option.html.eex
+++ b/lib/plausible_web/templates/billing/_plan_option.html.eex
@@ -1,7 +1,7 @@
'" :class="{'border-2 border-green-300 bg-opacity-20 bg-green-300': volume === '<%= @volume %>', 'border-b border-gray-200 cursor-pointer': volume !== '<%= @volume %>'}">
<%= @volume %> |
- <%= @monthly_price %>
- <%= @yearly_price %>
+ <%= @monthly_price %> / mo
+ <%= @yearly_price %> / yr
|
diff --git a/lib/plausible_web/templates/billing/change_plan.html.eex b/lib/plausible_web/templates/billing/change_plan.html.eex
index 5c440717d..254b98fad 100644
--- a/lib/plausible_web/templates/billing/change_plan.html.eex
+++ b/lib/plausible_web/templates/billing/change_plan.html.eex
@@ -1,5 +1,27 @@
@@ -7,7 +29,7 @@
-
+
Select your new plan
@@ -48,15 +70,9 @@
- <%= render("_plan_option.html", volume: "10k", monthly_price: "$6", yearly_price: "$4") %>
- <%= render("_plan_option.html", volume: "100k", monthly_price: "$12", yearly_price: "$8") %>
- <%= render("_plan_option.html", volume: "200k", monthly_price: "$18", yearly_price: "$12") %>
- <%= render("_plan_option.html", volume: "500k", monthly_price: "$27", yearly_price: "$18") %>
- <%= render("_plan_option.html", volume: "1M", monthly_price: "$48", yearly_price: "$32") %>
- <%= render("_plan_option.html", volume: "2M", monthly_price: "$69", yearly_price: "$46") %>
- <%= render("_plan_option.html", volume: "5M", monthly_price: "$99", yearly_price: "$69") %>
- <%= render("_plan_option.html", volume: "10M", monthly_price: "$150", yearly_price: "$100") %>
- <%= render("_plan_option.html", volume: "20M", monthly_price: "$225", yearly_price: "$150") %>
+ <%= for plan <- Plausible.Billing.Plans.plans_for(@conn.assigns[:current_user]) do %>
+ <%= render("_plan_option.html", volume: PlausibleWeb.StatsView.large_number_format(plan[:limit]), monthly_price: plan[:monthly_cost], yearly_price: plan[:yearly_cost]) %>
+ <% end %>
@@ -65,12 +81,12 @@
-
+
Preview changes
-
+
Preview changes
diff --git a/lib/plausible_web/templates/billing/upgrade.html.eex b/lib/plausible_web/templates/billing/upgrade.html.eex
index 9e4e0a187..d57a8db80 100644
--- a/lib/plausible_web/templates/billing/upgrade.html.eex
+++ b/lib/plausible_web/templates/billing/upgrade.html.eex
@@ -1,5 +1,27 @@
@@ -8,7 +30,7 @@
-
+
You've used <%= PlausibleWeb.AuthView.delimit_integer(@usage) %> billable pageviews in the last 30 days
@@ -39,20 +61,14 @@
Monthly pageviews
- Price per month
+ Price
|
- <%= render("_plan_option.html", volume: "10k", monthly_price: "$6", yearly_price: "$4") %>
- <%= render("_plan_option.html", volume: "100k", monthly_price: "$12", yearly_price: "$8") %>
- <%= render("_plan_option.html", volume: "200k", monthly_price: "$18", yearly_price: "$12") %>
- <%= render("_plan_option.html", volume: "500k", monthly_price: "$27", yearly_price: "$18") %>
- <%= render("_plan_option.html", volume: "1M", monthly_price: "$48", yearly_price: "$32") %>
- <%= render("_plan_option.html", volume: "2M", monthly_price: "$69", yearly_price: "$46") %>
- <%= render("_plan_option.html", volume: "5M", monthly_price: "$99", yearly_price: "$69") %>
- <%= render("_plan_option.html", volume: "10M", monthly_price: "$150", yearly_price: "$100") %>
- <%= render("_plan_option.html", volume: "20M", monthly_price: "$225", yearly_price: "$150") %>
+ <%= for plan <- Plausible.Billing.Plans.plans_for(@user) do %>
+ <%= render("_plan_option.html", volume: PlausibleWeb.StatsView.large_number_format(plan[:limit]), monthly_price: plan[:monthly_cost], yearly_price: plan[:yearly_cost]) %>
+ <% end %>
@@ -60,9 +76,9 @@
-
Due today: $6
+
Due today: $6
-