Enable pricing (#151)

* Enable Pro plan - WIP

* no pricing page if have no paid plans

* Set pricing ids in env

* views & submissions FREE for all

* extra param for env

* form password FREE for all

* Custom Code is PRO feature

* Replace codeinput prism with codemirror

* Better form Cleaning message

* Added risky user email spam protection

* fix form cleaning

* Pricing page new UI

* form cleaner

* Polish changes

* Fixed tests

---------

Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
formsdev
2023-08-30 13:28:29 +05:30
committed by GitHub
parent 29b153bd76
commit fb79a5bf3e
48 changed files with 1011 additions and 269 deletions

View File

@@ -49,23 +49,7 @@
</div>
</div>
<div v-if="getFormCleaningsMsg"
class="border shadow-sm p-2 my-4 flex items-center rounded-md bg-yellow-100 border-yellow-500"
>
<div class="flex-grow">
<p class="mb-0 py-2 px-4 text-yellow-600">
You're seeing this because you are an owner of this form. <br>
All your Pro features are de-activated when sharing this form: <br>
<span v-html="getFormCleaningsMsg" />
</p>
</div>
<div class="text-right">
<v-button color="yellow" shade="light" @click="form.cleanings=false">
Close
</v-button>
</div>
</div>
<form-cleanings v-if="!adminPreview" :hideable="true" class="mb-4 mx-2" :form="form" :specify-form-owner="true" />
<transition
v-if="!form.is_password_protected && (!isPublicFormPage || (!form.is_closed && !form.max_number_of_submissions_reached && form.visibility!='closed'))"
@@ -131,9 +115,10 @@ import { themes } from '~/config/form-themes.js'
import VButton from '../../common/Button.vue'
import VTransition from '../../common/transitions/VTransition.vue'
import FormPendingSubmissionKey from '../../../mixins/forms/form-pending-submission-key.js'
import FormCleanings from '../../pages/forms/show/FormCleanings.vue'
export default {
components: { VTransition, VButton, OpenFormButton, OpenForm },
components: { VTransition, VButton, OpenFormButton, OpenForm, FormCleanings },
props: {
form: { type: Object, required: true },
@@ -166,22 +151,6 @@ export default {
theme () {
return this.themes[this.themes.hasOwnProperty(this.form.theme) ? this.form.theme : 'default']
},
getFormCleaningsMsg () {
if (this.form.cleanings && Object.keys(this.form.cleanings).length > 0) {
let message = ''
Object.keys(this.form.cleanings).forEach((key) => {
const fieldName = key.charAt(0).toUpperCase() + key.slice(1)
let fieldInfo = '<br/>' + fieldName + "<br/><ul class='list-disc list-inside'>"
this.form.cleanings[key].forEach((msg) => {
fieldInfo = fieldInfo + '<li>' + msg + '</li>'
})
message = message + fieldInfo + '<ul/>'
})
return message
}
return false
},
isPublicFormPage () {
return this.$route.name === 'forms.show_public'
},

View File

@@ -7,8 +7,8 @@
<form v-else-if="dataForm" @submit.prevent="">
<transition name="fade" mode="out-in" appear>
<template v-for="group, groupIndex in fieldGroups">
<div v-if="currentFieldGroupIndex===groupIndex"
:key="groupIndex"
<div v-if="currentFieldGroupIndex===groupIndex"
:key="groupIndex"
class="form-group flex flex-wrap w-full">
<draggable v-model="currentFields"

View File

@@ -52,11 +52,6 @@
</p>
</template>
</div>
<!-- Field options -->
<!-- <div class="flex-grow" v-if="['files'].includes(field.type) || field.type.startsWith('nf-')">-->
<!-- <pro-tag/>-->
<!-- </div>-->
<template v-if="removing == field.id">
<div class="flex text-sm items-center">

View File

@@ -1,6 +1,6 @@
<template>
<div class="border border-nt-blue-light bg-blue-50 dark:bg-notion-dark-light rounded-md p-4 mb-5 w-full mx-auto mt-4 select-all">
<div v-if="!form.is_pro" class="relative">
<div v-if="false" class="relative">
<div class="absolute inset-0 z-10">
<div class="p-5 max-w-md mx-auto mt-5">
<p class="text-center">
@@ -102,7 +102,7 @@ export default {
},
methods: {
getChartData () {
if (!this.form || !this.form.is_pro) { return null }
if (!this.form) { return null }
this.isLoading = true
axios.get('/api/open/workspaces/' + this.form.workspace_id + '/form-stats/' + this.form.id).then((response) => {
const statsData = response.data

View File

@@ -21,8 +21,13 @@
/>
<toggle-switch-input name="editable_submissions" :form="form" class="mt-4"
label="Allow users to edit their submission"
/>
help="Gives user a unique url to update their submission"
>
<template #label>
Editable submissions
<pro-tag class="ml-1" />
</template>
</toggle-switch-input>
<text-input v-if="form.editable_submissions" name="editable_submissions_button_text"
:form="form"
label="Text of editable submissions button"
@@ -111,7 +116,6 @@
/>
</template>
<template v-else>
<pro-tag class="float-right"/>
<toggle-switch-input name="re_fillable" :form="form" class="mt-4"
label="Allow users to fill the form again"
/>

View File

@@ -12,10 +12,7 @@
</h3>
</template>
<p class="mt-4">
The code will be injected in the <span class="font-semibold">head</span> section of your form page. <a href="#" class="text-gray-500"
@click.prevent="$crisp.push(['do', 'helpdesk:article:open', ['en', 'how-to-inject-custom-code-in-my-form-1amadj3']])"
>Click
here to get an example CSS code.</a>
The code will be injected in the <span class="font-semibold">head</span> section of your form page.
</p>
<code-input name="custom_code" class="mt-4"
:form="form" help="Custom code cannot be previewed in our editor. Please test your code using

View File

@@ -10,7 +10,6 @@
</svg>
Customization
<pro-tag />
</h3>
</template>
@@ -62,9 +61,12 @@
<toggle-switch-input name="hide_title" :form="form" class="mt-4"
label="Hide Title"
/>
<toggle-switch-input name="no_branding" :form="form" class="mt-4"
label="Remove OpnForm Branding"
/>
<toggle-switch-input name="no_branding" :form="form" class="mt-4">
<template #label>
Remove OpnForm Branding
<pro-tag class="ml-1" />
</template>
</toggle-switch-input>
<toggle-switch-input name="uppercase_labels" :form="form" class="mt-4"
label="Uppercase Input Labels"
/>

View File

@@ -17,7 +17,6 @@
label="Protect your form with a Captcha"
help="If enabled we will make sure respondant is a human"
/>
<pro-tag class="float-right" />
<text-input name="password" :form="form" class="mt-4"
label="Form Password" help="Leave empty to disable password"
/>

View File

@@ -2,7 +2,6 @@
<div v-if="logic" :key="resetKey" class="-mx-4 sm:-mx-6 p-5 border-b">
<h3 class="font-semibold block text-lg">
Logic
<pro-tag/>
</h3>
<p class="text-gray-400 text-xs mb-5">
Add some logic to this block. Start by adding some conditions, and then add some actions.

View File

@@ -99,7 +99,6 @@
<div v-if="field.type === 'number'" class="-mx-4 sm:-mx-6 p-5 border-b">
<h3 class="font-semibold block text-lg">
Number Options
<pro-tag/>
</h3>
<v-checkbox v-model="field.is_rating" class="mt-4"
:name="field.id+'_is_rating'" @input="initRating"
@@ -136,7 +135,6 @@
<div v-if="field.type === 'date'" class="-mx-4 sm:-mx-6 p-5 border-b">
<h3 class="font-semibold block text-lg">
Date Options
<pro-tag/>
</h3>
<v-checkbox v-model="field.date_range" class="mt-4"
:name="field.id+'_date_range'"
@@ -191,7 +189,6 @@
<div v-if="['select','multi_select'].includes(field.type)" class="-mx-4 sm:-mx-6 p-5 border-b">
<h3 class="font-semibold block text-lg">
Select Options
<pro-tag/>
</h3>
<p class="text-gray-400 mb-5 text-xs">
Advanced options for your select/multiselect fields.
@@ -218,7 +215,6 @@
<div v-if="displayBasedOnAdvanced" class="-mx-4 sm:-mx-6 p-5 border-b">
<h3 class="font-semibold block text-lg">
Customization
<pro-tag/>
</h3>
<p class="text-gray-400 mb-5 text-xs">
@@ -322,7 +318,6 @@
<div v-if="field.type === 'text'" class="-mx-4 sm:-mx-6 p-5 border-b">
<h3 class="font-semibold block text-lg">
Advanced Options
<pro-tag/>
</h3>
<v-checkbox v-model="field.generates_uuid"