analytics/lib/plausible_web/templates/layout/focus.html.eex
RobertJoonas 8bc86d165f
Use Phoenix LiveView for the upgrade page (#3382)
* add a new upgrade page liveview behind a FF

* Create plans_v4.json file

* Add the upgrade page UI template and some basic functionalities

* different content based on subscription plan existing or not
* pageview slider
* monthly/yearly switch

* fix tests

* split into 2 separate functions

* rename variables

* implement volume slider + read default interval/volume from plan

* organize choose-plan.ex better

* remove unused vars from tests

* make monthly_cost and yearly_cost nil by default

The actual prices for all plans are stored in Paddle. We don't need to
keep the duplicates in the JSON files.

* add fetch_prices/1 to PaddleApi

* make v4 business ID's differ from growth ones

* render actual price information from plans

...and make the prices in both growth and business plan boxes change
dynamically when the pageview slider or interval is changed.

* highlight current subscription plan box

* add test describe block for business tier subscription

* connect to live socket only on the specific LV page using focus.html

* only wrap the input slider inside the form

* little readability improvement

* add v4 team_member_limits (after rebase with master)

* extract monthly_quota_box function in user_settings

When the business_tier FF is enabled, this section is different and
links to the new upgrade page.

* document subscription statuses

* change _notice.html.eex to .heex

* extract subscription status notice components

* add failed payment notices to upgrade page

* create class_of_element/2 convenience function for testing

* add cancel_subscription mix task

* implement checkout buttons

* mix format

* get all available plans with prices through plans.ex

* use more suitable function for fetching usage

* avoid double db lookups on mount

* rename variable

* separate functions for getting plan by product_id vs subscription

* separate subscription status docs into context module

* consider cancelled subscriptions

* default volume by usage if no subscription plan

* add enterprise-level volume option to slider

* optimize for darkmode

* UI improvements

* display 2 months free notice for yearly billing
* VAT excluded notice
* note about having a business subscription in user settings
* make the page pop and fit plans on screen on first render

* optimize for mobile and remove background containers

* change default price tag to simply 'N/A'

* fix tests

* Change Paddle.js integration to use JavaScript directly
* rename many variables

* allow users on v1 and v2 plan subscribe to 20M and 50M tiers

* add a test for two months free label

* make it work with a free_10k subscription

* small test improvement and formatting

* change other upgrade link in user settings if FF enabled

* dialyzer

* fix typo

* add test for free_10k user

* silence credo

* mix format

* credo - add moduledoc

* credo - another moduledoc

* handle calls to sentry on the api level

* refactor getting regular subscription plan for LiveView

* post review code style tweaks

* remove unused aliases

* credo - add @moduledoc false to Subscriptions

* crash in cancel_subscription task when Repo update fails

* readability improvements (review suggestions)

* add comment about 'external_resource' module attr

---------

Co-authored-by: Vinicius Brasil <vini@hey.com>
2023-10-03 13:36:22 +03:00

40 lines
2.1 KiB
Elixir

<!DOCTYPE html>
<html lang="en" class="h-full">
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="description" content="A lightweight, non-intrusive alternative to Google Analytics."/>
<meta name="robots" content="<%= @conn.private.robots %>" />
<%= if @conn.assigns[:connect_live_socket] do %>
<meta name="csrf-token" content="<%= Plug.CSRFProtection.get_csrf_token() %>" />
<meta name="websocket-url" content="<%= websocket_url() %>" />
<% end %>
<link rel="icon" type="image/png" sizes="32x32" href="<%= PlausibleWeb.Router.Helpers.static_path(@conn, "/images/icon/plausible_favicon.png") %>">
<title><%= assigns[:title] || "Plausible · Web analytics" %></title>
<link rel="stylesheet" href="<%= Routes.static_path(@conn, "/css/app.css") %>"/>
<%= render("_tracking.html", assigns) %>
<script type="text/javascript" data-pref="<%= @conn.assigns[:current_user] && @conn.assigns[:current_user].theme %>" src="<%= Routes.static_path(@conn, "/js/applyTheme.js") %>"></script>
</head>
<body class="flex flex-col h-full bg-gray-100 dark:bg-gray-900">
<div class="w-full my-8 text-center">
<a href="<%= home_dest(@conn) %>">
<%= img_tag(PlausibleWeb.Router.Helpers.static_path(@conn, "/images/icon/plausible_logo_dark.png"), class: "hidden dark:inline", style: "height: 2.5rem;", alt: "Plausible logo") %>
<%= img_tag(PlausibleWeb.Router.Helpers.static_path(@conn, "/images/icon/plausible_logo.png"), class: "inline dark:hidden", style: "height: 2.5rem;", alt: "Plausible logo")%>
</a>
</div>
<%= if assigns[:flash] do %>
<%= render("_flash.html", assigns) %>
<% end %>
<%= @inner_content %>
<p class="text-center text-gray-500 text-xs py-8">
© <%= DateTime.utc_now().year() %> Plausible Analytics. All rights reserved.
</p>
<script type="text/javascript" src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
</body>
</html>