mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-10-30 21:21:09 -04:00 
			
		
		
		
	Merge branch 'user-avatar' into 'master'
User Avatar See merge request mohit.panjvani/crater-web!67
This commit is contained in:
		| @ -58,7 +58,7 @@ | ||||
|             aria-expanded="false" | ||||
|             class="avatar" | ||||
|           > | ||||
|             <img src="/images/avatar.png" alt="Avatar"> | ||||
|             <img :src="ProfilePicture" alt="Avatar"> | ||||
|           </a> | ||||
|           <v-dropdown-item> | ||||
|             <router-link class="dropdown-item" to="/admin/settings"> | ||||
| @ -83,7 +83,25 @@ | ||||
| import { mapGetters, mapActions } from 'vuex' | ||||
|  | ||||
| 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: { | ||||
|     ...mapActions('userProfile', [ | ||||
|       'loadData' | ||||
|     ]), | ||||
|     ...mapActions({ | ||||
|       companySelect: 'changeCompany' | ||||
|     }), | ||||
|  | ||||
| @ -12,6 +12,9 @@ | ||||
|           <div class="col-md-6"> | ||||
|             <label class="input-label">{{ $tc('settings.company_info.company_logo') }}</label> | ||||
|             <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"> | ||||
|               <div v-else class="upload-content"> | ||||
|                 <font-awesome-icon class="upload-icon" icon="cloud-upload-alt"/> | ||||
| @ -174,7 +177,6 @@ export default { | ||||
|       isFetchingData: false, | ||||
|       formData: { | ||||
|         name: null, | ||||
|         logo: '', | ||||
|         email: '', | ||||
|         phone: '', | ||||
|         zip: '', | ||||
| @ -301,17 +303,8 @@ export default { | ||||
|         return 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) { | ||||
|         this.isLoading = false | ||||
|         if (this.fileObject && this.previewLogo) { | ||||
|  | ||||
| @ -8,6 +8,31 @@ | ||||
|             {{ $t('settings.account_settings.section_description') }} | ||||
|           </p> | ||||
|         </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="col-md-6 mb-4 form-group"> | ||||
|             <label class="input-label">{{ $tc('settings.account_settings.name') }}</label> | ||||
| @ -81,19 +106,33 @@ | ||||
| <script> | ||||
| import { validationMixin } from 'vuelidate' | ||||
| import { mapActions } from 'vuex' | ||||
| import AvatarCropper from 'vue-avatar-cropper' | ||||
| const { required, requiredIf, sameAs, email, minLength } = require('vuelidate/lib/validators') | ||||
|  | ||||
| export default { | ||||
|   components: { AvatarCropper }, | ||||
|   mixins: [validationMixin], | ||||
|   data () { | ||||
|     return { | ||||
|       isLoading: false, | ||||
|       cropperOutputOptions: { | ||||
|         width: 150, | ||||
|         height: 150 | ||||
|       }, | ||||
|       cropperOptions: { | ||||
|         autoCropArea: 1, | ||||
|         viewMode: 0, | ||||
|         movable: true, | ||||
|         zoomable: true | ||||
|       }, | ||||
|       formData: { | ||||
|         name: null, | ||||
|         email: null, | ||||
|         password: null, | ||||
|         confirm_password: null | ||||
|       } | ||||
|       }, | ||||
|       isLoading: false, | ||||
|       previewAvatar: null, | ||||
|       fileObject: null | ||||
|     } | ||||
|   }, | ||||
|   validations: { | ||||
| @ -128,12 +167,27 @@ export default { | ||||
|   methods: { | ||||
|     ...mapActions('userProfile', [ | ||||
|       '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 () { | ||||
|       let response = await this.loadData() | ||||
|       this.formData.name = response.data.name | ||||
|       this.formData.email = response.data.email | ||||
|       if (response.data.avatar) { | ||||
|         this.previewAvatar = response.data.avatar | ||||
|       } else { | ||||
|         this.previewAvatar = '/images/default-avatar.jpg' | ||||
|       } | ||||
|     }, | ||||
|     async updateUserData () { | ||||
|       this.$v.formData.$touch() | ||||
| @ -151,6 +205,14 @@ export default { | ||||
|       let response = await this.editUser(data) | ||||
|       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')) | ||||
|         return true | ||||
|       } | ||||
|  | ||||
| @ -7,6 +7,9 @@ | ||||
|         <div class="col-md-6"> | ||||
|           <label class="input-label">{{ $tc('settings.company_info.company_logo') }}</label> | ||||
|           <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"> | ||||
|             <div v-else class="upload-content"> | ||||
|               <font-awesome-icon class="upload-icon" icon="cloud-upload-alt"/> | ||||
|  | ||||
| @ -3,6 +3,31 @@ | ||||
|     <form action="" @submit.prevent="next()"> | ||||
|       <p class="form-title">{{ $t('wizard.account_info') }}</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="col-md-6"> | ||||
|           <label class="form-label">{{ $t('wizard.name') }}</label><span class="text-danger"> *</span> | ||||
| @ -75,24 +100,37 @@ | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| import MultiSelect from 'vue-multiselect' | ||||
| import AvatarCropper from 'vue-avatar-cropper' | ||||
| import { validationMixin } from 'vuelidate' | ||||
| import { mapActions } from 'vuex' | ||||
| const { required, requiredIf, sameAs, minLength, email } = require('vuelidate/lib/validators') | ||||
|  | ||||
| export default { | ||||
|   components: { | ||||
|     MultiSelect | ||||
|     AvatarCropper | ||||
|   }, | ||||
|   mixins: [validationMixin], | ||||
|   data () { | ||||
|     return { | ||||
|       cropperOutputOptions: { | ||||
|         width: 150, | ||||
|         height: 150 | ||||
|       }, | ||||
|       cropperOptions: { | ||||
|         autoCropArea: 1, | ||||
|         viewMode: 0, | ||||
|         movable: true, | ||||
|         zoomable: true | ||||
|       }, | ||||
|       profileData: { | ||||
|         name: null, | ||||
|         email: null, | ||||
|         password: null, | ||||
|         confirm_password: null | ||||
|       }, | ||||
|       loading: false | ||||
|       loading: false, | ||||
|       previewAvatar: '/images/default-avatar.jpg', | ||||
|       fileObject: null | ||||
|     } | ||||
|   }, | ||||
|   validations: { | ||||
| @ -124,6 +162,18 @@ export default { | ||||
|     } | ||||
|   }, | ||||
|   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 () { | ||||
|       this.$v.profileData.$touch() | ||||
|       if (this.$v.profileData.$invalid) { | ||||
| @ -131,7 +181,20 @@ export default { | ||||
|       } | ||||
|       this.loading = true | ||||
|       let response = await window.axios.post('/api/admin/onboarding/profile', this.profileData) | ||||
|       console.log('user_id', response.data.user.id) | ||||
|  | ||||
|       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.loading = false | ||||
|       } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user