AppointmentStatus.vue
139 lines
| 1 | <template> |
| 2 | <div> |
| 3 | <AmSelect |
| 4 | v-if="status && shortcodeData.cabinetType === 'employee'" |
| 5 | v-model="status" |
| 6 | :prefix-icon="bookingStatuses.find((i) => i.value === status).icon" |
| 7 | :prefix-icon-color="bookingStatuses.find((i) => i.value === status).color" |
| 8 | :disabled="loading" |
| 9 | size="small" |
| 10 | append-to=".am-fs__main-content" |
| 11 | @click="(e) => e.stopPropagation()" |
| 12 | @change="appointmentStatusChange" |
| 13 | > |
| 14 | <AmOption |
| 15 | v-for="item in bookingStatuses" |
| 16 | :key="item.value" |
| 17 | :value="item.value" |
| 18 | :label="item.label" |
| 19 | > |
| 20 | <span :class="`am-icon-${item.icon}`" :style="`color: ${item.color}`"></span> |
| 21 | {{ item.label }} |
| 22 | </AmOption> |
| 23 | </AmSelect> |
| 24 | </div> |
| 25 | </template> |
| 26 | |
| 27 | <script setup> |
| 28 | // * Import from Vue |
| 29 | import { ref, computed, inject, onMounted } from 'vue' |
| 30 | |
| 31 | // * Import from Vuex |
| 32 | import { useStore } from 'vuex' |
| 33 | |
| 34 | // * Composables |
| 35 | import { useStatuses } from '../../../../../assets/js/admin/status' |
| 36 | import AmOption from '../../../../_components/select/AmOption.vue' |
| 37 | import AmSelect from '../../../../_components/select/AmSelect.vue' |
| 38 | import httpClient from '../../../../../plugins/axios' |
| 39 | |
| 40 | // * Component props |
| 41 | let props = defineProps({ |
| 42 | id: { |
| 43 | type: [Number], |
| 44 | default: 0, |
| 45 | }, |
| 46 | status: { |
| 47 | type: String, |
| 48 | default: '', |
| 49 | }, |
| 50 | }) |
| 51 | |
| 52 | // * Data in shortcode |
| 53 | const shortcodeData = inject('shortcodeData') |
| 54 | |
| 55 | // * Labels |
| 56 | let amLabels = inject('amLabels') |
| 57 | |
| 58 | // * Store |
| 59 | let store = useStore() |
| 60 | |
| 61 | // * Components emits |
| 62 | let emits = defineEmits(['statusChange']) |
| 63 | |
| 64 | // * Booking Statuses |
| 65 | let bookingStatuses = computed(() => { |
| 66 | return useStatuses().filter((i) => i.value !== 'waiting') |
| 67 | }) |
| 68 | |
| 69 | function appointmentStatusChange() { |
| 70 | loading.value = true |
| 71 | |
| 72 | httpClient |
| 73 | .post( |
| 74 | '/appointments/status/' + props.id, |
| 75 | { |
| 76 | status: status.value, |
| 77 | }, |
| 78 | { |
| 79 | params: { source: 'cabinet-provider' }, |
| 80 | }, |
| 81 | ) |
| 82 | .then((result) => { |
| 83 | let message = |
| 84 | amLabels.value.appointment_status_changed + |
| 85 | amLabels.value[result.data.data.status].toLowerCase() |
| 86 | let type = 'success' |
| 87 | |
| 88 | if ( |
| 89 | 'maximumCapacityReached' in result.data.data && |
| 90 | result.data.data.maximumCapacityReached === true |
| 91 | ) { |
| 92 | message = amLabels.value.maximum_capacity_reached |
| 93 | type = 'error' |
| 94 | |
| 95 | status.value = props.status |
| 96 | } |
| 97 | |
| 98 | emits('statusChange', message, type) |
| 99 | |
| 100 | loading.value = false |
| 101 | }) |
| 102 | .catch((e) => { |
| 103 | let message = amLabels.value.error |
| 104 | let type = 'error' |
| 105 | |
| 106 | if ('response' in e && 'data' in e.response && 'data' in e.response.data) { |
| 107 | if ( |
| 108 | 'timeSlotUnavailable' in e.response.data.data && |
| 109 | e.response.data.data.timeSlotUnavailable === true |
| 110 | ) { |
| 111 | message = amLabels.value.time_slot_unavailable |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | status.value = props.status |
| 116 | |
| 117 | emits('statusChange', message, type) |
| 118 | |
| 119 | loading.value = false |
| 120 | }) |
| 121 | } |
| 122 | |
| 123 | let loading = ref(false) |
| 124 | |
| 125 | let status = ref('') |
| 126 | |
| 127 | onMounted(() => { |
| 128 | status.value = props.status |
| 129 | }) |
| 130 | </script> |
| 131 | |
| 132 | <script> |
| 133 | export default { |
| 134 | name: 'CollapseCard', |
| 135 | } |
| 136 | </script> |
| 137 | |
| 138 | <style lang="scss"></style> |
| 139 |