This commit is contained in:
Uku Taht 2020-11-06 13:30:38 +02:00
parent 0e667baaa9
commit d046773328
9 changed files with 286 additions and 39 deletions

View File

@ -7,15 +7,19 @@
@import "tooltip.css"; @import "tooltip.css";
.button { .button {
@apply inline-block bg-indigo-600 text-white text-center font-bold tracking-wide py-2 px-5 rounded no-underline; @apply bg-indigo-600 border border-transparent rounded-md py-2 px-4 inline-flex justify-center text-sm leading-5 font-medium text-white transition-all duration-150 ease-in-out;
} }
.button:hover { .button:hover {
@apply shadow; @apply bg-gray-700;
} }
.button:focus { .button:focus {
@apply outline-none; @apply outline-none border-gray-900 shadow-outline-gray;
}
.button:active {
@apply bg-gray-900;
} }
.button-outline { .button-outline {

View File

@ -1160,11 +1160,6 @@
"postcss-selector-parser": "^6.0.2" "postcss-selector-parser": "^6.0.2"
} }
}, },
"@types/color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ=="
},
"@types/d3": { "@types/d3": {
"version": "3.5.38", "version": "3.5.38",
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.38.tgz", "resolved": "https://registry.npmjs.org/@types/d3/-/d3-3.5.38.tgz",
@ -1369,9 +1364,9 @@
}, },
"dependencies": { "dependencies": {
"acorn": { "acorn": {
"version": "7.4.0", "version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
"integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==" "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
} }
} }
}, },
@ -4159,6 +4154,11 @@
"resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
"integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ=="
}, },
"html-tags": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz",
"integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg=="
},
"https-browserify": { "https-browserify": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
@ -5081,6 +5081,11 @@
} }
} }
}, },
"object-hash": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.0.3.tgz",
"integrity": "sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg=="
},
"object-inspect": { "object-inspect": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz",
@ -7108,7 +7113,7 @@
}, },
"pretty-hrtime": { "pretty-hrtime": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "http://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
"integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE="
}, },
"process": { "process": {
@ -8193,9 +8198,9 @@
} }
}, },
"tailwindcss": { "tailwindcss": {
"version": "1.6.2", "version": "1.9.6",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-1.6.2.tgz", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-1.9.6.tgz",
"integrity": "sha512-Cpa0kElG8Sg5sJSvTYi2frmIQZq0w37RLNNrYyy/W6HIWKspqSdTfb9tIN6X1gm4KV5a+TE/n7EKmn5Q9C7EUQ==", "integrity": "sha512-nY8WYM/RLPqGsPEGEV2z63riyQPcHYZUJpAwdyBzVpxQHOHqHE+F/fvbCeXhdF1+TA5l72vSkZrtYCB9hRcwkQ==",
"requires": { "requires": {
"@fullhuman/postcss-purgecss": "^2.1.2", "@fullhuman/postcss-purgecss": "^2.1.2",
"autoprefixer": "^9.4.5", "autoprefixer": "^9.4.5",
@ -8205,43 +8210,46 @@
"color": "^3.1.2", "color": "^3.1.2",
"detective": "^5.2.0", "detective": "^5.2.0",
"fs-extra": "^8.0.0", "fs-extra": "^8.0.0",
"lodash": "^4.17.15", "html-tags": "^3.1.0",
"lodash": "^4.17.20",
"node-emoji": "^1.8.1", "node-emoji": "^1.8.1",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"object-hash": "^2.0.3",
"postcss": "^7.0.11", "postcss": "^7.0.11",
"postcss-functions": "^3.0.0", "postcss-functions": "^3.0.0",
"postcss-js": "^2.0.0", "postcss-js": "^2.0.0",
"postcss-nested": "^4.1.1", "postcss-nested": "^4.1.1",
"postcss-selector-parser": "^6.0.0", "postcss-selector-parser": "^6.0.0",
"postcss-value-parser": "^4.1.0",
"pretty-hrtime": "^1.0.3", "pretty-hrtime": "^1.0.3",
"reduce-css-calc": "^2.1.6", "reduce-css-calc": "^2.1.6",
"resolve": "^1.14.2" "resolve": "^1.14.2"
}, },
"dependencies": { "dependencies": {
"ansi-styles": { "ansi-styles": {
"version": "4.2.1", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": { "requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1" "color-convert": "^2.0.1"
} }
}, },
"browserslist": { "browserslist": {
"version": "4.14.0", "version": "4.14.7",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.0.tgz", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.14.7.tgz",
"integrity": "sha512-pUsXKAF2lVwhmtpeA3LJrZ76jXuusrNyhduuQs7CDFf9foT4Y38aQOserd2lMe5DSSrjf3fx34oHwryuvxAUgQ==", "integrity": "sha512-BSVRLCeG3Xt/j/1cCGj1019Wbty0H+Yvu2AOuZSuoaUWn3RatbL33Cxk+Q4jRMRAbOm0p7SLravLjpnT6s0vzQ==",
"requires": { "requires": {
"caniuse-lite": "^1.0.30001111", "caniuse-lite": "^1.0.30001157",
"electron-to-chromium": "^1.3.523", "colorette": "^1.2.1",
"escalade": "^3.0.2", "electron-to-chromium": "^1.3.591",
"node-releases": "^1.1.60" "escalade": "^3.1.1",
"node-releases": "^1.1.66"
} }
}, },
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001114", "version": "1.0.30001157",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001114.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001157.tgz",
"integrity": "sha512-ml/zTsfNBM+T1+mjglWRPgVsu2L76GAaADKX5f4t0pbhttEp0WMawJsHDYlFkVZkoA+89uvBRrVrEE4oqenzXQ==" "integrity": "sha512-gOerH9Wz2IRZ2ZPdMfBvyOi3cjaz4O4dgNwPGzx8EhqAs4+2IL/O+fJsbt+znSigujoZG8bVcIAUM/I/E5K3MA=="
}, },
"chalk": { "chalk": {
"version": "4.1.0", "version": "4.1.0",
@ -8265,20 +8273,40 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
}, },
"electron-to-chromium": {
"version": "1.3.593",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.593.tgz",
"integrity": "sha512-GvO7G1ZxvffnMvPCr4A7+iQPVuvpyqMrx2VWSERAjG+pHK6tmO9XqYdBfMIq9corRyi4bNImSDEiDvIoDb8HrA=="
},
"escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
},
"has-flag": { "has-flag": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
}, },
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
},
"node-releases": { "node-releases": {
"version": "1.1.60", "version": "1.1.66",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.60.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.66.tgz",
"integrity": "sha512-gsO4vjEdQaTusZAEebUWp2a5d7dF5DYoIpDG7WySnk7BuZDW+GPpHXoXXuYawRBr/9t5q54tirPz79kFIWg4dA==" "integrity": "sha512-JHEQ1iWPGK+38VLB2H9ef2otU4l8s3yAMt9Xf934r6+ojCYDMHPMqvCc9TnzfeFSP1QEOeU6YZEd3+De0LTCgg=="
},
"postcss-value-parser": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ=="
}, },
"supports-color": { "supports-color": {
"version": "7.1.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": { "requires": {
"has-flag": "^4.0.0" "has-flag": "^4.0.0"
} }

View File

@ -29,7 +29,7 @@
"react-flip-move": "^3.0.4", "react-flip-move": "^3.0.4",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-transition-group": "^4.4.1", "react-transition-group": "^4.4.1",
"tailwindcss": "^1.6.2", "tailwindcss": "^1.9.6",
"uglifyjs-webpack-plugin": "^2.2.0", "uglifyjs-webpack-plugin": "^2.2.0",
"url-search-params-polyfill": "^8.0.0", "url-search-params-polyfill": "^8.0.0",
"webpack": "4.39.2", "webpack": "4.39.2",

View File

@ -87,6 +87,10 @@ defmodule PlausibleWeb.SiteController do
end end
def settings(conn, %{"website" => website}) do def settings(conn, %{"website" => website}) do
redirect(conn, to: "/#{URI.encode_www_form(website)}/settings/general")
end
def settings_general(conn, %{"website" => website}) do
site = site =
Sites.get_for_user!(conn.assigns[:current_user].id, website) Sites.get_for_user!(conn.assigns[:current_user].id, website)
|> Repo.preload(:google_auth) |> Repo.preload(:google_auth)
@ -99,8 +103,8 @@ defmodule PlausibleWeb.SiteController do
weekly_report = Repo.get_by(Plausible.Site.WeeklyReport, site_id: site.id) weekly_report = Repo.get_by(Plausible.Site.WeeklyReport, site_id: site.id)
monthly_report = Repo.get_by(Plausible.Site.MonthlyReport, site_id: site.id) monthly_report = Repo.get_by(Plausible.Site.MonthlyReport, site_id: site.id)
goals = Goals.for_site(site.domain)
shared_links = Repo.all(from l in Plausible.Site.SharedLink, where: l.site_id == ^site.id) shared_links = Repo.all(from l in Plausible.Site.SharedLink, where: l.site_id == ^site.id)
goals = Goals.for_site(site.domain)
conn conn
|> assign(:skip_plausible_tracking, true) |> assign(:skip_plausible_tracking, true)
@ -115,6 +119,18 @@ defmodule PlausibleWeb.SiteController do
) )
end end
def settings_goals(conn, %{"website" => website}) do
site = Sites.get_for_user!(conn.assigns[:current_user].id, website)
goals = Goals.for_site(site.domain)
conn
|> assign(:skip_plausible_tracking, true)
|> render("settings_goals.html",
site: site,
goals: goals
)
end
def update_google_auth(conn, %{"website" => website, "google_auth" => attrs}) do def update_google_auth(conn, %{"website" => website, "google_auth" => attrs}) do
site = site =
Sites.get_for_user!(conn.assigns[:current_user].id, website) Sites.get_for_user!(conn.assigns[:current_user].id, website)

View File

@ -145,7 +145,8 @@ defmodule PlausibleWeb.Router do
get "/:website/snippet", SiteController, :add_snippet get "/:website/snippet", SiteController, :add_snippet
get "/:website/settings", SiteController, :settings get "/:website/settings", SiteController, :settings
get "/:website/goals", SiteController, :goals get "/:website/settings/general", SiteController, :settings_general
get "/:website/settings/goals", SiteController, :settings_goals
get "/:website/goals/new", SiteController, :new_goal get "/:website/goals/new", SiteController, :new_goal
post "/:website/goals", SiteController, :create_goal post "/:website/goals", SiteController, :create_goal
delete "/:website/goals/:id", SiteController, :delete_goal delete "/:website/goals/:id", SiteController, :delete_goal

View File

@ -0,0 +1,5 @@
<%= if @current_tab == @this_tab do %>
<a href="/<%= URI.encode_www_form(@site.domain) %>/settings/<%= @this_tab %>" class="flex items-center px-3 py-2 text-sm leading-5 font-medium text-gray-900 rounded-md bg-gray-100 hover:text-gray-900 hover:bg-gray-100 focus:outline-none focus:bg-gray-200 transition ease-in-out duration-150 <%= if @this_tab != "general", do: "mt-1" %>"><%= @text %></a>
<% else %>
<a href="/<%= URI.encode_www_form(@site.domain) %>/settings/<%= @this_tab %>" class="flex items-center px-3 py-2 text-sm leading-5 font-medium text-gray-600 rounded-md hover:text-gray-900 hover:bg-gray-50 focus:outline-none focus:text-gray-900 focus:bg-gray-50 transition ease-in-out duration-150 <%= if @this_tab != "general", do: "mt-1" %>"><%= @text %></a>
<% end %>

View File

@ -1,3 +1,140 @@
<div class="container">
<div class="lg:grid lg:grid-cols-12 lg:gap-x-5 mt-6">
<%= render("settings_header.html", tab: "general", site: @site) %>
<div class="space-y-6 sm:px-6 lg:px-0 lg:col-span-9">
<%= form_for @changeset, "/#{URI.encode_www_form(@site.domain)}/settings", fn f -> %>
<div class="shadow sm:rounded-md sm:overflow-hidden">
<div class="bg-white py-6 px-4 space-y-6 sm:p-6">
<div>
<h2 class="text-lg leading-6 font-medium text-gray-900">General information</h2>
<p class="mt-1 text-sm leading-5 text-gray-500">Update your billing information. Please note that updating your location could affect your tax rates.</p>
</div>
<div class="grid grid-cols-4 gap-6">
<div class="col-span-4 sm:col-span-2">
<%= label f, :domain, class: "block text-sm font-medium leading-5 text-gray-700" %>
<%= text_input f, :domain, class: "form-input mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 transition duration-150 ease-in-out sm:text-sm sm:leading-5", disabled: "disabled" %>
</div>
<div class="col-span-4 sm:col-span-2">
<%= label f, :timezone, "Reporting Timezone", class: "block text-sm font-medium leading-5 text-gray-700" %>
<%= select f, :timezone, Plausible.Timezones.options(), class: "form-select mt-1 block w-full bg-white border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 transition duration-150 ease-in-out sm:text-sm sm:leading-5" %>
</div>
</div>
</div>
<div class="px-4 py-3 bg-gray-50 text-right sm:px-6">
<span class="inline-flex rounded-md shadow-sm">
<%= submit "Save", class: "bg-indigo-600 border border-transparent rounded-md py-2 px-4 inline-flex justify-center text-sm leading-5 font-medium text-white hover:bg-gray-700 focus:outline-none focus:border-gray-900 focus:shadow-outline-gray active:bg-gray-900 transition duration-150 ease-in-out" %>
</span>
</div>
</div>
<% end %>
<div class="shadow bg-white sm:rounded-md sm:overflow-hidden mt-12 py-6 px-4 sm:p-6">
<div>
<h2 class="text-lg leading-6 font-medium text-gray-900">Dashboard visibility</h2>
<p class="mt-1 text-sm leading-5 text-gray-500">Share your stats publicly or keep them private</p>
</div>
<fieldset class="mt-6">
<div class="bg-white rounded-md -space-y-px">
<!-- On: "bg-indigo-50 border-indigo-200 z-10", Off: "border-gray-200" -->
<div class="relative border rounded-tl-md rounded-tr-md p-4 flex">
<div class="flex items-center h-5">
<input id="settings-option-0" name="privacy_setting" type="radio" class="form-radio h-4 w-4 text-indigo-600 transition duration-150 ease-in-out cursor-pointer" checked>
</div>
<label for="settings-option-0" class="ml-3 flex flex-col cursor-pointer">
<!-- On: "text-indigo-900", Off: "text-gray-900" -->
<span class="block text-sm leading-5 font-medium">
Public
</span>
<!-- On: "text-indigo-700", Off: "text-gray-500" -->
<span class="block text-sm leading-5">
Make your dashboard publicly accessible on <a class="text-indigo-600" target="_blank">https://plausible.io/plausible.io</a>
</span>
</label>
</div>
<!-- On: "bg-indigo-50 border-indigo-200 z-10", Off: "border-gray-200" -->
<div class="relative border border-gray-200 p-4 flex">
<div class="flex items-center h-5">
<input id="settings-option-1" name="privacy_setting" type="radio" class="form-radio h-4 w-4 text-indigo-600 transition duration-150 ease-in-out cursor-pointer">
</div>
<label for="settings-option-1" class="ml-3 flex flex-col cursor-pointer">
<!-- On: "text-indigo-900", Off: "text-gray-900" -->
<span class="block text-sm leading-5 font-medium">
Private
</span>
<!-- On: "text-indigo-700", Off: "text-gray-500" -->
<span class="block text-sm leading-5">
Only you can see the dashboard
</span>
</label>
</div>
</div>
</fieldset>
<div class="mt-6">
<div>
<h2 class="text-lg leading-6 font-medium text-gray-900">Shared links</h2>
<p class="mt-1 text-sm leading-5 text-gray-500">You can share your stats privately by generating a shared link. The links are impossible to guess and you can add password protection for extra security.</p>
</div>
<div class="mt-6">
<%= for link <- @shared_links do %>
<div class="flex relative w-full max-w-xl mt-2 text-sm">
<input type="text" id="<%= link.slug %>" readonly="readonly" value="<%= shared_link_dest(link) %>" class="transition bg-gray-100 appearance-none border border-transparent rounded rounded-r-none w-full p-2 text-gray-700 appearance-none focus:outline-none focus:border-gray-300" />
<button onclick="var input = document.getElementById('<%= link.slug %>'); input.focus(); input.select(); document.execCommand('copy');" href="javascript:void(0)" class="py-2 px-4 bg-gray-100 text-indigo-800 rounded-none border-r border-gray-300">
<svg class="feather-sm" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>
</button>
<%= button(to: "/sites/#{URI.encode_www_form(@site.domain)}/shared-links/#{link.slug}", method: :delete, class: "py-2 px-4 bg-gray-100 text-red-600 rounded-l-none", data: [confirm: "Are you sure you want to delete this shared link? The stats will not be accessible with this link anymore."]) do %>
<svg class="feather feather-sm" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>
<% end %>
</div>
<% end %>
<%= link("+ New link", to: "/sites/#{URI.encode_www_form(@site.domain)}/shared-links/new", class: "button mt-4") %>
</div>
</div>
</div>
<div class="sm:rounded-md sm:overflow-hidden mt-12 border border-red-400">
<div class="bg-white py-6 px-4 space-y-6 sm:p-6">
<div>
<h2 class="text-lg leading-6 font-medium text-gray-900">Danger zone</h2>
<p class="mt-1 text-sm leading-5 text-gray-500">Desctructive actions below can result in irrecoverable data loss. Be careful.</p>
</div>
<li class="py-4 flex items-center justify-between space-x-4">
<div class="flex flex-col">
<p class="text-sm leading-5 font-medium text-gray-900">
Reset stats
</p>
<p class="text-sm leading-5 text-gray-500">
Removes all pageviews but keeps the site configuration
</p>
</div>
<%= link("Reset #{@site.domain} stats", to: "/#{URI.encode_www_form(@site.domain)}/stats", method: :delete, class: "inline-block px-4 py-2 border border-gray-300 text-sm leading-5 font-medium rounded-md text-red-700 bg-white hover:text-red-500 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:text-red-800 active:bg-gray-50 transition ease-in-out duration-150", data: [confirm: "Resetting the stats cannot be reversed. Are you sure?"]) %>
</li>
<div class="border-b border-gray-200"></div>
<li class="py-4 flex items-center justify-between space-x-4">
<div class="flex flex-col">
<p class="text-sm leading-5 font-medium text-gray-900">
Delete site
</p>
<p class="text-sm leading-5 text-gray-500">
Removes all stats along with the site configuration
</p>
</div>
<%= link "Delete #{@site.domain}", to: "/#{URI.encode_www_form(@site.domain)}", method: :delete, class: "inline-block px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-50 focus:outline-none focus:border-red-300 focus:shadow-outline-red active:bg-red-200 transition ease-in-out duration-150 sm:text-sm sm:leading-5", data: [confirm: "Deleting the site data cannot be reversed. Are you sure?"] %>
</li>
</div>
</div>
</div>
</div>
</div>
<div class="pt-12"></div> <div class="pt-12"></div>
<div class="max-w-xl mx-auto flex justify-between"> <div class="max-w-xl mx-auto flex justify-between">
<a href="/<%= URI.encode_www_form(@site.domain) %>"><h1 class="text-2xl font-black">Settings for <%= @site.domain %></h1></a> <a href="/<%= URI.encode_www_form(@site.domain) %>"><h1 class="text-2xl font-black">Settings for <%= @site.domain %></h1></a>

View File

@ -0,0 +1,31 @@
<div class="container">
<div class="lg:grid lg:grid-cols-12 lg:gap-x-5 mt-6">
<%= render("settings_header.html", tab: "goals", site: @site) %>
<div class="space-y-6 sm:px-6 lg:px-0 lg:col-span-9">
<div class="shadow bg-white sm:rounded-md sm:overflow-hidden py-6 px-4 sm:p-6">
<header>
<h2 class="text-lg leading-6 font-medium text-gray-900">Goals</h2>
<p class="mt-1 text-sm leading-5 text-gray-500">Define actions that you want your users to take like visiting a certain page, submitting a form, etc.</p>
</header>
<%= if Enum.count(@goals) > 0 do %>
<div class="mt-4">
<%= for goal <- @goals do %>
<div class="border-b border-gray-300 py-3 flex justify-between">
<span class="text-sm font-medium text-gray-900"><%= goal_name(goal) %></span>
<%= button(to: "/#{URI.encode_www_form(@site.domain)}/goals/#{goal.id}", method: :delete, class: "text-sm text-red-600", data: [confirm: "Are you sure you want to remove goal #{goal_name(goal)}? This will just affect the UI, all of your analytics data will stay intact."]) do %>
<svg class="feather feather-sm" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>
<% end %>
</div>
<% end %>
</div>
<% else %>
<div class="mt-4">No goals configured for this site yet</div>
<% end %>
<%= link("+ Add goal", to: "/#{URI.encode_www_form(@site.domain)}/goals/new", class: "button mt-6") %>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,25 @@
<div class="py-6 px-2 sm:px-6 lg:py-0 lg:px-0 lg:col-span-3">
<div class="lg:hidden">
<select class="mt-1 form-select block w-full pl-3 pr-10 py-2 text-base leading-6 border-gray-300 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 sm:text-sm sm:leading-5 transition ease-in-out duration-150">
<option selected>General</option>
<option>Password</option>
<option>Notifications</option>
<option>Plan</option>
<option>Billing</option>
<option>Team Members</option>
</select>
</div>
<div class="hidden lg:block">
<%= render("_settings_tab.html", current_tab: @tab, this_tab: "general", text: "General", site: @site) %>
<%= render("_settings_tab.html", current_tab: @tab, this_tab: "goals", text: "Goals", site: @site) %>
<%= render("_settings_tab.html", current_tab: @tab, this_tab: "search-console", text: "Search Console", site: @site) %>
<%= render("_settings_tab.html", current_tab: @tab, this_tab: "email-reports", text: "Email reports", site: @site) %>
<%= render("_settings_tab.html", current_tab: @tab, this_tab: "custom-domain", text: "Custom domain", site: @site) %>
<%= render("_settings_tab.html", current_tab: @tab, this_tab: "js-snippet", text: "JS snippet", site: @site) %>
</div>
</div>