mirror of
				https://github.com/crater-invoice/crater.git
				synced 2025-10-31 05:31:10 -04:00 
			
		
		
		
	init crater
This commit is contained in:
		
							
								
								
									
										334
									
								
								resources/assets/js/views/settings/CompanyInfo.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										334
									
								
								resources/assets/js/views/settings/CompanyInfo.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,334 @@ | ||||
| <template> | ||||
|   <div class="setting-main-container"> | ||||
|     <form action="" @submit.prevent="updateCompany"> | ||||
|       <div class="card setting-card"> | ||||
|         <div class="page-header"> | ||||
|           <h3 class="page-title">{{ $t('settings.company_info.company_info') }}</h3> | ||||
|           <p class="page-sub-title"> | ||||
|             {{ $t('settings.company_info.section_description') }} | ||||
|           </p> | ||||
|         </div> | ||||
|         <div class="row mb-4"> | ||||
|           <div class="col-md-6"> | ||||
|             <label class="input-label">{{ $tc('settings.company_info.company_logo') }}</label> | ||||
|             <div id="pick-avatar" class="image-upload-box"> | ||||
|               <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"/> | ||||
|                 <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" | ||||
|           /> | ||||
|         </div> | ||||
|         <div class="row"> | ||||
|           <div class="col-md-6 mb-4"> | ||||
|             <label class="input-label">{{ $tc('settings.company_info.company_name') }}</label> <span class="text-danger"> * </span> | ||||
|             <base-input | ||||
|               v-model="formData.name" | ||||
|               :invalid="$v.formData.name.$error" | ||||
|               :placeholder="$t('settings.company_info.company_name')" | ||||
|               @input="$v.formData.name.$touch()" | ||||
|             /> | ||||
|             <div v-if="$v.formData.name.$error"> | ||||
|               <span v-if="!$v.formData.name.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4"> | ||||
|             <label class="input-label">{{ $tc('settings.company_info.phone') }}</label> | ||||
|             <base-input | ||||
|               v-model="formData.phone" | ||||
|               :invalid="$v.formData.phone.$error" | ||||
|               :placeholder="$t('settings.company_info.phone')" | ||||
|               @input="$v.formData.phone.$touch()" | ||||
|             /> | ||||
|             <div v-if="$v.formData.phone.$error"> | ||||
|               <span v-if="!$v.formData.phone.phone" class="text-danger">{{ $tc('validation.numbers_only') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4"> | ||||
|             <label class="input-label">{{ $tc('settings.company_info.country') }}</label><span class="text-danger"> * </span> | ||||
|             <base-select | ||||
|               v-model="country" | ||||
|               :options="countries" | ||||
|               :class="{'error': $v.formData.country_id.$error }" | ||||
|               :searchable="true" | ||||
|               :show-labels="false" | ||||
|               :allow-empty="false" | ||||
|               :placeholder="$t('general.select_country')" | ||||
|               label="name" | ||||
|               track-by="id" | ||||
|             /> | ||||
|             <div v-if="$v.formData.country_id.$error"> | ||||
|               <span v-if="!$v.formData.country_id.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4"> | ||||
|             <label class="input-label">{{ $tc('settings.company_info.state') }}</label> | ||||
|             <base-select | ||||
|               v-model="state" | ||||
|               :options="states" | ||||
|               :searchable="true" | ||||
|               :disabled="isDisabledState" | ||||
|               :show-labels="false" | ||||
|               :placeholder="$t('general.select_state')" | ||||
|               label="name" | ||||
|               track-by="id" | ||||
|             /> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4"> | ||||
|             <label class="input-label">{{ $tc('settings.company_info.city') }}</label> | ||||
|             <base-select | ||||
|               v-model="city" | ||||
|               :options="cities" | ||||
|               :searchable="true" | ||||
|               :show-labels="false" | ||||
|               :disabled="isDisabledCity" | ||||
|               :placeholder="$t('general.select_city')" | ||||
|               label="name" | ||||
|               track-by="id" | ||||
|             /> | ||||
|           </div> | ||||
|           <!-- <div class="col-md-6 mb-3"> | ||||
|             <label class="input-label">Website</label> | ||||
|             <base-input | ||||
|               v-model="formData.website" | ||||
|               placeholder="Website" | ||||
|             /> | ||||
|           </div> --> | ||||
|           <div class="col-md-6 mb-4"> | ||||
|             <label class="input-label">{{ $tc('settings.company_info.zip') }}</label> | ||||
|             <base-input | ||||
|               v-model="formData.zip" | ||||
|               :placeholder="$tc('settings.company_info.zip')" | ||||
|             /> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4"> | ||||
|             <label class="input-label">{{ $tc('settings.company_info.address') }}</label> | ||||
|             <base-text-area | ||||
|               v-model="formData.address_street_1" | ||||
|               :placeholder="$tc('general.street_1')" | ||||
|               rows="2" | ||||
|             /> | ||||
|             <base-text-area | ||||
|               v-model="formData.address_street_2" | ||||
|               :placeholder="$tc('general.street_1')" | ||||
|               rows="2" | ||||
|             /> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="row"> | ||||
|           <div class="col-md-12"> | ||||
|             <base-button | ||||
|               :loading="isLoading" | ||||
|               :disabled="isLoading" | ||||
|               icon="save" | ||||
|               color="theme" | ||||
|               type="submit" | ||||
|             > | ||||
|               {{ $tc('settings.company_info.save') }} | ||||
|             </base-button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </form> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| import IconUpload from '../../components/icon/upload' | ||||
| import ImageBox from '../components/ImageBox.vue' | ||||
| import AvatarCropper from 'vue-avatar-cropper' | ||||
| import { validationMixin } from 'vuelidate' | ||||
| import { mapActions } from 'vuex' | ||||
| const { required, email, numeric } = require('vuelidate/lib/validators') | ||||
|  | ||||
| export default { | ||||
|   components: { AvatarCropper, IconUpload, ImageBox }, | ||||
|   mixins: [validationMixin], | ||||
|   data () { | ||||
|     return { | ||||
|       cropperOutputOptions: { | ||||
|         width: 150, | ||||
|         height: 150 | ||||
|       }, | ||||
|       cropperOptions: { | ||||
|         autoCropArea: 1, | ||||
|         viewMode: 0, | ||||
|         movable: true, | ||||
|         zoomable: true | ||||
|       }, | ||||
|       isFetchingData: false, | ||||
|       formData: { | ||||
|         name: '', | ||||
|         logo: null, | ||||
|         email: '', | ||||
|         phone: null, | ||||
|         zip: null, | ||||
|         address_street_1: null, | ||||
|         address_street_2: null, | ||||
|         website: null, | ||||
|         country_id: null, | ||||
|         state_id: '', | ||||
|         city_id: '' | ||||
|       }, | ||||
|       isLoading: false, | ||||
|       isHidden: false, | ||||
|       country: null, | ||||
|       previewLogo: null, | ||||
|       city: null, | ||||
|       state: null, | ||||
|       countries: [], | ||||
|       isDisabledState: true, | ||||
|       isDisabledCity: true, | ||||
|       states: [], | ||||
|       cities: [], | ||||
|       passData: [], | ||||
|       fileSendUrl: '/api/settings/company', | ||||
|       fileObject: null | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     country (newCountry) { | ||||
|       this.formData.country_id = newCountry.id | ||||
|       if (this.formData.country_id) { | ||||
|         this.isDisabledState = false | ||||
|       } | ||||
|       this.fetchState() | ||||
|       if (this.isFetchingData) { | ||||
|         return true | ||||
|       } | ||||
|  | ||||
|       this.state = null | ||||
|       this.city = null | ||||
|     }, | ||||
|     state (newState) { | ||||
|       if (newState !== null && newState !== undefined) { | ||||
|         this.formData.state_id = newState.id | ||||
|         this.fetchCities() | ||||
|         this.isDisabledCity = false | ||||
|  | ||||
|         if (this.isFetchingData) { | ||||
|           this.isFetchingData = false | ||||
|           return true | ||||
|         } | ||||
|         this.city = null | ||||
|         return true | ||||
|       } | ||||
|       // this.formData.state_id = null | ||||
|       this.cities = [] | ||||
|       this.city = null | ||||
|       // this.formData.city_id = null | ||||
|       this.isDisabledCity = true | ||||
|       return true | ||||
|     }, | ||||
|     city (newCity) { | ||||
|       if (newCity !== null && newCity !== undefined) { | ||||
|         this.formData.city_id = newCity.id | ||||
|         return true | ||||
|       } | ||||
|       // this.formData.city_id = null | ||||
|       // return true | ||||
|     } | ||||
|   }, | ||||
|   validations: { | ||||
|     formData: { | ||||
|       name: { | ||||
|         required | ||||
|       }, | ||||
|       country_id: { | ||||
|         required | ||||
|       }, | ||||
|       email: { | ||||
|         email | ||||
|       }, | ||||
|       phone: { | ||||
|         numeric | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   mounted () { | ||||
|     this.fetchCountry() | ||||
|     this.setInitialData() | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('companyInfo', [ | ||||
|       'loadData', | ||||
|       'editCompany', | ||||
|       'getFile' | ||||
|     ]), | ||||
|     cropperHandler (cropper) { | ||||
|       this.previewLogo = cropper.getCroppedCanvas().toDataURL(this.cropperOutputMime) | ||||
|     }, | ||||
|     setFileObject (file) { | ||||
|       this.fileObject = file | ||||
|     }, | ||||
|     async setInitialData () { | ||||
|       let response = await this.loadData() | ||||
|       this.isFetchingData = true | ||||
|       this.formData.name = response.data.user.company.name | ||||
|       this.formData.address_street_1 = response.data.user.addresses[0].address_street_1 | ||||
|       this.formData.address_street_2 = response.data.user.addresses[0].address_street_2 | ||||
|       this.formData.zip = response.data.user.addresses[0].zip | ||||
|       this.formData.phone = response.data.user.addresses[0].phone | ||||
|       this.country = response.data.user.addresses[0].country | ||||
|       this.state = response.data.user.addresses[0].state | ||||
|       this.city = response.data.user.addresses[0].city | ||||
|       this.previewLogo = response.data.user.company.logo | ||||
|     }, | ||||
|     async updateCompany () { | ||||
|       this.$v.formData.$touch() | ||||
|       if (this.$v.$invalid) { | ||||
|         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) | ||||
|       if (this.fileObject) { | ||||
|         data.append('logo', this.fileObject) | ||||
|       } | ||||
|       let response = await this.editCompany(data) | ||||
|       if (response.data.success) { | ||||
|         this.isLoading = false | ||||
|         window.toastr['success'](this.$t('settings.company_info.updated_message')) | ||||
|         return true | ||||
|       } | ||||
|       window.toastr['error'](response.data.error) | ||||
|       return true | ||||
|     }, | ||||
|     async fetchCountry () { | ||||
|       let res = await window.axios.get('/api/countries') | ||||
|       if (res) { | ||||
|         this.countries = res.data.countries | ||||
|       } | ||||
|     }, | ||||
|     async fetchState () { | ||||
|       this.$v.formData.country_id.$touch() | ||||
|       let res = await window.axios.get(`/api/states/${this.country.id}`) | ||||
|       if (res) { | ||||
|         this.states = res.data.states | ||||
|       } | ||||
|     }, | ||||
|     async fetchCities () { | ||||
|       let res = await window.axios.get(`/api/cities/${this.state.id}`) | ||||
|       if (res) { | ||||
|         this.cities = res.data.cities | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										131
									
								
								resources/assets/js/views/settings/ExpenseCategory.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								resources/assets/js/views/settings/ExpenseCategory.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | ||||
| <template> | ||||
|  | ||||
|   <div class="setting-main-container"> | ||||
|     <div class="card setting-card"> | ||||
|       <div class="page-header d-flex justify-content-between"> | ||||
|         <div> | ||||
|           <h3 class="page-title">{{ $t('settings.expense_category.title') }}</h3> | ||||
|           <p class="page-sub-title"> | ||||
|             {{ $t('settings.expense_category.description') }} | ||||
|           </p> | ||||
|         </div> | ||||
|         <base-button | ||||
|           outline | ||||
|           class="add-new-tax" | ||||
|           color="theme" | ||||
|           @click="openCategoryModal" | ||||
|         > | ||||
|           {{ $t('settings.expense_category.add_new_category') }} | ||||
|         </base-button> | ||||
|       </div> | ||||
|  | ||||
|       <table-component | ||||
|         ref="table" | ||||
|         :show-filter="false" | ||||
|         :data="categories" | ||||
|         table-class="table expense-category" | ||||
|       > | ||||
|         <table-column | ||||
|           :label="$t('settings.expense_category.category_name')" | ||||
|           show="name" | ||||
|         /> | ||||
|         <table-column | ||||
|           :sortable="true" | ||||
|           :filterable="true" | ||||
|           :label="$t('settings.expense_category.category_description')" | ||||
|         > | ||||
|           <template slot-scope="row"> | ||||
|             <span>{{ $t('settings.expense_category.category_description') }}</span> | ||||
|             <div class="notes"> | ||||
|               <div class="note">{{ row.description }}</div> | ||||
|             </div> | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
|           :sortable="false" | ||||
|           :filterable="false" | ||||
|           cell-class="action-dropdown" | ||||
|         > | ||||
|           <template slot-scope="row"> | ||||
|             <span>{{ $t('settings.expense_category.action') }}</span> | ||||
|             <v-dropdown> | ||||
|               <a slot="activator" href="#"> | ||||
|                 <dot-icon /> | ||||
|               </a> | ||||
|               <v-dropdown-item> | ||||
|                 <div class="dropdown-item" @click="EditCategory(row.id)"> | ||||
|                   <font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon" /> | ||||
|                   {{ $t('general.edit') }} | ||||
|                 </div> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item> | ||||
|                 <div class="dropdown-item" @click="removeExpenseCategory(row.id)"> | ||||
|                   <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|                   {{ $t('general.delete') }} | ||||
|                 </div> | ||||
|               </v-dropdown-item> | ||||
|             </v-dropdown> | ||||
|           </template> | ||||
|         </table-column> | ||||
|       </table-component> | ||||
|     </div> | ||||
|   </div> | ||||
|  | ||||
| </template> | ||||
| <script> | ||||
|  | ||||
| import { mapActions, mapGetters } from 'vuex' | ||||
|  | ||||
| export default { | ||||
|   data () { | ||||
|     return { | ||||
|       id: null | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapGetters('category', [ | ||||
|       'categories', | ||||
|       'getCategoryById' | ||||
|     ]) | ||||
|   }, | ||||
|   mounted () { | ||||
|     this.fetchCategories() | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('modal', [ | ||||
|       'openModal' | ||||
|     ]), | ||||
|     ...mapActions('category', [ | ||||
|       'fetchCategories', | ||||
|       'fetchCategory', | ||||
|       'deleteCategory' | ||||
|     ]), | ||||
|     async removeExpenseCategory (id, index) { | ||||
|       let response = await this.deleteCategory(id) | ||||
|       if (response.data.success) { | ||||
|         window.toastr['success'](this.$tc('settings.expense_category.deleted_message')) | ||||
|         this.id = null | ||||
|         this.$refs.table.refresh() | ||||
|         return true | ||||
|       } window.toastr['success'](this.$t('settings.expense_category.already_in_use')) | ||||
|     }, | ||||
|     openCategoryModal () { | ||||
|       this.openModal({ | ||||
|         'title': 'Add Category', | ||||
|         'componentName': 'CategoryModal' | ||||
|       }) | ||||
|       this.$refs.table.refresh() | ||||
|     }, | ||||
|     async EditCategory (id) { | ||||
|       let response = await this.fetchCategory(id) | ||||
|       this.openModal({ | ||||
|         'title': 'Edit Category', | ||||
|         'componentName': 'CategoryModal', | ||||
|         'id': id, | ||||
|         'data': response.data.category | ||||
|       }) | ||||
|       this.$refs.table.refresh() | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										102
									
								
								resources/assets/js/views/settings/GeneralSetting.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								resources/assets/js/views/settings/GeneralSetting.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,102 @@ | ||||
| <template> | ||||
|   <div class="main-content"> | ||||
|     <div class="card setting-card"> | ||||
|       <div class="page-header"> | ||||
|         <h3 class="page-title">{{ $t('settings.title') }}</h3> | ||||
|         <ol class="breadcrumb"> | ||||
|           <li class="breadcrumb-item"><router-link slot="item-title" to="/admin/dashboard">{{ $t('general.home') }}</router-link></li> | ||||
|           <li class="breadcrumb-item"><router-link slot="item-title" to="#">{{ $t('settings.general') }}</router-link></li> | ||||
|         </ol> | ||||
|       </div> | ||||
|       <form action="" @submit.prevent="submitData"> | ||||
|         <div class="row"> | ||||
|           <div class="col-sm-8"> | ||||
|             <div class="card"> | ||||
|               <div class="card-header"> | ||||
|                 <div class="caption"> | ||||
|                   <h6>{{ $t('settings.general') }}</h6> | ||||
|                 </div> | ||||
|                 <div class="actions"> | ||||
|                   <base-button icon="backward" color="theme" size="small" type="submit"> | ||||
|                     {{ $t('general.save') }} | ||||
|                   </base-button> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="card-body"> | ||||
|                 <div class="form-group row"> | ||||
|                   <label class="col-md-2 form-control-label">{{ $t('settings.language') }}: </label> | ||||
|                   <div class="col-md-10"> | ||||
|                     <setting-dropdown | ||||
|                       :options="languages" | ||||
|                       :get-data="settings" | ||||
|                       :current-data="settings.language" | ||||
|                       type="languages" | ||||
|                     /> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="form-group row"> | ||||
|                   <label class="col-md-2 form-control-label">{{ $t('settings.primary_currency') }}: </label> | ||||
|                   <div class="col-md-10"> | ||||
|                     <setting-dropdown | ||||
|                       :options="currencies" | ||||
|                       :get-data="settings" | ||||
|                       :current-data="settings.currency" | ||||
|                       type="currencies" | ||||
|                     /> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="form-group row"> | ||||
|                   <label class="col-md-2 form-control-label">{{ $t('settings.timezone') }}: </label> | ||||
|                   <div class="col-md-10"> | ||||
|                     <setting-dropdown | ||||
|                       :options="time_zones" | ||||
|                       :get-data="settings" | ||||
|                       :current-data="settings.time_zone" | ||||
|                       type="time_zones" | ||||
|                     /> | ||||
|                   </div> | ||||
|                 </div> | ||||
|                 <div class="form-body"> | ||||
|                   <div class="form-group row"> | ||||
|                     <label class="col-md-2 form-control-label">{{ $t('settings.date_format') }}: </label> | ||||
|                     <div class="col-md-10"> | ||||
|                       <setting-dropdown | ||||
|                         :options="date_formats" | ||||
|                         :get-data="settings" | ||||
|                         :current-data="settings.date_format" | ||||
|                         type="date_formats" | ||||
|                       /> | ||||
|                     </div> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </form> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import SettingDropdown from '../components/SettingListBox.vue' | ||||
| import { mapActions } from 'vuex' | ||||
|  | ||||
| export default { | ||||
|   components: { | ||||
|     'setting-dropdown': SettingDropdown | ||||
|   }, | ||||
|   data () { | ||||
|     return this.$store.state.general | ||||
|   }, | ||||
|   mounted () { | ||||
|     this.loadData() | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('general', [ | ||||
|       'loadData', | ||||
|       'submitData' | ||||
|     ]) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										153
									
								
								resources/assets/js/views/settings/Notifications.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								resources/assets/js/views/settings/Notifications.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,153 @@ | ||||
| <template> | ||||
|   <div class="setting-main-container"> | ||||
|     <div class="card setting-card"> | ||||
|       <div class="page-header"> | ||||
|         <h3 class="page-title">{{ $t('settings.notification.title') }}</h3> | ||||
|         <p class="page-sub-title"> | ||||
|           {{ $t('settings.notification.description') }} | ||||
|         </p> | ||||
|       </div> | ||||
|       <form action="" @submit.prevent="saveEmail()"> | ||||
|         <div class="form-group"> | ||||
|           <label class="form-label">{{ $t('settings.notification.email') }}</label><span class="text-danger"> *</span> | ||||
|           <base-input | ||||
|             :invalid="$v.notification_email.$error" | ||||
|             v-model.trim="notification_email" | ||||
|             :placeholder="$tc('settings.notification.please_enter_email')" | ||||
|             type="text" | ||||
|             name="notification_email" | ||||
|             icon="envelope" | ||||
|             input-class="col-md-6" | ||||
|             @input="$v.notification_email.$touch()" | ||||
|           /> | ||||
|           <div v-if="$v.notification_email.$error"> | ||||
|             <span v-if="!$v.notification_email.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|             <span v-if="!$v.notification_email.email" class="text-danger"> {{ $tc('validation.email_incorrect') }} </span> | ||||
|           </div> | ||||
|           <base-button | ||||
|             :loading="isLoading" | ||||
|             :disabled="isLoading" | ||||
|             class="mt-4" | ||||
|             icon="save" | ||||
|             color="theme" | ||||
|             type="submit" | ||||
|           > {{ $tc('settings.notification.save') }} </base-button> | ||||
|         </div> | ||||
|       </form> | ||||
|       <hr> | ||||
|       <div class="flex-box mt-3 mb-4"> | ||||
|         <div class="left"> | ||||
|           <base-switch v-model="notify_invoice_viewed" class="btn-switch" @change="setInvoiceViewd"/> | ||||
|         </div> | ||||
|         <div class="right ml-15"> | ||||
|           <p class="box-title">  {{ $t('settings.notification.invoice_viewed') }} </p> | ||||
|           <p class="box-desc">  {{ $t('settings.notification.invoice_viewed_desc') }} </p> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="flex-box mb-2"> | ||||
|         <div class="left"> | ||||
|           <base-switch v-model="notify_estimate_viewed" class="btn-switch" @change="setEstimateViewd"/> | ||||
|         </div> | ||||
|         <div class="right ml-15"> | ||||
|           <p class="box-title">  {{ $t('settings.notification.estimate_viewed') }} </p> | ||||
|           <p class="box-desc">  {{ $t('settings.notification.estimate_viewed_desc') }} </p> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| import { validationMixin } from 'vuelidate' | ||||
| const { required, email } = require('vuelidate/lib/validators') | ||||
|  | ||||
| export default { | ||||
|  | ||||
|   mixins: [validationMixin], | ||||
|   data () { | ||||
|     return { | ||||
|       isLoading: false, | ||||
|       notification_email: null, | ||||
|       notify_invoice_viewed: null, | ||||
|       notify_estimate_viewed: null | ||||
|     } | ||||
|   }, | ||||
|   validations: { | ||||
|     notification_email: { | ||||
|       required, | ||||
|       email | ||||
|     } | ||||
|   }, | ||||
|   mounted () { | ||||
|     this.fetchData() | ||||
|   }, | ||||
|   methods: { | ||||
|     async fetchData () { | ||||
|       let response1 = await axios.get('/api/settings/get-setting?key=notify_invoice_viewed') | ||||
|       if (response1.data) { | ||||
|         let data = response1.data | ||||
|         data.notify_invoice_viewed === 'YES' ? | ||||
|           this.notify_invoice_viewed = true : | ||||
|           this.notify_invoice_viewed = null | ||||
|       } | ||||
|       let response2 = await axios.get('/api/settings/get-setting?key=notify_estimate_viewed') | ||||
|       if (response2.data) { | ||||
|         let data = response2.data | ||||
|         data.notify_estimate_viewed === 'YES' ? | ||||
|           this.notify_estimate_viewed = true : | ||||
|           this.notify_estimate_viewed = null | ||||
|       } | ||||
|       let response3 = await axios.get('/api/settings/get-setting?key=notification_email') | ||||
|       if (response3.data) { | ||||
|         this.notification_email = response3.data.notification_email | ||||
|       } | ||||
|     }, | ||||
|     async saveEmail () { | ||||
|       this.$v.$touch() | ||||
|       if (this.$v.$invalid) { | ||||
|         return true | ||||
|       } | ||||
|       this.isLoading = true | ||||
|       let data = { | ||||
|         key: 'notification_email', | ||||
|         value: this.notification_email | ||||
|       } | ||||
|       let response = await axios.put('/api/settings/update-setting', data) | ||||
|       if (response.data.success) { | ||||
|         this.isLoading = false | ||||
|         window.toastr['success'](this.$tc('settings.notification.email_save_message')) | ||||
|       } | ||||
|     }, | ||||
|     async setInvoiceViewd (val) { | ||||
|       this.$v.$touch() | ||||
|       if (this.$v.$invalid) { | ||||
|         this.notify_invoice_viewed = !this.notify_invoice_viewed | ||||
|         return true | ||||
|       } | ||||
|       let data = { | ||||
|         key: 'notify_invoice_viewed', | ||||
|         value: this.notify_invoice_viewed ? 'YES' : 'NO' | ||||
|       } | ||||
|  | ||||
|       let response = await axios.put('/api/settings/update-setting', data) | ||||
|       if (response.data.success) { | ||||
|         window.toastr['success'](this.$tc('general.setting_updated')) | ||||
|       } | ||||
|     }, | ||||
|     async setEstimateViewd (val) { | ||||
|       this.$v.$touch() | ||||
|       if (this.$v.$invalid) { | ||||
|         this.notify_estimate_viewed = !this.notify_estimate_viewed | ||||
|         return true | ||||
|       } | ||||
|       let data = { | ||||
|         key: 'notify_estimate_viewed', | ||||
|         value: this.notify_estimate_viewed ? 'YES' : 'NO' | ||||
|       } | ||||
|       let response = await axios.put('/api/settings/update-setting', data) | ||||
|       if (response.data) { | ||||
|         window.toastr['success'](this.$tc('general.setting_updated')) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										74
									
								
								resources/assets/js/views/settings/PDFSetting.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								resources/assets/js/views/settings/PDFSetting.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | ||||
| <template> | ||||
|   <div class="main-content pdfsetting"> | ||||
|     <div class="page-header"> | ||||
|       <h3 class="page-title">{{ $t('settings.title') }}</h3> | ||||
|       <ol class="breadcrumb"> | ||||
|         <li class="breadcrumb-item"><router-link slot="item-title" to="/admin/dashboard">{{ $t('general.home') }}</router-link></li> | ||||
|         <li class="breadcrumb-item"><router-link slot="item-title" to="#">{{ $t('settings.pdf.title') }}</router-link></li> | ||||
|       </ol> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|       <div class="col-sm-12"> | ||||
|         <div class="card"> | ||||
|           <div class="card-header"> | ||||
|             <div class="caption"> | ||||
|               <h6>{{ $t('settings.pdf.title') }}</h6> | ||||
|             </div> | ||||
|             <div class="actions"> | ||||
|               <base-button color="theme" size="small" @click="submitData"> | ||||
|                 {{ $t('general.update') }} | ||||
|               </base-button> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="card-body"> | ||||
|             <div class="row"> | ||||
|               <label class="col-md-2 form-control-label">{{ $t('settings.pdf.footer_text') }} : </label> | ||||
|               <div class="col-md-12"> | ||||
|                 <input v-model="footerText" type="text" class="form-control"> | ||||
|               </div> | ||||
|             </div> | ||||
|             <div class="row pdfsetting__img-row"> | ||||
|               <label class="col-md-2 form-control-label">{{ $t('settings.pdf.pdf_layout') }} : </label> | ||||
|               <div class="col-md-12"> | ||||
|                 <image-radio :current-p-d-f="pdfSet" @selectedPDF="selectedPDF"/> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import ImageRadio from '../components/ImageRadio.vue' | ||||
| import { mapActions, mapMutations } from 'vuex' | ||||
|  | ||||
| export default { | ||||
|   components: { | ||||
|     'image-radio': ImageRadio | ||||
|   }, | ||||
|   data () { | ||||
|     return this.$store.state.pdf_setting | ||||
|     // return { | ||||
|     //   pdfSet: '1', | ||||
|     //   footerText: null | ||||
|     // } | ||||
|   }, | ||||
|   mounted () { | ||||
|     this.loadData() | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('pdf_setting', [ | ||||
|       'loadData', | ||||
|       'submitData' | ||||
|     ]), | ||||
|     // async submitData () { | ||||
|  | ||||
|     // }, | ||||
|     ...mapMutations('pdf_setting', [ | ||||
|       'selectedPDF' | ||||
|     ]) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										243
									
								
								resources/assets/js/views/settings/Preferences.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										243
									
								
								resources/assets/js/views/settings/Preferences.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,243 @@ | ||||
| <template> | ||||
|   <div class="setting-main-container"> | ||||
|     <div class="card setting-card"> | ||||
|       <div class="page-header"> | ||||
|         <h3 class="page-title">{{ $tc('settings.preferences.preference',2) }}</h3> | ||||
|         <p class="page-sub-title"> | ||||
|           {{ $t('settings.preferences.general_settings') }} | ||||
|         </p> | ||||
|       </div> | ||||
|       <form action="" @submit.prevent="updatePreferencesData"> | ||||
|         <div class="row"> | ||||
|           <div class="col-md-6 mb-4 form-group"> | ||||
|             <label class="input-label">{{ $tc('settings.preferences.currency') }}</label><span class="text-danger"> * </span> | ||||
|             <base-select | ||||
|               v-model="formData.currency" | ||||
|               :options="currencies" | ||||
|               :class="{'error': $v.formData.currency.$error }" | ||||
|               :searchable="true" | ||||
|               :show-labels="false" | ||||
|               :allow-empty="false" | ||||
|               :placeholder="$tc('settings.currencies.select_currency')" | ||||
|               label="name" | ||||
|               track-by="id" | ||||
|             /> | ||||
|             <div v-if="$v.formData.currency.$error"> | ||||
|               <span v-if="!$v.formData.currency.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4 form-group"> | ||||
|             <label class="input-label">{{ $tc('settings.preferences.language') }}</label><span class="text-danger"> * </span> | ||||
|             <base-select | ||||
|               v-model="formData.language" | ||||
|               :options="languages" | ||||
|               :class="{'error': $v.formData.language.$error }" | ||||
|               :searchable="true" | ||||
|               :show-labels="false" | ||||
|               :allow-empty="false" | ||||
|               :placeholder="$tc('settings.preferences.select_language')" | ||||
|               label="name" | ||||
|               track-by="code" | ||||
|             /> | ||||
|             <div v-if="$v.formData.language.$error"> | ||||
|               <span v-if="!$v.formData.language.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4 form-group"> | ||||
|             <label class="input-label">{{ $tc('settings.preferences.time_zone') }}</label><span class="text-danger"> * </span> | ||||
|             <base-select | ||||
|               v-model="formData.timeZone" | ||||
|               :options="timeZones" | ||||
|               :class="{'error': $v.formData.timeZone.$error }" | ||||
|               :searchable="true" | ||||
|               :show-labels="false" | ||||
|               :allow-empty="false" | ||||
|               :placeholder="$tc('settings.preferences.select_time_zone')" | ||||
|               label="key" | ||||
|               track-by="key" | ||||
|             /> | ||||
|             <div v-if="$v.formData.timeZone.$error"> | ||||
|               <span v-if="!$v.formData.timeZone.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4 form-group"> | ||||
|             <label class="input-label">{{ $tc('settings.preferences.date_format') }}</label><span class="text-danger"> * </span> | ||||
|             <base-select | ||||
|               v-model="formData.dateFormat" | ||||
|               :options="dateFormats" | ||||
|               :class="{'error': $v.formData.dateFormat.$error }" | ||||
|               :searchable="true" | ||||
|               :show-labels="false" | ||||
|               :allow-empty="false" | ||||
|               :placeholder="$tc('settings.preferences.select_date_formate')" | ||||
|               label="display_date" | ||||
|             /> | ||||
|             <div v-if="$v.formData.dateFormat.$error"> | ||||
|               <span v-if="!$v.formData.dateFormat.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4 form-group"> | ||||
|             <label class="input-label">{{ $tc('settings.preferences.fiscal_year') }}</label><span class="text-danger"> * </span> | ||||
|             <base-select | ||||
|               v-model="formData.fiscalYear" | ||||
|               :options="fiscalYears" | ||||
|               :class="{'error': $v.formData.fiscalYear.$error }" | ||||
|               :show-labels="false" | ||||
|               :allow-empty="false" | ||||
|               :searchable="true" | ||||
|               :placeholder="$tc('settings.preferences.select_financial_year')" | ||||
|               label="key" | ||||
|               track-by="value" | ||||
|             /> | ||||
|             <div v-if="$v.formData.fiscalYear.$error"> | ||||
|               <span v-if="!$v.formData.fiscalYear.required" class="text-danger">{{ $tc('settings.company_info.errors.required') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="row mb-3"> | ||||
|           <div class="col-md-12 input-group"> | ||||
|             <base-button | ||||
|               :loading="isLoading" | ||||
|               :disabled="isLoading" | ||||
|               icon="save" | ||||
|               color="theme" | ||||
|               type="submit" | ||||
|             > | ||||
|               {{ $tc('settings.company_info.save') }} | ||||
|             </base-button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </form> | ||||
|       <hr> | ||||
|       <div class="page-header mt-3"> | ||||
|         <h3 class="page-title">{{ $t('settings.preferences.discount_setting') }}</h3> | ||||
|         <div class="flex-box"> | ||||
|           <div class="left"> | ||||
|             <base-switch v-model="discount_per_item" class="btn-switch" @change="setDiscount" /> | ||||
|           </div> | ||||
|           <div class="right ml-15"> | ||||
|             <p class="box-title">  {{ $t('settings.preferences.discount_per_item') }} </p> | ||||
|             <p class="box-desc">  {{ $t('settings.preferences.discount_setting_description') }} </p> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| import MultiSelect from 'vue-multiselect' | ||||
| import { validationMixin } from 'vuelidate' | ||||
| import { mapActions } from 'vuex' | ||||
| const { required } = require('vuelidate/lib/validators') | ||||
|  | ||||
| export default { | ||||
|   components: { MultiSelect }, | ||||
|   mixins: [validationMixin], | ||||
|   data () { | ||||
|     return { | ||||
|       isLoading: false, | ||||
|       formData: { | ||||
|         language: null, | ||||
|         currency: null, | ||||
|         timeZone: null, | ||||
|         dateFormat: null, | ||||
|         fiscalYear: null | ||||
|       }, | ||||
|       discount_per_item: null, | ||||
|       languages: [], | ||||
|       currencies: [], | ||||
|       timeZones: [], | ||||
|       dateFormats: [], | ||||
|       fiscalYears: [] | ||||
|     } | ||||
|   }, | ||||
|   validations: { | ||||
|     formData: { | ||||
|       currency: { | ||||
|         required | ||||
|       }, | ||||
|       language: { | ||||
|         required | ||||
|       }, | ||||
|       dateFormat: { | ||||
|         required | ||||
|       }, | ||||
|       timeZone: { | ||||
|         required | ||||
|       }, | ||||
|       fiscalYear: { | ||||
|         required | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   mounted () { | ||||
|     this.setInitialData() | ||||
|     this.getDiscountSettings() | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('currency', [ | ||||
|       'setDefaultCurrency' | ||||
|     ]), | ||||
|     ...mapActions('preferences', [ | ||||
|       'loadData', | ||||
|       'editPreferences' | ||||
|     ]), | ||||
|     async setInitialData () { | ||||
|       let response = await this.loadData() | ||||
|       this.languages = [...response.data.languages] | ||||
|       this.currencies = response.data.currencies | ||||
|       this.dateFormats = response.data.date_formats | ||||
|       this.timeZones = response.data.time_zones | ||||
|       this.fiscalYears = [...response.data.fiscal_years] | ||||
|       this.formData.currency = response.data.currencies.find(currency => currency.id == response.data.selectedCurrency) | ||||
|       this.formData.language = response.data.languages.find(language => language.code == response.data.selectedLanguage) | ||||
|       this.formData.timeZone = response.data.time_zones.find(timeZone => timeZone.value == response.data.time_zone) | ||||
|       this.formData.fiscalYear = response.data.fiscal_years.find(fiscalYear => fiscalYear.value == response.data.fiscal_year) | ||||
|       this.formData.dateFormat = response.data.date_formats.find(dateFormat => dateFormat.carbon_format_value == response.data.carbon_date_format) | ||||
|     }, | ||||
|     async updatePreferencesData () { | ||||
|       this.$v.formData.$touch() | ||||
|       if (this.$v.$invalid) { | ||||
|         return true | ||||
|       } | ||||
|       this.isLoading = true | ||||
|       let data = { | ||||
|         currency: this.formData.currency.id, | ||||
|         time_zone: this.formData.timeZone.value, | ||||
|         fiscal_year: this.formData.fiscalYear.value, | ||||
|         language: this.formData.language.code, | ||||
|         carbon_date_format: this.formData.dateFormat.carbon_format_value, | ||||
|         moment_date_format: this.formData.dateFormat.moment_format_value | ||||
|       } | ||||
|       let response = await this.editPreferences(data) | ||||
|       if (response.data.success) { | ||||
|         this.isLoading = false | ||||
|         window.i18n.locale = this.formData.language.code | ||||
|         this.setDefaultCurrency(this.formData.currency) | ||||
|         window.toastr['success'](this.$t('settings.preferences.updated_message')) | ||||
|         return true | ||||
|       } | ||||
|       window.toastr['error'](response.data.error) | ||||
|       return true | ||||
|     }, | ||||
|     async getDiscountSettings () { | ||||
|       let response = await axios.get('/api/settings/get-setting?key=discount_per_item') | ||||
|       if (response.data) { | ||||
|         response.data.discount_per_item === 'YES' ? | ||||
|           this.discount_per_item = true : | ||||
|           this.discount_per_item = false | ||||
|       } | ||||
|     }, | ||||
|     async setDiscount () { | ||||
|       let data = { | ||||
|         key: 'discount_per_item', | ||||
|         value: this.discount_per_item ? 'YES' : 'NO' | ||||
|       } | ||||
|       let response = await axios.put('/api/settings/update-setting', data) | ||||
|       if (response.data.success) { | ||||
|         window.toastr['success'](this.$t('general.setting_updated')) | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										189
									
								
								resources/assets/js/views/settings/TaxTypes.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								resources/assets/js/views/settings/TaxTypes.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,189 @@ | ||||
| <template> | ||||
|   <div class="setting-main-container"> | ||||
|     <div class="card setting-card"> | ||||
|       <div class="page-header d-flex justify-content-between"> | ||||
|         <div> | ||||
|           <h3 class="page-title"> | ||||
|             {{ $t('settings.tax_types.title') }} | ||||
|           </h3> | ||||
|           <p class="page-sub-title"> | ||||
|             {{ $t('settings.tax_types.description') }} | ||||
|           </p> | ||||
|         </div> | ||||
|         <base-button | ||||
|           outline | ||||
|           class="add-new-tax" | ||||
|           color="theme" | ||||
|           @click="openTaxModal" | ||||
|         > | ||||
|           {{ $t('settings.tax_types.add_new_tax') }} | ||||
|         </base-button> | ||||
|       </div> | ||||
|  | ||||
|       <table-component | ||||
|         ref="table" | ||||
|         :show-filter="false" | ||||
|         :data="taxTypes" | ||||
|         table-class="table tax-table" | ||||
|         class="mb-3" | ||||
|       > | ||||
|         <table-column | ||||
|           :sortable="true" | ||||
|           :filterable="true" | ||||
|           :label="$t('settings.tax_types.tax_name')" | ||||
|         > | ||||
|           <template slot-scope="row"> | ||||
|             <span>{{ $t('settings.tax_types.tax_name') }}</span> | ||||
|             <span class="tax-name"> | ||||
|               {{ row.name }} | ||||
|             </span> | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
|           :sortable="true" | ||||
|           :filterable="true" | ||||
|           :label="$t('settings.tax_types.compound_tax')" | ||||
|         > | ||||
|           <template slot-scope="row"> | ||||
|             <span>{{ $t('settings.tax_types.compound_tax') }}</span> | ||||
|             <div class="compound-tax"> | ||||
|               {{ row.compound_tax ? 'Yes' : 'No' }} | ||||
|             </div> | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
|           :sortable="true" | ||||
|           :filterable="true" | ||||
|           :label="$t('settings.tax_types.percent')" | ||||
|         > | ||||
|           <template slot-scope="row"> | ||||
|             <span>{{ $t('settings.tax_types.percent') }}</span> | ||||
|             {{ row.percent }} % | ||||
|           </template> | ||||
|         </table-column> | ||||
|         <table-column | ||||
|           :sortable="false" | ||||
|           :filterable="false" | ||||
|           cell-class="action-dropdown" | ||||
|         > | ||||
|           <template slot-scope="row"> | ||||
|             <span>{{ $t('settings.tax_types.action') }}</span> | ||||
|             <v-dropdown> | ||||
|               <a slot="activator" href="#"> | ||||
|                 <dot-icon /> | ||||
|               </a> | ||||
|               <v-dropdown-item> | ||||
|                 <div class="dropdown-item" @click="EditTax(row.id)"> | ||||
|                   <font-awesome-icon :icon="['fas', 'pencil-alt']" class="dropdown-item-icon" /> | ||||
|                   {{ $t('general.edit') }} | ||||
|                 </div> | ||||
|               </v-dropdown-item> | ||||
|               <v-dropdown-item> | ||||
|                 <div class="dropdown-item" @click="removeTax(row.id)"> | ||||
|                   <font-awesome-icon :icon="['fas', 'trash']" class="dropdown-item-icon" /> | ||||
|                   {{ $t('general.delete') }} | ||||
|                 </div> | ||||
|               </v-dropdown-item> | ||||
|             </v-dropdown> | ||||
|           </template> | ||||
|         </table-column> | ||||
|       </table-component> | ||||
|       <hr> | ||||
|       <div class="page-header mt-3"> | ||||
|         <h3 class="page-title"> | ||||
|           {{ $t('settings.tax_types.tax_settings') }} | ||||
|         </h3> | ||||
|         <div class="flex-box"> | ||||
|           <div class="left"> | ||||
|             <base-switch | ||||
|               v-model="formData.tax_per_item" | ||||
|               class="btn-switch" | ||||
|               @change="setTax" | ||||
|             /> | ||||
|           </div> | ||||
|           <div class="right ml-15"> | ||||
|             <p class="box-title">  {{ $t('settings.tax_types.tax_per_item') }} </p> | ||||
|             <p class="box-desc">  {{ $t('settings.tax_types.tax_setting_description') }} </p> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import { mapActions, mapGetters } from 'vuex' | ||||
| export default { | ||||
|   data () { | ||||
|     return { | ||||
|       id: null, | ||||
|       formData: { | ||||
|         tax_per_item: false | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     ...mapGetters('taxType', [ | ||||
|       'taxTypes', | ||||
|       'getTaxTypeById' | ||||
|     ]) | ||||
|   }, | ||||
|   mounted () { | ||||
|     this.getTaxSetting() | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('modal', [ | ||||
|       'openModal' | ||||
|     ]), | ||||
|     ...mapActions('taxType', [ | ||||
|       'indexLoadData', | ||||
|       'deleteTaxType', | ||||
|       'fetchTaxType' | ||||
|     ]), | ||||
|     async getTaxSetting (val) { | ||||
|       let response = await axios.get('/api/settings/get-setting?key=tax_per_item') | ||||
|       if (response.data) { | ||||
|         response.data.tax_per_item === 'YES' ? | ||||
|           this.formData.tax_per_item = true : | ||||
|           this.formData.tax_per_item = false | ||||
|       } | ||||
|     }, | ||||
|     async setTax (val) { | ||||
|       let data = { | ||||
|         key: 'tax_per_item', | ||||
|         value: this.formData.tax_per_item ? 'YES' : 'NO' | ||||
|       } | ||||
|       let response = await axios.put('/api/settings/update-setting', data) | ||||
|       if (response.data) { | ||||
|         window.toastr['success'](this.$t('general.setting_updated')) | ||||
|       } | ||||
|     }, | ||||
|     async removeTax (id, index) { | ||||
|       let response = await this.deleteTaxType(id) | ||||
|       if (response.data.success) { | ||||
|         window.toastr['success'](this.$t('settings.sales_taxes.deleted_message')) | ||||
|         this.id = null | ||||
|         this.$refs.table.refresh() | ||||
|         return true | ||||
|       }window.toastr['success'](this.$t('settings.sales_taxes.already_in_use')) | ||||
|     }, | ||||
|     openTaxModal () { | ||||
|       this.openModal({ | ||||
|         'title': 'Add Tax', | ||||
|         'componentName': 'TaxTypeModal' | ||||
|       }) | ||||
|       this.$refs.table.refresh() | ||||
|     }, | ||||
|     async EditTax (id) { | ||||
|       let response = await this.fetchTaxType(id) | ||||
|       this.openModal({ | ||||
|         'title': 'Edit Tax', | ||||
|         'componentName': 'TaxTypeModal', | ||||
|         'id': id, | ||||
|         'data': response.data.taxType | ||||
|       }) | ||||
|       this.$refs.table.refresh() | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										158
									
								
								resources/assets/js/views/settings/UserProfile.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								resources/assets/js/views/settings/UserProfile.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,158 @@ | ||||
| <template> | ||||
|   <div class="setting-main-container"> | ||||
|     <form action="" @submit.prevent="updateUserData"> | ||||
|       <div class="card setting-card"> | ||||
|         <div class="page-header"> | ||||
|           <h3 class="page-title">{{ $t('settings.account_settings.account_settings') }}</h3> | ||||
|           <p class="page-sub-title"> | ||||
|             {{ $t('settings.account_settings.section_description') }} | ||||
|           </p> | ||||
|         </div> | ||||
|         <div class="row"> | ||||
|           <div class="col-md-6 mb-4 form-group"> | ||||
|             <label class="input-label">{{ $tc('settings.account_settings.name') }}</label> | ||||
|             <base-input | ||||
|               v-model="formData.name" | ||||
|               :invalid="$v.formData.name.$error" | ||||
|               :placeholder="$t('settings.user_profile.name')" | ||||
|               @input="$v.formData.name.$touch()" | ||||
|             /> | ||||
|             <div v-if="$v.formData.name.$error"> | ||||
|               <span v-if="!$v.formData.name.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4 form-group"> | ||||
|             <label class="input-label">{{ $tc('settings.account_settings.email') }}</label> | ||||
|             <base-input | ||||
|               v-model="formData.email" | ||||
|               :invalid="$v.formData.email.$error" | ||||
|               :placeholder="$t('settings.user_profile.email')" | ||||
|               @input="$v.formData.email.$touch()" | ||||
|             /> | ||||
|             <div v-if="$v.formData.email.$error"> | ||||
|               <span v-if="!$v.formData.email.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|               <span v-if="!$v.formData.email.email" class="text-danger">{{ $tc('validation.email_incorrect') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4 form-group"> | ||||
|             <label class="input-label">{{ $tc('settings.account_settings.password') }}</label> | ||||
|             <base-input | ||||
|               v-model="formData.password" | ||||
|               :invalid="$v.formData.password.$error" | ||||
|               :placeholder="$t('settings.user_profile.password')" | ||||
|               type="password" | ||||
|               @input="$v.formData.password.$touch()" | ||||
|             /> | ||||
|           </div> | ||||
|           <div class="col-md-6 mb-4 form-group"> | ||||
|             <label class="input-label">{{ $tc('settings.account_settings.confirm_password') }}</label> | ||||
|             <base-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()" | ||||
|             /> | ||||
|             <div v-if="$v.formData.confirm_password.$error"> | ||||
|               <span v-if="!$v.formData.confirm_password.sameAsPassword" class="text-danger">{{ $tc('validation.password_incorrect') }}</span> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|         <div class="row  mb-4"> | ||||
|           <div class="col-md-12 input-group"> | ||||
|             <base-button | ||||
|               :loading="isLoading" | ||||
|               :disabled="isLoading" | ||||
|               icon="save" | ||||
|               color="theme" | ||||
|               type="submit" | ||||
|             > | ||||
|               {{ $tc('settings.account_settings.save') }} | ||||
|             </base-button> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </form> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| import { validationMixin } from 'vuelidate' | ||||
| import { mapActions } from 'vuex' | ||||
| const { required, requiredIf, sameAs, email } = require('vuelidate/lib/validators') | ||||
|  | ||||
| export default { | ||||
|   mixins: [validationMixin], | ||||
|   data () { | ||||
|     return { | ||||
|       isLoading: false, | ||||
|       formData: { | ||||
|         name: null, | ||||
|         email: null, | ||||
|         password: null, | ||||
|         confirm_password: null | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   validations: { | ||||
|     formData: { | ||||
|       name: { | ||||
|         required | ||||
|       }, | ||||
|       email: { | ||||
|         required, | ||||
|         email | ||||
|       }, | ||||
|       password: { | ||||
|       }, | ||||
|       confirm_password: { | ||||
|         required: requiredIf('isRequired'), | ||||
|         sameAsPassword: sameAs('password') | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     isRequired () { | ||||
|       if (this.formData.password === null || this.formData.password === undefined || this.formData.password === '') { | ||||
|         return false | ||||
|       } | ||||
|       return true | ||||
|     } | ||||
|   }, | ||||
|   mounted () { | ||||
|     this.setInitialData() | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('userProfile', [ | ||||
|       'loadData', | ||||
|       'editUser' | ||||
|     ]), | ||||
|     async setInitialData () { | ||||
|       let response = await this.loadData() | ||||
|       this.formData.name = response.data.name | ||||
|       this.formData.email = response.data.email | ||||
|     }, | ||||
|     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 | ||||
|       } | ||||
|       if (this.formData.password != null && this.formData.password != undefined && this.formData.password != '') { | ||||
|         data = { ...data, password: this.formData.password } | ||||
|       } | ||||
|       let response = await this.editUser(data) | ||||
|       if (response.data.success) { | ||||
|         this.isLoading = false | ||||
|         window.toastr['success'](this.$t('settings.account_settings.updated_message')) | ||||
|         return true | ||||
|       } | ||||
|       window.toastr['error'](response.data.error) | ||||
|       return true | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										126
									
								
								resources/assets/js/views/settings/currency/Index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								resources/assets/js/views/settings/currency/Index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,126 @@ | ||||
| <template> | ||||
|   <div class="main-content"> | ||||
|     <div class="page-header"> | ||||
|       <h3 class="page-title">{{ $tc('navigation.currency', 2) }}</h3> | ||||
|       <ol class="breadcrumb"> | ||||
|         <li class="breadcrumb-item"> | ||||
|           <router-link | ||||
|             slot="item-title" | ||||
|             to="/admin/dashboard"> | ||||
|             {{ $t('navigation.home') }} | ||||
|           </router-link> | ||||
|         </li> | ||||
|         <li class="breadcrumb-item"> | ||||
|           <router-link | ||||
|             slot="item-title" | ||||
|             to="#"> | ||||
|             {{ $tc('navigation.currency', 2) }} | ||||
|           </router-link> | ||||
|         </li> | ||||
|       </ol> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|       <div class="col-sm-6"> | ||||
|         <div class="card"> | ||||
|           <div class="card-header"> | ||||
|             <div class="caption"> | ||||
|               <h6>{{ $t('settings.currencies.select_currency') }}:</h6> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="card-body"> | ||||
|             <div class="form-group"> | ||||
|               <select | ||||
|                 v-model.trim="currencyId" | ||||
|                 class="form-control" | ||||
|                 @change="selectCurrency()" | ||||
|               > | ||||
|                 <option | ||||
|                   v-for="(currency, index) in currencies" | ||||
|                   :key="index" | ||||
|                   :value="currency.id" | ||||
|                 > | ||||
|                   {{ currency.name }} | ||||
|                 </option> | ||||
|               </select> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|       <div class="col-sm-12"> | ||||
|         <div class="card"> | ||||
|           <div class="card-header"> | ||||
|             <div class="caption"> | ||||
|               <h6>{{ $t('settings.currencies.currencies_list') }}</h6> | ||||
|             </div> | ||||
|             <div class="actions"> | ||||
|               <router-link slot="item-title" to="currencies/create"> | ||||
|                 <base-button icon="plus" color="theme" size="small"> | ||||
|                   {{ $t('navigation.add') }} {{ $t('navigation.new') }} | ||||
|                 </base-button> | ||||
|               </router-link> | ||||
|             </div> | ||||
|           </div> | ||||
|           <div class="card-body"> | ||||
|             <table-component | ||||
|               ref="table" | ||||
|               :data="currencies" | ||||
|               table-class="table" | ||||
|               sort-by="name" | ||||
|               sort-order="asc" | ||||
|             > | ||||
|               <table-column :label="$t('settings.currencies.name')" show="name" /> | ||||
|               <table-column :label="$t('settings.currencies.code')" show="code" /> | ||||
|               <table-column :label="$t('settings.currencies.symbol')" show="symbol" /> | ||||
|               <table-column :label="$t('settings.currencies.precision')" show="precision" /> | ||||
|               <table-column :label="$t('settings.currencies.thousand_separator')" show="thousand_separator" /> | ||||
|               <table-column :label="$t('settings.currencies.decimal_separator')" show="decimal_separator" /> | ||||
|               <table-column | ||||
|                 :sortable="false" | ||||
|                 :filterable="false" | ||||
|                 :label="$t('settings.currencies.position')" | ||||
|               > | ||||
|                 <template slot-scope="row"> | ||||
|                   <span v-if="row.swap_currency_symbol === 0">{{ $t('settings.currencies.right') }}</span> | ||||
|                   <span v-if="row.swap_currency_symbol === 1">{{ $t('settings.currencies.left') }}</span> | ||||
|                 </template> | ||||
|               </table-column> | ||||
|               <table-column | ||||
|                 :sortable="false" | ||||
|                 :filterable="false" | ||||
|                 :label="$t('settings.currencies.action')" | ||||
|               > | ||||
|                 <template slot-scope="row"> | ||||
|                   <div class="table__actions"> | ||||
|                     <router-link slot="item-title" :to="{path: `currencies/${row.id}/edit`}">{{ $t('navigation.edit') }}</router-link> | ||||
|                     <div class="table__item--cursor-pointer" @click="removeItems(row.id)">{{ $t('navigation.delete') }}</div> | ||||
|                   </div> | ||||
|                 </template> | ||||
|               </table-column> | ||||
|             </table-component> | ||||
|           </div> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| import { mapActions } from 'vuex' | ||||
|  | ||||
| export default { | ||||
|   data () { | ||||
|     return this.$store.state.currency | ||||
|   }, | ||||
|   mounted () { | ||||
|     this.indexLoadData() | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('currency', [ | ||||
|       'indexLoadData', | ||||
|       'removeItems', | ||||
|       'selectCurrency' | ||||
|     ]) | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										185
									
								
								resources/assets/js/views/settings/currency/currency.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										185
									
								
								resources/assets/js/views/settings/currency/currency.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,185 @@ | ||||
| <template> | ||||
|   <div class="main-content currencycreate"> | ||||
|     <div class="page-header"> | ||||
|       <h3 class="page-title">{{ $t('settings.currencies.add_currency') }}</h3> | ||||
|       <ol class="breadcrumb"> | ||||
|         <li class="breadcrumb-item"><router-link slot="item-title" to="/admin/dashboard">{{ $t('general.home') }}</router-link></li> | ||||
|         <li class="breadcrumb-item"><router-link slot="item-title" to="/admin/settings/currencies">{{ $tc('settings.currencies.currency',2) }}</router-link></li> | ||||
|         <li class="breadcrumb-item"><a href="#">{{ $t('navigation.add') }}</a></li> | ||||
|       </ol> | ||||
|       <div class="page-actions"> | ||||
|         <router-link slot="item-title" to="/admin/settings/currencies"> | ||||
|           <base-button icon="backward" color="theme"> | ||||
|             {{ $t('navigation.go_back') }} | ||||
|           </base-button> | ||||
|         </router-link> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="row"> | ||||
|       <div class="col-sm-6"> | ||||
|         <div class="card"> | ||||
|           <form action="" @submit.prevent="submiteCurrency"> | ||||
|             <div class="card-body"> | ||||
|               <div class="form-group"> | ||||
|                 <label class="control-label">{{ $t('settings.currencies.name') }}:</label><span class="required text-danger"> *</span> | ||||
|                 <input | ||||
|                   :class="{ error: $v.formData.name.$error }" | ||||
|                   v-model.trim="formData.name" | ||||
|                   type="text" | ||||
|                   name="name" | ||||
|                   class="form-control" | ||||
|                   @input="$v.formData.name.$touch()" | ||||
|                 > | ||||
|                 <div v-if="$v.formData.name.$error"> | ||||
|                   <span v-if="!$v.formData.name.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="form-group"> | ||||
|                 <label class="control-label">{{ $t('settings.currencies.code') }}:</label><span class="required"> *</span> | ||||
|                 <input | ||||
|                   :class="{ error: $v.formData.code.$error }" | ||||
|                   v-model="formData.code" | ||||
|                   type="text" | ||||
|                   name="code" | ||||
|                   class="form-control" | ||||
|                   @input="$v.formData.code.$touch()" | ||||
|                 > | ||||
|                 <div v-if="$v.formData.code.$error"> | ||||
|                   <span v-if="!$v.formData.code.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="form-group"> | ||||
|                 <label class="control-label">{{ $t('settings.currencies.symbol') }}:</label> | ||||
|                 <input | ||||
|                   v-model="formData.symbol" | ||||
|                   type="text" | ||||
|                   name="symbol" | ||||
|                   class="form-control" | ||||
|                 > | ||||
|               </div> | ||||
|               <div class="form-group"> | ||||
|                 <label class="control-label">{{ $t('settings.currencies.precision') }}:</label> | ||||
|                 <input | ||||
|                   v-model="formData.precision" | ||||
|                   type="text" | ||||
|                   name="precision" | ||||
|                   class="form-control" | ||||
|                 > | ||||
|               </div> | ||||
|               <div class="form-group"> | ||||
|                 <label class="control-label">{{ $t('settings.currencies.thousand_separator') }}:</label><span class="required"> *</span> | ||||
|                 <input | ||||
|                   :class="{ error: $v.formData.thousand_separator.$error }" | ||||
|                   v-model="formData.thousand_separator" | ||||
|                   type="text" | ||||
|                   name="thousand_separator" | ||||
|                   class="form-control" | ||||
|                   @input="$v.formData.thousand_separator.$touch()" | ||||
|                 > | ||||
|                 <div v-if="$v.formData.thousand_separator.$error"> | ||||
|                   <span v-if="!$v.formData.thousand_separator.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="form-group"> | ||||
|                 <label class="control-label">{{ $t('settings.currencies.decimal_separator') }}:</label><span class="required"> *</span> | ||||
|                 <input | ||||
|                   :class="{ error: $v.formData.decimal_separator.$error }" | ||||
|                   v-model="formData.decimal_separator" | ||||
|                   type="text" | ||||
|                   name="decimal_separator" | ||||
|                   class="form-control" | ||||
|                   @input="$v.formData.decimal_separator.$touch()" | ||||
|                 > | ||||
|                 <div v-if="$v.formData.decimal_separator.$error"> | ||||
|                   <span v-if="!$v.formData.decimal_separator.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <div class="form-group"> | ||||
|                 <label>{{ $t('settings.currencies.position_of_symbol') }}:</label><span class="required"> *</span> | ||||
|                 <select | ||||
|                   v-model="formData.swap_currency_symbol" | ||||
|                   :class="{ error: $v.formData.swap_currency_symbol.$error }" | ||||
|                   class="form-control ls-select2" | ||||
|                   name="swap_currency_symbol" | ||||
|                   @select="$v.formData.swap_currency_symbol.$touch()" | ||||
|                 > | ||||
|                   <option value="0">{{ $t('settings.currencies.right') }}</option> | ||||
|                   <option value="1">{{ $t('settings.currencies.left') }}</option> | ||||
|                 </select> | ||||
|                 <div v-if="$v.formData.swap_currency_symbol.$error"> | ||||
|                   <span v-if="!$v.formData.swap_currency_symbol.required" class="text-danger">{{ $tc('validation.required') }}</span> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <base-button color="theme" type="submit"> | ||||
|                 {{ $t('navigation.add') }} | ||||
|               </base-button> | ||||
|             </div> | ||||
|           </form> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| import { mapActions } from 'vuex' | ||||
| import { validationMixin } from 'vuelidate' | ||||
| const { required } = require('vuelidate/lib/validators') | ||||
| export default { | ||||
|   mixins: [validationMixin], | ||||
|   data () { | ||||
|     return this.$store.state.currency | ||||
|   }, | ||||
|   computed: { | ||||
|     isEdit () { | ||||
|       if (this.$route.name === 'currencyedit') { | ||||
|         return true | ||||
|       } | ||||
|       return false | ||||
|     } | ||||
|   }, | ||||
|   validations: { | ||||
|     formData: { | ||||
|       name: { | ||||
|         required | ||||
|       }, | ||||
|       code: { | ||||
|         required | ||||
|       }, | ||||
|       thousand_separator: { | ||||
|         required | ||||
|       }, | ||||
|       decimal_separator: { | ||||
|         required | ||||
|       }, | ||||
|       swap_currency_symbol: { | ||||
|         required | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   mounted () { | ||||
|     if (!this.isEdit) { | ||||
|       return true | ||||
|     } | ||||
|     this.loadData(this.$route.params.id) | ||||
|   }, | ||||
|   methods: { | ||||
|     ...mapActions('currency', [ | ||||
|       'loadData', | ||||
|       'addCurrency', | ||||
|       'editCurrency' | ||||
|     ]), | ||||
|     async submiteCurrency () { | ||||
|       this.$v.formData.$touch() | ||||
|       if (this.$v.$invalid) { | ||||
|         return false | ||||
|       } | ||||
|       if (this.isEdit) { | ||||
|         this.editCurrency(this.$route.params.id) | ||||
|         return true | ||||
|       } | ||||
|       this.addCurrency() | ||||
|       return true | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
							
								
								
									
										93
									
								
								resources/assets/js/views/settings/layout/Index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								resources/assets/js/views/settings/layout/Index.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | ||||
| <template> | ||||
|   <div class="invoice-create-page main-content"> | ||||
|     <div class="page-header"> | ||||
|       <h3 class="page-title">{{ $tc('settings.setting',1) }}</h3> | ||||
|       <ol class="breadcrumb"> | ||||
|         <li class="breadcrumb-item"><router-link slot="item-title" to="/admin/dashboard">{{ $t('general.home') }}</router-link></li> | ||||
|         <li class="breadcrumb-item"><router-link slot="item-title" to="/admin/settings/user-profile">{{ $tc('settings.setting', 2) }}</router-link></li> | ||||
|       </ol> | ||||
|     </div> | ||||
|     <div class="row settings-container"> | ||||
|       <div class="col-lg-3 settings-sidebar-container"> | ||||
|         <ol class="settings-sidebar"> | ||||
|           <li v-for="(menuItem, index) in menuItems" :key="index" class="settings-menu-item"> | ||||
|             <router-link :class="['link-color', {'active-setting': hasActiveUrl(menuItem.link)}]" :to="menuItem.link"> | ||||
|               <font-awesome-icon :icon="[menuItem.iconType, menuItem.icon]" class="setting-icon"/> | ||||
|               <span class="menu-title ml-3">{{ $t(menuItem.title) }}</span> | ||||
|             </router-link> | ||||
|           </li> | ||||
|         </ol> | ||||
|       </div> | ||||
|       <div class="col-lg-9"> | ||||
|         <transition | ||||
|           name="fade" | ||||
|           mode="out-in"> | ||||
|           <router-view/> | ||||
|         </transition> | ||||
|       </div> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| export default { | ||||
|   data () { | ||||
|     return { | ||||
|       menuItems: [ | ||||
|         { | ||||
|           link: '/admin/settings/user-profile', | ||||
|           title: 'settings.menu_title.account_settings', | ||||
|           icon: 'user', | ||||
|           iconType: 'far' | ||||
|         }, | ||||
|         { | ||||
|           link: '/admin/settings/company-info', | ||||
|           title: 'settings.menu_title.company_information', | ||||
|           icon: 'building', | ||||
|           iconType: 'far' | ||||
|         }, | ||||
|         { | ||||
|           link: '/admin/settings/preferences', | ||||
|           title: 'settings.menu_title.preferences', | ||||
|           icon: 'cog', | ||||
|           iconType: 'fas' | ||||
|         }, | ||||
|         { | ||||
|           link: '/admin/settings/tax-types', | ||||
|           title: 'settings.menu_title.tax_types', | ||||
|           icon: 'check-circle', | ||||
|           iconType: 'far' | ||||
|         }, | ||||
|         { | ||||
|           link: '/admin/settings/expense-category', | ||||
|           title: 'settings.menu_title.expense_category', | ||||
|           icon: 'list-alt', | ||||
|           iconType: 'far' | ||||
|         }, | ||||
|         { | ||||
|           link: '/admin/settings/notifications', | ||||
|           title: 'settings.menu_title.notifications', | ||||
|           icon: 'bell', | ||||
|           iconType: 'far' | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   }, | ||||
|   watch: { | ||||
|     '$route.path' (newValue) { | ||||
|       if (newValue === '/admin/settings') { | ||||
|         this.$router.push('/admin/settings/user-profile') | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   created () { | ||||
|     if (this.$route.path === '/admin/settings') { | ||||
|       this.$router.push('/admin/settings/user-profile') | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     hasActiveUrl (url) { | ||||
|       return this.$route.path.indexOf(url) > -1 | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
		Reference in New Issue
	
	Block a user