Files
crater/resources/assets/js/views/settings/UserProfileSetting.vue
2021-01-06 21:12:22 +05:30

367 lines
9.0 KiB
Vue

<template>
<form class="relative h-full" @submit.prevent="updateUserData">
<base-loader v-if="isRequestOnGoing" :show-bg-overlay="true" />
<sw-card variant="setting-card">
<template slot="header">
<h6 class="sw-section-title">
{{ $t('settings.account_settings.account_settings') }}
</h6>
<p
class="mt-2 text-sm leading-snug text-gray-500"
style="max-width: 680px"
>
{{ $t('settings.account_settings.section_description') }}
</p>
</template>
<div class="grid mb-4 md:grid-cols-6">
<div>
<label
class="text-sm not-italic font-medium leading-4 text-black whitespace-nowrap"
>
{{ $tc('settings.account_settings.profile_picture') }}
</label>
<sw-avatar
:preview-avatar="previewAvatar"
:label="$tc('general.choose_file')"
@changed="onChange"
@uploadHandler="onUploadHandler"
@handleUploadError="onHandleUploadError"
>
<template v-slot:icon>
<cloud-upload-icon
class="h-5 mb-2 text-xl leading-6 text-gray-400"
/>
</template>
</sw-avatar>
</div>
</div>
<div class="grid gap-6 sm:grid-col-1 md:grid-cols-2">
<sw-input-group
:label="$tc('settings.account_settings.name')"
:error="nameError"
>
<sw-input
v-model="formData.name"
:invalid="$v.formData.name.$error"
:placeholder="$t('settings.user_profile.name')"
class="mt-2"
@input="$v.formData.name.$touch()"
/>
</sw-input-group>
<sw-input-group
:label="$tc('settings.account_settings.email')"
:error="emailError"
>
<sw-input
v-model="formData.email"
:invalid="$v.formData.email.$error"
:placeholder="$t('settings.user_profile.email')"
class="mt-2"
@input="$v.formData.email.$touch()"
/>
</sw-input-group>
<sw-input-group
:label="$tc('settings.account_settings.password')"
:error="passwordError"
>
<sw-input
v-model="formData.password"
:invalid="$v.formData.password.$error"
:placeholder="$t('settings.user_profile.password')"
type="password"
class="mt-2"
@input="$v.formData.password.$touch()"
/>
</sw-input-group>
<sw-input-group
:label="$tc('settings.account_settings.confirm_password')"
:error="confirmPasswordError"
class="mt-1 mb-2"
>
<sw-input
v-model="formData.confirm_password"
:invalid="$v.formData.confirm_password.$error"
:placeholder="$t('settings.user_profile.confirm_password')"
type="password"
@input="$v.formData.confirm_password.$touch()"
/>
</sw-input-group>
</div>
<div class="grid gap-6 mt-4 sm:grid-col-1 md:grid-cols-2">
<sw-input-group
:label="$tc('settings.language')"
:error="languageError"
>
<sw-select
v-model="language"
:options="languages"
:class="{ error: $v.language.$error }"
:searchable="true"
:show-labels="false"
:allow-empty="false"
:placeholder="$tc('settings.preferences.select_language')"
class="mt-2"
label="name"
track-by="code"
/>
</sw-input-group>
</div>
<sw-button
:loading="isLoading"
:disabled="isLoading"
class="mt-6"
variant="primary"
>
<save-icon v-if="!isLoading" class="mr-2 -ml-1" />
{{ $tc('settings.account_settings.save') }}
</sw-button>
</sw-card>
</form>
</template>
<script>
import { mapActions, mapGetters, mapState } from 'vuex'
import { CloudUploadIcon } from '@vue-hero-icons/solid'
import BaseLoader from '../../components/base/BaseLoader.vue'
const {
required,
requiredIf,
sameAs,
email,
minLength,
} = require('vuelidate/lib/validators')
export default {
components: {
CloudUploadIcon,
BaseLoader,
},
data() {
return {
formData: {
name: null,
email: null,
password: null,
confirm_password: null,
},
isLoading: false,
previewAvatar: null,
cropperOutputMime: '',
fileObject: null,
language: null,
isRequestOnGoing: false,
}
},
validations: {
formData: {
name: {
required,
},
email: {
required,
email,
},
password: {
minLength: minLength(8),
},
confirm_password: {
sameAsPassword: sameAs('password'),
},
},
language: {
required,
},
},
computed: {
...mapGetters(['languages']),
emailError() {
if (!this.$v.formData.email.$error) {
return ''
}
if (!this.$v.formData.email.required) {
return this.$tc('validation.required')
}
if (!this.$v.formData.email.email) {
return this.$tc('validation.email_incorrect')
}
},
passwordError() {
if (!this.$v.formData.password.$error) {
return ''
}
if (!this.$v.formData.password.minLength) {
return this.$tc(
'validation.password_min_length',
this.$v.formData.password.$params.minLength.min,
{ count: this.$v.formData.password.$params.minLength.min }
)
}
},
nameError() {
if (!this.$v.formData.name.$error) {
return ''
}
if (!this.$v.formData.name.required) {
return this.$tc('validation.required')
}
},
confirmPasswordError() {
if (!this.$v.formData.confirm_password.$error) {
return ''
}
if (!this.$v.formData.confirm_password.sameAsPassword) {
return this.$tc('validation.password_incorrect')
}
},
languageError() {
if (!this.$v.language.$error) {
return ''
}
if (!this.$v.language.required) {
return this.$tc('validation.required')
}
},
},
watch: {
'formData.password'(val) {
if (!val) {
this.formData.confirm_password = ''
}
},
},
mounted() {
this.setInitialData()
this.fetchLanguages()
},
methods: {
...mapActions('user', [
'fetchCurrentUser',
'updateCurrentUser',
'fetchUserSettings',
'updateUserSettings',
'uploadAvatar',
]),
...mapActions(['fetchLanguages']),
onUploadHandler(cropper) {
this.previewAvatar = cropper
.getCroppedCanvas()
.toDataURL(this.cropperOutputMime)
},
onHandleUploadError() {
window.toastr['error']('Oops! Something went wrong...')
},
onChange(file) {
this.cropperOutputMime = file.type
this.fileObject = file
},
async setInitialData() {
this.isRequestOnGoing = true
let response = await this.fetchCurrentUser()
this.formData.name = response.data.user.name
this.formData.email = response.data.user.email
if (response.data.user.avatar) {
this.previewAvatar = response.data.user.avatar
} else {
this.previewAvatar = '/images/default-avatar.jpg'
}
let res = await this.fetchUserSettings(['language'])
this.language = this.languages.find(
(language) => language.code == res.data.language
)
this.isRequestOnGoing = false
},
async updateUserData() {
this.$v.formData.$touch()
if (this.$v.$invalid) {
return true
}
this.isLoading = true
let data = {
name: this.formData.name,
email: this.formData.email,
}
try {
if (
this.formData.password != null &&
this.formData.password !== undefined &&
this.formData.password !== ''
) {
data = { ...data, password: this.formData.password }
}
let response = await this.updateCurrentUser(data)
let languageData = {
settings: {
language: this.language.code,
},
}
let languageRes = await this.updateUserSettings(languageData)
if (response.data.success) {
this.isLoading = false
if (this.fileObject && this.previewAvatar) {
let avatarData = new FormData()
avatarData.append(
'admin_avatar',
JSON.stringify({
name: this.fileObject.name,
data: this.previewAvatar,
})
)
this.uploadAvatar(avatarData)
}
window.toastr['success'](
this.$t('settings.account_settings.updated_message')
)
this.formData.password = ''
this.formData.confirm_password = ''
}
} catch (error) {
this.isLoading = false
return true
}
},
},
}
</script>