Migrating amplitude and crisp plugin/composable

This commit is contained in:
Julien Nahum 2023-12-09 16:33:56 +01:00
parent 1f853e8178
commit 12778fad34
8 changed files with 72 additions and 51 deletions

View File

@ -1,6 +1,5 @@
<template> <template>
<div id="app" class="bg-white dark:bg-notion-dark"> <div id="app" class="bg-white dark:bg-notion-dark">
<ServiceCrisp/>
<transition enter-active-class="linear duration-200 overflow-hidden" <transition enter-active-class="linear duration-200 overflow-hidden"
enter-from-class="max-h-0" enter-from-class="max-h-0"
enter-to-class="max-h-screen" enter-to-class="max-h-screen"
@ -45,12 +44,17 @@ export default {
setup() { setup() {
const appStore = useAppStore() const appStore = useAppStore()
return { return {
layout: computed(() => appStore.layout), layout: computed(() => appStore.layout),
isIframe: useIsIframe() isIframe: useIsIframe()
} }
}, },
mounted() {
useCrisp().showChat()
},
data: () => ({ data: () => ({
metaTitle: 'OpnForm', metaTitle: 'OpnForm',
metaDescription: 'Create beautiful forms for free. Unlimited fields, unlimited submissions. It\'s free and it takes less than 1 minute to create your first form.', metaDescription: 'Create beautiful forms for free. Unlimited fields, unlimited submissions. It\'s free and it takes less than 1 minute to create your first form.',

View File

@ -28,7 +28,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
@import "styles.css"; @import "vue-notion/src/styles.css";
.notion-blue { .notion-blue {
@apply text-nt-blue; @apply text-nt-blue;

View File

@ -1,32 +0,0 @@
<template />
<script>
export default {
name: 'Crisp',
setup () {
return {
isIframe: useIsIframe()
}
},
mounted () {
this.loadCrisp()
},
methods: {
loadCrisp () {
if (process.server) return
if (this.isIframe || !this.$config.crisp_website_id) return
window.CRISP_WEBSITE_ID = this.$config.crisp_website_id
const script = document.createElement('script')
script.setAttribute('src', 'https://client.crisp.chat/l.js')
script.setAttribute('id', 'crisp-widget')
script.setAttribute('async', 1)
document.head.appendChild(script)
}
}
}
</script>

View File

@ -1,46 +1,72 @@
export const useCrisp = () => { export const useCrisp = () => {
function push(args) { let crisp = process.client ? window.Crisp : null
if (process.client) {
window.$crisp.push(args)
}
}
function openChat() { function openChat() {
push(['do', 'chat:open']) if (!crisp) return
crisp.chat.open()
} }
function showChat() { function showChat() {
push(['do', 'chat:show']) if (!crisp) return
crisp.chat.show()
} }
function hideChat() { function hideChat() {
push(['do', 'chat:hide']) if (!crisp) return
crisp.chat.hide()
} }
function closeChat() { function closeChat() {
push(['do', 'chat:close']) if (!crisp) return
crisp.chat.close()
} }
function openAndShowChat(message = null) { function openAndShowChat(message = null) {
if (!crisp) return
showChat() showChat()
openChat() openChat()
if (message) sendTextMessage(message) if (message) sendTextMessage(message)
} }
function openHelpdesk(){ function openHelpdesk(){
push(['do', 'helpdesk:search']) if (!crisp) return
openChat()
crisp.chat.setHelpdeskView()
} }
function openHelpdeskArticle(articleSlug, lang = 'en') { function openHelpdeskArticle(articleSlug, locale = 'en') {
push(['do', 'helpdesk:article:open', [lang, articleSlug]]) if (!crisp) return
crisp.chat.openHelpdeskArticle(locale, articleSlug);
} }
function sendTextMessage(message) { function sendTextMessage(message) {
push(['do', 'message:send', ['text',message]]) if (!crisp) return
crisp.message.send('text', message)
}
function setUser (user) {
if (!crisp) return
crisp.user.setEmail(user.email);
crisp.user.setNickname(user.name);
crisp.session.setData({
user_id : user.id,
'pro-subscription' : user?.is_subscribed ?? false,
'stripe-id' : user?.stripe_id ?? '',
'subscription' : user?.has_enterprise_subscription ? 'enterprise' : 'pro'
});
if (user?.is_subscribed ?? false) {
setSegments([['subscribed', user?.has_enterprise_subscription ? 'enterprise' : 'pro']])
}
}
function setSegments(segments, overwrite = false) {
if (!crisp) return
crisp.session.setSegments(segments, overwrite)
} }
return { return {
push, crisp,
openChat, openChat,
showChat, showChat,
hideChat, hideChat,
@ -48,6 +74,7 @@ export const useCrisp = () => {
openAndShowChat, openAndShowChat,
openHelpdesk, openHelpdesk,
openHelpdeskArticle, openHelpdeskArticle,
sendTextMessage sendTextMessage,
setUser
} }
} }

10
client/plugins/crisp.client.js vendored Normal file
View File

@ -0,0 +1,10 @@
import {Crisp} from "crisp-sdk-web"
import config from "~/opnform.config.js";
export default defineNuxtPlugin(nuxtApp => {
const isIframe = useIsIframe()
if (config.crisp_website_id && !isIframe) {
Crisp.configure(config.crisp_website_id)
window.Crisp = Crisp
}
});

View File

@ -38,6 +38,7 @@ export const useAuthStore = defineStore('auth', {
try { try {
const { data } = await axios.get('/api/user') const { data } = await axios.get('/api/user')
this.user = data this.user = data
this.initServiceClients()
return data return data
} catch (e) { } catch (e) {
@ -50,7 +51,11 @@ export const useAuthStore = defineStore('auth', {
this.user = payload this.user = payload
}, },
load initServiceClients() {
if (!this.user) return
useAmplitude().setUser(this.user)
useCrisp().setUser(this.user)
},
async logout () { async logout () {
try { try {

6
package-lock.json generated
View File

@ -16,6 +16,7 @@
"axios": "^0.21.1", "axios": "^0.21.1",
"chart.js": "^4.4.0", "chart.js": "^4.4.0",
"clone-deep": "^4.0.1", "clone-deep": "^4.0.1",
"crisp-sdk-web": "^1.0.21",
"date-fns": "^2.28.0", "date-fns": "^2.28.0",
"debounce": "^1.2.1", "debounce": "^1.2.1",
"fuse.js": "^6.4.6", "fuse.js": "^6.4.6",
@ -5139,6 +5140,11 @@
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
"dev": true "dev": true
}, },
"node_modules/crisp-sdk-web": {
"version": "1.0.21",
"resolved": "https://registry.npmjs.org/crisp-sdk-web/-/crisp-sdk-web-1.0.21.tgz",
"integrity": "sha512-jNF/zSSA0lsAWT3q4JLG6YxtMRvgai++PwesxEL2Zm6utZaN+AoWPAH01QTfjJC/c++nFT7YM56ucdi+Y5yP4A=="
},
"node_modules/cross-env": { "node_modules/cross-env": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",

View File

@ -17,6 +17,7 @@
"axios": "^0.21.1", "axios": "^0.21.1",
"chart.js": "^4.4.0", "chart.js": "^4.4.0",
"clone-deep": "^4.0.1", "clone-deep": "^4.0.1",
"crisp-sdk-web": "^1.0.21",
"date-fns": "^2.28.0", "date-fns": "^2.28.0",
"debounce": "^1.2.1", "debounce": "^1.2.1",
"fuse.js": "^6.4.6", "fuse.js": "^6.4.6",
@ -36,8 +37,8 @@
"vue-country-flag-next": "^2.3.2", "vue-country-flag-next": "^2.3.2",
"vue-i18n": "^8.25.0", "vue-i18n": "^8.25.0",
"vue-meta": "^3.0.0-alpha.2", "vue-meta": "^3.0.0-alpha.2",
"vue-router": "^4.2.5",
"vue-notion": "^3.0.0-beta.1", "vue-notion": "^3.0.0-beta.1",
"vue-router": "^4.2.5",
"vue-signature-pad": "^3.0.2", "vue-signature-pad": "^3.0.2",
"vue3-editor": "^0.1.1", "vue3-editor": "^0.1.1",
"vue3-vt-notifications": "^1.0.0", "vue3-vt-notifications": "^1.0.0",