Created
September 22, 2020 20:54
-
-
Save adriaandotcom/10981ed13f6966ff2666a3ac5874f798 to your computer and use it in GitHub Desktop.
Sales popup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
Shared because of this Tweet: https://twitter.com/iammarcthomas/status/1308507994334822400 | |
--> | |
<div | |
data-sales-vue | |
v-bind:class="[{ finished: isFinished }, 'sales-popup', 'box']" | |
> | |
<a v-if="!isFinished" class="close" v-on:click="onClose">×</a> | |
<h2 v-if="!isFinished"> | |
\{{ heading || (currentQuestion || questions[0]).question }} | |
</h2> | |
<p v-if="error" role="alert">\{{ error }}</p> | |
<div class="finished" v-if="isFinished"> | |
<svg | |
xmlns="http://www.w3.org/2000/svg" | |
width="100px" | |
height="100px" | |
viewBox="0 0 24 24" | |
> | |
<path | |
fill="var(--primary-color, #ff6600)" | |
d="M18 1l-6 4-6-4-6 5v7l12 10 12-10v-7z" | |
/> | |
</svg> | |
<p class="mb-0">Thank you</p> | |
</div> | |
<ul class="choices" v-else-if="!heading"> | |
<li | |
v-for="answer in (currentQuestion || questions[0]).answers" | |
:key="answer.slug" | |
v-on:click="choose((currentQuestion || questions[0]), answer)" | |
> | |
\{{ answer.text }} | |
</li> | |
</ul> | |
<form v-else v-on:submit.prevent="onSubmit"> | |
<input | |
class="mt-1" | |
type="email" | |
placeholder="Enter your email..." | |
autocomplete="username" | |
v-model="email" | |
/> | |
<input class="button" type="submit" value="Tell me more" /> | |
</form> | |
</div> | |
<script> | |
(function () { | |
var hideSalesPopup = | |
IS_ROBOT || getCookie("closed").indexOf("sales-popup") > -1; | |
if (hideSalesPopup) return; | |
var localhost = window.location.hostname === "localhost"; | |
var environment = localhost ? "development" : "production"; | |
var script = document.createElement("script"); | |
var isBelowTheFold = false; | |
var loaded = false; | |
var src = | |
"https://assets.simpleanalytics.com/libraries/vue-" + | |
environment + | |
"-2.6.10.js"; | |
script.crossorigin = "anonymous"; | |
script.integrity = localhost | |
? "" | |
: "sha384-8t+aLluUVnn5SPPG/NbeZCH6TWIvaXIm/gDbutRvtEeElzxxWaZN+G/ZIEdI/f+y"; | |
script.src = src; | |
script.onload = useVue; | |
document.body.appendChild(script); | |
var updateScrollPercentage = function () { | |
var heightOfWindow = window.innerHeight; | |
var contentScrolled = window.pageYOffset; | |
var bodyHeight = document.body.offsetHeight; | |
var total = bodyHeight - heightOfWindow; | |
var got = contentScrolled; | |
var percent = parseInt((got / total) * 100); | |
if (percent >= 25) { | |
isBelowTheFold = true; | |
window.removeEventListener("scroll", updateScrollPercentage, true); | |
useVue(); | |
} | |
}; | |
function setClosedCookie() { | |
var closed = (getCookie("closed") || "") | |
.split(",") | |
.filter(function (slug) { | |
return slug; | |
}); | |
closed.push("sales-popup"); | |
setCookie("closed", closed.join(","), 7); | |
} | |
updateScrollPercentage(); | |
window.addEventListener("scroll", updateScrollPercentage, true); | |
function useVue() { | |
if (!isBelowTheFold || typeof Vue === "undefined" || loaded) return; | |
loaded = true; | |
var element = document.querySelector("[data-sales-vue]"); | |
var event = function (event) { | |
if (typeof sa_event === "function") sa_event("sales_popup_" + event); | |
}; | |
var app = new Vue({ | |
el: element, | |
data: { | |
error: null, | |
isFinished: false, | |
currentQuestion: null, | |
heading: null, | |
email: "", | |
questions: [ | |
{ | |
slug: "main_reason", | |
question: | |
"What is the main reason that brought you to Simple Analytics?", | |
goTo: "replacing", | |
answer: null, | |
answers: [ | |
{ | |
slug: "privacy_laws", | |
text: "Privacy laws", | |
}, | |
{ | |
slug: "ethical", | |
text: "Ethical reasons", | |
}, | |
{ | |
slug: "cookie_free", | |
text: "No cookie banner", | |
}, | |
{ | |
slug: "ease_of_use", | |
text: "Ease of use", | |
}, | |
{ | |
slug: "other", | |
text: "Other", | |
}, | |
], | |
}, | |
{ | |
slug: "replacing", | |
question: "What tool you consider replacing?", | |
answer: null, | |
answers: [ | |
{ | |
slug: "google_analytics", | |
text: "Google Analytics", | |
}, | |
{ | |
slug: "matomo", | |
text: "Matomo", | |
}, | |
{ | |
slug: "clicky", | |
text: "Clicky", | |
}, | |
{ | |
slug: "fathom", | |
text: "Fathom", | |
}, | |
{ | |
slug: "none", | |
text: "None", | |
}, | |
{ | |
slug: "other", | |
text: "Other", | |
}, | |
], | |
}, | |
], | |
}, | |
methods: { | |
choose: function (question, answer) { | |
event("answer"); | |
event("answered_" + question.slug); | |
question.answer = answer; | |
var goTo = answer.goTo || question.goTo; | |
var found = goTo | |
? this.questions.find(function (item) { | |
return item.slug === goTo; | |
}) | |
: null; | |
if (found) return (this.currentQuestion = found); | |
this.askEmail(); | |
}, | |
askEmail: function () { | |
event("ask_email"); | |
var answers = this.questions.reduce(function (object, question) { | |
object[question.slug] = question.answer; | |
return object; | |
}, {}); | |
var reason = | |
answers.main_reason.slug === "other" | |
? null | |
: answers.main_reason.text; | |
var compares = | |
answers.replacing.slug === "none" | |
? null | |
: answers.replacing.slug === "other" | |
? "others" | |
: answers.replacing.text; | |
var text = | |
reason && compares | |
? "Learn how Simple Analytics handles " + | |
reason.toLowerCase() + | |
" and compares with " + | |
compares | |
: reason | |
? "Learn how Simple Analytics handles " + reason.toLowerCase() | |
: compares | |
? "Learn how Simple Analytics compares with " + compares | |
: null; | |
this.heading = | |
text || "Learn more about how Simple Analytics can help you"; | |
}, | |
onSubmit: function () { | |
event("submit"); | |
this.error = null; | |
var answers = this.questions.reduce(function (object, question) { | |
object[question.slug] = question.answer.slug; | |
return object; | |
}, {}); | |
var options = { | |
email: this.email, | |
type: "sales-popup", | |
answers, | |
}; | |
if (document.referrer) options.referrer = document.referrer; | |
var context = this; | |
postJSON("/subscribe", options, function (response) { | |
if (response.message) context.error = response.message; | |
else if (response.status < 400) context.isFinished = true; | |
else context.error = "Oops, something whent wrong"; | |
if (context.isFinished) setClosedCookie(); | |
}); | |
}, | |
onClose: function () { | |
event("close"); | |
setClosedCookie(); | |
this.isFinished = true; | |
}, | |
}, | |
mounted: function () { | |
event("show"); | |
var style = document.getElementById("sales-popup-style"); | |
style.parentNode.removeChild(style); | |
}, | |
}); | |
} | |
})(); | |
</script> | |
<style id="sales-popup-style"> | |
[data-sales-vue] { | |
display: none; | |
} | |
</style> | |
<style> | |
@keyframes fadeInUp { | |
from { | |
transform: translate3d(0, 100%, 0); | |
} | |
to { | |
transform: translate3d(0, 0, 0); | |
} | |
} | |
.sales-popup { | |
--background-color: white; | |
--option-background: var(--background-primary); | |
--option-background-hover: var(--background-block-alt); | |
--transform: translateY(0); | |
position: fixed; | |
background-color: var(--background-color); | |
transition: all var(--dark-mode-transition), transform 2s ease-in-out 2s; | |
width: 320px; | |
max-width: calc(100% - 3rem); | |
border: 1px solid var(--border-color); | |
border-color: var(--border-color); | |
padding: 2rem; | |
bottom: 0; | |
left: 1.5rem; | |
z-index: 100; | |
border-radius: 4px 4px 0 0; | |
animation-name: fadeInUp; | |
animation-duration: 1s; | |
color: var(--text-color); | |
transform: var(--transform); | |
} | |
.sales-popup::after { | |
content: ""; | |
position: absolute; | |
z-index: -1; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
border-radius: 4px 4px 0 0; | |
box-shadow: 0px 0px 10px 5px #20292a; | |
opacity: 0; | |
transition: opacity var(--dark-mode-transition); | |
} | |
html.dark .sales-popup { | |
--background-color: var(--background-primary); | |
--option-background: var(--background-secondary); | |
--option-background-hover: var(--background-block-alt); | |
} | |
html.dark .sales-popup::after { | |
opacity: 1; | |
} | |
.sales-popup.finished { | |
--transform: translateY(120%); | |
} | |
.sales-popup .close { | |
position: absolute; | |
display: block; | |
top: 0rem; | |
right: 0.2rem; | |
padding: 0.5rem; | |
line-height: 1; | |
font-size: 20px; | |
color: var(--icon-color); | |
} | |
.sales-popup h2 { | |
font-size: 16px !important; | |
margin: 0 !important; | |
} | |
.sales-popup .choices { | |
list-style-type: none; | |
padding: 0; | |
margin: 1rem 0 0 0; | |
} | |
.sales-popup .choices li { | |
margin: 0 0 0.5rem 0; | |
padding: 0.2rem 0; | |
display: block; | |
transition: all var(--dark-mode-transition); | |
cursor: pointer; | |
background-color: var(--option-background); | |
} | |
.sales-popup .choices li:last-of-type { | |
margin-bottom: 0; | |
} | |
.sales-popup .choices li:hover { | |
background-color: var(--option-background-hover); | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment