|
|
@@ -0,0 +1,164 @@
|
|
|
+<template>
|
|
|
+ <div class="col-12">
|
|
|
+ <div class="text-h6 q-mb-md">{{ $t('provider_specialities.header') }}</div>
|
|
|
+
|
|
|
+ <div class="row items-center">
|
|
|
+ <SpecialitySelect
|
|
|
+ v-model="selectedSpeciality"
|
|
|
+ :label="$t('provider_specialities.select_placeholder')"
|
|
|
+ :disable="!providerId || loading"
|
|
|
+ :exclude-ids="excludedSpecialityIds"
|
|
|
+ class="col-md-6 col-12 q-pb-none q-mr-sm"
|
|
|
+ />
|
|
|
+
|
|
|
+ <div class="col-auto">
|
|
|
+ <q-btn
|
|
|
+ color="primary"
|
|
|
+ :label="$t('provider_specialities.add_button')"
|
|
|
+ :disable="!selectedSpeciality || loading"
|
|
|
+ :loading="adding"
|
|
|
+ padding="16px 16px"
|
|
|
+ @click="handleAdd"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="loading" class="q-mt-md text-center">
|
|
|
+ <q-spinner color="primary" size="40px" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-else-if="providerSpecialities.length > 0" class="q-mt-md q-gutter-sm">
|
|
|
+ <q-chip
|
|
|
+ v-for="item in providerSpecialities"
|
|
|
+ :key="item.id"
|
|
|
+ removable
|
|
|
+ color="primary"
|
|
|
+ text-color="white"
|
|
|
+ @remove="handleRemove(item)"
|
|
|
+ >
|
|
|
+ {{ item.speciality?.description || '-' }}
|
|
|
+ </q-chip>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-else class="q-mt-md text-grey-7 text-center">
|
|
|
+ {{ $t('provider_specialities.empty_state') }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, computed, watch, onMounted } from 'vue'
|
|
|
+import { useQuasar } from 'quasar'
|
|
|
+import { useI18n } from 'vue-i18n'
|
|
|
+import SpecialitySelect from 'src/components/speciality/SpecialitySelect.vue'
|
|
|
+import {
|
|
|
+ getProviderSpecialities,
|
|
|
+ createProviderSpeciality,
|
|
|
+ deleteProviderSpeciality
|
|
|
+} from 'src/api/providerSpeciality.js'
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ providerId: {
|
|
|
+ type: Number,
|
|
|
+ default: null
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const $q = useQuasar()
|
|
|
+const { t } = useI18n()
|
|
|
+
|
|
|
+const providerSpecialities = ref([])
|
|
|
+const selectedSpeciality = ref(null)
|
|
|
+const loading = ref(false)
|
|
|
+const adding = ref(false)
|
|
|
+
|
|
|
+const excludedSpecialityIds = computed(() => {
|
|
|
+ return providerSpecialities.value.map(item => item.speciality_id)
|
|
|
+})
|
|
|
+
|
|
|
+const loadProviderSpecialities = async () => {
|
|
|
+ if (!props.providerId) {
|
|
|
+ providerSpecialities.value = []
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ loading.value = true
|
|
|
+ const response = await getProviderSpecialities(props.providerId)
|
|
|
+ providerSpecialities.value = response.payload || []
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error loading provider specialities:', error)
|
|
|
+ $q.notify({
|
|
|
+ type: 'negative',
|
|
|
+ message: error.response?.data?.message || t('http.errors.failed')
|
|
|
+ })
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const handleAdd = async () => {
|
|
|
+ if (!selectedSpeciality.value) return
|
|
|
+
|
|
|
+ try {
|
|
|
+ adding.value = true
|
|
|
+ await createProviderSpeciality(props.providerId, {
|
|
|
+ speciality_id: selectedSpeciality.value.value
|
|
|
+ })
|
|
|
+
|
|
|
+ $q.notify({
|
|
|
+ type: 'positive',
|
|
|
+ message: t('http.success')
|
|
|
+ })
|
|
|
+
|
|
|
+ selectedSpeciality.value = null
|
|
|
+ await loadProviderSpecialities()
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error adding speciality:', error)
|
|
|
+ $q.notify({
|
|
|
+ type: 'negative',
|
|
|
+ message: error.response?.data?.message || t('http.errors.failed')
|
|
|
+ })
|
|
|
+ } finally {
|
|
|
+ adding.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const handleRemove = async (item) => {
|
|
|
+ $q.dialog({
|
|
|
+ title: t('common.messages.confirm'),
|
|
|
+ message: t('provider_specialities.remove_confirm'),
|
|
|
+ cancel: true,
|
|
|
+ persistent: true
|
|
|
+ }).onOk(async () => {
|
|
|
+ try {
|
|
|
+ await deleteProviderSpeciality(props.providerId, item.id)
|
|
|
+
|
|
|
+ $q.notify({
|
|
|
+ type: 'positive',
|
|
|
+ message: t('common.messages.deleted_successfully')
|
|
|
+ })
|
|
|
+
|
|
|
+ await loadProviderSpecialities()
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Error removing speciality:', error)
|
|
|
+ $q.notify({
|
|
|
+ type: 'negative',
|
|
|
+ message: error.response?.data?.message || t('common.messages.error_deleting')
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+watch(() => props.providerId, () => {
|
|
|
+ loadProviderSpecialities()
|
|
|
+}, { immediate: true })
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ loadProviderSpecialities()
|
|
|
+})
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ loadProviderSpecialities
|
|
|
+})
|
|
|
+</script>
|