249 lines
7.6 KiB
Vue
249 lines
7.6 KiB
Vue
<script setup>
|
|
import { ref, onMounted, computed, watch } from 'vue'
|
|
import axios from 'axios'
|
|
import UISelect from '../ui/UISelect.vue'
|
|
import { useReportStore } from '../../store/Report.js'
|
|
import { useToast } from 'primevue/usetoast'
|
|
|
|
const reportStore = useReportStore()
|
|
const props = defineProps({
|
|
reportData: {
|
|
type: Object,
|
|
default: null
|
|
},
|
|
isEdit: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
isFullscreen: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
})
|
|
|
|
const emit = defineEmits(['submit', 'cancel'])
|
|
const toast = useToast()
|
|
|
|
const form = ref({
|
|
document_id: null,
|
|
doctor_id: null,
|
|
medium_id: null,
|
|
status: 'Draft',
|
|
body: '',
|
|
submitted_at: null
|
|
})
|
|
|
|
const isLoading = ref(false)
|
|
|
|
const quillToolbar = computed(() => {
|
|
return props.isFullscreen ? 'full' : 'essential'
|
|
})
|
|
|
|
const statusOptions = [
|
|
{ label: 'پیشنویس', value: 'Draft' },
|
|
{ label: 'در حال انجام', value: 'InProgress' },
|
|
{ label: 'تکمیل شده', value: 'Completed' },
|
|
{ label: 'بررسی شده', value: 'Reviewed' },
|
|
{ label: 'تایید شده', value: 'Approved' },
|
|
{ label: 'رد شده', value: 'Rejected' }
|
|
]
|
|
|
|
const documentOptions = ref([])
|
|
const doctorOptions = ref([])
|
|
const mediaOptions = ref([])
|
|
const isLoadingOptions = ref(true)
|
|
|
|
onMounted(() => {
|
|
loadInitialOptions()
|
|
|
|
if (props.isEdit && props.reportData) {
|
|
populateFormWithData()
|
|
addCurrentToOptions()
|
|
}
|
|
})
|
|
|
|
const loadInitialOptions = async () => {
|
|
try {
|
|
isLoadingOptions.value = true
|
|
|
|
const documentsResponse = await axios.get('/admin/documents-options')
|
|
if (documentsResponse.data.success) {
|
|
documentOptions.value = documentsResponse.data.data
|
|
}
|
|
|
|
const doctorsResponse = await axios.get('/admin/doctors-options')
|
|
if (doctorsResponse.data.success) {
|
|
doctorOptions.value = doctorsResponse.data.data
|
|
}
|
|
|
|
mediaOptions.value = []
|
|
} catch (error) {
|
|
console.error('Error loading initial options:', error)
|
|
} finally {
|
|
isLoadingOptions.value = false
|
|
}
|
|
}
|
|
|
|
const populateFormWithData = () => {
|
|
if (props.reportData) {
|
|
const statusOption = statusOptions.find(option => option.label === props.reportData.status)
|
|
const statusValue = statusOption ? statusOption.value : 'Draft'
|
|
|
|
form.value = {
|
|
document_id: props.reportData.document?.id || null,
|
|
doctor_id: props.reportData.doctor?.id || null,
|
|
medium_id: props.reportData.medium_id || null,
|
|
status: statusValue,
|
|
body: props.reportData.body || '',
|
|
submitted_at: props.reportData.submitted_at_form
|
|
}
|
|
}
|
|
}
|
|
|
|
const addCurrentToOptions = () => {
|
|
if (props.reportData) {
|
|
if (props.reportData.document && !documentOptions.value.find(opt => opt.value === props.reportData.document.id)) {
|
|
documentOptions.value.unshift({
|
|
label: `پرونده ${props.reportData.document.code}`,
|
|
value: props.reportData.document.id
|
|
})
|
|
}
|
|
|
|
if (props.reportData.doctor && !doctorOptions.value.find(opt => opt.value === props.reportData.doctor.id)) {
|
|
doctorOptions.value.unshift({
|
|
label: props.reportData.doctor.fullname,
|
|
value: props.reportData.doctor.id
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
const handleSubmit = async () => {
|
|
|
|
isLoading.value = true
|
|
try {
|
|
reportStore.createForm = form.value
|
|
await emit('submit', props.isEdit ? props.reportData.id : null)
|
|
} catch (error) {
|
|
console.error('Error submitting form:', error)
|
|
} finally {
|
|
isLoading.value = false
|
|
}
|
|
}
|
|
|
|
const handleCancel = () => {
|
|
resetForm()
|
|
emit('cancel')
|
|
}
|
|
|
|
const resetForm = () => {
|
|
form.value = {
|
|
document_id: null,
|
|
doctor_id: null,
|
|
medium_id: null,
|
|
status: 'Draft',
|
|
body: '',
|
|
submitted_at: null
|
|
}
|
|
loadInitialOptions()
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="space-y-6 overflow-hidden">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
<div class="grid grid-cols-1">
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
|
انتخاب پرونده
|
|
</label>
|
|
<UISelect
|
|
v-model="form.document_id"
|
|
:options="documentOptions"
|
|
optionValue="value"
|
|
optionLabel="label"
|
|
searchUrl="/admin/documents-options"
|
|
searchParam="search"
|
|
:placeholder="isLoadingOptions ? 'در حال بارگذاری...' : 'انتخاب پرونده'"
|
|
:filter="true"
|
|
@update:options="documentOptions = $event"
|
|
/>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1">
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
|
انتخاب پزشک
|
|
</label>
|
|
<UISelect
|
|
v-model="form.doctor_id"
|
|
:options="doctorOptions"
|
|
optionValue="value"
|
|
optionLabel="label"
|
|
searchUrl="/admin/doctors-options"
|
|
searchParam="search"
|
|
:placeholder="isLoadingOptions ? 'در حال بارگذاری...' : ' انتخاب پزشک'"
|
|
:filter="true"
|
|
@update:options="doctorOptions = $event"
|
|
/>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1">
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
|
وضعیت
|
|
</label>
|
|
<UISelect
|
|
v-model="form.status"
|
|
:options="statusOptions"
|
|
optionValue="value"
|
|
optionLabel="label"
|
|
placeholder="انتخاب وضعیت"
|
|
/>
|
|
</div>
|
|
|
|
<div class="">
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
|
تاریخ ارسال
|
|
</label>
|
|
<CustomDatePicker
|
|
v-model="form.submitted_at"
|
|
type="datetime"
|
|
compact-time
|
|
class="w-full"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1">
|
|
<label class="block text-sm font-medium text-gray-700 mb-2">
|
|
محتوای گزارش
|
|
</label>
|
|
<div class="text-right w-full max-w-full">
|
|
<quill-editor
|
|
:key="`quill-${props.isFullscreen ? 'full' : 'essential'}`"
|
|
theme="snow"
|
|
:toolbar="quillToolbar"
|
|
:content="form.body"
|
|
@update:content="form.body = $event"
|
|
content-type="html"
|
|
placeholder="محتوای گزارش را اینجا بنویسید..."
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-end gap-3 pt-4 border-t border-gray-200">
|
|
<Button
|
|
class="!text-sm"
|
|
label="انصراف"
|
|
severity="secondary"
|
|
@click="handleCancel"
|
|
:disabled="isLoading"
|
|
/>
|
|
<Button
|
|
class="!text-sm"
|
|
:label="isEdit ? 'ویرایش گزارش' : 'ایجاد گزارش'"
|
|
@click="handleSubmit"
|
|
:loading="isLoading"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</template>
|