@@ -89,11 +89,38 @@ defmodule PlausibleWeb.Live.Sites do
8989 < p :if = { not @ has_sites? } class = "dark:text-gray-100 " >
9090 You don't have any sites yet.
9191 </ p >
92- < div class = "mt-4 flex sm:ml-4 sm:mt-0 " >
93- < a href = { "/sites/new?flow=#{ PlausibleWeb.Flows . provisioning ( ) } " } class = "button " >
94- + Add website
95- </ a >
96- </ div >
92+ <!-- The `z-49` class is to make the dropdown appear above the site cards and (TODO) below the top-right drop down. -->
93+ <!-- The proper solution is for Prima to render the dropdown menu within a <.portal> element to avoid -->
94+ <!-- any stacking context issues. TODO -->
95+ < PlausibleWeb.Components.PrimaDropdown . dropdown
96+ :if = { @ consolidated_view_cta_dismissed? }
97+ class = "z-[49] "
98+ id = "add-site-dropdown "
99+ >
100+ < PlausibleWeb.Components.PrimaDropdown . dropdown_trigger as = { & button / 1 } mt? = { false } >
101+ + Add < Heroicons . chevron_down mini class = "size-4 mt-0.5 " />
102+ </ PlausibleWeb.Components.PrimaDropdown . dropdown_trigger >
103+
104+ < PlausibleWeb.Components.PrimaDropdown . dropdown_menu >
105+ < PlausibleWeb.Components.PrimaDropdown . dropdown_item
106+ as = { & link / 1 }
107+ href = { Routes . site_path ( @ socket , :new , % { flow: PlausibleWeb.Flows . provisioning ( ) } ) }
108+ >
109+ + Add website
110+ </ PlausibleWeb.Components.PrimaDropdown . dropdown_item >
111+ < PlausibleWeb.Components.PrimaDropdown . dropdown_item phx-click = "consolidated-view-cta-restore " >
112+ + Add consolidated view
113+ </ PlausibleWeb.Components.PrimaDropdown . dropdown_item >
114+ </ PlausibleWeb.Components.PrimaDropdown . dropdown_menu >
115+ </ PlausibleWeb.Components.PrimaDropdown . dropdown >
116+
117+ < a
118+ :if = { ! @ consolidated_view_cta_dismissed? }
119+ href = { "/sites/new?flow=#{ PlausibleWeb.Flows . provisioning ( ) } " }
120+ class = "whitespace-nowrap truncate inline-flex items-center justify-center gap-x-2 font-medium rounded-md px-3.5 py-2.5 text-sm transition-all duration-150 cursor-pointer disabled:cursor-not-allowed bg-indigo-600 text-white hover:bg-indigo-700 focus-visible:outline-indigo-600 disabled:bg-indigo-400/60 disabled:dark:bg-indigo-600/30 disabled:dark:text-white/35 "
121+ >
122+ + Add website
123+ </ a >
97124 </ div >
98125
99126 < p :if = { @ filter_text != "" and @ sites . entries == [ ] } class = "mt-4 dark:text-gray-100 text-center " >
@@ -115,7 +142,16 @@ defmodule PlausibleWeb.Live.Sites do
115142
116143 < div :if = { @ has_sites? } >
117144 < ul class = "my-6 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3 " >
118- <!-- Insert upgrade_card here -->
145+ < . consolidated_view_card_cta
146+ :if = {
147+ ! @ consolidated_view and @ no_consolidated_view_reason not in [ :no_sites , :ce ] and
148+ not @ consolidated_view_cta_dismissed?
149+ }
150+ can_manage_consolidated_view? = { @ can_manage_consolidated_view? }
151+ no_consolidated_view_reason = { @ no_consolidated_view_reason }
152+ current_user = { @ current_user }
153+ current_team = { @ current_team }
154+ />
119155 < . consolidated_view_card
120156 :if = { @ consolidated_view && consolidated_view_ok_to_display? ( @ current_team , @ current_user ) }
121157 can_manage_consolidated_view? = { @ can_manage_consolidated_view? }
@@ -190,29 +226,84 @@ defmodule PlausibleWeb.Live.Sites do
190226 """
191227 end
192228
193- def upgrade_card ( assigns ) do
229+ def consolidated_view_card_cta ( assigns ) do
194230 ~H"""
195- < li class = "relative col-span-1 flex flex-col justify-between bg-white p-6 dark:bg-gray-800 rounded-md shadow-lg dark:shadow-xl " >
231+ < li
232+ data-test-id = "consolidated-view-card-cta "
233+ class = "relative col-span-1 flex flex-col justify-between bg-white p-6 dark:bg-gray-800 rounded-md shadow-lg dark:shadow-xl "
234+ >
196235 < div class = "flex flex-col " >
197236 < p class = "text-sm text-gray-600 dark:text-gray-400 " >
198237 Introducing
199238 </ p >
200239 < h3 class = "text-[1.35rem] font-bold text-gray-900 leading-tighter dark:text-gray-100 " >
201- consolidated view
240+ Consolidated view
202241 </ h3 >
203242 </ div >
204- < p class = "text-gray-900 dark:text-gray-100 leading-tighter mb-2.5 " >
205- See stats for all your sites in one single dashboard.
206- </ p >
207- < div class = "flex gap-x-2 " >
208- < a href = "# " class = "button " >
209- Upgrade
210- </ a >
211- < a href = "# " class = "button button-outline " >
212- Learn more
213- </ a >
243+
244+ < div
245+ :if = { @ no_consolidated_view_reason == :team_not_setup }
246+ class = "flex flex-col gap-y-4 "
247+ >
248+ < p class = "text-gray-900 dark:text-gray-100 leading-tighter " >
249+ To create a consolidated view, you'll need to set up a team.
250+ </ p >
251+ < div class = "flex gap-x-2 " >
252+ < . button_link
253+ href = { Routes . team_setup_path ( PlausibleWeb.Endpoint , :setup ) }
254+ mt? = { false }
255+ >
256+ Create team
257+ </ . button_link >
258+ < . button_link
259+ theme = "secondary "
260+ href = "https://plausible.io/docs/consolidated-views "
261+ mt? = { false }
262+ >
263+ Learn more
264+ </ . button_link >
265+ </ div >
214266 </ div >
215- < Heroicons . x_mark class = "absolute top-6 right-6 size-5 text-gray-400 transition-colors duration-150 cursor-pointer dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300 " />
267+
268+ < div
269+ :if = { @ no_consolidated_view_reason == :upgrade_required }
270+ class = "flex flex-col gap-y-4 "
271+ >
272+ < p
273+ :if = { @ can_manage_consolidated_view? }
274+ class = "text-gray-900 dark:text-gray-100 leading-tighter "
275+ >
276+ Upgrade to the Business plan< span :if = { not Teams . setup? ( @ current_team ) } > and set up a team</ span > to enable consolidated views.
277+ </ p >
278+
279+ < p
280+ :if = { not @ can_manage_consolidated_view? }
281+ class = "text-gray-900 dark:text-gray-100 leading-tighter "
282+ >
283+ Available on Business plans. Contact your team owner to create it.
284+ </ p >
285+
286+ < div class = "flex gap-x-2 " >
287+ < . button_link
288+ :if = { @ can_manage_consolidated_view? }
289+ href = { PlausibleWeb.Router.Helpers . billing_url ( PlausibleWeb.Endpoint , :choose_plan ) }
290+ mt? = { false }
291+ >
292+ Upgrade
293+ </ . button_link >
294+
295+ < . button_link
296+ theme = "secondary "
297+ href = "https://plausible.io/docs/consolidated-views "
298+ mt? = { false }
299+ >
300+ Learn more
301+ </ . button_link >
302+ </ div >
303+ </ div >
304+ < a phx-click = "consolidated-view-cta-dismiss " >
305+ < Heroicons . x_mark class = "absolute top-6 right-6 size-5 text-gray-400 transition-colors duration-150 cursor-pointer dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300 " />
306+ </ a >
216307 </ li >
217308 """
218309 end
@@ -781,6 +872,28 @@ defmodule PlausibleWeb.Live.Sites do
781872 { :noreply , socket }
782873 end
783874
875+ on_ee do
876+ def handle_event ( "consolidated-view-cta-dismiss" , _ , socket ) do
877+ :ok =
878+ Plausible.ConsolidatedView . dismiss_cta (
879+ socket . assigns . current_user ,
880+ socket . assigns . current_team
881+ )
882+
883+ { :noreply , assign ( socket , :consolidated_view_cta_dismissed? , true ) }
884+ end
885+
886+ def handle_event ( "consolidated-view-cta-restore" , _ , socket ) do
887+ :ok =
888+ Plausible.ConsolidatedView . restore_cta (
889+ socket . assigns . current_user ,
890+ socket . assigns . current_team
891+ )
892+
893+ { :noreply , assign ( socket , :consolidated_view_cta_dismissed? , false ) }
894+ end
895+ end
896+
784897 defp load_sites ( % { assigns: assigns } = socket ) do
785898 sites =
786899 Sites . list_with_invitations ( assigns . current_user , assigns . params ,
@@ -912,11 +1025,16 @@ defmodule PlausibleWeb.Live.Sites do
9121025 :sha |> :crypto . hash ( domain ) |> Base . encode16 ( )
9131026 end
9141027
915- @ no_consolidated_view % {
916- consolidated_view: nil ,
917- can_manage_consolidated_view?: false ,
918- consolidated_stats: nil
919- }
1028+ def no_consolidated_view ( overrides \\ [ ] ) do
1029+ [
1030+ consolidated_view: nil ,
1031+ can_manage_consolidated_view?: false ,
1032+ consolidated_stats: nil ,
1033+ no_consolidated_view_reason: nil ,
1034+ consolidated_view_cta_dismissed?: false
1035+ ]
1036+ |> Keyword . merge ( overrides )
1037+ end
9201038
9211039 on_ee do
9221040 alias Plausible.ConsolidatedView
@@ -925,19 +1043,28 @@ defmodule PlausibleWeb.Live.Sites do
9251043 ConsolidatedView . ok_to_display? ( team , user )
9261044 end
9271045
928- defp init_consolidated_view_assigns ( _user , nil ) , do: @ no_consolidated_view
1046+ defp init_consolidated_view_assigns ( _user , nil ) do
1047+ # technically this is team not setup, but is also equivalent of having no sites at this moment (can have invitations though), so CTA should not be shown
1048+ no_consolidated_view ( no_consolidated_view_reason: :no_sites )
1049+ end
9291050
9301051 defp init_consolidated_view_assigns ( user , team ) do
931- if Teams . setup? ( team ) do
932- view = ConsolidatedView . get ( team )
1052+ case ConsolidatedView . enable ( team ) do
1053+ { :ok , view } ->
1054+ % {
1055+ consolidated_view: view ,
1056+ can_manage_consolidated_view?: ConsolidatedView . can_manage? ( user , team ) ,
1057+ consolidated_stats: :loading ,
1058+ no_consolidated_view_reason: nil ,
1059+ consolidated_view_cta_dismissed?: ConsolidatedView . cta_dismissed? ( user , team )
1060+ }
9331061
934- % {
935- consolidated_view: view ,
936- can_manage_consolidated_view?: ConsolidatedView . can_manage? ( user , team ) ,
937- consolidated_stats: :loading
938- }
939- else
940- @ no_consolidated_view
1062+ { :error , reason } ->
1063+ no_consolidated_view (
1064+ no_consolidated_view_reason: reason ,
1065+ can_manage_consolidated_view?: ConsolidatedView . can_manage? ( user , team ) ,
1066+ consolidated_view_cta_dismissed?: ConsolidatedView . cta_dismissed? ( user , team )
1067+ )
9411068 end
9421069 end
9431070
@@ -950,7 +1077,10 @@ defmodule PlausibleWeb.Live.Sites do
9501077 end
9511078 else
9521079 defp consolidated_view_ok_to_display? ( _team , _user ) , do: false
953- defp init_consolidated_view_assigns ( _user , _team ) , do: @ no_consolidated_view
1080+
1081+ defp init_consolidated_view_assigns ( _user , _team ) ,
1082+ do: no_consolidated_view ( no_consolidated_view_reason: :ce )
1083+
9541084 defp load_consolidated_stats ( _consolidated_view ) , do: nil
9551085 end
9561086end
0 commit comments