Upgrade deps, add storybook (#4947)
* Add `<.dropdown_item>` * Make the ellipsis menu functional again * Upgrade deps so that storybook can be added * Add storybook and dropdown story * Remove lingering warnings/errors * Add color mode to storybook * Use new liveview used_input? function * Alpine improvements * Add select input to storybook * Bring back `render_form` for CRM * Configure eslint so it can see deps * Remove LiveViewTest patch * Fix test for phoenix liveview 1.0 * Build assets in prod * Fix tests * Attempt to fix lint error * Add explicit text color to input * mix format * Format after merge master * Add moduledocs * Only run storybook in production * Update storybook dependency * Mix format
This commit is contained in:
parent
32d1783604
commit
6c30f62d5d
|
|
@ -2,5 +2,10 @@
|
|||
plugins: [Phoenix.LiveView.HTMLFormatter],
|
||||
import_deps: [:ecto, :ecto_sql, :phoenix],
|
||||
subdirectories: ["priv/*/migrations"],
|
||||
inputs: ["*.{heex,ex,exs}", "{config,lib,test,extra}/**/*.{heex,ex,exs}", "priv/*/seeds.exs"]
|
||||
inputs: [
|
||||
"*.{heex,ex,exs}",
|
||||
"{config,lib,test,extra}/**/*.{heex,ex,exs}",
|
||||
"priv/*/seeds.exs",
|
||||
"storybook/**/*.exs"
|
||||
]
|
||||
]
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ COPY tracker ./tracker
|
|||
COPY priv ./priv
|
||||
COPY lib ./lib
|
||||
COPY extra ./extra
|
||||
COPY storybook ./storybook
|
||||
|
||||
RUN npm run deploy --prefix ./tracker && \
|
||||
mix assets.deploy && \
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@
|
|||
"import/resolver": {
|
||||
"typescript": {
|
||||
"alwaysTryTypes": true // always try to resolve types under `<root>@types` directory even it doesn't contain any source code, like `@types/unist`
|
||||
},
|
||||
"node": {
|
||||
"moduleDirectory": ["node_modules", "../deps"]
|
||||
}
|
||||
},
|
||||
"react": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
@import "tailwindcss/base";
|
||||
@import "tailwindcss/components";
|
||||
@import "tailwindcss/utilities";
|
||||
|
||||
/*
|
||||
* Put your component styling within the Tailwind utilities layer.
|
||||
* See the https://hexdocs.pm/phoenix_storybook/sandboxing.html guide for more info.
|
||||
*/
|
||||
|
||||
@layer utilities {
|
||||
* {
|
||||
font-family: system-ui;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,11 @@
|
|||
// eslint-disable-next-line import/no-unresolved
|
||||
import "phoenix_html"
|
||||
import Alpine from 'alpinejs'
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { Socket } from "phoenix"
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import { LiveSocket } from "phoenix_live_view"
|
||||
// eslint-disable-next-line import/no-unresolved
|
||||
import Alpine from 'alpinejs'
|
||||
|
||||
let csrfToken = document.querySelector("meta[name='csrf-token']")
|
||||
let websocketUrl = document.querySelector("meta[name='websocket-url']")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
import Alpine from 'alpinejs'
|
||||
import dropdown from "./liveview/dropdown"
|
||||
|
||||
// If your components require any hooks or custom uploaders, or if your pages
|
||||
// require connect parameters, uncomment the following lines and declare them as
|
||||
// such:
|
||||
//
|
||||
// import * as Hooks from "./hooks";
|
||||
// import * as Params from "./params";
|
||||
// import * as Uploaders from "./uploaders";
|
||||
|
||||
// (function () {
|
||||
// window.storybook = { Hooks, Params, Uploaders };
|
||||
// })();
|
||||
|
||||
|
||||
window.Alpine = Alpine
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
window.Alpine.start();
|
||||
});
|
||||
|
||||
document.addEventListener('alpine:init', () => {
|
||||
window.Alpine.data('dropdown', dropdown)
|
||||
});
|
||||
|
||||
|
||||
(function () {
|
||||
window.storybook = {
|
||||
LiveSocketOptions: {
|
||||
dom: {
|
||||
onBeforeElUpdated(from, to) {
|
||||
if (from._x_dataStack) {
|
||||
window.Alpine.clone(from, to)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
|
@ -26,9 +26,6 @@
|
|||
"d3": "^7.9.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"iframe-resizer": "^4.3.2",
|
||||
"phoenix": "^1.7.2",
|
||||
"phoenix_html": "^3.3.1",
|
||||
"phoenix_live_view": "^0.18.18",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-flatpickr": "3.10.5",
|
||||
|
|
@ -9308,17 +9305,6 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/phoenix": {
|
||||
"version": "1.7.2",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/phoenix_html": {
|
||||
"version": "3.3.1"
|
||||
},
|
||||
"node_modules/phoenix_live_view": {
|
||||
"version": "0.18.18",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
|
||||
|
|
|
|||
|
|
@ -30,9 +30,6 @@
|
|||
"d3": "^7.9.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"iframe-resizer": "^4.3.2",
|
||||
"phoenix": "^1.7.2",
|
||||
"phoenix_html": "^3.3.1",
|
||||
"phoenix_live_view": "^0.18.18",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-flatpickr": "3.10.5",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ module.exports = {
|
|||
"max-w-screen-xl"
|
||||
],
|
||||
darkMode: 'class',
|
||||
important: '.plausible',
|
||||
theme: {
|
||||
container: {
|
||||
center: true,
|
||||
|
|
@ -51,7 +52,6 @@ module.exports = {
|
|||
plugins: [
|
||||
require('@tailwindcss/forms'),
|
||||
require('@tailwindcss/aspect-ratio'),
|
||||
plugin(({ addVariant }) => addVariant("phx-no-feedback", [".phx-no-feedback&", ".phx-no-feedback &"])),
|
||||
plugin(({ addVariant }) => addVariant("phx-click-loading", [".phx-click-loading&", ".phx-click-loading &"])),
|
||||
plugin(({ addVariant }) => addVariant("phx-submit-loading", [".phx-submit-loading&", ".phx-submit-loading &"])),
|
||||
plugin(({ addVariant }) => addVariant("phx-change-loading", [".phx-change-loading&", ".phx-change-loading &"])),
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ config :esbuild,
|
|||
version: "0.17.11",
|
||||
default: [
|
||||
args:
|
||||
~w(js/app.js js/dashboard.tsx js/embed.host.js js/embed.content.js --bundle --target=es2017 --loader:.js=jsx --outdir=../priv/static/js --define:BUILD_EXTRA=true),
|
||||
~w(js/app.js js/storybook.js js/dashboard.tsx js/embed.host.js js/embed.content.js --bundle --target=es2017 --loader:.js=jsx --outdir=../priv/static/js --define:BUILD_EXTRA=true),
|
||||
cd: Path.expand("../assets", __DIR__),
|
||||
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
|
||||
]
|
||||
|
|
@ -34,6 +34,14 @@ config :tailwind,
|
|||
--output=../priv/static/css/app.css
|
||||
),
|
||||
cd: Path.expand("../assets", __DIR__)
|
||||
],
|
||||
storybook: [
|
||||
args: ~w(
|
||||
--config=tailwind.config.js
|
||||
--input=css/storybook.css
|
||||
--output=../priv/static/css/storybook.css
|
||||
),
|
||||
cd: Path.expand("../assets", __DIR__)
|
||||
]
|
||||
|
||||
config :ua_inspector,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ config :plausible, PlausibleWeb.Endpoint,
|
|||
watchers: [
|
||||
esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]},
|
||||
tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]},
|
||||
storybook_tailwind: {Tailwind, :install_and_run, [:storybook, ~w(--watch)]},
|
||||
npm: ["--prefix", "assets", "run", "typecheck", "--", "--watch", "--preserveWatchOutput"],
|
||||
npm: [
|
||||
"run",
|
||||
|
|
@ -21,7 +22,8 @@ config :plausible, PlausibleWeb.Endpoint,
|
|||
],
|
||||
patterns: [
|
||||
~r{priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$},
|
||||
~r"lib/plausible_web/(controllers|live|components|templates|views|plugs)/.*(ex|heex)$"
|
||||
~r"lib/plausible_web/(controllers|live|components|templates|views|plugs)/.*(ex|heex)$",
|
||||
~r"storybook/.*(exs)$"
|
||||
]
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -969,3 +969,5 @@ unless s3_disabled? do
|
|||
exports_bucket: s3_env_value.("S3_EXPORTS_BUCKET"),
|
||||
imports_bucket: s3_env_value.("S3_IMPORTS_BUCKET")
|
||||
end
|
||||
|
||||
config :phoenix_storybook, enabled: env !== "prod"
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ defmodule PlausibleWeb.Live.FunnelSettings do
|
|||
<.flash_messages flash={@flash} />
|
||||
|
||||
<%= if @setup_funnel? do %>
|
||||
<%= live_render(
|
||||
{live_render(
|
||||
@socket,
|
||||
PlausibleWeb.Live.FunnelSettings.Form,
|
||||
id: "funnels-form",
|
||||
|
|
@ -56,7 +56,7 @@ defmodule PlausibleWeb.Live.FunnelSettings do
|
|||
"domain" => @domain,
|
||||
"funnel_id" => @funnel_id
|
||||
}
|
||||
) %>
|
||||
)}
|
||||
<% end %>
|
||||
<div :if={@goal_count >= Funnel.min_steps()}>
|
||||
<.live_component
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
|
|||
class="bg-white dark:bg-gray-800 shadow-md rounded px-8 pt-6 pb-8 mb-4 mt-8"
|
||||
>
|
||||
<.title class="mb-6">
|
||||
<%= if @funnel, do: "Edit", else: "Add" %> Funnel
|
||||
{if @funnel, do: "Edit", else: "Add"} Funnel
|
||||
</.title>
|
||||
|
||||
<.input
|
||||
|
|
@ -136,7 +136,7 @@ defmodule PlausibleWeb.Live.FunnelSettings.Form do
|
|||
length(@step_ids) > map_size(@selections_made)
|
||||
}
|
||||
>
|
||||
<span><%= if @funnel, do: "Update", else: "Add" %> Funnel</span>
|
||||
<span>{if @funnel, do: "Update", else: "Add"} Funnel</span>
|
||||
</.button>
|
||||
</div>
|
||||
</.form>
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@ defmodule PlausibleWeb.Live.FunnelSettings.List do
|
|||
<.table rows={@funnels}>
|
||||
<:tbody :let={funnel}>
|
||||
<.td truncate>
|
||||
<span class="font-medium"><%= funnel.name %></span>
|
||||
<span class="font-medium">{funnel.name}</span>
|
||||
</.td>
|
||||
<.td hide_on_mobile>
|
||||
<span class="text-gray-500 dark:text-gray-400">
|
||||
<%= funnel.steps_count %>-step funnel
|
||||
{funnel.steps_count}-step funnel
|
||||
</span>
|
||||
</.td>
|
||||
<.td actions>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ defmodule PlausibleWeb.HelpScoutView do
|
|||
|
||||
<%= if @conn.assigns[:error] do %>
|
||||
<p>
|
||||
Failed to get details: <%= @error %>
|
||||
Failed to get details: {@error}
|
||||
</p>
|
||||
<% else %>
|
||||
<div class="status">
|
||||
|
|
@ -25,7 +25,7 @@ defmodule PlausibleWeb.HelpScoutView do
|
|||
Status
|
||||
</p>
|
||||
<p class="value">
|
||||
<a href={@status_link} target="_blank"><%= @status_label %></a>
|
||||
<a href={@status_link} target="_blank">{@status_label}</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -34,13 +34,13 @@ defmodule PlausibleWeb.HelpScoutView do
|
|||
Plan
|
||||
</p>
|
||||
<p class="value">
|
||||
<a href={@plan_link} target="_blank"><%= @plan_label %></a>
|
||||
<a href={@plan_link} target="_blank">{@plan_label}</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="sites">
|
||||
<p class="label">
|
||||
Owner of <b><a href={@sites_link} target="_blank"><%= @sites_count %> sites</a></b>
|
||||
Owner of <b><a href={@sites_link} target="_blank">{@sites_count} sites</a></b>
|
||||
</p>
|
||||
<p class="value"></p>
|
||||
</div>
|
||||
|
|
@ -51,7 +51,7 @@ defmodule PlausibleWeb.HelpScoutView do
|
|||
</p>
|
||||
|
||||
<div class="value">
|
||||
<%= Phoenix.HTML.Format.text_to_html(@notes, escape: true) %>
|
||||
{PhoenixHTMLHelpers.Format.text_to_html(@notes, escape: true)}
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
@ -64,7 +64,7 @@ defmodule PlausibleWeb.HelpScoutView do
|
|||
<.layout>
|
||||
<%= if @conn.assigns[:error] do %>
|
||||
<p>
|
||||
Failed to run search: <%= @error %>
|
||||
Failed to run search: {@error}
|
||||
</p>
|
||||
<% else %>
|
||||
<div class="search">
|
||||
|
|
@ -82,7 +82,7 @@ defmodule PlausibleWeb.HelpScoutView do
|
|||
onclick={"loadContent('/helpscout/show?#{URI.encode_query(email: user.email, conversation_id: @conversation_id, customer_id: @customer_id)}')"}
|
||||
href="#"
|
||||
>
|
||||
<%= user.email %> (<%= user.sites_count %> sites)
|
||||
{user.email} ({user.sites_count} sites)
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
@ -160,7 +160,7 @@ defmodule PlausibleWeb.HelpScoutView do
|
|||
|
||||
<body>
|
||||
<div id="content">
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ end
|
|||
|
||||
defmodule Plausible.Billing.Ecto.FeatureList do
|
||||
@moduledoc """
|
||||
Ecto type representing a list of features. This is a proxy for
|
||||
Ecto type representing a list of features. This is a proxy for
|
||||
`{:array, Plausible.Billing.Ecto.Feature}` and is required for Kaffy to
|
||||
render the HTML input correctly.
|
||||
"""
|
||||
|
|
@ -52,15 +52,8 @@ defmodule Plausible.Billing.Ecto.FeatureList do
|
|||
for mod <- Plausible.Billing.Feature.list(), not mod.free?() do
|
||||
[
|
||||
{:safe, ~s(<label style="padding-right: 15px;">)},
|
||||
Phoenix.HTML.Tag.tag(
|
||||
:input,
|
||||
name: Phoenix.HTML.Form.input_name(form, field) <> "[]",
|
||||
id: Phoenix.HTML.Form.input_id(form, field, mod.name()),
|
||||
type: "checkbox",
|
||||
value: mod.name(),
|
||||
style: "margin-right: 3px;",
|
||||
checked: mod in features
|
||||
),
|
||||
{:safe,
|
||||
~s(<input type="checkbox" name="#{form.name}[#{field}][]" "#{form.name}_#{field}_#{mod.name()}" value="#{mod.name()}" style="margin-right: 3px;" #{if mod in features, do: "checked", else: ""}>)},
|
||||
mod.display_name(),
|
||||
{:safe, ~s(</label>)}
|
||||
]
|
||||
|
|
@ -68,7 +61,7 @@ defmodule Plausible.Billing.Ecto.FeatureList do
|
|||
|
||||
[
|
||||
{:safe, ~s(<div class="form-group">)},
|
||||
Phoenix.HTML.Form.label(form, field),
|
||||
{:safe, ~s(<label for="#{form.name}_#{field}">#{Phoenix.Naming.humanize(field)}</label>)},
|
||||
{:safe, ~s(<div class="form-control">)},
|
||||
checkboxes,
|
||||
{:safe, ~s(</div>)},
|
||||
|
|
|
|||
|
|
@ -25,14 +25,9 @@ defmodule Plausible.Billing.Ecto.Limit do
|
|||
|
||||
[
|
||||
{:safe, ~s(<div class="form-group">)},
|
||||
Phoenix.HTML.Form.label(form, field),
|
||||
Phoenix.HTML.Form.number_input(form, field,
|
||||
class: "form-control",
|
||||
name: "#{form.name}[#{field}]",
|
||||
id: "#{form.name}_#{field}",
|
||||
value: value,
|
||||
min: -1
|
||||
),
|
||||
{:safe, ~s(<label for="#{form.name}_#{field}">#{Phoenix.Naming.humanize(field)}</label>)},
|
||||
{:safe,
|
||||
~s(<input id="#{form.name}_#{field}" name="#{form.name}[#{field}]" class="form-control" value="#{value}" min="-1" type="number" />)},
|
||||
{:safe, ~s(<p class="help_text">Use -1 for unlimited.</p>)},
|
||||
{:safe, ~s(</div>)}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ defmodule PlausibleWeb do
|
|||
|
||||
use Phoenix.Component
|
||||
|
||||
import PlausibleWeb.ErrorHelpers
|
||||
import PlausibleWeb.Components.Generic
|
||||
import PlausibleWeb.Live.Components.Form
|
||||
alias PlausibleWeb.Router.Helpers, as: Routes
|
||||
|
|
|
|||
|
|
@ -114,12 +114,12 @@ defmodule PlausibleWeb.Components.Billing do
|
|||
class="text-sm dark:text-gray-100"
|
||||
x-bind:class={"tab === '#{@tab}' ? 'text-indigo-600 dark:text-indigo-500 font-semibold' : 'font-medium'"}
|
||||
>
|
||||
<%= @name %>
|
||||
{@name}
|
||||
</span>
|
||||
<span class="flex text-xs text-gray-500 dark:text-gray-400">
|
||||
<%= if @disabled,
|
||||
{if @disabled,
|
||||
do: "Not available",
|
||||
else: PlausibleWeb.TextHelpers.format_date_range(@date_range) %>
|
||||
else: PlausibleWeb.TextHelpers.format_date_range(@date_range)}
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
|
|
@ -152,7 +152,7 @@ defmodule PlausibleWeb.Components.Billing do
|
|||
~H"""
|
||||
<table class="min-w-full text-gray-900 dark:text-gray-100" {@rest}>
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-gray-600">
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</tbody>
|
||||
</table>
|
||||
"""
|
||||
|
|
@ -168,11 +168,11 @@ defmodule PlausibleWeb.Components.Billing do
|
|||
~H"""
|
||||
<tr {@rest}>
|
||||
<td class={["text-sm py-4 pr-1 sm:whitespace-nowrap text-left", @pad && "pl-6"]}>
|
||||
<%= @title %>
|
||||
{@title}
|
||||
</td>
|
||||
<td class="text-sm py-4 sm:whitespace-nowrap text-right">
|
||||
<%= Cldr.Number.to_string!(@usage) %>
|
||||
<%= if is_number(@limit), do: "/ #{Cldr.Number.to_string!(@limit)}" %>
|
||||
{Cldr.Number.to_string!(@usage)}
|
||||
{if is_number(@limit), do: "/ #{Cldr.Number.to_string!(@limit)}"}
|
||||
</td>
|
||||
</tr>
|
||||
"""
|
||||
|
|
@ -186,7 +186,7 @@ defmodule PlausibleWeb.Components.Billing do
|
|||
>
|
||||
<h4 class="font-black dark:text-gray-100">Monthly quota</h4>
|
||||
<div class="py-2 text-xl font-medium dark:text-gray-100">
|
||||
<%= PlausibleWeb.AuthView.subscription_quota(@subscription, format: :long) %>
|
||||
{PlausibleWeb.AuthView.subscription_quota(@subscription, format: :long)}
|
||||
</div>
|
||||
<.styled_link
|
||||
:if={
|
||||
|
|
@ -196,7 +196,7 @@ defmodule PlausibleWeb.Components.Billing do
|
|||
id="#upgrade-or-change-plan-link"
|
||||
href={Routes.billing_path(PlausibleWeb.Endpoint, :choose_plan)}
|
||||
>
|
||||
<%= change_plan_or_upgrade_text(@subscription) %>
|
||||
{change_plan_or_upgrade_text(@subscription)}
|
||||
</.styled_link>
|
||||
</div>
|
||||
"""
|
||||
|
|
@ -206,13 +206,13 @@ defmodule PlausibleWeb.Components.Billing do
|
|||
~H"""
|
||||
<ul class="w-full py-4">
|
||||
<li>
|
||||
Up to <b><%= present_limit(@plan, :monthly_pageview_limit) %></b> monthly pageviews
|
||||
Up to <b>{present_limit(@plan, :monthly_pageview_limit)}</b> monthly pageviews
|
||||
</li>
|
||||
<li>
|
||||
Up to <b><%= present_limit(@plan, :site_limit) %></b> sites
|
||||
Up to <b>{present_limit(@plan, :site_limit)}</b> sites
|
||||
</li>
|
||||
<li>
|
||||
Up to <b><%= present_limit(@plan, :hourly_api_request_limit) %></b> hourly api requests
|
||||
Up to <b>{present_limit(@plan, :hourly_api_request_limit)}</b> hourly api requests
|
||||
</li>
|
||||
</ul>
|
||||
"""
|
||||
|
|
@ -258,7 +258,7 @@ defmodule PlausibleWeb.Components.Billing do
|
|||
@checkout_disabled && "pointer-events-none bg-gray-400 dark:bg-gray-600"
|
||||
]}
|
||||
>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</button>
|
||||
"""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ defmodule PlausibleWeb.Components.Billing.Notice do
|
|||
title="Notice"
|
||||
{@rest}
|
||||
>
|
||||
<%= account_label(@current_user, @billable_user) %> does not have access to <%= @feature_mod.display_name() %>. To get access to this feature,
|
||||
{account_label(@current_user, @billable_user)} does not have access to {@feature_mod.display_name()}. To get access to this feature,
|
||||
<.upgrade_call_to_action
|
||||
current_team={@current_team}
|
||||
current_user={@current_user}
|
||||
|
|
@ -96,7 +96,7 @@ defmodule PlausibleWeb.Components.Billing.Notice do
|
|||
def limit_exceeded(assigns) do
|
||||
~H"""
|
||||
<.notice {@rest} title="Notice">
|
||||
<%= account_label(@current_user, @billable_user) %> is limited to <%= @limit %> <%= @resource %>. To increase this limit,
|
||||
{account_label(@current_user, @billable_user)} is limited to {@limit} {@resource}. To increase this limit,
|
||||
<.upgrade_call_to_action
|
||||
current_team={@current_team}
|
||||
current_user={@current_user}
|
||||
|
|
@ -239,7 +239,7 @@ defmodule PlausibleWeb.Components.Billing.Notice do
|
|||
~H"""
|
||||
<aside class={@class}>
|
||||
<.notice title="Pending ownership transfers" class="shadow-md dark:shadow-none mt-4">
|
||||
<%= @message %> To exclude pending sites from your usage, please go to
|
||||
{@message} To exclude pending sites from your usage, please go to
|
||||
<.link href="https://plausible.io/sites" class="whitespace-nowrap font-semibold">
|
||||
plausible.io/sites
|
||||
</.link>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ defmodule PlausibleWeb.Components.Billing.PageviewSlider do
|
|||
<output class="lg:w-1/4 lg:order-1 font-medium text-lg text-gray-600 dark:text-gray-200">
|
||||
<span :if={@volume != :enterprise}>Up to</span>
|
||||
<strong id="slider-value" class="text-gray-900 dark:text-gray-100">
|
||||
<%= format_volume(@volume, @available_volumes) %>
|
||||
{format_volume(@volume, @available_volumes)}
|
||||
</strong>
|
||||
monthly pageviews
|
||||
</output>
|
||||
|
|
@ -39,7 +39,7 @@ defmodule PlausibleWeb.Components.Billing.PageviewSlider do
|
|||
<form class="max-w-md lg:max-w-none w-full lg:w-1/2 lg:order-2">
|
||||
<div class="flex items-baseline space-x-2">
|
||||
<span class="text-xs font-medium text-gray-600 dark:text-gray-200">
|
||||
<%= List.first(@slider_labels) %>
|
||||
{List.first(@slider_labels)}
|
||||
</span>
|
||||
<div class="flex-1 relative">
|
||||
<input
|
||||
|
|
@ -64,7 +64,7 @@ defmodule PlausibleWeb.Components.Billing.PageviewSlider do
|
|||
/>
|
||||
</div>
|
||||
<span class="text-xs font-medium text-gray-600 dark:text-gray-200">
|
||||
<%= List.last(@slider_labels) %>
|
||||
{List.last(@slider_labels)}
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBenefits do
|
|||
<ul role="list" class={["mt-8 space-y-3 text-sm leading-6 xl:mt-10", @class]}>
|
||||
<li :for={benefit <- @benefits} class="flex gap-x-3">
|
||||
<Heroicons.check class="h-6 w-5 text-indigo-600 dark:text-green-600" />
|
||||
<%= if is_binary(benefit), do: benefit, else: benefit.(assigns) %>
|
||||
{if is_binary(benefit), do: benefit, else: benefit.(assigns)}
|
||||
</li>
|
||||
</ul>
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
!@highlight && "text-gray-900 dark:text-gray-100",
|
||||
@highlight && "text-indigo-600 dark:text-indigo-300"
|
||||
]}>
|
||||
<%= String.capitalize(to_string(@kind)) %>
|
||||
{String.capitalize(to_string(@kind))}
|
||||
</h3>
|
||||
<.pill :if={@highlight} text={@highlight} />
|
||||
</div>
|
||||
|
|
@ -98,7 +98,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
id="highlight-pill"
|
||||
class="rounded-full bg-indigo-600/10 px-2.5 py-1 text-xs font-semibold leading-5 text-indigo-600 dark:text-indigo-300 dark:ring-1 dark:ring-indigo-300/50"
|
||||
>
|
||||
<%= @text %>
|
||||
{@text}
|
||||
</p>
|
||||
</div>
|
||||
"""
|
||||
|
|
@ -142,7 +142,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
id={"#{@kind}-price-tag-amount"}
|
||||
class="text-4xl font-bold tracking-tight text-gray-900 dark:text-gray-100"
|
||||
>
|
||||
<%= @plan_to_render.monthly_cost |> Plausible.Billing.format_price() %>
|
||||
{@plan_to_render.monthly_cost |> Plausible.Billing.format_price()}
|
||||
</span>
|
||||
<span
|
||||
id={"#{@kind}-price-tag-interval"}
|
||||
|
|
@ -156,13 +156,13 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
defp price_tag(%{selected_interval: :yearly} = assigns) do
|
||||
~H"""
|
||||
<span class="text-2xl font-bold w-max tracking-tight line-through text-gray-500 dark:text-gray-600 mr-1">
|
||||
<%= @plan_to_render.monthly_cost |> Money.mult!(12) |> Plausible.Billing.format_price() %>
|
||||
{@plan_to_render.monthly_cost |> Money.mult!(12) |> Plausible.Billing.format_price()}
|
||||
</span>
|
||||
<span
|
||||
id={"#{@kind}-price-tag-amount"}
|
||||
class="text-4xl font-bold tracking-tight text-gray-900 dark:text-gray-100"
|
||||
>
|
||||
<%= @plan_to_render.yearly_cost |> Plausible.Billing.format_price() %>
|
||||
{@plan_to_render.yearly_cost |> Plausible.Billing.format_price()}
|
||||
</span>
|
||||
<span id={"#{@kind}-price-tag-interval"} class="text-sm font-semibold leading-6 text-gray-600">
|
||||
/year
|
||||
|
|
@ -234,13 +234,13 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
<% end %>
|
||||
<.tooltip :if={@exceeded_plan_limits != [] && @disabled_message}>
|
||||
<div class="pt-2 text-sm w-full flex items-center text-red-700 dark:text-red-500 justify-center">
|
||||
<%= @disabled_message %>
|
||||
{@disabled_message}
|
||||
<Heroicons.information_circle class="hidden sm:block w-5 h-5 sm:ml-2" />
|
||||
</div>
|
||||
<:tooltip_content>
|
||||
Your usage exceeds the following limit(s):<br /><br />
|
||||
<p :for={limit <- @exceeded_plan_limits}>
|
||||
<%= Phoenix.Naming.humanize(limit) %><br />
|
||||
{Phoenix.Naming.humanize(limit)}<br />
|
||||
</p>
|
||||
</:tooltip_content>
|
||||
</.tooltip>
|
||||
|
|
@ -248,7 +248,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
:if={@disabled_message && @exceeded_plan_limits == []}
|
||||
class="pt-2 text-sm w-full text-red-700 dark:text-red-500 text-center"
|
||||
>
|
||||
<%= @disabled_message %>
|
||||
{@disabled_message}
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
|
@ -337,7 +337,7 @@ defmodule PlausibleWeb.Components.Billing.PlanBox do
|
|||
@checkout_disabled && "pointer-events-none bg-gray-400 dark:bg-gray-600"
|
||||
]}
|
||||
>
|
||||
<%= @change_plan_link_text %>
|
||||
{@change_plan_link_text}
|
||||
</button>
|
||||
"""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -34,25 +34,25 @@ defmodule PlausibleWeb.Components.FlowProgress do
|
|||
:if={idx == @current_step_idx}
|
||||
class="w-5 h-5 bg-indigo-600 text-white rounded-full flex items-center justify-center font-semibold"
|
||||
>
|
||||
<%= idx + 1 %>
|
||||
{idx + 1}
|
||||
</div>
|
||||
<div
|
||||
:if={idx > @current_step_idx}
|
||||
class="w-5 h-5 bg-gray-300 text-white dark:bg-gray-800 rounded-full flex items-center justify-center"
|
||||
>
|
||||
<%= idx + 1 %>
|
||||
{idx + 1}
|
||||
</div>
|
||||
<span :if={idx < @current_step_idx} class="ml-2 text-gray-500">
|
||||
<%= step %>
|
||||
{step}
|
||||
</span>
|
||||
<span
|
||||
:if={idx == @current_step_idx}
|
||||
class="ml-2 font-semibold text-black dark:text-gray-300"
|
||||
>
|
||||
<%= step %>
|
||||
{step}
|
||||
</span>
|
||||
<span :if={idx > @current_step_idx} class="ml-2 text-gray-500">
|
||||
<%= step %>
|
||||
{step}
|
||||
</span>
|
||||
</div>
|
||||
<div :if={idx + 1 != length(@steps)} class="flex-1 h-px bg-gray-300 mx-4 dark:bg-gray-800 ">
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
]}
|
||||
{@rest}
|
||||
>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</button>
|
||||
"""
|
||||
end
|
||||
|
|
@ -84,7 +84,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
[]
|
||||
else
|
||||
[
|
||||
"data-csrf": Phoenix.HTML.Tag.csrf_token_value(assigns.href),
|
||||
"data-csrf": Phoenix.Controller.get_csrf_token(),
|
||||
"data-method": assigns.method,
|
||||
"data-to": assigns.href
|
||||
]
|
||||
|
|
@ -126,7 +126,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
{@extra}
|
||||
{@rest}
|
||||
>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</.link>
|
||||
"""
|
||||
end
|
||||
|
|
@ -178,11 +178,11 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
</div>
|
||||
<div class={["w-full", @title && "ml-3"]}>
|
||||
<h3 :if={@title} class={"font-medium #{@theme.title_text} mb-2"}>
|
||||
<%= @title %>
|
||||
{@title}
|
||||
</h3>
|
||||
<div class={"#{@theme.body_text}"}>
|
||||
<p>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -216,7 +216,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
class={"text-indigo-600 hover:text-indigo-700 dark:text-indigo-500 dark:hover:text-indigo-600 " <> @class}
|
||||
{@rest}
|
||||
>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</.unstyled_link>
|
||||
"""
|
||||
end
|
||||
|
|
@ -241,10 +241,11 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
class="relative inline-block text-left"
|
||||
>
|
||||
<button x-ref="button" x-on:click="toggle()" type="button" class={List.first(@button).class}>
|
||||
<%= render_slot(List.first(@button)) %>
|
||||
{render_slot(List.first(@button))}
|
||||
</button>
|
||||
<div
|
||||
x-show="open"
|
||||
x-cloak
|
||||
x-transition:enter="transition ease-out duration-100"
|
||||
x-transition:enter-start="opacity-0 scale-95"
|
||||
x-transition:enter-end="opacity-100 scale-100"
|
||||
|
|
@ -258,7 +259,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
@menu_class
|
||||
]}
|
||||
>
|
||||
<%= render_slot(List.first(@menu)) %>
|
||||
{render_slot(List.first(@menu))}
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
|
@ -293,7 +294,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
data-ui-state={@state}
|
||||
{@rest}
|
||||
>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</.unstyled_link>
|
||||
"""
|
||||
else
|
||||
|
|
@ -301,7 +302,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
|
||||
~H"""
|
||||
<div data-ui-state={@state} class={@class}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
|
@ -327,7 +328,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
[]
|
||||
else
|
||||
[
|
||||
"data-csrf": Phoenix.HTML.Tag.csrf_token_value(assigns.href),
|
||||
"data-csrf": Phoenix.Controller.get_csrf_token(),
|
||||
"data-method": assigns.method,
|
||||
"data-to": assigns.href
|
||||
]
|
||||
|
|
@ -350,13 +351,13 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
{@extra}
|
||||
{@rest}
|
||||
>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
<Heroicons.arrow_top_right_on_square class={["opacity-60", @icon_class]} />
|
||||
</.link>
|
||||
"""
|
||||
else
|
||||
~H"""
|
||||
<.link class={@class} href={@href} {@extra} {@rest}><%= render_slot(@inner_block) %></.link>
|
||||
<.link class={@class} href={@href} {@extra} {@rest}>{render_slot(@inner_block)}</.link>
|
||||
"""
|
||||
end
|
||||
end
|
||||
|
|
@ -388,7 +389,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
def settings_tiles(assigns) do
|
||||
~H"""
|
||||
<div class="text-gray-900 leading-5 dark:text-gray-100">
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
|
@ -406,12 +407,12 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
<div class="shadow bg-white dark:bg-gray-800 rounded-md mb-6">
|
||||
<header class="relative py-4 px-6">
|
||||
<.title>
|
||||
<%= render_slot(@title) %>
|
||||
{render_slot(@title)}
|
||||
|
||||
<.docs_info :if={@docs} slug={@docs} />
|
||||
</.title>
|
||||
<div class="text-sm mt-px text-gray-500 dark:text-gray-400 leading-5">
|
||||
<%= render_slot(@subtitle) %>
|
||||
{render_slot(@subtitle)}
|
||||
</div>
|
||||
<%= if @feature_mod do %>
|
||||
<PlausibleWeb.Components.Site.Feature.toggle
|
||||
|
|
@ -424,7 +425,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
</header>
|
||||
|
||||
<div class="pb-4 px-6">
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
|
@ -455,7 +456,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
x-transition:leave-start="opacity-100"
|
||||
x-transition:leave-end="opacity-0"
|
||||
>
|
||||
<%= render_slot(List.first(@tooltip_content)) %>
|
||||
{render_slot(List.first(@tooltip_content))}
|
||||
</div>
|
||||
<div
|
||||
x-on:click="sticky = true; hovered = true"
|
||||
|
|
@ -463,7 +464,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
x-on:mouseover="hovered = true"
|
||||
x-on:mouseout="hovered = false"
|
||||
>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
|
@ -500,7 +501,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
~H"""
|
||||
<ol class="list-disc space-y-1 ml-4 text-sm">
|
||||
<li :for={item <- @item} class="marker:text-indigo-700 dark:marker:text-indigo-700">
|
||||
<%= render_slot(item) %>
|
||||
{render_slot(item)}
|
||||
</li>
|
||||
</ol>
|
||||
"""
|
||||
|
|
@ -520,20 +521,20 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
>
|
||||
<div class="p-8">
|
||||
<.title :if={@title != []}>
|
||||
<%= render_slot(@title) %>
|
||||
{render_slot(@title)}
|
||||
</.title>
|
||||
<div></div>
|
||||
|
||||
<div :if={@subtitle != []} class="text-sm mt-4 leading-6">
|
||||
<%= render_slot(@subtitle) %>
|
||||
{render_slot(@subtitle)}
|
||||
</div>
|
||||
|
||||
<div :if={@title != []} class="mt-8">
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
|
||||
<div :if={@title == []}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -541,7 +542,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
class="flex flex-col dark:text-gray-200 border-t border-gray-300 dark:border-gray-700"
|
||||
>
|
||||
<div class="p-8">
|
||||
<%= render_slot(@footer) %>
|
||||
{render_slot(@footer)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -561,14 +562,14 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
<table :if={not Enum.empty?(@rows)} class={@width} {@rest}>
|
||||
<thead :if={@thead != []}>
|
||||
<tr class="border-b border-gray-200 dark:border-gray-700">
|
||||
<%= render_slot(@thead) %>
|
||||
{render_slot(@thead)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<tr :for={item <- @rows} {if @row_attrs, do: @row_attrs.(item), else: %{}}>
|
||||
<%= render_slot(@tbody, item) %>
|
||||
{render_slot(@tbody, item)}
|
||||
</tr>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</tbody>
|
||||
</table>
|
||||
"""
|
||||
|
|
@ -605,10 +606,10 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
{@rest}
|
||||
>
|
||||
<div :if={@actions} class="flex gap-2">
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
<div :if={!@actions}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
</td>
|
||||
"""
|
||||
|
|
@ -630,7 +631,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
|
||||
~H"""
|
||||
<th scope="col" class={[@hide_on_mobile && "hidden md:table-cell", @class]}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</th>
|
||||
"""
|
||||
end
|
||||
|
|
@ -667,7 +668,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
else: "text-gray-900 dark:text-gray-100"
|
||||
)
|
||||
]}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</span>
|
||||
</div>
|
||||
"""
|
||||
|
|
@ -743,7 +744,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
|
@ -754,7 +755,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
def h2(assigns) do
|
||||
~H"""
|
||||
<h2 class={[@class || "font-semibold leading-6 text-gray-900 dark:text-gray-100"]}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</h2>
|
||||
"""
|
||||
end
|
||||
|
|
@ -765,7 +766,7 @@ defmodule PlausibleWeb.Components.Generic do
|
|||
def title(assigns) do
|
||||
~H"""
|
||||
<.h2 class={["text-lg font-medium text-gray-900 dark:text-gray-100 leading-7", @class]}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</.h2>
|
||||
"""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ defmodule PlausibleWeb.Components.Site.Feature do
|
|||
class={@class}
|
||||
>
|
||||
<.toggle_submit set_to={@current_setting} disabled?={@disabled?}>
|
||||
Show <%= @feature_mod.display_name() %> in the Dashboard
|
||||
Show {@feature_mod.display_name()} in the Dashboard
|
||||
</.toggle_submit>
|
||||
</.form>
|
||||
|
||||
<div :if={@current_setting}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ defmodule PlausibleWeb.Components.TwoFactor do
|
|||
assigns = assign(assigns, :code, qr_code)
|
||||
|
||||
~H"""
|
||||
<%= Phoenix.HTML.raw(@code) %>
|
||||
{Phoenix.HTML.raw(@code)}
|
||||
"""
|
||||
end
|
||||
|
||||
|
|
@ -38,25 +38,29 @@ defmodule PlausibleWeb.Components.TwoFactor do
|
|||
end
|
||||
|
||||
assigns = assign(assigns, :input_class, input_class)
|
||||
assigns = assign(assigns, :field, assigns[:form][assigns[:field]])
|
||||
|
||||
~H"""
|
||||
<div class={[@class, "flex items-center"]}>
|
||||
<%= Phoenix.HTML.Form.text_input(@form, @field,
|
||||
autocomplete: "off",
|
||||
class: @input_class,
|
||||
oninput:
|
||||
<input
|
||||
type="text"
|
||||
name={@field.name}
|
||||
value={@field.value}
|
||||
autocomplete="off"
|
||||
class={@input_class}
|
||||
oninput={
|
||||
if @show_button? do
|
||||
"this.value=this.value.replace(/[^0-9]/g, ''); if (this.value.length >= 6) document.getElementById('#{@id}').focus()"
|
||||
else
|
||||
"this.value=this.value.replace(/[^0-9]/g, '');"
|
||||
end,
|
||||
onclick: "this.select();",
|
||||
oninvalid: @show_button? && "document.getElementById('#{@id}').disabled = false",
|
||||
maxlength: "6",
|
||||
placeholder: "••••••",
|
||||
value: "",
|
||||
required: "required"
|
||||
) %>
|
||||
end
|
||||
}
|
||||
onclick="this.select();"
|
||||
oninvalid={@show_button? && "document.getElementById('#{@id}').disabled = false"}
|
||||
maxlength="6"
|
||||
placeholder="••••••"
|
||||
required="required"
|
||||
/>
|
||||
<.button
|
||||
:if={@show_button?}
|
||||
type="submit"
|
||||
|
|
@ -142,19 +146,19 @@ defmodule PlausibleWeb.Components.TwoFactor do
|
|||
</div>
|
||||
<div class="sm:flex sm:items-start">
|
||||
<div class="mx-auto flex-shrink-0 flex items-center justify-center h-12 w-12 rounded-full bg-green-100 sm:mx-0 sm:h-10 sm:w-10">
|
||||
<%= render_slot(@icon) %>
|
||||
{render_slot(@icon)}
|
||||
</div>
|
||||
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left text-gray-900 dark:text-gray-100">
|
||||
<h3 class="text-lg leading-6 font-medium" id="modal-title">
|
||||
<%= @title %>
|
||||
{@title}
|
||||
</h3>
|
||||
|
||||
<%= render_slot(@inner_block, f) %>
|
||||
{render_slot(@inner_block, f)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-50 dark:bg-gray-850 px-4 py-3 sm:px-9 sm:flex sm:flex-row-reverse">
|
||||
<%= render_slot(@buttons) %>
|
||||
{render_slot(@buttons)}
|
||||
<.button
|
||||
type="button"
|
||||
x-on:click={"#{@state_param} = false"}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ defmodule PlausibleWeb.AuthController do
|
|||
flow = params["flow"] || PlausibleWeb.Flows.register()
|
||||
|
||||
render(conn, "activate.html",
|
||||
error: nil,
|
||||
has_email_code?: Plausible.Users.has_email_code?(user),
|
||||
has_any_memberships?: Plausible.Teams.Users.has_sites?(user),
|
||||
form_submit_url: "/activate?flow=#{flow}"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ defmodule PlausibleWeb.Live.ChoosePlan do
|
|||
LiveView for upgrading to a plan, or changing an existing plan.
|
||||
"""
|
||||
use PlausibleWeb, :live_view
|
||||
use Phoenix.HTML
|
||||
|
||||
require Plausible.Billing.Subscription.Status
|
||||
|
||||
|
|
@ -107,9 +106,9 @@ defmodule PlausibleWeb.Live.ChoosePlan do
|
|||
<Notice.upgrade_ineligible :if={not Quota.eligible_for_upgrade?(@usage)} />
|
||||
<div class="mx-auto max-w-4xl text-center">
|
||||
<p class="text-4xl font-bold tracking-tight lg:text-5xl">
|
||||
<%= if @owned_plan,
|
||||
{if @owned_plan,
|
||||
do: "Change subscription plan",
|
||||
else: "Upgrade your account" %>
|
||||
else: "Upgrade your account"}
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-12 flex flex-col gap-8 lg:flex-row items-center lg:items-baseline">
|
||||
|
|
|
|||
|
|
@ -253,9 +253,9 @@ defmodule PlausibleWeb.Live.Components.ComboBox do
|
|||
class="block truncate py-2 px-3"
|
||||
>
|
||||
<%= if @creatable do %>
|
||||
Create "<%= @display_value %>"
|
||||
Create "{@display_value}"
|
||||
<% else %>
|
||||
<%= @display_value %>
|
||||
{@display_value}
|
||||
<% end %>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
<.input name="my-input" errors={["oh no!"]} />
|
||||
"""
|
||||
|
||||
@default_input_class "text-sm dark:bg-gray-900 block pl-3.5 py-2.5 border-gray-300 dark:border-gray-500 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 rounded-md"
|
||||
@default_input_class "text-sm text-gray-900 dark:text-white dark:bg-gray-900 block pl-3.5 py-2.5 border-gray-300 dark:border-gray-500 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 rounded-md"
|
||||
|
||||
attr(:id, :any, default: nil)
|
||||
attr(:name, :any)
|
||||
|
|
@ -55,6 +55,8 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
slot(:inner_block)
|
||||
|
||||
def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
|
||||
errors = if Phoenix.Component.used_input?(field), do: field.errors, else: []
|
||||
|
||||
assigns
|
||||
|> assign(
|
||||
field: nil,
|
||||
|
|
@ -63,7 +65,7 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
mt?: assigns.mt?,
|
||||
width: assigns.width
|
||||
)
|
||||
|> assign(:errors, Enum.map(field.errors, &translate_error(&1)))
|
||||
|> assign(:errors, Enum.map(errors, &translate_error(&1)))
|
||||
|> assign_new(:name, fn -> if assigns.multiple, do: field.name <> "[]", else: field.name end)
|
||||
|> assign_new(:value, fn -> field.value end)
|
||||
|> input()
|
||||
|
|
@ -71,27 +73,27 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
|
||||
def input(%{type: "select"} = assigns) do
|
||||
~H"""
|
||||
<div phx-feedback-for={@name} class={@mt? && "mt-2"}>
|
||||
<.label for={@id} class="mb-2"><%= @label %></.label>
|
||||
<div class={@mt? && "mt-2"}>
|
||||
<.label for={@id} class="mb-2">{@label}</.label>
|
||||
|
||||
<p :if={@help_text} class="text-gray-500 dark:text-gray-400 mb-2 text-sm">
|
||||
<%= @help_text %>
|
||||
{@help_text}
|
||||
</p>
|
||||
<select id={@id} name={@name} multiple={@multiple} class={[@class, @width]} {@rest}>
|
||||
<option :if={@prompt} value=""><%= @prompt %></option>
|
||||
<%= Phoenix.HTML.Form.options_for_select(@options, @value) %>
|
||||
<option :if={@prompt} value="">{@prompt}</option>
|
||||
{Phoenix.HTML.Form.options_for_select(@options, @value)}
|
||||
</select>
|
||||
<.error :for={msg <- @errors}><%= msg %></.error>
|
||||
<.error :for={msg <- @errors}>{msg}</.error>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def input(%{type: "checkbox"} = assigns) do
|
||||
~H"""
|
||||
<div
|
||||
phx-feedback-for={@name}
|
||||
class={["flex flex-inline items-center sm:justify-start justify-center gap-x-2", @mt? && "mt-2"]}
|
||||
>
|
||||
<div class={[
|
||||
"flex flex-inline items-center sm:justify-start justify-center gap-x-2",
|
||||
@mt? && "mt-2"
|
||||
]}>
|
||||
<input
|
||||
type="checkbox"
|
||||
value={@value || "true"}
|
||||
|
|
@ -99,7 +101,7 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
name={@name}
|
||||
class="block h-5 w-5 rounded dark:bg-gray-700 border-gray-300 text-indigo-600 focus:ring-indigo-600"
|
||||
/>
|
||||
<.label for={@id}><%= @label %></.label>
|
||||
<.label for={@id}>{@label}</.label>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
|
@ -116,12 +118,12 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
assigns = assign(assigns, :errors, errors)
|
||||
|
||||
~H"""
|
||||
<div phx-feedback-for={@name} class={@mt? && "mt-2"}>
|
||||
<div class={@mt? && "mt-2"}>
|
||||
<.label :if={@label != nil and @label != ""} for={@id} class="mb-2">
|
||||
<%= @label %>
|
||||
{@label}
|
||||
</.label>
|
||||
<p :if={@help_text} class="text-gray-500 dark:text-gray-400 mb-2 text-sm">
|
||||
<%= @help_text %>
|
||||
{@help_text}
|
||||
</p>
|
||||
<input
|
||||
type={@type}
|
||||
|
|
@ -131,9 +133,9 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
class={[@class, @width, assigns[:rest][:disabled] && "text-gray-500 dark:text-gray-400"]}
|
||||
{@rest}
|
||||
/>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
<.error :for={msg <- @errors}>
|
||||
<%= msg %>
|
||||
{msg}
|
||||
</.error>
|
||||
</div>
|
||||
"""
|
||||
|
|
@ -153,7 +155,7 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
<div>
|
||||
<div :if={@label}>
|
||||
<.label for={@id} class="mb-2">
|
||||
<%= @label %>
|
||||
{@label}
|
||||
</.label>
|
||||
</div>
|
||||
<div class="relative">
|
||||
|
|
@ -218,10 +220,14 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
|> assign(:too_weak?, too_weak?)
|
||||
|> assign(:field, %{field | errors: errors})
|
||||
|> assign(:strength, strength)
|
||||
|> assign(
|
||||
:show_meter?,
|
||||
Phoenix.Component.used_input?(field) && (too_weak? || strength.score > 0)
|
||||
)
|
||||
|
||||
~H"""
|
||||
<.input field={@field} type="password" autocomplete="new-password" label={@label} id={@id} {@rest}>
|
||||
<.strength_meter :if={@too_weak? or @strength.score > 0} {@strength} />
|
||||
<.strength_meter :if={@show_meter?} {@strength} />
|
||||
</.input>
|
||||
"""
|
||||
end
|
||||
|
|
@ -256,7 +262,7 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
assigns = assign(assigns, :class, final_class)
|
||||
|
||||
~H"""
|
||||
<p class={@class}>Min <%= @minimum %> characters</p>
|
||||
<p class={@class}>Min {@minimum} characters</p>
|
||||
"""
|
||||
end
|
||||
|
||||
|
|
@ -311,11 +317,11 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
>
|
||||
</div>
|
||||
</div>
|
||||
<p :if={@score <= 2} class="text-sm text-red-500 phx-no-feedback:hidden">
|
||||
<p :if={@score <= 2} class="text-sm text-red-500">
|
||||
Password is too weak
|
||||
</p>
|
||||
<p :if={@feedback} class="text-xs text-gray-500">
|
||||
<%= @feedback %>
|
||||
{@feedback}
|
||||
</p>
|
||||
"""
|
||||
end
|
||||
|
|
@ -330,7 +336,7 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
def label(assigns) do
|
||||
~H"""
|
||||
<label for={@for} class={["text-sm block font-medium dark:text-gray-100", @class]}>
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</label>
|
||||
"""
|
||||
end
|
||||
|
|
@ -342,8 +348,8 @@ defmodule PlausibleWeb.Live.Components.Form do
|
|||
|
||||
def error(assigns) do
|
||||
~H"""
|
||||
<p class="flex gap-3 text-sm leading-6 text-red-500 phx-no-feedback:hidden">
|
||||
<%= render_slot(@inner_block) %>
|
||||
<p class="flex gap-3 text-sm leading-6 text-red-500">
|
||||
{render_slot(@inner_block)}
|
||||
</p>
|
||||
"""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -260,7 +260,7 @@ defmodule PlausibleWeb.Live.Components.Modal do
|
|||
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||
x-on:click.outside="closeModal()"
|
||||
>
|
||||
<%= render_slot(@inner_block, modal_unique_id(@modal_sequence_id)) %>
|
||||
{render_slot(@inner_block, modal_unique_id(@modal_sequence_id))}
|
||||
</Phoenix.Component.focus_wrap>
|
||||
<div x-show="modalOpen" class="modal-loading hidden w-full self-center">
|
||||
<div class="text-center">
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ defmodule PlausibleWeb.Live.Components.Pagination do
|
|||
>
|
||||
<div class="hidden sm:block">
|
||||
<p class="text-sm text-gray-700 dark:text-gray-300">
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex-1 flex justify-between sm:justify-end">
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ defmodule PlausibleWeb.Live.Components.Verification do
|
|||
<span :if={not @finished?}>Verifying your installation</span>
|
||||
|
||||
<span :if={@finished? and not @success? and @interpretation}>
|
||||
<%= List.first(@interpretation.errors) %>
|
||||
{List.first(@interpretation.errors)}
|
||||
</span>
|
||||
</.title>
|
||||
<p :if={@finished? and @success?} id="progress" class="text-sm mt-4">
|
||||
|
|
@ -67,19 +67,19 @@ defmodule PlausibleWeb.Live.Components.Verification do
|
|||
</p>
|
||||
<p
|
||||
:if={@finished? and @success? and @awaiting_first_pageview?}
|
||||
id="progress"
|
||||
id="awaiting"
|
||||
class="text-sm mt-4 animate-pulse"
|
||||
>
|
||||
Awaiting your first pageview
|
||||
</p>
|
||||
<p :if={not @finished?} class="text-sm mt-4 animate-pulse" id="progress"><%= @message %></p>
|
||||
<p :if={not @finished?} class="text-sm mt-4 animate-pulse" id="progress">{@message}</p>
|
||||
|
||||
<p
|
||||
:if={@finished? and not @success? and @interpretation}
|
||||
class="mt-4 text-sm text-ellipsis overflow-hidden"
|
||||
id="recommendation"
|
||||
>
|
||||
<span><%= List.first(@interpretation.recommendations).text %>. </span>
|
||||
<span>{List.first(@interpretation.recommendations).text}. </span>
|
||||
<.styled_link href={List.first(@interpretation.recommendations).url} new_tab={true}>
|
||||
Learn more
|
||||
</.styled_link>
|
||||
|
|
@ -145,7 +145,7 @@ defmodule PlausibleWeb.Live.Components.Verification do
|
|||
<.focus_list>
|
||||
<:item :for={{diag, value} <- Map.from_struct(@verification_state.diagnostics)}>
|
||||
<span class="text-sm">
|
||||
<%= Phoenix.Naming.humanize(diag) %>: <span class="font-mono"><%= value %></span>
|
||||
{Phoenix.Naming.humanize(diag)}: <span class="font-mono">{value}</span>
|
||||
</span>
|
||||
</:item>
|
||||
</.focus_list>
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ defmodule PlausibleWeb.Live.CSVExport do
|
|||
<:tbody :let={export}>
|
||||
<.td>
|
||||
<.styled_link href={@href}>
|
||||
<%= export.name %>
|
||||
{export.name}
|
||||
</.styled_link>
|
||||
</.td>
|
||||
<.td actions>
|
||||
|
|
@ -188,14 +188,14 @@ defmodule PlausibleWeb.Live.CSVExport do
|
|||
<p :if={@export.expires_at} class="text-sm">
|
||||
Note: this file will expire
|
||||
<.hint message={@export.expires_at}>
|
||||
<%= Timex.Format.DateTime.Formatters.Relative.format!(@export.expires_at, "{relative}") %>.
|
||||
{Timex.Format.DateTime.Formatters.Relative.format!(@export.expires_at, "{relative}")}.
|
||||
</.hint>
|
||||
</p>
|
||||
|
||||
<p :if={@storage == "local"} class="text-sm">
|
||||
Located at
|
||||
<.hint message={@export.path}><%= format_path(@export.path) %></.hint>
|
||||
(<%= format_bytes(@export.size) %>)
|
||||
<.hint message={@export.path}>{format_path(@export.path)}</.hint>
|
||||
({format_bytes(@export.size)})
|
||||
</p>
|
||||
"""
|
||||
end
|
||||
|
|
@ -203,7 +203,7 @@ defmodule PlausibleWeb.Live.CSVExport do
|
|||
defp hint(assigns) do
|
||||
~H"""
|
||||
<span title={@message} class="underline cursor-help underline-offset-2 decoration-dashed">
|
||||
<%= render_slot(@inner_block) %>
|
||||
{render_slot(@inner_block)}
|
||||
</span>
|
||||
"""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ defmodule PlausibleWeb.Live.CSVImport do
|
|||
original={@original_date_range}
|
||||
/>
|
||||
<p :for={error <- upload_errors(@uploads.import)} class="text-red-400">
|
||||
<%= error_to_string(error) %>
|
||||
{error_to_string(error)}
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
|
|
@ -151,8 +151,8 @@ defmodule PlausibleWeb.Live.CSVImport do
|
|||
defp dates(assigns) do
|
||||
~H"""
|
||||
<span class="whitespace-nowrap">
|
||||
<span class="font-medium"><%= @range.first %></span>
|
||||
to <span class="font-medium"><%= @range.last %></span>
|
||||
<span class="font-medium">{@range.first}</span>
|
||||
to <span class="font-medium">{@range.last}</span>
|
||||
</span>
|
||||
"""
|
||||
end
|
||||
|
|
@ -182,15 +182,15 @@ defmodule PlausibleWeb.Live.CSVImport do
|
|||
if(@status == :error, do: "text-red-600 dark:text-red-700")
|
||||
]}>
|
||||
<%= if @upload do %>
|
||||
<%= @upload.client_name %>
|
||||
{@upload.client_name}
|
||||
<% else %>
|
||||
<%= @table %>_YYYYMMDD_YYYYMMDD.csv
|
||||
{@table}_YYYYMMDD_YYYYMMDD.csv
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<p :for={error <- @errors} class="ml-6 text-sm text-red-600 dark:text-red-700">
|
||||
<%= error_to_string(error) %>
|
||||
{error_to_string(error)}
|
||||
</p>
|
||||
</li>
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -55,10 +55,10 @@ defmodule PlausibleWeb.Live.Flash do
|
|||
<.icon_success />
|
||||
</:icon>
|
||||
<:title>
|
||||
<%= Flash.get(@flash, :success_title) || "Success!" %>
|
||||
{Flash.get(@flash, :success_title) || "Success!"}
|
||||
</:title>
|
||||
<:message>
|
||||
<%= Flash.get(@flash, :success) %>
|
||||
{Flash.get(@flash, :success)}
|
||||
</:message>
|
||||
</.flash>
|
||||
<.flash :if={Flash.get(@flash, :error)} key="error">
|
||||
|
|
@ -66,10 +66,10 @@ defmodule PlausibleWeb.Live.Flash do
|
|||
<.icon_error />
|
||||
</:icon>
|
||||
<:title>
|
||||
<%= Flash.get(@flash, :error_title) || "Error!" %>
|
||||
{Flash.get(@flash, :error_title) || "Error!"}
|
||||
</:title>
|
||||
<:message>
|
||||
<%= Flash.get(@flash, :error) %>
|
||||
{Flash.get(@flash, :error)}
|
||||
</:message>
|
||||
</.flash>
|
||||
<.flash
|
||||
|
|
@ -96,7 +96,7 @@ defmodule PlausibleWeb.Live.Flash do
|
|||
end
|
||||
|
||||
slot(:icon, required: true)
|
||||
slot(:title, require: true)
|
||||
slot(:title, required: true)
|
||||
slot(:message, required: true)
|
||||
attr(:key, :string, default: nil)
|
||||
attr(:on_close, :any, default: "lv:clear-flash")
|
||||
|
|
@ -115,13 +115,13 @@ defmodule PlausibleWeb.Live.Flash do
|
|||
<div class="rounded-lg ring-1 ring-black ring-opacity-5 overflow-hidden">
|
||||
<div class="p-4">
|
||||
<div class="flex items-start">
|
||||
<%= render_slot(@icon) %>
|
||||
{render_slot(@icon)}
|
||||
<div class="ml-3 w-0 flex-1 pt-0.5">
|
||||
<p class="text-sm leading-5 font-medium text-gray-900 dark:text-gray-100">
|
||||
<%= render_slot(@title) %>
|
||||
{render_slot(@title)}
|
||||
</p>
|
||||
<p class="mt-1 text-sm leading-5 text-gray-500 dark:text-gray-200">
|
||||
<%= render_slot(@message) %>
|
||||
{render_slot(@message)}
|
||||
</p>
|
||||
</div>
|
||||
<div class="ml-4 flex-shrink-0 flex">
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
def render(assigns) do
|
||||
~H"""
|
||||
<div id={@id}>
|
||||
<%= if @goal, do: edit_form(assigns) %>
|
||||
<%= if is_nil(@goal), do: create_form(assigns) %>
|
||||
{if @goal, do: edit_form(assigns)}
|
||||
{if is_nil(@goal), do: create_form(assigns)}
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
|
@ -65,7 +65,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
def edit_form(assigns) do
|
||||
~H"""
|
||||
<.form :let={f} for={@form} phx-submit="save-goal" phx-target={@myself}>
|
||||
<.title>Edit Goal for <%= @domain %></.title>
|
||||
<.title>Edit Goal for {@domain}</.title>
|
||||
|
||||
<.custom_event_fields
|
||||
:if={@selected_tab == "custom_events"}
|
||||
|
|
@ -105,7 +105,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
>
|
||||
<.spinner class="spinner block absolute right-9 top-8" x-show="tabSelectionInProgress" />
|
||||
|
||||
<.title>Add Goal for <%= @domain %></.title>
|
||||
<.title>Add Goal for {@domain}</.title>
|
||||
|
||||
<.tabs selected_tab={@selected_tab} myself={@myself} />
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
phx-target={@myself}
|
||||
>
|
||||
<span :if={@event_name_options_count > 1}>
|
||||
Already sending custom events? We've found <%= @event_name_options_count %> custom events from the last 6 months that are not yet configured as goals. Click here to add them.
|
||||
Already sending custom events? We've found {@event_name_options_count} custom events from the last 6 months that are not yet configured as goals. Click here to add them.
|
||||
</span>
|
||||
<span :if={@event_name_options_count == 1}>
|
||||
Already sending custom events? We've found 1 custom event from the last 6 months that is not yet configured as a goal. Click here to add it.
|
||||
|
|
@ -182,7 +182,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
/>
|
||||
|
||||
<.error :for={msg <- Enum.map(@f[:page_path].errors, &translate_error/1)}>
|
||||
<%= msg %>
|
||||
{msg}
|
||||
</.error>
|
||||
|
||||
<.input
|
||||
|
|
@ -241,7 +241,7 @@ defmodule PlausibleWeb.Live.GoalSettings.Form do
|
|||
/>
|
||||
|
||||
<.error :for={msg <- Enum.map(@f[:event_name].errors, &translate_error/1)}>
|
||||
<%= msg %>
|
||||
{msg}
|
||||
</.error>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ defmodule PlausibleWeb.Live.GoalSettings.List do
|
|||
<div class="truncate block">
|
||||
<%= if not @revenue_goals_enabled? && goal.currency do %>
|
||||
<div class="truncate">
|
||||
<%= goal %>
|
||||
{goal}
|
||||
<br />
|
||||
<span class="text-red-600">
|
||||
Unlock Revenue Goals by upgrading to a business plan
|
||||
|
|
@ -44,7 +44,7 @@ defmodule PlausibleWeb.Live.GoalSettings.List do
|
|||
</div>
|
||||
<% else %>
|
||||
<.goal_description goal={goal} />
|
||||
<span><%= goal %></span>
|
||||
<span>{goal}</span>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -115,11 +115,11 @@ defmodule PlausibleWeb.Live.GoalSettings.List do
|
|||
def goal_description(assigns) do
|
||||
~H"""
|
||||
<span :if={@goal.page_path} class="block truncate text-gray-400 dark:text-gray-600">
|
||||
<%= pageview_description(@goal) %>
|
||||
{pageview_description(@goal)}
|
||||
</span>
|
||||
|
||||
<span :if={@goal.event_name} class="block truncate text-gray-400 dark:text-gray-600">
|
||||
<%= custom_event_description(@goal) %>
|
||||
{custom_event_description(@goal)}
|
||||
</span>
|
||||
"""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ defmodule PlausibleWeb.Live.ImportsExportsSettings do
|
|||
|
||||
~H"""
|
||||
<.notice :if={@import_warning} theme={:gray}>
|
||||
<%= @import_warning %>
|
||||
{@import_warning}
|
||||
</.notice>
|
||||
|
||||
<div class="mt-4 flex justify-end gap-x-4">
|
||||
|
|
@ -132,24 +132,22 @@ defmodule PlausibleWeb.Live.ImportsExportsSettings do
|
|||
class="max-w-sm"
|
||||
title={"#{Plausible.Imported.SiteImport.label(entry.site_import)} created at #{format_date(entry.site_import.inserted_at)}"}
|
||||
>
|
||||
<%= Plausible.Imported.SiteImport.label(entry.site_import) %>
|
||||
{Plausible.Imported.SiteImport.label(entry.site_import)}
|
||||
</div>
|
||||
</div>
|
||||
</.td>
|
||||
|
||||
<.td hide_on_mobile>
|
||||
<%= format_date(entry.site_import.start_date) %> - <%= format_date(
|
||||
entry.site_import.end_date
|
||||
) %>
|
||||
{format_date(entry.site_import.start_date)} - {format_date(entry.site_import.end_date)}
|
||||
</.td>
|
||||
|
||||
<.td>
|
||||
<div class="text-right">
|
||||
<%= if entry.live_status == SiteImport.completed(),
|
||||
{if entry.live_status == SiteImport.completed(),
|
||||
do:
|
||||
PlausibleWeb.StatsView.large_number_format(
|
||||
pageview_count(entry.site_import, @pageview_counts)
|
||||
) %>
|
||||
)}
|
||||
</div>
|
||||
</.td>
|
||||
<.td actions>
|
||||
|
|
|
|||
|
|
@ -293,12 +293,12 @@ defmodule PlausibleWeb.Live.Installation do
|
|||
class="block h-5 w-5 rounded dark:bg-gray-700 border-gray-300 text-indigo-600 focus:ring-indigo-600 mr-2"
|
||||
/>
|
||||
<label for={"check-#{@variant}"}>
|
||||
<%= @label %>
|
||||
{@label}
|
||||
</label>
|
||||
<div class="ml-2 collapse md:visible">
|
||||
<.tooltip sticky?={false}>
|
||||
<:tooltip_content>
|
||||
<%= @tooltip %>
|
||||
{@tooltip}
|
||||
<br /><br />Click to learn more.
|
||||
</:tooltip_content>
|
||||
<a href={@learn_more} target="_blank" rel="noopener noreferrer">
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ defmodule PlausibleWeb.Live.Plugins.API.Settings do
|
|||
<.flash_messages flash={@flash} />
|
||||
|
||||
<%= if @add_token? do %>
|
||||
<%= live_render(
|
||||
{live_render(
|
||||
@socket,
|
||||
PlausibleWeb.Live.Plugins.API.TokenForm,
|
||||
id: "token-form",
|
||||
|
|
@ -44,7 +44,7 @@ defmodule PlausibleWeb.Live.Plugins.API.Settings do
|
|||
"token_description" => @token_description,
|
||||
"rendered_by" => self()
|
||||
}
|
||||
) %>
|
||||
)}
|
||||
<% end %>
|
||||
|
||||
<div>
|
||||
|
|
@ -64,14 +64,14 @@ defmodule PlausibleWeb.Live.Plugins.API.Settings do
|
|||
<:tbody :let={token}>
|
||||
<.td>
|
||||
<span class="token-description">
|
||||
<%= token.description %>
|
||||
{token.description}
|
||||
</span>
|
||||
</.td>
|
||||
<.td hide_on_mobile>
|
||||
**********<%= token.hint %>
|
||||
**********{token.hint}
|
||||
</.td>
|
||||
<.td hide_on_mobile>
|
||||
<%= Plausible.Plugins.API.Token.last_used_humanize(token) %>
|
||||
{Plausible.Plugins.API.Token.last_used_humanize(token)}
|
||||
</.td>
|
||||
<.td actions>
|
||||
<.delete_button
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ defmodule PlausibleWeb.Live.Plugins.API.TokenForm do
|
|||
phx-click-away="cancel-add-token"
|
||||
>
|
||||
<.title>
|
||||
Add Plugin Token for <%= @domain %>
|
||||
Add Plugin Token for {@domain}
|
||||
</.title>
|
||||
|
||||
<div class="mt-4">
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ defmodule PlausibleWeb.Live.PropsSettings do
|
|||
<section id="props-settings-main">
|
||||
<.flash_messages flash={@flash} />
|
||||
<%= if @add_prop? do %>
|
||||
<%= live_render(
|
||||
{live_render(
|
||||
@socket,
|
||||
PlausibleWeb.Live.PropsSettings.Form,
|
||||
id: "props-form",
|
||||
|
|
@ -48,7 +48,7 @@ defmodule PlausibleWeb.Live.PropsSettings do
|
|||
"site_id" => @site_id,
|
||||
"rendered_by" => self()
|
||||
}
|
||||
) %>
|
||||
)}
|
||||
<% end %>
|
||||
|
||||
<.live_component
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ defmodule PlausibleWeb.Live.PropsSettings.Form do
|
|||
phx-submit="allow-prop"
|
||||
phx-click-away="cancel-allow-prop"
|
||||
>
|
||||
<.title>Add Property for <%= @domain %></.title>
|
||||
<.title>Add Property for {@domain}</.title>
|
||||
|
||||
<div class="mt-6">
|
||||
<.label for="prop_input">
|
||||
|
|
@ -89,9 +89,9 @@ defmodule PlausibleWeb.Live.PropsSettings.Form do
|
|||
/>
|
||||
|
||||
<.error :for={{msg, opts} <- f[:allowed_event_props].errors}>
|
||||
<%= Enum.reduce(opts, msg, fn {key, value}, acc ->
|
||||
{Enum.reduce(opts, msg, fn {key, value}, acc ->
|
||||
String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end)
|
||||
end) %>
|
||||
end)}
|
||||
</.error>
|
||||
</div>
|
||||
|
||||
|
|
@ -105,7 +105,7 @@ defmodule PlausibleWeb.Live.PropsSettings.Form do
|
|||
class="mt-4 text-sm hover:underline text-indigo-600 dark:text-indigo-400 text-left"
|
||||
phx-click="allow-existing-props"
|
||||
>
|
||||
Already sending custom properties? Click to add <%= @prop_key_options_count %> existing properties we found.
|
||||
Already sending custom properties? Click to add {@prop_key_options_count} existing properties we found.
|
||||
</button>
|
||||
</.form>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ defmodule PlausibleWeb.Live.PropsSettings.List do
|
|||
<%= if is_list(@props) && length(@props) > 0 do %>
|
||||
<.table id="allowed-props" rows={Enum.with_index(@props)}>
|
||||
<:tbody :let={{prop, index}}>
|
||||
<.td id={"prop-#{index}"}><span class="font-medium"><%= prop %></span></.td>
|
||||
<.td id={"prop-#{index}"}><span class="font-medium">{prop}</span></.td>
|
||||
<.td actions>
|
||||
<.delete_button
|
||||
id={"disallow-prop-#{prop}"}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
|||
def render(%{invitation_expired: true} = assigns) do
|
||||
~H"""
|
||||
<div class="mx-auto mt-6 text-center dark:text-gray-300">
|
||||
<h1 class="text-3xl font-black"><%= Plausible.product_name() %></h1>
|
||||
<h1 class="text-3xl font-black">{Plausible.product_name()}</h1>
|
||||
<div class="text-xl font-medium">Lightweight and privacy-friendly web analytics</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
|||
<div class="mx-auto text-center dark:text-gray-300">
|
||||
<h1 class="text-3xl font-black">
|
||||
<%= if ce?() or @live_action == :register_from_invitation_form do %>
|
||||
Register your <%= Plausible.product_name() %> account
|
||||
Register your {Plausible.product_name()} account
|
||||
<% else %>
|
||||
Register your 30-day free trial
|
||||
<% end %>
|
||||
|
|
@ -155,7 +155,7 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
|||
</div>
|
||||
<%= if @captcha_error do %>
|
||||
<div class="text-red-500 text-xs italic mt-3" x-data x-init="hcaptcha.reset()">
|
||||
<%= @captcha_error %>
|
||||
{@captcha_error}
|
||||
</div>
|
||||
<% end %>
|
||||
<script
|
||||
|
|
@ -176,7 +176,7 @@ defmodule PlausibleWeb.Live.RegisterForm do
|
|||
"Start my free trial"
|
||||
end %>
|
||||
<.button id="register" disabled={@disable_submit} type="submit" class="mt-4 w-full">
|
||||
<%= submit_text %>
|
||||
{submit_text}
|
||||
</.button>
|
||||
|
||||
<p class="text-center text-gray-600 dark:text-gray-500 mt-4">
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ defmodule PlausibleWeb.Live.Shields.CountryRules do
|
|||
theme={:gray}
|
||||
>
|
||||
<p>
|
||||
You've reached the maximum number of countries you can block (<%= Shields.maximum_country_rules() %>). Please remove one before adding another.
|
||||
You've reached the maximum number of countries you can block ({Shields.maximum_country_rules()}). Please remove one before adding another.
|
||||
</p>
|
||||
</.notice>
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ defmodule PlausibleWeb.Live.Shields.CountryRules do
|
|||
class="mr-4 cursor-help"
|
||||
title={"Added at #{format_added_at(rule.inserted_at, @site.timezone)} by #{rule.added_by}"}
|
||||
>
|
||||
<%= country.flag %> <%= country.name %>
|
||||
{country.flag} {country.name}
|
||||
</span>
|
||||
</div>
|
||||
</.td>
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ defmodule PlausibleWeb.Live.Shields.HostnameRules do
|
|||
alias Plausible.Shields
|
||||
alias Plausible.Shield
|
||||
|
||||
import PlausibleWeb.ErrorHelpers
|
||||
|
||||
def update(assigns, socket) do
|
||||
socket =
|
||||
socket
|
||||
|
|
@ -58,7 +56,7 @@ defmodule PlausibleWeb.Live.Shields.HostnameRules do
|
|||
theme={:gray}
|
||||
>
|
||||
<p>
|
||||
You've reached the maximum number of hostnames you can block (<%= Shields.maximum_hostname_rules() %>). Please remove one before adding another.
|
||||
You've reached the maximum number of hostnames you can block ({Shields.maximum_hostname_rules()}). Please remove one before adding another.
|
||||
</p>
|
||||
</.notice>
|
||||
|
||||
|
|
@ -83,7 +81,7 @@ defmodule PlausibleWeb.Live.Shields.HostnameRules do
|
|||
class="mr-4 cursor-help text-ellipsis truncate max-w-xs"
|
||||
title={"Added at #{format_added_at(rule.inserted_at, @site.timezone)} by #{rule.added_by}"}
|
||||
>
|
||||
<%= rule.hostname %>
|
||||
{rule.hostname}
|
||||
</span>
|
||||
</div>
|
||||
</.td>
|
||||
|
|
@ -136,12 +134,11 @@ defmodule PlausibleWeb.Live.Shields.HostnameRules do
|
|||
id={"#{f[:hostname].id}-#{modal_unique_id}"}
|
||||
creatable
|
||||
/>
|
||||
|
||||
<%= error_tag(f, :hostname) %>
|
||||
<.error :for={msg <- f[:hostname].errors}>{translate_error(msg)}</.error>
|
||||
|
||||
<p class="mt-4 text-sm text-gray-500 dark:text-gray-400">
|
||||
You can use a wildcard (<code>*</code>) to match multiple hostnames. For example,
|
||||
<code>*<%= @site.domain %></code>
|
||||
<code>*{@site.domain}</code>
|
||||
will only record traffic on your main domain and all of its subdomains.<br /><br />
|
||||
|
||||
<%= if @hostname_rules_count >= 1 do %>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ defmodule PlausibleWeb.Live.Shields.IPRules do
|
|||
theme={:gray}
|
||||
>
|
||||
<p>
|
||||
You've reached the maximum number of IP addresses you can block (<%= Shields.maximum_ip_rules() %>). Please remove one before adding another.
|
||||
You've reached the maximum number of IP addresses you can block ({Shields.maximum_ip_rules()}). Please remove one before adding another.
|
||||
</p>
|
||||
</.notice>
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ defmodule PlausibleWeb.Live.Shields.IPRules do
|
|||
class="cursor-help"
|
||||
title={"Added at #{format_added_at(rule.inserted_at, @site.timezone)} by #{rule.added_by}"}
|
||||
>
|
||||
<%= rule.inet %>
|
||||
{rule.inet}
|
||||
</span>
|
||||
</div>
|
||||
</.td>
|
||||
|
|
@ -97,7 +97,7 @@ defmodule PlausibleWeb.Live.Shields.IPRules do
|
|||
</.td>
|
||||
<.td hide_on_mobile truncate>
|
||||
<span :if={rule.description} title={rule.description}>
|
||||
<%= rule.description %>
|
||||
{rule.description}
|
||||
</span>
|
||||
<span :if={!rule.description} class="text-gray-400 dark:text-gray-600">
|
||||
--
|
||||
|
|
|
|||
|
|
@ -9,8 +9,6 @@ defmodule PlausibleWeb.Live.Shields.PageRules do
|
|||
alias Plausible.Shields
|
||||
alias Plausible.Shield
|
||||
|
||||
import PlausibleWeb.ErrorHelpers
|
||||
|
||||
def update(assigns, socket) do
|
||||
socket =
|
||||
socket
|
||||
|
|
@ -58,7 +56,7 @@ defmodule PlausibleWeb.Live.Shields.PageRules do
|
|||
theme={:gray}
|
||||
>
|
||||
<p>
|
||||
You've reached the maximum number of pages you can block (<%= Shields.maximum_page_rules() %>). Please remove one before adding another.
|
||||
You've reached the maximum number of pages you can block ({Shields.maximum_page_rules()}). Please remove one before adding another.
|
||||
</p>
|
||||
</.notice>
|
||||
|
||||
|
|
@ -79,7 +77,7 @@ defmodule PlausibleWeb.Live.Shields.PageRules do
|
|||
class="mr-4 cursor-help text-ellipsis truncate max-w-xs"
|
||||
title={"Added at #{format_added_at(rule.inserted_at, @site.timezone)} by #{rule.added_by}"}
|
||||
>
|
||||
<%= rule.page_path %>
|
||||
{rule.page_path}
|
||||
</span>
|
||||
</.td>
|
||||
<.td hide_on_mobile>
|
||||
|
|
@ -132,7 +130,7 @@ defmodule PlausibleWeb.Live.Shields.PageRules do
|
|||
creatable
|
||||
/>
|
||||
|
||||
<%= error_tag(f, :page_path) %>
|
||||
<.error :for={msg <- f[:page_path].errors}>{translate_error(msg)}</.error>
|
||||
|
||||
<p class="mt-4 text-sm text-gray-500 dark:text-gray-400">
|
||||
You can use a wildcard (<code>*</code>) to match multiple pages. For example,
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
page_number={@sites.page_number}
|
||||
total_pages={@sites.total_pages}
|
||||
>
|
||||
Total of <span class="font-medium"><%= @sites.total_entries %></span> sites
|
||||
Total of <span class="font-medium">{@sites.total_entries}</span> sites
|
||||
</.pagination>
|
||||
<.invitation_modal :if={Enum.any?(@sites.entries, &(&1.entry_type == "invitation"))} />
|
||||
</div>
|
||||
|
|
@ -166,7 +166,7 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
/>
|
||||
<div class="flex-1 truncate -mt-px">
|
||||
<h3 class="text-gray-900 font-medium text-lg truncate dark:text-gray-100">
|
||||
<%= @site.domain %>
|
||||
{@site.domain}
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
class="text-gray-900 font-medium text-lg truncate dark:text-gray-100"
|
||||
style="width: calc(100% - 4rem)"
|
||||
>
|
||||
<%= @site.domain %>
|
||||
{@site.domain}
|
||||
</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -308,7 +308,7 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
<div class="flex justify-between items-center">
|
||||
<p>
|
||||
<span class="text-gray-800 dark:text-gray-200">
|
||||
<b><%= PlausibleWeb.StatsView.large_number_format(@hourly_stats.visitors) %></b>
|
||||
<b>{PlausibleWeb.StatsView.large_number_format(@hourly_stats.visitors)}</b>
|
||||
visitor<span :if={@hourly_stats.visitors != 1}>s</span> in last 24h
|
||||
</span>
|
||||
</p>
|
||||
|
|
@ -357,7 +357,7 @@ defmodule PlausibleWeb.Live.Sites do
|
|||
</path>
|
||||
</svg>
|
||||
|
||||
<%= abs(@change) %>%
|
||||
{abs(@change)}%
|
||||
</p>
|
||||
"""
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ defmodule PlausibleWeb.Router do
|
|||
use PlausibleWeb, :router
|
||||
use Plausible
|
||||
import Phoenix.LiveView.Router
|
||||
import PhoenixStorybook.Router
|
||||
|
||||
pipeline :browser do
|
||||
plug :accepts, ["html"]
|
||||
|
|
@ -77,6 +78,15 @@ defmodule PlausibleWeb.Router do
|
|||
forward "/sent-emails", Bamboo.SentEmailViewerPlug
|
||||
end
|
||||
|
||||
scope "/" do
|
||||
storybook_assets()
|
||||
end
|
||||
|
||||
scope "/", PlausibleWeb do
|
||||
pipe_through :browser
|
||||
live_storybook("/storybook", backend_module: PlausibleWeb.Storybook)
|
||||
end
|
||||
|
||||
on_ee do
|
||||
use Kaffy.Routes,
|
||||
scope: "/crm",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
defmodule PlausibleWeb.Storybook do
|
||||
@moduledoc false
|
||||
|
||||
use PhoenixStorybook,
|
||||
otp_app: :plausible_web,
|
||||
title: "Plausible Storybook",
|
||||
content_path: Path.expand("../../storybook", __DIR__),
|
||||
# assets path are remote path, not local file-system paths
|
||||
css_path: "/css/storybook.css",
|
||||
js_path: "/js/storybook.js",
|
||||
sandbox_class: "plausible",
|
||||
color_mode: true
|
||||
end
|
||||
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
<:subtitle :if={@has_email_code?}>
|
||||
<p class="truncate">
|
||||
Please enter the 4-digit code we sent to <b><%= @conn.assigns[:current_user].email %></b>
|
||||
Please enter the 4-digit code we sent to <b>{@conn.assigns[:current_user].email}</b>
|
||||
</p>
|
||||
</:subtitle>
|
||||
|
||||
<:subtitle :if={!@has_email_code?}>
|
||||
<p class="truncate">
|
||||
A 4-digit activation code will be sent to <b><%= @conn.assigns[:current_user].email %></b>
|
||||
A 4-digit activation code will be sent to <b>{@conn.assigns[:current_user].email}</b>
|
||||
</p>
|
||||
</:subtitle>
|
||||
|
||||
|
|
@ -46,7 +46,7 @@
|
|||
</.form>
|
||||
</div>
|
||||
|
||||
<%= error_tag(assigns, :error) %>
|
||||
<.error>{@error}</.error>
|
||||
|
||||
<div :if={!@has_email_code?}>
|
||||
<.button_link method="post" class="w-full" href="/activate/request-code">
|
||||
|
|
@ -65,7 +65,7 @@
|
|||
<.styled_link href="/activate/request-code" method="post">
|
||||
Send a new code
|
||||
</.styled_link>
|
||||
to <%= @conn.assigns[:current_user].email %>
|
||||
to {@conn.assigns[:current_user].email}
|
||||
</:item>
|
||||
<:item :if={ee?()}>
|
||||
<.styled_link href="https://plausible.io/contact" new_tab={true}>
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
<.styled_link method="post" href={Routes.settings_path(@conn, :cancel_update_email)}>
|
||||
Change email back to
|
||||
</.styled_link>
|
||||
<%= @conn.assigns[:current_user].previous_email %>
|
||||
{@conn.assigns[:current_user].previous_email}
|
||||
</:item>
|
||||
|
||||
<:item :if={not @has_any_memberships?}>
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
class="font-mono border-2 border-dotted border-gray-200 dark:border-gray-700 rounded-md text-gray-600 dark:text-gray-200 text-lg bg-gray-100 dark:bg-gray-900 p-2 mt-6 flex flex-wrap"
|
||||
>
|
||||
<%= for code <- @recovery_codes do %>
|
||||
<div class="basis-1/2 text-center"><%= code %></div>
|
||||
<div class="basis-1/2 text-center">{code}</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<.focus_box>
|
||||
<:title>
|
||||
<%= Phoenix.Flash.get(@flash, :login_title) || "Enter your account credentials" %>
|
||||
{Phoenix.Flash.get(@flash, :login_title) || "Enter your account credentials"}
|
||||
</:title>
|
||||
<:subtitle>
|
||||
<%= if Phoenix.Flash.get(@flash, :login_instructions) do %>
|
||||
<p class="text-gray-500 mt-1 mb-2">
|
||||
<%= Phoenix.Flash.get(@flash, :login_instructions) %>
|
||||
{Phoenix.Flash.get(@flash, :login_instructions)}
|
||||
</p>
|
||||
<% end %>
|
||||
</:subtitle>
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
</div>
|
||||
|
||||
<%= if @conn.assigns[:error] do %>
|
||||
<div class="text-red-500 mt-4"><%= @conn.assigns[:error] %></div>
|
||||
<div class="text-red-500 mt-4">{@conn.assigns[:error]}</div>
|
||||
<% end %>
|
||||
|
||||
<.button class="w-full" type="submit">Log in</.button>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<%= live_render(@conn, PlausibleWeb.Live.ResetPasswordForm,
|
||||
{live_render(@conn, PlausibleWeb.Live.ResetPasswordForm,
|
||||
container: {:div, class: "contents"},
|
||||
session: %{"email" => @email}
|
||||
) %>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@
|
|||
<.input type="email" field={f[:email]} placeholder="user@example.com" />
|
||||
</div>
|
||||
<%= if @conn.assigns[:error] do %>
|
||||
<div class="text-red-500 my-2"><%= @conn.assigns[:error] %></div>
|
||||
<div class="text-red-500 my-2">{@conn.assigns[:error]}</div>
|
||||
<% end %>
|
||||
|
||||
<%= if PlausibleWeb.Captcha.enabled?() do %>
|
||||
<div class="mt-4">
|
||||
<div class="h-captcha" data-sitekey={PlausibleWeb.Captcha.sitekey()}></div>
|
||||
<%= if assigns[:captcha_error] do %>
|
||||
<div class="text-red-500 text-xs mt-3"><%= @captcha_error %></div>
|
||||
<div class="text-red-500 text-xs mt-3">{@captcha_error}</div>
|
||||
<% end %>
|
||||
<script src="https://hcaptcha.com/1/api.js" async defer>
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<div class="bg-white dark:bg-gray-800 max-w-md w-full mx-auto shadow-md rounded px-8 pt-6 pb-8 mb-4 mt-8">
|
||||
<h2 class="text-xl font-black dark:text-gray-100">Success!</h2>
|
||||
<div class="my-4 leading-tight dark:text-gray-100">
|
||||
We've sent an email containing password reset instructions to <b><%= @email %></b>
|
||||
We've sent an email containing password reset instructions to <b>{@email}</b>
|
||||
if it's registered in our system.
|
||||
</div>
|
||||
<div class="mt-8 text-sm dark:text-gray-100">
|
||||
|
|
|
|||
|
|
@ -25,12 +25,12 @@
|
|||
<tbody class="bg-white dark:bg-gray-800">
|
||||
<tr class="border-b border-gray-200">
|
||||
<td class="px-6 py-4 text-sm leading-5 font-bold dark:text-gray-100">
|
||||
<%= present_currency(@preview_info["immediate_payment"]["currency"]) %><%= @preview_info[
|
||||
{present_currency(@preview_info["immediate_payment"]["currency"])}{@preview_info[
|
||||
"immediate_payment"
|
||||
]["amount"] %>
|
||||
]["amount"]}
|
||||
</td>
|
||||
<td class="px-6 py-4 text-sm leading-5 dark:text-gray-100">
|
||||
<%= present_date(@preview_info["immediate_payment"]["date"]) %>
|
||||
{present_date(@preview_info["immediate_payment"]["date"])}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
@ -60,12 +60,12 @@
|
|||
<tbody class="bg-white dark:bg-gray-800">
|
||||
<tr class="border-b border-gray-200">
|
||||
<td class="px-6 py-4 text-sm leading-5 font-bold dark:text-gray-100">
|
||||
<%= present_currency(@preview_info["immediate_payment"]["currency"]) %><%= @preview_info[
|
||||
{present_currency(@preview_info["immediate_payment"]["currency"])}{@preview_info[
|
||||
"next_payment"
|
||||
]["amount"] %>
|
||||
]["amount"]}
|
||||
</td>
|
||||
<td class="px-6 py-4 text-sm leading-5 dark:text-gray-100">
|
||||
<%= present_date(@preview_info["next_payment"]["date"]) %>
|
||||
{present_date(@preview_info["next_payment"]["date"])}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<%= live_render(@conn, PlausibleWeb.Live.ChoosePlan,
|
||||
{live_render(@conn, PlausibleWeb.Live.ChoosePlan,
|
||||
id: "choose-plan",
|
||||
session: %{"remote_ip" => PlausibleWeb.RemoteIP.get(@conn)}
|
||||
) %>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
<div class="mx-auto mt-6 text-center">
|
||||
<h1 class="text-3xl font-black text-black dark:text-gray-100">
|
||||
<%= if @subscription_resumable,
|
||||
{if @subscription_resumable,
|
||||
do: "Change subscription plan",
|
||||
else: "Upgrade to Enterprise" %>
|
||||
else: "Upgrade to Enterprise"}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="w-full max-w-lg px-4 mx-auto mt-4 text-gray-900 dark:text-gray-100">
|
||||
<div class="flex-1 p-8 mt-8 rounded bg-white shadow-md dark:bg-gray-800 dark:shadow-none">
|
||||
<div class="w-full pb-4">
|
||||
<span>
|
||||
<%= if @subscription_resumable,
|
||||
{if @subscription_resumable,
|
||||
do:
|
||||
"We've prepared your account for an upgrade to custom limits outside the listed plans:",
|
||||
else:
|
||||
"We've prepared a custom enterprise plan for your account with the following limits:" %>
|
||||
"We've prepared a custom enterprise plan for your account with the following limits:"}
|
||||
</span>
|
||||
</div>
|
||||
<PlausibleWeb.Components.Billing.present_enterprise_plan plan={@latest_enterprise_plan} />
|
||||
|
|
@ -21,19 +21,19 @@
|
|||
<span>
|
||||
The plan is priced at
|
||||
<b>
|
||||
<%= case @price do
|
||||
{case @price do
|
||||
%Money{} = money -> Plausible.Billing.format_price(money)
|
||||
nil -> "N/A"
|
||||
end %>
|
||||
end}
|
||||
</b>
|
||||
</span>
|
||||
<span>
|
||||
per <%= if @latest_enterprise_plan.billing_interval == :yearly,
|
||||
per {if @latest_enterprise_plan.billing_interval == :yearly,
|
||||
do: "year",
|
||||
else: "month" %> + VAT if applicable. <%= if @subscription_resumable,
|
||||
else: "month"} + VAT if applicable. {if @subscription_resumable,
|
||||
do:
|
||||
"On the next page, our payment provider will calculate the prorated amount that your card will be charged if you decide to upgrade now.",
|
||||
else: "Click the button below to upgrade." %>
|
||||
else: "Click the button below to upgrade."}
|
||||
</span>
|
||||
</ul>
|
||||
<div class="w-max">
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
<%= for log <- @queries do %>
|
||||
<details class="group py-1">
|
||||
<summary class="flex cursor-pointer flex-row items-center justify-between py-1 font-semibold text-gray-800 dark:text-gray-200 pt-4">
|
||||
<%= log["request_method"] %> <%= controller_name(log["phoenix_controller"]) %>.<%= log[
|
||||
{log["request_method"]} {controller_name(log["phoenix_controller"])}.{log[
|
||||
"phoenix_action"
|
||||
] %> (<%= log[:query_duration_ms] %>ms)
|
||||
]} ({log[:query_duration_ms]}ms)
|
||||
<svg
|
||||
class="h-6 w-6 rotate-0 transform text-gray-400 dark:text-gray-200 group-open:rotate-180"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
<tbody>
|
||||
<%= for {key, value} <- log do %>
|
||||
<tr class="table-row">
|
||||
<td class="table-cell p-2"><%= key %></td>
|
||||
<td class="table-cell p-2">{key}</td>
|
||||
<td class="table-cell p-2">
|
||||
<%= case key do %>
|
||||
<% :query -> %>
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
<% "params" -> %>
|
||||
<pre><%= Jason.encode!(value, pretty: true) %></pre>
|
||||
<% _ -> %>
|
||||
<%= value %>
|
||||
{value}
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Enter <%= @code %> to verify your email address. This code will expire in 4 hours.
|
||||
Enter {@code} to verify your email address. This code will expire in 4 hours.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
You used to have an active account with <%= Plausible.product_name() %>, a simple, lightweight, open source and privacy-first Google Analytics alternative.
|
||||
You used to have an active account with {Plausible.product_name()}, a simple, lightweight, open source and privacy-first Google Analytics alternative.
|
||||
<br /><br />
|
||||
We've noticed that you're still sending us stats so we're writing to inform you that we'll stop accepting stats from your sites <%= @time %>. We're an independent, bootstrapped service and we don't sell your data, so this will reduce our server costs and help keep us sustainable.
|
||||
We've noticed that you're still sending us stats so we're writing to inform you that we'll stop accepting stats from your sites {@time}. We're an independent, bootstrapped service and we don't sell your data, so this will reduce our server costs and help keep us sustainable.
|
||||
<br /><br /> If you'd like to continue counting your site stats in a privacy-friendly way, please
|
||||
<a href={plausible_url()}>login to your Plausible account</a> and start a subscription.
|
||||
<br /><br />
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ You've activated
|
|||
<%= if Plausible.ee?() do %>
|
||||
your free 30-day trial of
|
||||
<% end %>
|
||||
<%= Plausible.product_name() %>, a simple and privacy-friendly website analytics tool.
|
||||
<br /><br />
|
||||
{Plausible.product_name()}, a simple and privacy-friendly website analytics tool. <br /><br />
|
||||
<a href={"#{plausible_url()}/sites/new"}>Click here</a>
|
||||
to add your website URL, your timezone and install our one-line JavaScript snippet to start collecting visitor statistics.
|
||||
<%= if Plausible.ee?() do %>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<%= if @success do %>
|
||||
Your CSV import has completed successfully. The Plausible dashboard for <%= @site_import.site.domain %> now contains historical imported data from <%= date_format(
|
||||
Your CSV import has completed successfully. The Plausible dashboard for {@site_import.site.domain} now contains historical imported data from {date_format(
|
||||
@site_import.start_date
|
||||
) %> to <%= date_format(@site_import.end_date) %>
|
||||
)} to {date_format(@site_import.end_date)}
|
||||
<br /><br />
|
||||
<a href={@link}>Click here</a>
|
||||
to view your dashboard.
|
||||
<% else %>
|
||||
Unfortunately, your CSV import for <%= @site_import.site.domain %> did not complete successfully. Sorry about that!
|
||||
Unfortunately, your CSV import for {@site_import.site.domain} did not complete successfully. Sorry about that!
|
||||
<br /><br /> Please try to do the import once again.
|
||||
<%= if ee?() do %>
|
||||
<br /> <br />
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
Last week we sent a reminder that your site traffic has exceeded the limits of your <%= Plausible.product_name() %> subscription tier for two consecutive months. Since we haven't received a response, we've had to temporarily lock access to your stats.
|
||||
Last week we sent a reminder that your site traffic has exceeded the limits of your {Plausible.product_name()} subscription tier for two consecutive months. Since we haven't received a response, we've had to temporarily lock access to your stats.
|
||||
<br /><br />
|
||||
Your subscription is still active, we're still counting your stats and haven't deleted any of your data but as you have outgrown your subscription tier, we kindly ask you to upgrade to match your new traffic levels. Upon upgrading to a suitable tier, your dashboard access will be immediately restored.
|
||||
<br /><br />
|
||||
During the last billing cycle (<%= PlausibleWeb.TextHelpers.format_date_range(
|
||||
During the last billing cycle ({PlausibleWeb.TextHelpers.format_date_range(
|
||||
@usage.last_cycle.date_range
|
||||
) %>), your account recorded <%= PlausibleWeb.AuthView.delimit_integer(@usage.last_cycle.total) %> billable pageviews. In the billing cycle before that (<%= PlausibleWeb.TextHelpers.format_date_range(
|
||||
)}), your account recorded {PlausibleWeb.AuthView.delimit_integer(@usage.last_cycle.total)} billable pageviews. In the billing cycle before that ({PlausibleWeb.TextHelpers.format_date_range(
|
||||
@usage.penultimate_cycle.date_range
|
||||
) %>), the usage was <%= PlausibleWeb.AuthView.delimit_integer(@usage.penultimate_cycle.total) %> billable pageviews. Note that billable pageviews include both standard pageviews and custom events. In your
|
||||
)}), the usage was {PlausibleWeb.AuthView.delimit_integer(@usage.penultimate_cycle.total)} billable pageviews. Note that billable pageviews include both standard pageviews and custom events. In your
|
||||
<a href={PlausibleWeb.Router.Helpers.settings_url(PlausibleWeb.Endpoint, :subscription)}>account settings</a>, you'll find an overview of your usage and limits.
|
||||
<br /><br />
|
||||
<%= if @suggested_plan == :enterprise do %>
|
||||
Your usage exceeds our standard plans, so please reply back to this email for a tailored quote.
|
||||
<% else %>
|
||||
<a href={PlausibleWeb.Router.Helpers.billing_url(PlausibleWeb.Endpoint, :choose_plan)}>Click here to upgrade your subscription</a>. We recommend you upgrade to the <%= @suggested_plan.volume %>/mo plan. The new charge will be prorated to reflect the amount you have already paid and the time until your current subscription is supposed to expire.
|
||||
<a href={PlausibleWeb.Router.Helpers.billing_url(PlausibleWeb.Endpoint, :choose_plan)}>Click here to upgrade your subscription</a>. We recommend you upgrade to the {@suggested_plan.volume}/mo plan. The new charge will be prorated to reflect the amount you have already paid and the time until your current subscription is supposed to expire.
|
||||
<br /><br />
|
||||
If your usage decreases in the future, you can switch to a lower plan at any time. Any credit balance will automatically apply to future payments.
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
We've recorded <%= @current_visitors %> visitors on
|
||||
We've recorded {@current_visitors} visitors on
|
||||
<a href={"https://" <> @site.domain}><%= @site.domain %></a> in the last 12 hours.
|
||||
<%= if @dashboard_link do %>
|
||||
<br /><br /> View dashboard: <a href={@dashboard_link}><%= @dashboard_link %></a>
|
||||
<br /><br /> View dashboard: <a href={@dashboard_link}>{@dashboard_link}</a>
|
||||
<br /><br /> Something looks off? Please
|
||||
<a href={@installation_link}>review your installation</a>
|
||||
to verify that Plausible has been integrated correctly.
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
Automated notice about an enterprise account that has gone over their limits. <br /><br />
|
||||
Customer email: <%= @user.email %><br />
|
||||
Last billing cycle: <%= PlausibleWeb.TextHelpers.format_date_range(
|
||||
Customer email: {@user.email}<br />
|
||||
Last billing cycle: {PlausibleWeb.TextHelpers.format_date_range(
|
||||
@pageview_usage.last_cycle.date_range
|
||||
) %><br />
|
||||
Last cycle pageview usage: <%= PlausibleWeb.AuthView.delimit_integer(
|
||||
)}<br />
|
||||
Last cycle pageview usage: {PlausibleWeb.AuthView.delimit_integer(
|
||||
@pageview_usage.last_cycle.total
|
||||
) %> billable pageviews<br />
|
||||
Penultimate billing cycle: <%= PlausibleWeb.TextHelpers.format_date_range(
|
||||
)} billable pageviews<br />
|
||||
Penultimate billing cycle: {PlausibleWeb.TextHelpers.format_date_range(
|
||||
@pageview_usage.penultimate_cycle.date_range
|
||||
) %><br />
|
||||
Penultimate cycle pageview usage: <%= PlausibleWeb.AuthView.delimit_integer(
|
||||
)}<br />
|
||||
Penultimate cycle pageview usage: {PlausibleWeb.AuthView.delimit_integer(
|
||||
@pageview_usage.penultimate_cycle.total
|
||||
) %> billable pageviews<br />
|
||||
Site usage: <%= @site_usage %> / <%= @site_allowance %> allowed sites<br />
|
||||
)} billable pageviews<br /> Site usage: {@site_usage} / {@site_allowance} allowed sites<br />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<h1>Error report</h1>
|
||||
<p>
|
||||
Reported by: <%= @reported_by %>
|
||||
<br /> Sentry trace: <a href={sentry_link(@trace_id)}><%= @trace_id %></a>
|
||||
Reported by: {@reported_by}
|
||||
<br /> Sentry trace: <a href={sentry_link(@trace_id)}>{@trace_id}</a>
|
||||
<br />
|
||||
</p>
|
||||
<h2>User feedback:</h2>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
<%= @inviter.email %> has invited you to the <%= @site.domain %> site on <%= Plausible.product_name() %>.
|
||||
{@inviter.email} has invited you to the {@site.domain} site on {Plausible.product_name()}.
|
||||
<a href={Routes.site_url(PlausibleWeb.Endpoint, :index)}>Click here</a> to view and respond to the invitation. The invitation
|
||||
will expire 48 hours after this email is sent.
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
<%= @inviter.email %> has invited you to the "<%= @team.name %>" team on <%= Plausible.product_name() %>.
|
||||
{@inviter.email} has invited you to the "{@team.name}" team on {Plausible.product_name()}.
|
||||
<a href={Routes.site_url(PlausibleWeb.Endpoint, :index)}>Click here</a> to view and respond to the invitation. The invitation
|
||||
will expire 48 hours after this email is sent.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Your <%= Plausible.product_name() %> export for <%= @site.domain %> has encountered an error and was unsuccessful.
|
||||
Your {Plausible.product_name()} export for {@site.domain} has encountered an error and was unsuccessful.
|
||||
Sorry for the trouble this may have caused. <br /><br /> Please attempt to export your data again.
|
||||
<%= if ee?() do %>
|
||||
Should the problem persist, do reply to this email so we can assist. Thanks!
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Your <%= Plausible.product_name() %> export for <%= @site.domain %> is now ready for download.
|
||||
Your {Plausible.product_name()} export for {@site.domain} is now ready for download.
|
||||
Please click <a href={@download_url}>here</a>
|
||||
to start the download process.
|
||||
<%= if @expires_in do %>
|
||||
Note that this link will expire <%= @expires_in %>.
|
||||
Note that this link will expire {@expires_in}.
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<%= if @success do %>
|
||||
Your Google Analytics import has completed successfully. The Plausible dashboard for <%= @site_import.site.domain %> now contains historical imported data from <%= date_format(
|
||||
Your Google Analytics import has completed successfully. The Plausible dashboard for {@site_import.site.domain} now contains historical imported data from {date_format(
|
||||
@site_import.start_date
|
||||
) %> to <%= date_format(@site_import.end_date) %>
|
||||
)} to {date_format(@site_import.end_date)}
|
||||
<br /><br />
|
||||
<a href={@link}>Click here</a>
|
||||
to view your dashboard.
|
||||
<% else %>
|
||||
Unfortunately, your Google Analytics import for <%= @site_import.site.domain %> did not complete successfully. Sorry about that!
|
||||
Unfortunately, your Google Analytics import for {@site_import.site.domain} did not complete successfully. Sorry about that!
|
||||
<br /><br />
|
||||
Please try to do the import once again. Sometimes the Google Analytics API just randomly returns empty data. It's intermittent and random. Trying to do the import again may return what you need.
|
||||
<%= if ee?() do %>
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
<%= @invitee_email %> has accepted your invitation to <%= @site.domain %>.
|
||||
{@invitee_email} has accepted your invitation to {@site.domain}.
|
||||
<a href={Routes.site_url(PlausibleWeb.Endpoint, :settings_general, @site.domain)}>Click here</a> to view site settings.
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
<%= @guest_invitation.team_invitation.email %> has rejected your invitation to <%= @guest_invitation.site.domain %>.
|
||||
{@guest_invitation.team_invitation.email} has rejected your invitation to {@guest_invitation.site.domain}.
|
||||
<a href={Routes.site_url(PlausibleWeb.Endpoint, :settings_general, @guest_invitation.site.domain)}>Click here</a> to view site settings.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<%= @inviter.email %> has invited you to join the <%= @site.domain %> site on <%= Plausible.product_name() %>.
|
||||
{@inviter.email} has invited you to join the {@site.domain} site on {Plausible.product_name()}.
|
||||
<a href={
|
||||
Routes.auth_url(
|
||||
PlausibleWeb.Endpoint,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<%= @inviter.email %> has invited you to join the "<%= @team.name %>" team on <%= Plausible.product_name() %>.
|
||||
{@inviter.email} has invited you to join the "{@team.name}" team on {Plausible.product_name()}.
|
||||
<a href={
|
||||
Routes.auth_url(
|
||||
PlausibleWeb.Endpoint,
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
Thanks for being a <%= Plausible.product_name() %> subscriber! <br /><br />
|
||||
Thanks for being a {Plausible.product_name()} subscriber! <br /><br />
|
||||
This is a friendly reminder that your traffic has exceeded your subscription tier for two consecutive months. Congrats on all that traffic!
|
||||
<br /><br />
|
||||
To maintain uninterrupted access to your stats, we kindly ask you to upgrade your account to match your new traffic levels. Please note, if your account isn't upgraded within the next 7 days, access to your stats will be temporarily locked.
|
||||
<br /><br />
|
||||
During the last billing cycle (<%= PlausibleWeb.TextHelpers.format_date_range(
|
||||
During the last billing cycle ({PlausibleWeb.TextHelpers.format_date_range(
|
||||
@usage.last_cycle.date_range
|
||||
) %>), your account recorded <%= PlausibleWeb.AuthView.delimit_integer(@usage.last_cycle.total) %> billable pageviews. In the billing cycle before that (<%= PlausibleWeb.TextHelpers.format_date_range(
|
||||
)}), your account recorded {PlausibleWeb.AuthView.delimit_integer(@usage.last_cycle.total)} billable pageviews. In the billing cycle before that ({PlausibleWeb.TextHelpers.format_date_range(
|
||||
@usage.penultimate_cycle.date_range
|
||||
) %>), your account used <%= PlausibleWeb.AuthView.delimit_integer(@usage.penultimate_cycle.total) %> billable pageviews. Note that billable pageviews include both standard pageviews and custom events. In your
|
||||
)}), your account used {PlausibleWeb.AuthView.delimit_integer(@usage.penultimate_cycle.total)} billable pageviews. Note that billable pageviews include both standard pageviews and custom events. In your
|
||||
<a href={plausible_url() <> PlausibleWeb.Router.Helpers.settings_path(PlausibleWeb.Endpoint, :subscription)}>account settings</a>, you'll find an overview of your usage and limits.
|
||||
<br /><br />
|
||||
<%= if @suggested_plan == :enterprise do %>
|
||||
Your usage exceeds our standard plans, so please reply back to this email for a tailored quote.
|
||||
<% else %>
|
||||
<a href={PlausibleWeb.Router.Helpers.billing_url(PlausibleWeb.Endpoint, :choose_plan)}>Click here to upgrade your subscription</a>. We recommend you upgrade to the <%= @suggested_plan.volume %>/mo plan. The new charge will be prorated to reflect the amount you have already paid and the time until your current subscription is supposed to expire.
|
||||
<a href={PlausibleWeb.Router.Helpers.billing_url(PlausibleWeb.Endpoint, :choose_plan)}>Click here to upgrade your subscription</a>. We recommend you upgrade to the {@suggested_plan.volume}/mo plan. The new charge will be prorated to reflect the amount you have already paid and the time until your current subscription is supposed to expire.
|
||||
<br /><br />
|
||||
If your usage decreases in the future, you can switch to a lower plan at any time. Any credit balance will automatically apply to future payments.
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
<%= @new_owner_email %> has accepted the ownership transfer of <%= @site.domain %>. They will be responsible for billing of it going
|
||||
{@new_owner_email} has accepted the ownership transfer of {@site.domain}. They will be responsible for billing of it going
|
||||
forward and your role has been changed to <b>admin</b>.
|
||||
<a href={Routes.site_url(PlausibleWeb.Endpoint, :settings_general, @site.domain)}>Click here</a> to view site settings.
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
<%= @site_transfer.email %> has rejected the ownership transfer of <%= @site_transfer.site.domain %>.
|
||||
{@site_transfer.email} has rejected the ownership transfer of {@site_transfer.site.domain}.
|
||||
<a href={Routes.site_url(PlausibleWeb.Endpoint, :settings_general, @site_transfer.site.domain)}>Click here</a> to view site settings.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<%= @inviter.email %> has requested to transfer the ownership of <%= @site.domain %> site on <%= Plausible.product_name() %> to you.
|
||||
{@inviter.email} has requested to transfer the ownership of {@site.domain} site on {Plausible.product_name()} to you.
|
||||
<%= if @new_owner_account do %>
|
||||
<a href={Routes.site_url(PlausibleWeb.Endpoint, :index)}>Click here</a>
|
||||
to view and respond to the invitation.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
An administrator of <%= @guest_membership.site.domain %> has removed you as a member. You won't be able to see the stats anymore.
|
||||
An administrator of {@guest_membership.site.domain} has removed you as a member. You won't be able to see the stats anymore.
|
||||
<br /><br />
|
||||
<a href={Routes.site_url(PlausibleWeb.Endpoint, :index)}>Click here</a>
|
||||
to view your sites.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
You signed up for a free 30-day trial of Plausible, a simple and privacy-friendly website analytics tool.
|
||||
<br /><br />
|
||||
<% end %>
|
||||
To finish your setup for <%= @site.domain %>, review
|
||||
To finish your setup for {@site.domain}, review
|
||||
<a href={"#{plausible_url()}/#{URI.encode_www_form(@site.domain)}/installation"}>your installation</a> and start collecting visitor statistics.
|
||||
<br /><br />
|
||||
This Plausible script is 45 times smaller than Google Analytics script so you’ll have a fast loading site while getting all the important traffic insights on one single page.
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
There are currently <%= @current_visitors %> visitors on
|
||||
There are currently {@current_visitors} visitors on
|
||||
<a href={"https://" <> @site.domain}><%= @site.domain %></a>.
|
||||
<%= if Enum.count(@sources) > 0 do %>
|
||||
<br />
|
||||
<br /> The top sources for current visitors:<br />
|
||||
<%= for %{name: source, count: visitors} <- @sources do %>
|
||||
<%= source %> - <%= visitors %> visitor<%= if visitors > 1, do: "s" %><br />
|
||||
{source} - {visitors} visitor{if visitors > 1, do: "s"}<br />
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<%= if @link do %>
|
||||
<br /><br /> View dashboard: <a href={@link}><%= @link %></a>
|
||||
<br /><br /> View dashboard: <a href={@link}>{@link}</a>
|
||||
<% end %>
|
||||
<br /><br /> Congrats on the spike in traffic!
|
||||
<%= if Plausible.ce? do %>
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
<%= @invitee_email %> has accepted your invitation to "<%= @team.name %>" team.
|
||||
{@invitee_email} has accepted your invitation to "{@team.name}" team.
|
||||
<a href={Routes.settings_url(PlausibleWeb.Endpoint, :team_general)}>Click here</a> to view team settings.
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
<%= @team_invitation.email %> has rejected your invitation to \"<%= @team_invitation.team.name %>\" team.
|
||||
{@team_invitation.email} has rejected your invitation to \"{@team_invitation.team.name}\" team.
|
||||
<a href={Routes.settings_url(PlausibleWeb.Endpoint, :team_general)}>Click here</a> to view team settings.
|
||||
|
|
|
|||
|
|
@ -4,5 +4,4 @@ Your free Plausible trial has now expired. Upgrade your account to continue rece
|
|||
<a href={PlausibleWeb.Router.Helpers.billing_url(PlausibleWeb.Endpoint, :choose_plan)}>
|
||||
Upgrade now
|
||||
</a>
|
||||
<br /><br />
|
||||
We will keep recording stats for <%= @extra_offset %> days to give you time to upgrade.
|
||||
<br /><br /> We will keep recording stats for {@extra_offset} days to give you time to upgrade.
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
Thanks for exploring Plausible, a simple and privacy-friendly alternative to Google Analytics. Your free 30-day trial is ending <%= @day %>, but you can keep using Plausible by upgrading to a paid plan.
|
||||
Thanks for exploring Plausible, a simple and privacy-friendly alternative to Google Analytics. Your free 30-day trial is ending {@day}, but you can keep using Plausible by upgrading to a paid plan.
|
||||
<br /><br />
|
||||
In the last month, your account has used <%= PlausibleWeb.AuthView.delimit_integer(@usage) %> billable pageviews<%= if @custom_events >
|
||||
0,
|
||||
do:
|
||||
" and custom events in total",
|
||||
else:
|
||||
"" %>.
|
||||
In the last month, your account has used {PlausibleWeb.AuthView.delimit_integer(@usage)} billable pageviews{if @custom_events >
|
||||
0,
|
||||
do:
|
||||
" and custom events in total",
|
||||
else:
|
||||
""}.
|
||||
<%= if @suggested_plan == :enterprise do %>
|
||||
This is more than our standard plans, so please reply back to this email to get a quote for your volume.
|
||||
<% else %>
|
||||
Based on that we recommend you select a <%= @suggested_plan.volume %>/mo plan. <br /><br />
|
||||
Based on that we recommend you select a {@suggested_plan.volume}/mo plan. <br /><br />
|
||||
<a href={PlausibleWeb.Router.Helpers.billing_url(PlausibleWeb.Endpoint, :choose_plan)}>
|
||||
Upgrade now
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Time flies! This is a reminder that your annual subscription for <%= Plausible.product_name() %> will expire on <%= @next_bill_date %>.
|
||||
Time flies! This is a reminder that your annual subscription for {Plausible.product_name()} will expire on {@next_bill_date}.
|
||||
<br /><br /> You need to
|
||||
<a href={PlausibleWeb.Router.Helpers.billing_url(PlausibleWeb.Endpoint, :choose_plan)}>renew your subscription</a> if you want to continue using Plausible to count your website stats in a privacy-friendly way.
|
||||
<br /><br />
|
||||
If you don't want to continue your subscription, there's no action required. You will lose access to your dashboard on <%= @next_bill_date %> and we'll stop accepting stats on <%= @accept_traffic_until %>.
|
||||
If you don't want to continue your subscription, there's no action required. You will lose access to your dashboard on {@next_bill_date} and we'll stop accepting stats on {@accept_traffic_until}.
|
||||
<br /><br />
|
||||
Have a question, feedback or need some guidance? Just reply to this email to get in touch!
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Time flies! This is a reminder that your annual subscription for <%= Plausible.product_name() %> is due to renew on <%= @date %>. We will automatically charge <%= PlausibleWeb.BillingView.present_currency(
|
||||
Time flies! This is a reminder that your annual subscription for {Plausible.product_name()} is due to renew on {@date}. We will automatically charge {PlausibleWeb.BillingView.present_currency(
|
||||
@currency
|
||||
) %><%= @next_bill_amount %> from your preferred billing method. <br /><br />
|
||||
)}{@next_bill_amount} from your preferred billing method. <br /><br />
|
||||
There's no action required if you're happy to continue using Plausible to count your website stats in a privacy-friendly way.
|
||||
<br /><br /> If you don't want to continue your subscription, you can cancel it on your
|
||||
<a href={"#{plausible_url()}/settings"}>account settings page</a>. <br /><br />
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div class="container flex flex-col items-center text-center mt-24">
|
||||
<h1 class="text-5xl font-black dark:text-gray-100"><%= @status %></h1>
|
||||
<h1 class="text-5xl font-black dark:text-gray-100">{@status}</h1>
|
||||
<div class="mt-4 text-xl dark:text-gray-100">Oops! There's nothing here</div>
|
||||
<div class="text-xl dark:text-gray-100">
|
||||
Trying to access your dashboard? You may need to log in again to see it
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div class="container text-center mt-24">
|
||||
<h1 class="text-5xl font-black dark:text-gray-100"><%= @status %></h1>
|
||||
<div class="my-4 text-xl dark:text-gray-100"><%= @message %></div>
|
||||
<h1 class="text-5xl font-black dark:text-gray-100">{@status}</h1>
|
||||
<div class="my-4 text-xl dark:text-gray-100">{@message}</div>
|
||||
<.button_link href={PlausibleWeb.LayoutView.home_dest(@conn)}>Go to homepage</.button_link>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
<div class="mt-6">
|
||||
<.label for={f[:property].id}>Google Analytics property</.label>
|
||||
<span class="block w-full text-base dark:text-gray-100 sm:text-sm dark:bg-gray-800">
|
||||
<%= @selected_property_name %>
|
||||
{@selected_property_name}
|
||||
</span>
|
||||
<.input type="hidden" value={@selected_property} field={f[:property]} readonly="true" />
|
||||
</div>
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
<div class="w-36">
|
||||
<.label for={f[:start_date].id}>From</.label>
|
||||
<span class="block w-full text-base dark:text-gray-100 sm:text-sm dark:bg-gray-800">
|
||||
<%= PlausibleWeb.EmailView.date_format(@start_date) %>
|
||||
{PlausibleWeb.EmailView.date_format(@start_date)}
|
||||
</span>
|
||||
<.input type="hidden" value={@start_date} field={f[:start_date]} readonly="true" />
|
||||
</div>
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
<div class="w-36">
|
||||
<.label for={f[:end_date].id}>To</.label>
|
||||
<span class="block w-full text-base dark:text-gray-100 sm:text-sm dark:bg-gray-800">
|
||||
<%= PlausibleWeb.EmailView.date_format(@end_date) %>
|
||||
{PlausibleWeb.EmailView.date_format(@end_date)}
|
||||
</span>
|
||||
<.input type="hidden" value={@end_date} field={f[:end_date]} readonly="true" />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
</:title>
|
||||
|
||||
<:subtitle>
|
||||
Choose the property in your Google Analytics account that will be imported to the <%= @site.domain %> dashboard.
|
||||
Choose the property in your Google Analytics account that will be imported to the {@site.domain} dashboard.
|
||||
</:subtitle>
|
||||
<.form
|
||||
:let={f}
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
/>
|
||||
|
||||
<p class="text-red-600 dark:text-red-700">
|
||||
<%= @conn.assigns[:selected_property_error] %>
|
||||
{@conn.assigns[:selected_property_error]}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@
|
|||
</div>
|
||||
<div class="ml-3 w-0 flex-1 pt-0.5">
|
||||
<p class="text-sm leading-5 font-medium text-gray-900 dark:text-gray-100">
|
||||
<%= Phoenix.Flash.get(@flash, :success_title) || "Success!" %>
|
||||
{Phoenix.Flash.get(@flash, :success_title) || "Success!"}
|
||||
</p>
|
||||
<p class="mt-1 text-sm leading-5 text-gray-500 dark:text-gray-200">
|
||||
<%= Phoenix.Flash.get(@flash, :success) %>
|
||||
{Phoenix.Flash.get(@flash, :success)}
|
||||
</p>
|
||||
</div>
|
||||
<div class="ml-4 flex-shrink-0 flex">
|
||||
|
|
@ -102,10 +102,10 @@
|
|||
</div>
|
||||
<div class="ml-3 w-0 flex-1 pt-0.5">
|
||||
<p class="text-sm leading-5 font-medium text-gray-900 dark:text-gray-100">
|
||||
<%= Phoenix.Flash.get(@flash, :error_title) || "Error" %>
|
||||
{Phoenix.Flash.get(@flash, :error_title) || "Error"}
|
||||
</p>
|
||||
<p class="mt-1 text-sm leading-5 text-gray-500 dark:text-gray-200">
|
||||
<%= Phoenix.Flash.get(@flash, :error) %>
|
||||
{Phoenix.Flash.get(@flash, :error)}
|
||||
</p>
|
||||
</div>
|
||||
<div class="ml-4 flex-shrink-0 flex">
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue