mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-10-31 05:31:10 -04:00 
			
		
		
		
	Merge branch 'user-avatar' into 'master'
User Avatar See merge request mohit.panjvani/crater-web!67
This commit is contained in:
		| @ -251,6 +251,7 @@ class CompanyController extends Controller | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         return response()->json([ |         return response()->json([ | ||||||
|  |             'user' => $user, | ||||||
|             'success' => true |             'success' => true | ||||||
|         ]); |         ]); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -99,6 +99,32 @@ class OnboardingController extends Controller | |||||||
|         ]); |         ]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public function uploadAdminAvatar(Request $request) | ||||||
|  |     { | ||||||
|  |         $setting = Setting::getSetting('profile_complete'); | ||||||
|  |  | ||||||
|  |         if ($setting == '1' || $setting == 'COMPLETED') { | ||||||
|  |             return response()->json(['error' => 'Profile already created.']); | ||||||
|  |         } | ||||||
|  |         $data = json_decode($request->admin_avatar); | ||||||
|  |  | ||||||
|  |         if($data) { | ||||||
|  |             $user = User::find($data->id); | ||||||
|  |             if($user) { | ||||||
|  |                 $user->clearMediaCollection('admin_avatar'); | ||||||
|  |  | ||||||
|  |                 $user->addMediaFromBase64($data->data) | ||||||
|  |                     ->usingFileName($data->name) | ||||||
|  |                     ->toMediaCollection('admin_avatar'); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return response()->json([ | ||||||
|  |             'user' => $user, | ||||||
|  |             'success' => true | ||||||
|  |         ]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public function adminCompany(CompanyRequest $request) |     public function adminCompany(CompanyRequest $request) | ||||||
|     { |     { | ||||||
|         $setting = Setting::getSetting('profile_complete'); |         $setting = Setting::getSetting('profile_complete'); | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								public/images/default-avatar.jpg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/images/default-avatar.jpg
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 32 KiB | 
| @ -603,6 +603,7 @@ export default { | |||||||
|       updated_message: 'Company information updated successfully' |       updated_message: 'Company information updated successfully' | ||||||
|     }, |     }, | ||||||
|     account_settings: { |     account_settings: { | ||||||
|  |       profile_picture: 'Profile Picture', | ||||||
|       name: 'Name', |       name: 'Name', | ||||||
|       email: 'Email', |       email: 'Email', | ||||||
|       password: 'Password', |       password: 'Password', | ||||||
|  | |||||||
| @ -599,6 +599,7 @@ export default { | |||||||
|       updated_message: 'Información de la empresa actualizada con éxito' |       updated_message: 'Información de la empresa actualizada con éxito' | ||||||
|     }, |     }, | ||||||
|     account_settings: { |     account_settings: { | ||||||
|  |       profile_picture: 'Foto de perfil', | ||||||
|       name: 'Nombre', |       name: 'Nombre', | ||||||
|       email: 'Email', |       email: 'Email', | ||||||
|       password: 'Contraseña', |       password: 'Contraseña', | ||||||
|  | |||||||
| @ -599,6 +599,7 @@ export default { | |||||||
|       updated_message: 'Informations sur la société mises à jour avec succès' |       updated_message: 'Informations sur la société mises à jour avec succès' | ||||||
|     }, |     }, | ||||||
|     account_settings: { |     account_settings: { | ||||||
|  |       profile_picture: 'Image de profil', | ||||||
|       name: 'Nom', |       name: 'Nom', | ||||||
|       email: 'Email', |       email: 'Email', | ||||||
|       password: 'Mot de passe', |       password: 'Mot de passe', | ||||||
|  | |||||||
| @ -12,11 +12,7 @@ export const loadData = ({ commit, dispatch, state }, id) => { | |||||||
|  |  | ||||||
| export const editCompany = ({ commit, dispatch, state }, data) => { | export const editCompany = ({ commit, dispatch, state }, data) => { | ||||||
|   return new Promise((resolve, reject) => { |   return new Promise((resolve, reject) => { | ||||||
|     window.axios.post('/api/settings/company', data, { |     window.axios.post('/api/settings/company', data).then((response) => { | ||||||
|       headers: { |  | ||||||
|         'Content-Type': 'multipart/form-data' |  | ||||||
|       } |  | ||||||
|     }).then((response) => { |  | ||||||
|       // commit(types.UPDATE_ITEM, response.data) |       // commit(types.UPDATE_ITEM, response.data) | ||||||
|       resolve(response) |       resolve(response) | ||||||
|     }).catch((err) => { |     }).catch((err) => { | ||||||
|  | |||||||
| @ -1,8 +1,9 @@ | |||||||
| // import * as types from './mutation-types' | import * as types from './mutation-types' | ||||||
|  |  | ||||||
| export const loadData = ({ commit, dispatch, state }, id) => { | export const loadData = ({ commit, dispatch, state }, id) => { | ||||||
|   return new Promise((resolve, reject) => { |   return new Promise((resolve, reject) => { | ||||||
|     window.axios.get(`/api/settings/profile`).then((response) => { |     window.axios.get(`/api/settings/profile`).then((response) => { | ||||||
|  |       commit(types.SET_USER, response.data) | ||||||
|       resolve(response) |       resolve(response) | ||||||
|     }).catch((err) => { |     }).catch((err) => { | ||||||
|       reject(err) |       reject(err) | ||||||
| @ -13,7 +14,29 @@ export const loadData = ({ commit, dispatch, state }, id) => { | |||||||
| export const editUser = ({ commit, dispatch, state }, data) => { | export const editUser = ({ commit, dispatch, state }, data) => { | ||||||
|   return new Promise((resolve, reject) => { |   return new Promise((resolve, reject) => { | ||||||
|     window.axios.put('/api/settings/profile', data).then((response) => { |     window.axios.put('/api/settings/profile', data).then((response) => { | ||||||
|       // commit(types.UPDATE_USER, response.data) |       commit(types.UPDATE_USER, response.data) | ||||||
|  |       resolve(response) | ||||||
|  |     }).catch((err) => { | ||||||
|  |       reject(err) | ||||||
|  |     }) | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const uploadOnboardAvatar = ({ commit, dispatch, state }, data) => { | ||||||
|  |   return new Promise((resolve, reject) => { | ||||||
|  |     window.axios.post(`/api/admin/profile/upload-avatar`, data).then((response) => { | ||||||
|  |       commit(types.UPDATE_USER, response.data.user) | ||||||
|  |       resolve(response) | ||||||
|  |     }).catch((err) => { | ||||||
|  |       reject(err) | ||||||
|  |     }) | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export const uploadAvatar = ({ commit, dispatch, state }, data) => { | ||||||
|  |   return new Promise((resolve, reject) => { | ||||||
|  |     window.axios.post('/api/settings/profile/upload-avatar', data).then((response) => { | ||||||
|  |       commit(types.UPDATE_USER, response.data.user) | ||||||
|       resolve(response) |       resolve(response) | ||||||
|     }).catch((err) => { |     }).catch((err) => { | ||||||
|       reject(err) |       reject(err) | ||||||
|  | |||||||
| @ -1,2 +1,3 @@ | |||||||
| export const SET_USER = 'SET_USER' | export const SET_USER = 'SET_USER' | ||||||
| export const UPDATE_USER = 'UPDATE_USER' | export const UPDATE_USER = 'UPDATE_USER' | ||||||
|  | export const UPDATE_USER_AVATAR = 'UPDATE_USER_AVATAR' | ||||||
|  | |||||||
| @ -2,10 +2,14 @@ import * as types from './mutation-types' | |||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   [types.SET_USER] (state, data) { |   [types.SET_USER] (state, data) { | ||||||
|     state.user = data.user |     state.user = data | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   [types.UPDATE_USER] (state, data) { |   [types.UPDATE_USER] (state, data) { | ||||||
|     state.user = data |     state.user = data | ||||||
|  |   }, | ||||||
|  |  | ||||||
|  |   [types.UPDATE_USER_AVATAR] (state, data) { | ||||||
|  |     state.user.avatar = data.avatar | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -58,7 +58,7 @@ | |||||||
|             aria-expanded="false" |             aria-expanded="false" | ||||||
|             class="avatar" |             class="avatar" | ||||||
|           > |           > | ||||||
|             <img src="/images/avatar.png" alt="Avatar"> |             <img :src="ProfilePicture" alt="Avatar"> | ||||||
|           </a> |           </a> | ||||||
|           <v-dropdown-item> |           <v-dropdown-item> | ||||||
|             <router-link class="dropdown-item" to="/admin/settings"> |             <router-link class="dropdown-item" to="/admin/settings"> | ||||||
| @ -83,7 +83,25 @@ | |||||||
| import { mapGetters, mapActions } from 'vuex' | import { mapGetters, mapActions } from 'vuex' | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|  |   computed: { | ||||||
|  |     ...mapGetters('userProfile', [ | ||||||
|  |       'user' | ||||||
|  |     ]), | ||||||
|  |     ProfilePicture () { | ||||||
|  |       if (this.user && this.user.avatar !== null) { | ||||||
|  |         return this.user.avatar | ||||||
|  |       } else { | ||||||
|  |         return '/images/default-avatar.jpg' | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created () { | ||||||
|  |     this.loadData() | ||||||
|  |   }, | ||||||
|   methods: { |   methods: { | ||||||
|  |     ...mapActions('userProfile', [ | ||||||
|  |       'loadData' | ||||||
|  |     ]), | ||||||
|     ...mapActions({ |     ...mapActions({ | ||||||
|       companySelect: 'changeCompany' |       companySelect: 'changeCompany' | ||||||
|     }), |     }), | ||||||
|  | |||||||
| @ -12,6 +12,9 @@ | |||||||
|           <div class="col-md-6"> |           <div class="col-md-6"> | ||||||
|             <label class="input-label">{{ $tc('settings.company_info.company_logo') }}</label> |             <label class="input-label">{{ $tc('settings.company_info.company_logo') }}</label> | ||||||
|             <div id="pick-avatar" class="image-upload-box"> |             <div id="pick-avatar" class="image-upload-box"> | ||||||
|  |               <div class="overlay"> | ||||||
|  |                 <font-awesome-icon class="white-icon" icon="camera"/> | ||||||
|  |               </div> | ||||||
|               <img v-if="previewLogo" :src="previewLogo" class="preview-logo"> |               <img v-if="previewLogo" :src="previewLogo" class="preview-logo"> | ||||||
|               <div v-else class="upload-content"> |               <div v-else class="upload-content"> | ||||||
|                 <font-awesome-icon class="upload-icon" icon="cloud-upload-alt"/> |                 <font-awesome-icon class="upload-icon" icon="cloud-upload-alt"/> | ||||||
| @ -174,7 +177,6 @@ export default { | |||||||
|       isFetchingData: false, |       isFetchingData: false, | ||||||
|       formData: { |       formData: { | ||||||
|         name: null, |         name: null, | ||||||
|         logo: '', |  | ||||||
|         email: '', |         email: '', | ||||||
|         phone: '', |         phone: '', | ||||||
|         zip: '', |         zip: '', | ||||||
| @ -301,17 +303,8 @@ export default { | |||||||
|         return true |         return true | ||||||
|       } |       } | ||||||
|       this.isLoading = true |       this.isLoading = true | ||||||
|       let data = new FormData() |  | ||||||
|       data.append('name', this.formData.name) |  | ||||||
|       data.append('address_street_1', this.formData.address_street_1) |  | ||||||
|       data.append('address_street_2', this.formData.address_street_2) |  | ||||||
|       data.append('city_id', this.formData.city_id) |  | ||||||
|       data.append('state_id', this.formData.state_id) |  | ||||||
|       data.append('country_id', this.formData.country_id) |  | ||||||
|       data.append('zip', this.formData.zip) |  | ||||||
|       data.append('phone', this.formData.phone) |  | ||||||
|  |  | ||||||
|       let response = await this.editCompany(data) |       let response = await this.editCompany(this.formData) | ||||||
|       if (response.data.success) { |       if (response.data.success) { | ||||||
|         this.isLoading = false |         this.isLoading = false | ||||||
|         if (this.fileObject && this.previewLogo) { |         if (this.fileObject && this.previewLogo) { | ||||||
|  | |||||||
| @ -8,6 +8,31 @@ | |||||||
|             {{ $t('settings.account_settings.section_description') }} |             {{ $t('settings.account_settings.section_description') }} | ||||||
|           </p> |           </p> | ||||||
|         </div> |         </div> | ||||||
|  |         <div class="row mb-4"> | ||||||
|  |           <div class="col-md-6"> | ||||||
|  |             <label class="input-label">{{ $tc('settings.account_settings.profile_picture') }}</label> | ||||||
|  |             <div id="pick-avatar" class="image-upload-box avatar-upload"> | ||||||
|  |               <div class="overlay"> | ||||||
|  |                 <font-awesome-icon class="white-icon" icon="camera"/> | ||||||
|  |               </div> | ||||||
|  |               <img v-if="previewAvatar" :src="previewAvatar" class="preview-logo"> | ||||||
|  |               <div v-if="!previewAvatar" class="upload-content"> | ||||||
|  |                 <font-awesome-icon class="upload-icon" icon="cloud-upload-alt"/> | ||||||
|  |                 <p class="upload-text"> {{ $tc('general.choose_file') }} </p> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <avatar-cropper | ||||||
|  |             :labels="{ submit: 'submit', cancel: 'Cancle'}" | ||||||
|  |             :cropper-options="cropperOptions" | ||||||
|  |             :output-options="cropperOutputOptions" | ||||||
|  |             :output-quality="0.8" | ||||||
|  |             :upload-handler="cropperHandler" | ||||||
|  |             trigger="#pick-avatar" | ||||||
|  |             @changed="setFileObject" | ||||||
|  |             @error="handleUploadError" | ||||||
|  |           /> | ||||||
|  |         </div> | ||||||
|         <div class="row"> |         <div class="row"> | ||||||
|           <div class="col-md-6 mb-4 form-group"> |           <div class="col-md-6 mb-4 form-group"> | ||||||
|             <label class="input-label">{{ $tc('settings.account_settings.name') }}</label> |             <label class="input-label">{{ $tc('settings.account_settings.name') }}</label> | ||||||
| @ -81,19 +106,33 @@ | |||||||
| <script> | <script> | ||||||
| import { validationMixin } from 'vuelidate' | import { validationMixin } from 'vuelidate' | ||||||
| import { mapActions } from 'vuex' | import { mapActions } from 'vuex' | ||||||
|  | import AvatarCropper from 'vue-avatar-cropper' | ||||||
| const { required, requiredIf, sameAs, email, minLength } = require('vuelidate/lib/validators') | const { required, requiredIf, sameAs, email, minLength } = require('vuelidate/lib/validators') | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|  |   components: { AvatarCropper }, | ||||||
|   mixins: [validationMixin], |   mixins: [validationMixin], | ||||||
|   data () { |   data () { | ||||||
|     return { |     return { | ||||||
|       isLoading: false, |       cropperOutputOptions: { | ||||||
|  |         width: 150, | ||||||
|  |         height: 150 | ||||||
|  |       }, | ||||||
|  |       cropperOptions: { | ||||||
|  |         autoCropArea: 1, | ||||||
|  |         viewMode: 0, | ||||||
|  |         movable: true, | ||||||
|  |         zoomable: true | ||||||
|  |       }, | ||||||
|       formData: { |       formData: { | ||||||
|         name: null, |         name: null, | ||||||
|         email: null, |         email: null, | ||||||
|         password: null, |         password: null, | ||||||
|         confirm_password: null |         confirm_password: null | ||||||
|       } |       }, | ||||||
|  |       isLoading: false, | ||||||
|  |       previewAvatar: null, | ||||||
|  |       fileObject: null | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   validations: { |   validations: { | ||||||
| @ -128,12 +167,27 @@ export default { | |||||||
|   methods: { |   methods: { | ||||||
|     ...mapActions('userProfile', [ |     ...mapActions('userProfile', [ | ||||||
|       'loadData', |       'loadData', | ||||||
|       'editUser' |       'editUser', | ||||||
|  |       'uploadAvatar' | ||||||
|     ]), |     ]), | ||||||
|  |     cropperHandler (cropper) { | ||||||
|  |       this.previewAvatar = cropper.getCroppedCanvas().toDataURL(this.cropperOutputMime) | ||||||
|  |     }, | ||||||
|  |     setFileObject (file) { | ||||||
|  |       this.fileObject = file | ||||||
|  |     }, | ||||||
|  |     handleUploadError (message, type, xhr) { | ||||||
|  |       window.toastr['error']('Oops! Something went wrong...') | ||||||
|  |     }, | ||||||
|     async setInitialData () { |     async setInitialData () { | ||||||
|       let response = await this.loadData() |       let response = await this.loadData() | ||||||
|       this.formData.name = response.data.name |       this.formData.name = response.data.name | ||||||
|       this.formData.email = response.data.email |       this.formData.email = response.data.email | ||||||
|  |       if (response.data.avatar) { | ||||||
|  |         this.previewAvatar = response.data.avatar | ||||||
|  |       } else { | ||||||
|  |         this.previewAvatar = '/images/default-avatar.jpg' | ||||||
|  |       } | ||||||
|     }, |     }, | ||||||
|     async updateUserData () { |     async updateUserData () { | ||||||
|       this.$v.formData.$touch() |       this.$v.formData.$touch() | ||||||
| @ -151,6 +205,14 @@ export default { | |||||||
|       let response = await this.editUser(data) |       let response = await this.editUser(data) | ||||||
|       if (response.data.success) { |       if (response.data.success) { | ||||||
|         this.isLoading = false |         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')) |         window.toastr['success'](this.$t('settings.account_settings.updated_message')) | ||||||
|         return true |         return true | ||||||
|       } |       } | ||||||
|  | |||||||
| @ -7,6 +7,9 @@ | |||||||
|         <div class="col-md-6"> |         <div class="col-md-6"> | ||||||
|           <label class="input-label">{{ $tc('settings.company_info.company_logo') }}</label> |           <label class="input-label">{{ $tc('settings.company_info.company_logo') }}</label> | ||||||
|           <div id="pick-avatar" class="image-upload-box"> |           <div id="pick-avatar" class="image-upload-box"> | ||||||
|  |             <div class="overlay"> | ||||||
|  |               <font-awesome-icon class="white-icon" icon="camera"/> | ||||||
|  |             </div> | ||||||
|             <img v-if="previewLogo" :src="previewLogo" class="preview-logo"> |             <img v-if="previewLogo" :src="previewLogo" class="preview-logo"> | ||||||
|             <div v-else class="upload-content"> |             <div v-else class="upload-content"> | ||||||
|               <font-awesome-icon class="upload-icon" icon="cloud-upload-alt"/> |               <font-awesome-icon class="upload-icon" icon="cloud-upload-alt"/> | ||||||
|  | |||||||
| @ -3,6 +3,31 @@ | |||||||
|     <form action="" @submit.prevent="next()"> |     <form action="" @submit.prevent="next()"> | ||||||
|       <p class="form-title">{{ $t('wizard.account_info') }}</p> |       <p class="form-title">{{ $t('wizard.account_info') }}</p> | ||||||
|       <p class="form-desc">{{ $t('wizard.account_info_desc') }}</p> |       <p class="form-desc">{{ $t('wizard.account_info_desc') }}</p> | ||||||
|  |       <div class="row mb-4"> | ||||||
|  |         <div class="col-md-6"> | ||||||
|  |           <label class="input-label">{{ $tc('settings.account_settings.profile_picture') }}</label> | ||||||
|  |           <div id="pick-avatar" class="image-upload-box avatar-upload"> | ||||||
|  |             <div class="overlay"> | ||||||
|  |               <font-awesome-icon class="white-icon" icon="camera"/> | ||||||
|  |             </div> | ||||||
|  |             <img v-if="previewAvatar" :src="previewAvatar" class="preview-logo"> | ||||||
|  |             <div v-else class="upload-content"> | ||||||
|  |               <font-awesome-icon class="upload-icon" icon="cloud-upload-alt"/> | ||||||
|  |               <p class="upload-text"> {{ $tc('general.choose_file') }} </p> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |         </div> | ||||||
|  |         <avatar-cropper | ||||||
|  |           :labels="{ submit: 'submit', cancel: 'Cancle'}" | ||||||
|  |           :cropper-options="cropperOptions" | ||||||
|  |           :output-options="cropperOutputOptions" | ||||||
|  |           :output-quality="0.8" | ||||||
|  |           :upload-handler="cropperHandler" | ||||||
|  |           trigger="#pick-avatar" | ||||||
|  |           @changed="setFileObject" | ||||||
|  |           @error="handleUploadError" | ||||||
|  |         /> | ||||||
|  |       </div> | ||||||
|       <div class="row"> |       <div class="row"> | ||||||
|         <div class="col-md-6"> |         <div class="col-md-6"> | ||||||
|           <label class="form-label">{{ $t('wizard.name') }}</label><span class="text-danger"> *</span> |           <label class="form-label">{{ $t('wizard.name') }}</label><span class="text-danger"> *</span> | ||||||
| @ -75,24 +100,37 @@ | |||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
| <script> | <script> | ||||||
| import MultiSelect from 'vue-multiselect' | import AvatarCropper from 'vue-avatar-cropper' | ||||||
| import { validationMixin } from 'vuelidate' | import { validationMixin } from 'vuelidate' | ||||||
|  | import { mapActions } from 'vuex' | ||||||
| const { required, requiredIf, sameAs, minLength, email } = require('vuelidate/lib/validators') | const { required, requiredIf, sameAs, minLength, email } = require('vuelidate/lib/validators') | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   components: { |   components: { | ||||||
|     MultiSelect |     AvatarCropper | ||||||
|   }, |   }, | ||||||
|   mixins: [validationMixin], |   mixins: [validationMixin], | ||||||
|   data () { |   data () { | ||||||
|     return { |     return { | ||||||
|  |       cropperOutputOptions: { | ||||||
|  |         width: 150, | ||||||
|  |         height: 150 | ||||||
|  |       }, | ||||||
|  |       cropperOptions: { | ||||||
|  |         autoCropArea: 1, | ||||||
|  |         viewMode: 0, | ||||||
|  |         movable: true, | ||||||
|  |         zoomable: true | ||||||
|  |       }, | ||||||
|       profileData: { |       profileData: { | ||||||
|         name: null, |         name: null, | ||||||
|         email: null, |         email: null, | ||||||
|         password: null, |         password: null, | ||||||
|         confirm_password: null |         confirm_password: null | ||||||
|       }, |       }, | ||||||
|       loading: false |       loading: false, | ||||||
|  |       previewAvatar: '/images/default-avatar.jpg', | ||||||
|  |       fileObject: null | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   validations: { |   validations: { | ||||||
| @ -124,6 +162,18 @@ export default { | |||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|  |     ...mapActions('userProfile', [ | ||||||
|  |       'uploadOnboardAvatar' | ||||||
|  |     ]), | ||||||
|  |     cropperHandler (cropper) { | ||||||
|  |       this.previewAvatar = cropper.getCroppedCanvas().toDataURL(this.cropperOutputMime) | ||||||
|  |     }, | ||||||
|  |     setFileObject (file) { | ||||||
|  |       this.fileObject = file | ||||||
|  |     }, | ||||||
|  |     handleUploadError (message, type, xhr) { | ||||||
|  |       window.toastr['error']('Oops! Something went wrong...') | ||||||
|  |     }, | ||||||
|     async next () { |     async next () { | ||||||
|       this.$v.profileData.$touch() |       this.$v.profileData.$touch() | ||||||
|       if (this.$v.profileData.$invalid) { |       if (this.$v.profileData.$invalid) { | ||||||
| @ -131,7 +181,20 @@ export default { | |||||||
|       } |       } | ||||||
|       this.loading = true |       this.loading = true | ||||||
|       let response = await window.axios.post('/api/admin/onboarding/profile', this.profileData) |       let response = await window.axios.post('/api/admin/onboarding/profile', this.profileData) | ||||||
|  |       console.log('user_id', response.data.user.id) | ||||||
|  |  | ||||||
|       if (response.data) { |       if (response.data) { | ||||||
|  |         if (this.fileObject && this.previewAvatar) { | ||||||
|  |           let avatarData = new FormData() | ||||||
|  |           avatarData.append('admin_avatar', JSON.stringify({ | ||||||
|  |             name: this.fileObject.name, | ||||||
|  |             data: this.previewAvatar, | ||||||
|  |             id: response.data.user.id | ||||||
|  |           })) | ||||||
|  |           console.log(avatarData); | ||||||
|  |  | ||||||
|  |           this.uploadOnboardAvatar(avatarData) | ||||||
|  |         } | ||||||
|         this.$emit('next') |         this.$emit('next') | ||||||
|         this.loading = false |         this.loading = false | ||||||
|       } |       } | ||||||
|  | |||||||
| @ -53,7 +53,8 @@ import { | |||||||
|   faPaperPlane, |   faPaperPlane, | ||||||
|   faEyeSlash, |   faEyeSlash, | ||||||
|   faSyncAlt, |   faSyncAlt, | ||||||
|   faRocket |   faRocket, | ||||||
|  |   faCamera | ||||||
| } from '@fortawesome/free-solid-svg-icons' | } from '@fortawesome/free-solid-svg-icons' | ||||||
| import { far } from '@fortawesome/free-regular-svg-icons' | import { far } from '@fortawesome/free-regular-svg-icons' | ||||||
| import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' | ||||||
| @ -117,7 +118,8 @@ library.add( | |||||||
|   faCopy, |   faCopy, | ||||||
|   faPaperPlane, |   faPaperPlane, | ||||||
|   faSyncAlt, |   faSyncAlt, | ||||||
|   faRocket |   faRocket, | ||||||
|  |   faCamera | ||||||
| ) | ) | ||||||
|  |  | ||||||
| Vue.component('font-awesome-icon', FontAwesomeIcon) | Vue.component('font-awesome-icon', FontAwesomeIcon) | ||||||
|  | |||||||
| @ -11,8 +11,10 @@ | |||||||
|     cursor: pointer; |     cursor: pointer; | ||||||
|  |  | ||||||
|     .preview-logo { |     .preview-logo { | ||||||
|         max-height: 50%; |         max-height: 80%; | ||||||
|         position: absolute; |         position: absolute; | ||||||
|  |         opacity: 1; | ||||||
|  |         animation: fadeIn 2s ease; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     .upload-content { |     .upload-content { | ||||||
| @ -35,4 +37,51 @@ | |||||||
|         margin-bottom: 10px; |         margin-bottom: 10px; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     .white-icon { | ||||||
|  |         font-size: 30px; | ||||||
|  |         line-height: 23px; | ||||||
|  |         color: $white; | ||||||
|  |         margin-bottom: 10px; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     .overlay { | ||||||
|  |         position: absolute; | ||||||
|  |         display: flex; | ||||||
|  |         justify-content: center; | ||||||
|  |         align-items: center; | ||||||
|  |         top: 0; | ||||||
|  |         left: 0; | ||||||
|  |         width: 100%; | ||||||
|  |         height: 100%; | ||||||
|  |         z-index: 10; | ||||||
|  |         transition: .5s ease; | ||||||
|  |         background-color: rgba(0,0,0,0.5); | ||||||
|  |         opacity: 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     &:hover { | ||||||
|  |         .overlay { | ||||||
|  |             opacity: 1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .avatar-upload { | ||||||
|  |     height: 130px; | ||||||
|  |     width: 130px; | ||||||
|  |     .preview-logo { | ||||||
|  |         max-width: 80% !important; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @keyframes fadeIn{ | ||||||
|  |       0%{ | ||||||
|  |         opacity: 0; | ||||||
|  |       } | ||||||
|  |       100%{ | ||||||
|  |         opacity: 1; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								resources/assets/sass/partials/header.scss
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								resources/assets/sass/partials/header.scss
									
									
									
									
										vendored
									
									
								
							| @ -62,6 +62,7 @@ | |||||||
|  |  | ||||||
|     .avatar img { |     .avatar img { | ||||||
|         width: 36px; |         width: 36px; | ||||||
|  |         height: 36px; | ||||||
|         border-radius: 2px; |         border-radius: 2px; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -96,6 +96,11 @@ Route::group(['middleware' => 'redirect-if-installed'], function () { | |||||||
|         'uses' => 'OnboardingController@adminProfile' |         'uses' => 'OnboardingController@adminProfile' | ||||||
|     ]); |     ]); | ||||||
|  |  | ||||||
|  |     Route::post('/admin/profile/upload-avatar', [ | ||||||
|  |         'as' => 'admin.on_boarding.avatar', | ||||||
|  |         'uses' => 'OnboardingController@uploadAdminAvatar' | ||||||
|  |     ]); | ||||||
|  |  | ||||||
|     Route::post('/admin/onboarding/company', [ |     Route::post('/admin/onboarding/company', [ | ||||||
|         'as' => 'admin.company', |         'as' => 'admin.company', | ||||||
|         'uses' => 'OnboardingController@adminCompany' |         'uses' => 'OnboardingController@adminCompany' | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user