In the last part, you looked at how you can set up Robin using its Javascript SDK while building a web applications customer service live chat feature. In this part, you will be looking at how you can set up Robin's Vue SDK to quickly set up a customer support client for CryptoDegen to respond to their user messages.
Prerequisites
To follow along with this tutorial, you should have the following:
- Knowledge of Vue.JS
- Robin API key
- A backend server to retrieve data from a database (You can use any of your choice)
If you haven't gotten your Robin API key already, you can get your Robin API key from your Robin Account.
Registering Robin Vue SDK
Before proceeding, you first need to install the Robin Vue SDK. Copy and paste the following code into your terminal.
npm install robin-vue --save
Next, in your main entry file, you will need to register the Robin Vue SDK in your Vue instance. In this tutorial, it's src/main.ts
. Copy and paste the following code:
// main.ts
import RobinChat from 'robin-vue'
Vue.use(RobinChat)
Next, import Robin's global styles. Add the following line of code to your src/main.ts
file:
// main.ts
import 'robin-vue/dist/style.css'
RobinChat Component
Before setting up your RobinChat component, Create a view component called src/views/Login.vue
. This is how the support team for CryptoDegen would gain access to the Robin platform to respond to user messages.
// login.vue
<template>
<div class="signin-ctn section" id="app">
<div class="inner">
<div class="auth-box">
<!-- image -->
<span>Distributing finance for everyone</span>
<form @submit.prevent>
<div class="form-group" :class="{ error: !emailValidate }">
<input
v-model="email"
type="email"
placeholder="email@company.com"
/>
<label>Your Email</label>
</div>
<div class="form-group">
<div class="password-field">
<input
v-model="password"
:type="obscure ? 'password' : 'text'"
placeholder="********"
/>
<i class="material-symbols-outlined" @click="obscure = !obscure">
{{ obscure ? 'visibility_off' : 'visibility' }}
</i>
</div>
<label>Password</label>
</div>
<button v-if="!isLoading" class="primary-btn" @click="signIn()">
Login
</button>
<button v-else class="primary-btn" disabled>
<div class="spinner2"></div>
</button>
</form>
</div>
</div>
</div>
</template>
export default Vue.extend({
name: 'Login',
data() {
return {
email: '' as string,
password: '',
obscure: true,
isLoading: false,
}
},
computed: {
emailValidate() {
// eslint-disable-next-line
return /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(
this.email
)
},
},
methods: {
},
})
</script>
<style scoped>
h1 {
font-weight: 500;
font-size: clamp(0.3rem, 7vw, 2rem);
}
span {
display: block;
font-size: clamp(0.3rem, 7vw, 1rem);
color: #8d9091;
margin: 0.625rem 0 1.375rem;
}
label {
font-size: clamp(0.3rem, 5vw, 1rem);
}
.section {
display: flex;
justify-content: center;
width: 100%;
}
.section > .inner {
width: 90%;
}
.signin-ctn.section {
min-height: 100vh;
align-items: center;
}
.signin-ctn > .inner {
max-width: 600px;
}
.auth-box {
text-align: center;
padding: 10% 15%;
height: auto;
min-height: 650px;
padding-bottom: 5%;
}
.auth-box img {
border-radius: 11px;
margin-bottom: 1rem;
}
.form-group {
margin-top: 1.5rem;
position: relative;
text-align: left;
display: flex;
flex-direction: column-reverse;
}
.form-group label {
font-size: 1rem;
display: block;
line-height: 32px;
transition: 0.3s;
}
.form-group input {
display: block;
background: #f5f7fc;
border-radius: 4px;
transition: 0.3s;
width: 100%;
height: 55px;
padding: 0 1.5rem;
font-size: 1rem;
-webkit-transition: 0.3s;
-moz-transition: 0.3s;
-ms-transition: 0.3s;
-o-transition: 0.3s;
}
.form-group input::placeholder {
color: #9999bc;
}
.form-group .password-field {
padding-right: 1.5rem;
display: flex;
align-items: center;
background: #f5f7fc;
border-radius: 4px;
width: 100%;
transition: 0.3s;
-webkit-transition: 0.3s;
-moz-transition: 0.3s;
-ms-transition: 0.3s;
-o-transition: 0.3s;
}
.form-group .password-field input {
border: none;
transition: 0s;
-webkit-transition: 0s;
-moz-transition: 0s;
-ms-transition: 0s;
-o-transition: 0s;
}
.form-group .icon {
position: absolute;
right: 16px;
top: 50%;
}
.flex-ctn.link {
width: max-content;
margin-left: auto;
margin-top: 0.5rem;
font-size: 0.925rem;
}
.flex-ctn.link div {
font-size: 1rem;
color: #f66b03;
cursor: pointer;
font-weight: 400;
line-height: 24px;
}
.header {
margin: 10% auto 0 auto;
}
form {
margin-top: 10%;
}
.primary-btn {
margin-top: 2rem;
}
@media screen and (max-width: 1450px) {
.section > .inner {
width: 90%;
}
}
@media screen and (max-height: 900px) {
.auth-box {
padding: 5% 15%;
min-height: 560px;
}
.header {
margin-top: 5%;
font-size: 1.3rem;
}
.primary-btn {
margin-left: auto;
margin-right: auto;
}
}
@media screen and (max-width: 600px) {
.auth-box {
padding: 5% 8%;
height: auto;
min-height: auto;
}
.primary-btn {
min-width: auto;
width: 100%;
font-size: 0.9rem;
height: 45px;
}
.flex-ctn.link {
margin-top: 15%;
font-size: 0.775rem;
}
.section > .inner {
width: 95%;
}
}
</style>
This tutorial mocks the user authentication process from the client side same as in the part 1 of this series.
Next, Create a function called signIn()
:
async signIn() {
this.isLoading = true
const promise: Promise<ObjectType> = new Promise((resolve, reject) => {
setTimeout(() => {
if (
this.email == 'cryptodegensuppor@gmail.com' &&
this.password == 'JetpaySupport'
) {
resolve({ status: 'success', data: {
_id: '983388d4d769496eb4bc0e42a6c0593a',
email: 'cryptodegensuppor@gmail.com',
username: 'Support',
user_token: 'SxPzdCcGZeyNUGPUZRNIiFXH'
}})
} else {
reject({ status: 'error', error: 'Invalid email or password' })
}
}, 2000)
})
const response = await promise as ObjectType
if (response.status === 'success') {
this.$router.push('/chat')
localStorage.setItem('data', JSON.stringify(response.data))
} else {
console.log(response)
}
this.isLoading = false
}
Now, to initialize the RobinChat component, create a view component src/views/Chat.vue
and paste the following code snippet below:
<template>
<div class="chat">
<RobinChat
logo="https://iili.io/wUVjdG.png"
api-key="NT-XmIzEmWUlsrQYypZOFRlogDFvQUsaEuxMfZf"
:users="users"
:user-token="userToken"
:keys="keys"
:user-name="userName"
channel="private_chat"
:features="[]"
>
</RobinChat>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
type ObjectType = Record<string, any>
export default Vue.extend({
name: 'Chat',
data() {
return {
userName: '',
userToken: '',
users: [] as Array<ObjectType>,
keys: {
userToken: 'robin_user_token',
profileImage: 'profile_photo',
userName: 'username',
},
}
},
created() {
if (localStorage.getItem('data')) {
const data = JSON.parse(localStorage.getItem('data') || '{}')
this.userToken = data.user_token
this.userName = data.user_name
}
this.getUsers()
},
methods: {
async getUsers() {
const promise: Promise<Array<ObjectType>> = new Promise((resolve) => {
setTimeout(() => {
const users = [
{
_id: '983388d4d769496eb4bc0e42a6c0593a',
email: 'cryptodegensupport@gmail.com',
username: 'CryptoDegen Support',
robin_user_token: 'SxPzdCcGZeyNUGPUZRNIiFXH',
profile_photo: '',
},
{
_id: 'b990738c18584abfbad077ad90712b56',
email: 'enoch11@gmail.com',
username: 'Enoch Chejieh',
robin_user_token: 'SHkPHNIYqwQIvyaYFaovLlHa',
profile_photo: '',
},
]
resolve(users)
}, 1000)
})
const response = await promise
this.users = [...response]
},
},
})
</script>
Robin Vue SDK provides extra options like features which allows you to specify which Robin feature you would like to use on the platform, such as create-chat
, forward-messages
, delete-messages, archive-chat
, reply-messages
, voice-recorder
, message-reactions.view
and message-reaction.delete
.
Conclusion
So quick recap. In this part you’ve learned how to use the Robin Vue SDK in your Vue application.
In-app live chat communication just got a lot easier with no extra configurations needed using Robin’s official SDKs is as easy as plug-in-play.
You can get the source code in this repository and view the demo in action.
I hope you enjoyed this short series, I can’t wait to see what you build!
Top comments (0)