feat: Add a pre-chat form on widget (#1769)

This commit is contained in:
Pranav Raj S
2021-02-16 00:14:13 +05:30
committed by GitHub
parent 5f2bf7dfd2
commit 037ffc7419
31 changed files with 604 additions and 200 deletions

View File

@@ -75,8 +75,6 @@ export default {
padding: $space-two $space-medium;
width: 100%;
box-sizing: border-box;
background: white;
@include shadow-large;
.header-branding {
display: flex;

View File

@@ -1,5 +1,5 @@
<template>
<header class="header-expanded py-8 px-6 bg-white relative box-border w-full">
<header class="header-expanded bg-white py-8 px-6 relative box-border w-full">
<div class="flex justify-between items-start">
<img v-if="avatarUrl" class="logo" :src="avatarUrl" />
<header-actions :show-popout-button="showPopoutButton" />
@@ -50,8 +50,6 @@ export default {
@import '~widget/assets/scss/mixins.scss';
.header-expanded {
@include shadow-large;
.logo {
width: 56px;
height: 56px;

View File

@@ -0,0 +1,59 @@
<template>
<label class="block">
<div
v-if="label"
class="mb-2 text-xs font-medium"
:class="{
'text-black-800': !error,
'text-red-400': error,
}"
>
{{ label }}
</div>
<input
:type="type"
class="border rounded w-full py-2 px-3 text-slate-700 leading-tight outline-none"
:class="{
'border-black-200 hover:border-black-300 focus:border-black-300': !error,
'border-red-200 hover:border-red-300 focus:border-red-300': error,
}"
:placeholder="placeholder"
:value="value"
@change="onChange"
/>
<div v-if="error" class="text-red-400 mt-2 text-xs font-medium">
{{ error }}
</div>
</label>
</template>
<script>
export default {
props: {
label: {
type: String,
default: '',
},
type: {
type: String,
default: 'text',
},
placeholder: {
type: String,
default: '',
},
value: {
type: [String, Number],
required: true,
},
error: {
type: String,
default: '',
},
},
methods: {
onChange(event) {
this.$emit('input', event.target.value);
},
},
};
</script>

View File

@@ -0,0 +1,63 @@
<template>
<label class="block">
<div
v-if="label"
class="mb-2 text-xs font-medium"
:class="{
'text-black-800': !error,
'text-red-400': error,
}"
>
{{ label }}
</div>
<textarea
class="resize-none border rounded w-full py-2 px-3 text-slate-700 leading-tight outline-none"
:class="{
'border-black-200 hover:border-black-300 focus:border-black-300': !error,
'border-red-200 hover:border-red-300 focus:border-red-300': error,
}"
:placeholder="placeholder"
:value="value"
@change="onChange"
/>
<div v-if="error" class="text-red-400 mt-2 text-xs font-medium">
{{ error }}
</div>
</label>
</template>
<script>
export default {
props: {
label: {
type: String,
default: '',
},
type: {
type: String,
default: 'text',
},
placeholder: {
type: String,
default: '',
},
value: {
type: [String, Number],
required: true,
},
error: {
type: String,
default: '',
},
},
methods: {
onChange(event) {
this.$emit('input', event.target.value);
},
},
};
</script>
<style lang="scss" scoped>
textarea {
min-height: 8rem;
}
</style>

View File

@@ -0,0 +1,117 @@
<template>
<form
class="flex flex-1 flex-col p-6 overflow-y-scroll"
@submit.prevent="onSubmit"
>
<div v-if="options.preChatMessage" class="text-black-800 text-sm leading-5">
{{ options.preChatMessage }}
</div>
<form-input
v-if="options.requireEmail"
v-model="fullName"
class="mt-5"
:label="$t('PRE_CHAT_FORM.FIELDS.FULL_NAME.LABEL')"
:placeholder="$t('PRE_CHAT_FORM.FIELDS.FULL_NAME.PLACEHOLDER')"
type="text"
:error="
$v.fullName.$error ? $t('PRE_CHAT_FORM.FIELDS.FULL_NAME.ERROR') : ''
"
/>
<form-input
v-if="options.requireEmail"
v-model="emailAddress"
class="mt-5"
:label="$t('PRE_CHAT_FORM.FIELDS.EMAIL_ADDRESS.LABEL')"
:placeholder="$t('PRE_CHAT_FORM.FIELDS.EMAIL_ADDRESS.PLACEHOLDER')"
type="email"
:error="
$v.emailAddress.$error
? $t('PRE_CHAT_FORM.FIELDS.EMAIL_ADDRESS.ERROR')
: ''
"
/>
<form-text-area
v-model="message"
class="my-5"
:label="$t('PRE_CHAT_FORM.FIELDS.MESSAGE.LABEL')"
:placeholder="$t('PRE_CHAT_FORM.FIELDS.MESSAGE.PLACEHOLDER')"
:error="$v.message.$error ? $t('PRE_CHAT_FORM.FIELDS.MESSAGE.ERROR') : ''"
/>
<woot-button
class="font-medium"
block
:bg-color="widgetColor"
:text-color="textColor"
:disabled="isCreating"
>
<spinner v-if="isCreating" class="p-0" />
{{ $t('START_CONVERSATION') }}
</woot-button>
</form>
</template>
<script>
import WootButton from 'shared/components/Button';
import FormInput from '../Form/Input';
import FormTextArea from '../Form/TextArea';
import Spinner from 'shared/components/Spinner';
import { mapGetters } from 'vuex';
import { getContrastingTextColor } from 'shared/helpers/ColorHelper';
import { required, minLength, email } from 'vuelidate/lib/validators';
export default {
components: {
FormInput,
FormTextArea,
WootButton,
Spinner,
},
props: {
options: {
type: Object,
default: () => ({}),
},
},
validations: {
fullName: {
required,
},
emailAddress: {
required,
email,
},
message: {
required,
minLength: minLength(10),
},
},
data() {
return {
fullName: '',
emailAddress: '',
message: '',
};
},
computed: {
...mapGetters({
widgetColor: 'appConfig/getWidgetColor',
isCreating: 'conversation/getIsCreating',
}),
textColor() {
return getContrastingTextColor(this.widgetColor);
},
},
methods: {
onSubmit() {
this.$v.$touch();
if (this.$v.$invalid) {
return;
}
this.$store.dispatch('conversation/createConversation', {
fullName: this.fullName,
emailAddress: this.emailAddress,
message: this.message,
});
},
},
};
</script>