diff --git a/extra/lib/plausible_web/live/customer_support/team.ex b/extra/lib/plausible_web/live/customer_support/team.ex
index bccbaecca0..546a6508a9 100644
--- a/extra/lib/plausible_web/live/customer_support/team.ex
+++ b/extra/lib/plausible_web/live/customer_support/team.ex
@@ -2,7 +2,7 @@ defmodule PlausibleWeb.Live.CustomerSupport.Team do
@moduledoc """
Team coordinator LiveView for Customer Support interface.
- Manages tab-based navigation and delegates rendering to specialized
+ Manages tab-based navigation and delegates rendering to specialized
components: Overview, Members, Sites, Billing, SSO, and Audit.
"""
use PlausibleWeb.CustomerSupport.Live
@@ -364,9 +364,7 @@ defmodule PlausibleWeb.Live.CustomerSupport.Team do
"unlimited"
end
- defp number_format(number) when is_integer(number) do
- Cldr.Number.to_string!(number)
+ defp number_format(input) do
+ PlausibleWeb.TextHelpers.number_format(input)
end
-
- defp number_format(other), do: other
end
diff --git a/extra/lib/plausible_web/live/customer_support/team/components/billing.ex b/extra/lib/plausible_web/live/customer_support/team/components/billing.ex
index 41971292fa..7d008df6c8 100644
--- a/extra/lib/plausible_web/live/customer_support/team/components/billing.ex
+++ b/extra/lib/plausible_web/live/customer_support/team/components/billing.ex
@@ -71,7 +71,9 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.Billing do
<.td>{cycle}
<.td>{date}
<.td>
- limit, do: "text-red-600"}>{number_format(total)}
+ limit, do: "text-red-600"}>
+ {number_format(total)}
+
<.td>{number_format(limit)}
@@ -360,12 +362,10 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.Billing do
"unlimited"
end
- defp number_format(number) when is_integer(number) do
- Cldr.Number.to_string!(number)
+ defp number_format(input) do
+ PlausibleWeb.TextHelpers.number_format(input)
end
- defp number_format(other), do: other
-
defp sanitize_params(params) do
params
|> Enum.map(&clear_param/1)
@@ -403,7 +403,8 @@ defmodule PlausibleWeb.CustomerSupport.Team.Components.Billing do
defp preview_number(n) do
case Integer.parse("#{n}") do
{n, ""} ->
- number_format(n) <> " (#{PlausibleWeb.StatsView.large_number_format(n)})"
+ number_format(n) <>
+ " (#{PlausibleWeb.StatsView.large_number_format(n)})"
_ ->
"0"
diff --git a/lib/plausible_web/components/billing/billing.ex b/lib/plausible_web/components/billing/billing.ex
index 31431eaa8b..0912d4193c 100644
--- a/lib/plausible_web/components/billing/billing.ex
+++ b/lib/plausible_web/components/billing/billing.ex
@@ -198,8 +198,8 @@ defmodule PlausibleWeb.Components.Billing do
{@title}
- {Cldr.Number.to_string!(@usage)}
- {if is_number(@limit), do: "/ #{Cldr.Number.to_string!(@limit)}"}
+ {PlausibleWeb.TextHelpers.number_format(@usage)}
+ {if is_number(@limit), do: "/ #{PlausibleWeb.TextHelpers.number_format(@limit)}"}
|
"""
diff --git a/lib/plausible_web/live/sites.ex b/lib/plausible_web/live/sites.ex
index 16883df7ec..263bfd256e 100644
--- a/lib/plausible_web/live/sites.ex
+++ b/lib/plausible_web/live/sites.ex
@@ -394,7 +394,7 @@ defmodule PlausibleWeb.Live.Sites do
- {abs(@change)}%
+ {PlausibleWeb.TextHelpers.number_format(abs(@change))}%
"""
end
diff --git a/lib/plausible_web/views/text_helpers.ex b/lib/plausible_web/views/text_helpers.ex
index 2f8029d417..17c346948d 100644
--- a/lib/plausible_web/views/text_helpers.ex
+++ b/lib/plausible_web/views/text_helpers.ex
@@ -44,4 +44,10 @@ defmodule PlausibleWeb.TextHelpers do
def format_date(date) do
Calendar.strftime(date, "%b %-d, %Y")
end
+
+ def number_format(number) when is_integer(number) do
+ Cldr.Number.to_string!(number)
+ end
+
+ def number_format(other), do: other
end
diff --git a/test/plausible_web/views/text_helpers_test.exs b/test/plausible_web/views/text_helpers_test.exs
new file mode 100644
index 0000000000..488ec321b8
--- /dev/null
+++ b/test/plausible_web/views/text_helpers_test.exs
@@ -0,0 +1,44 @@
+defmodule PlausibleWeb.TextHelpersTest do
+ use PlausibleWeb.ConnCase, async: true
+ alias PlausibleWeb.TextHelpers
+ doctest PlausibleWeb.TextHelpers
+
+ describe "number_format" do
+ test "numbers under 1000 stay the same" do
+ assert TextHelpers.number_format(0) == "0"
+ assert TextHelpers.number_format(1) == "1"
+ assert TextHelpers.number_format(123) == "123"
+ assert TextHelpers.number_format(999) == "999"
+ end
+
+ test "thousands get comma separator" do
+ assert TextHelpers.number_format(1_000) == "1,000"
+ assert TextHelpers.number_format(1_234) == "1,234"
+ assert TextHelpers.number_format(12_345) == "12,345"
+ assert TextHelpers.number_format(123_456) == "123,456"
+ end
+
+ test "millions get multiple comma separators" do
+ assert TextHelpers.number_format(1_000_000) == "1,000,000"
+ assert TextHelpers.number_format(1_234_567) == "1,234,567"
+ assert TextHelpers.number_format(12_345_678) == "12,345,678"
+ assert TextHelpers.number_format(123_456_789) == "123,456,789"
+ end
+
+ test "billions get multiple comma separators" do
+ assert TextHelpers.number_format(1_000_000_000) == "1,000,000,000"
+ assert TextHelpers.number_format(1_234_567_890) == "1,234,567,890"
+ assert TextHelpers.number_format(12_345_678_901) == "12,345,678,901"
+ end
+
+ test "handles negative numbers" do
+ assert TextHelpers.number_format(-1234) == "-1,234"
+ assert TextHelpers.number_format(-1_234_567) == "-1,234,567"
+ end
+
+ test "handles edge cases" do
+ assert TextHelpers.number_format(0) == "0"
+ assert TextHelpers.number_format(-0) == "0"
+ end
+ end
+end