@@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<div class="admin-missionary-page">
|
||||
<BoxedIconTitleBlock
|
||||
class="admin-missionary-page__heading"
|
||||
title="مدیریت مبلغین"
|
||||
desc="در این قسمت میتوانید درخواستهای اعزام مبلغین را مشاهده و مدیریت کنید"
|
||||
>
|
||||
<template #icon>
|
||||
<SvgIcon name="user-sound" :size="24" color="var(--color-primary)" />
|
||||
</template>
|
||||
</BoxedIconTitleBlock>
|
||||
|
||||
<SimpleTitleIconBlock title="لیست همه درخواستها" class="admin-missionary-page__list-title">
|
||||
<template #header-icon>
|
||||
<SvgIcon name="list-bullets" :size="16" color="#bcbcbc" />
|
||||
</template>
|
||||
</SimpleTitleIconBlock>
|
||||
|
||||
<SkeletonLoaderBlock v-if="isLoading" :rows="6" :cols-per-row="1" />
|
||||
<div v-else-if="requests.length > 0">
|
||||
<MissionaryRequestItem
|
||||
v-for="request in requests"
|
||||
:key="request.id"
|
||||
:request="request"
|
||||
:always-actionable="true"
|
||||
@show-details="onShowDetails"
|
||||
@change-status="onAskChangeStatus"
|
||||
/>
|
||||
</div>
|
||||
<NoItems v-else title="متاسفیم" desc="درخواستی برای نمایش وجود ندارد." />
|
||||
|
||||
<PaginationBlock :pagination="paginationMeta" @update:page="setPage" />
|
||||
|
||||
<RequestDetailsModal v-if="isModal('RequestDetailsModal')" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed, ref } from 'vue'
|
||||
import useModal from '@/composables/useModal'
|
||||
import { MISSIONARY_REQUEST_STATUS } from '@/enums'
|
||||
import { useQueryClient } from '@tanstack/vue-query'
|
||||
import SvgIcon from '@/components/icons/SvgIcon.vue'
|
||||
import NoItems from '@/components/blocks/NoItems.vue'
|
||||
import { formatJalaaliDate } from '@/utils/date-utils'
|
||||
import { usePagination } from '@/composables/usePagination'
|
||||
import PaginationBlock from '@/components/blocks/PaginationBlock.vue'
|
||||
import BoxedIconTitleBlock from '@/components/blocks/BoxedIconTitleBlock.vue'
|
||||
import SkeletonLoaderBlock from '@/components/blocks/SkeletonLoaderBlock.vue'
|
||||
import SimpleTitleIconBlock from '@/components/blocks/SimpleTitleIconBlock.vue'
|
||||
import MissionaryRequestItem from '@/features/missionary/components/MissionaryRequestItem.vue'
|
||||
import RequestDetailsModal from '@/features/missionary/components/modals/RequestDetailsModal.vue'
|
||||
import {
|
||||
adminMissionaryRequestsKeys,
|
||||
useAdminMissionaryRequestsListQuery,
|
||||
useChangeAdminMissionaryRequestStatusMutation,
|
||||
} from '@/services/query/admin-missionary-requests'
|
||||
|
||||
const queryClient = useQueryClient()
|
||||
const { openModal, isModal } = useModal()
|
||||
|
||||
const filters = ref({})
|
||||
const { pagination, setPage } = usePagination({ page: 1, perPage: 10 })
|
||||
|
||||
const { data, isLoading } = useAdminMissionaryRequestsListQuery(filters, pagination, {
|
||||
keepPreviousData: true,
|
||||
})
|
||||
|
||||
const toRequestView = (request) => ({
|
||||
...request,
|
||||
code: request.id,
|
||||
requestNumber: request.id,
|
||||
requestDate: formatJalaaliDate(request.requestedDate),
|
||||
statusLabel: MISSIONARY_REQUEST_STATUS[request.status] || request.status || '—',
|
||||
phone: request.requesterPhone,
|
||||
address: request.location,
|
||||
})
|
||||
|
||||
const requests = computed(() => (data.value?.data ?? []).map((r) => toRequestView(r)))
|
||||
|
||||
const paginationMeta = computed(() => ({
|
||||
page: pagination.value.page,
|
||||
perPage: pagination.value.perPage,
|
||||
...data.value?.meta,
|
||||
}))
|
||||
|
||||
const statusMutation = useChangeAdminMissionaryRequestStatusMutation()
|
||||
|
||||
const invalidate = () =>
|
||||
queryClient.invalidateQueries({ queryKey: adminMissionaryRequestsKeys.all, refetchType: 'all' })
|
||||
|
||||
const STATUS_CONFIRMS = {
|
||||
accepted: { title: 'پذیرش درخواست', verb: 'پذیرش' },
|
||||
rejected: { title: 'رد درخواست', verb: 'رد' },
|
||||
}
|
||||
|
||||
const onAskChangeStatus = ({ id, status }) => {
|
||||
const config = STATUS_CONFIRMS[status]
|
||||
if (!config) return
|
||||
const request = requests.value.find((r) => r.id === id)
|
||||
openModal('ConfirmModal', {
|
||||
title: config.title,
|
||||
message: `آیا از ${config.verb} درخواست <strong>${request?.title || ''}</strong> مطمئن هستید؟`,
|
||||
onConfirm: () => statusMutation.mutate({ id, payload: { status } }, { onSuccess: invalidate }),
|
||||
})
|
||||
}
|
||||
|
||||
const onShowDetails = (request) => {
|
||||
openModal('RequestDetailsModal', request)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.admin-missionary-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
|
||||
&__heading {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
&__list-title {
|
||||
margin-bottom: 0.375rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -252,4 +252,15 @@ export default [
|
||||
subtitle: 'جلسات مشاوره را پیگیری کرده و پاسخگوی نیازهای کاربران باشید.',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '/missionary-requests',
|
||||
name: 'admin-missionary-requests',
|
||||
component: () => import('@/features/admin/missionary/pages/AdminMissionaryRequestsPage.vue'),
|
||||
meta: {
|
||||
layout: 'admin',
|
||||
role: 'admin',
|
||||
title: 'مدیریت مبلغین',
|
||||
subtitle: 'درخواستهای اعزام مبلغین را مشاهده و مدیریت نمایید.',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user