feat: Implement Fast Request feature with file upload and request management
This commit is contained in:
@@ -1,108 +1,96 @@
|
||||
<script setup>
|
||||
import UiButton from '../../components/ui/UiButton.vue';
|
||||
import { ref, computed } from 'vue';
|
||||
import Dialog from 'primevue/dialog';
|
||||
import ProgressBar from 'primevue/progressbar';
|
||||
import RequestType from './fastRequest/RequestType.vue';
|
||||
import RequestCase from './fastRequest/RequestCase.vue';
|
||||
import RequestDetails from './fastRequest/RequestDetails.vue';
|
||||
import RequestDoctor from './fastRequest/RequestDoctor.vue';
|
||||
import RequestReview from './fastRequest/RequestReview.vue';
|
||||
import UiButton from '../../components/ui/UiButton.vue';
|
||||
import { computed, watch } from 'vue';
|
||||
import Dialog from 'primevue/dialog';
|
||||
import ProgressBar from 'primevue/progressbar';
|
||||
import { toast } from 'vue3-toastify';
|
||||
import RequestType from './fastRequest/RequestType.vue';
|
||||
import RequestCase from './fastRequest/RequestCase.vue';
|
||||
import RequestDetails from './fastRequest/RequestDetails.vue';
|
||||
import RequestDoctor from './fastRequest/RequestDoctor.vue';
|
||||
import RequestReview from './fastRequest/RequestReview.vue';
|
||||
import { useFastRequestStore } from '../../store/FastRequest';
|
||||
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
const visible = defineModel('visible');
|
||||
const fastRequestStore = useFastRequestStore();
|
||||
|
||||
const step = ref(1);
|
||||
const stepRef = ref(null);
|
||||
const steps = [
|
||||
{ label: 'نوع درخواست', component: RequestType },
|
||||
{ label: 'انتخاب کیس', component: RequestCase },
|
||||
{ label: 'جزئیات درخواست', component: RequestDetails },
|
||||
{ label: 'انتخاب پزشک', component: RequestDoctor },
|
||||
{ label: 'مرور نهایی', component: RequestReview },
|
||||
];
|
||||
|
||||
const steps = ref({
|
||||
1: RequestType,
|
||||
2: RequestCase,
|
||||
3: RequestDetails,
|
||||
4: RequestDoctor,
|
||||
5: RequestReview,
|
||||
});
|
||||
const currentStepComponent = computed(() => {
|
||||
return steps[fastRequestStore.step - 1]?.component || RequestType;
|
||||
});
|
||||
|
||||
const currentStepComponent = computed(() => {
|
||||
return steps.value[step.value] || RequestType
|
||||
});
|
||||
|
||||
const handleNext = () => {
|
||||
step.value++;
|
||||
const isLastStep = computed(() => fastRequestStore.step === steps.length);
|
||||
|
||||
watch(visible, (isVisible) => {
|
||||
if (isVisible) {
|
||||
fastRequestStore.fetchCreateData();
|
||||
} else {
|
||||
fastRequestStore.reset();
|
||||
}
|
||||
});
|
||||
|
||||
const handleNext = async () => {
|
||||
if (!fastRequestStore.canProceed) {
|
||||
toast.error('لطفا اطلاعات این مرحله را کامل کنید.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isLastStep.value) {
|
||||
fastRequestStore.nextStep();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const document = await fastRequestStore.submit();
|
||||
toast.success(`درخواست شما با شماره پرونده ${document.code} با موفقیت ثبت شد.`);
|
||||
visible.value = false;
|
||||
} catch (error) {
|
||||
toast.error(error.response?.data?.message || 'خطا در ثبت درخواست. لطفا دوباره تلاش کنید.');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<Dialog :modal="true" :closable="true" :dismissableMask="true" :maximizable="false" :style="{ width: '688px' , minHeight: '376px' }" :pt="{header : '!bg-client-primaryBlue'}">
|
||||
<Dialog v-model:visible="visible" :modal="true" :closable="true" :dismissableMask="true" :maximizable="false" :style="{ width: '688px' , minHeight: '376px' }" class="fast-request-dialog" :pt="{header : '!bg-client-primaryBlue'}">
|
||||
<template #header>
|
||||
<div class="w-full flex items-center justify-start">
|
||||
<h2 class="text-[14px] font-[700] text-[#576989]">ثبت آنی درخواست</h2>
|
||||
</div>
|
||||
</template>
|
||||
<div class="w-full h-[56px] flex items-center justify-between border-b border-[#EBEBEB] pb-3">
|
||||
<div class="w-auto h-[40px] grid grid-cols-1 items-center justify-center gap-1">
|
||||
<div class="w-full h-[20px] flex items-center justify-center ">
|
||||
<span class="w-[20px] h-[20px] bg-[#576989] rounded-full text-white flex items-center justify-center text-[10px] font-[600]">1</span>
|
||||
<template v-for="(item, index) in steps" :key="item.label">
|
||||
<ProgressBar v-if="index > 0" :value="fastRequestStore.step > index ? 100 : 0" :showValue="false" mode="determinate"></ProgressBar>
|
||||
<div class="w-auto h-[40px] grid grid-cols-1 items-center justify-center gap-1">
|
||||
<div class="w-full h-[20px] flex items-center justify-center">
|
||||
<span
|
||||
class="w-[20px] h-[20px] rounded-full text-white flex items-center justify-center text-[10px] font-[600]"
|
||||
:class="fastRequestStore.step >= index + 1 ? 'bg-[#576989]' : 'bg-[#C1D0E8]'"
|
||||
>{{ index + 1 }}</span>
|
||||
</div>
|
||||
<span class="text-[10px] font-[600]" :class="fastRequestStore.step >= index + 1 ? 'text-[#576989]' : 'text-[#7188AD]'">{{ item.label }}</span>
|
||||
</div>
|
||||
<span class="text-[10px] font-[600] text-[#7188AD]">نوع درخواست</span>
|
||||
</div>
|
||||
<ProgressBar :value="value1" :showValue="false" mode="determinate"></ProgressBar>
|
||||
<div class="w-auto h-[40px] grid grid-cols-1 items-center justify-center gap-1">
|
||||
<div class="w-full h-[20px] flex items-center justify-center ">
|
||||
<span class="w-[20px] h-[20px] bg-[#576989] rounded-full text-white flex items-center justify-center text-[10px] font-[600]">2</span>
|
||||
</div>
|
||||
<span class="text-[10px] font-[600] text-[#7188AD]">انتخاب کیس</span>
|
||||
</div>
|
||||
<ProgressBar :value="value2" :showValue="false" mode="determinate"></ProgressBar>
|
||||
<div class="w-auto h-[40px] grid grid-cols-1 items-center justify-center gap-1">
|
||||
<div class="w-full h-[20px] flex items-center justify-center ">
|
||||
<span class="w-[20px] h-[20px] bg-[#576989] rounded-full text-white flex items-center justify-center text-[10px] font-[600]">3</span>
|
||||
</div>
|
||||
<span class="text-[10px] font-[600] text-[#7188AD]">جزئیات درخواست</span>
|
||||
</div>
|
||||
<ProgressBar :value="value3" :showValue="false" mode="determinate"></ProgressBar>
|
||||
<div class="w-auto h-[40px] grid grid-cols-1 items-center justify-center gap-1">
|
||||
<div class="w-full h-[20px] flex items-center justify-center ">
|
||||
<span class="w-[20px] h-[20px] bg-[#576989] rounded-full text-white flex items-center justify-center text-[10px] font-[600]">4</span>
|
||||
</div>
|
||||
<span class="text-[10px] font-[600] text-[#7188AD]">انتخاب پزشک</span>
|
||||
</div>
|
||||
<ProgressBar :value="value4" :showValue="false" mode="determinate"></ProgressBar>
|
||||
<div class="w-auto h-[40px] grid grid-cols-1 items-center justify-center gap-1">
|
||||
<div class="w-full h-[20px] flex items-center justify-center ">
|
||||
<span class="w-[20px] h-[20px] bg-[#576989] rounded-full text-white flex items-center justify-center text-[10px] font-[600]">5</span>
|
||||
</div>
|
||||
<span class="text-[10px] font-[600] text-[#7188AD]">مرور نهایی</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<component :is="currentStepComponent" ref="stepRef" @validated="onValidated"/>
|
||||
<component :is="currentStepComponent" />
|
||||
|
||||
<div class="w-full pt-3 flex items-center justify-end border-t border-[#EBEBEB]">
|
||||
<ui-button label="تایید و مرحله بعد" severity="success" size="small" @click="handleNext" />
|
||||
<div class="w-full pt-3 flex items-center justify-between border-t border-[#EBEBEB]">
|
||||
<ui-button v-if="fastRequestStore.step > 1" label="مرحله قبل" severity="secondary" size="small" @click="fastRequestStore.prevStep" />
|
||||
<span v-else></span>
|
||||
<ui-button
|
||||
:label="isLastStep ? 'ثبت نهایی درخواست' : 'تایید و مرحله بعد'"
|
||||
severity="success"
|
||||
size="small"
|
||||
:loading="fastRequestStore.submitting"
|
||||
:disabled="fastRequestStore.submitting"
|
||||
@click="handleNext"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.p-progressbar) {
|
||||
min-width: 60px !important;
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
:deep(.p-progressbar-value) {
|
||||
background: #576989 !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user