137 lines
4.3 KiB
Vue
137 lines
4.3 KiB
Vue
<!-- /src/views/professors/ProfessorListView.vue -->
|
|
<template>
|
|
<div class="professor-list-view">
|
|
<PageHeader :title="$t('professors.title')" :subtitle="$t('professors.subtitle')">
|
|
<PermissionGate permission="professors:create">
|
|
<Button :label="$t('professors.addProfessor')" icon="pi pi-plus" @click="$router.push('/professors/create')" />
|
|
</PermissionGate>
|
|
</PageHeader>
|
|
|
|
<DataTableWrapper
|
|
:items="items"
|
|
:totalCount="totalCount"
|
|
:page="queryParams.page"
|
|
:limit="queryParams.limit"
|
|
:sortBy="queryParams.sortBy"
|
|
:sortOrder="queryParams.sortOrder"
|
|
:loading="isLoading"
|
|
@page-change="onPageChange"
|
|
@sort-change="onSort"
|
|
@search-change="onSearch"
|
|
>
|
|
<Column field="name" header="نام و نام خانوادگی" sortable>
|
|
<template #body="{ data }">
|
|
<span class="font-bold text-color">{{ data.name }} {{ data.surname }}</span>
|
|
</template>
|
|
</Column>
|
|
|
|
<Column field="nationalIdCode" header="کد ملی">
|
|
<template #body="{ data }">
|
|
{{ toPersianDigits(data.nationalIdCode || data.nationalId) || '-' }}
|
|
</template>
|
|
</Column>
|
|
|
|
<Column field="specialization" header="تخصص">
|
|
<template #body="{ data }">
|
|
<Tag :value="data.specialization || 'عمومی'" severity="secondary" />
|
|
</template>
|
|
</Column>
|
|
|
|
<Column field="phoneNumber" header="شماره همراه">
|
|
<template #body="{ data }">
|
|
{{ toPersianDigits(data.phoneNumber || data.phone) || '-' }}
|
|
</template>
|
|
</Column>
|
|
|
|
<Column field="email" header="ایمیل">
|
|
<template #body="{ data }">
|
|
{{ data.email || '-' }}
|
|
</template>
|
|
</Column>
|
|
|
|
<Column field="activeCoursesCount" header="دورههای فعال">
|
|
<template #body="{ data }">
|
|
{{ toPersianDigits(data.activeCoursesCount || data.courses?.length || 0) }}
|
|
</template>
|
|
</Column>
|
|
|
|
<Column header="عملیات" style="width: 110px">
|
|
<template #body="{ data }">
|
|
<div class="flex align-items-center gap-1">
|
|
<PermissionGate permission="professors:update">
|
|
<Button icon="pi pi-pencil" text rounded size="small" severity="warning" v-tooltip.top="'ویرایش'" @click="$router.push(`/professors/edit/${data._id || data.id}`)" />
|
|
</PermissionGate>
|
|
|
|
<PermissionGate permission="professors:delete">
|
|
<Button icon="pi pi-trash" text rounded size="small" severity="danger" v-tooltip.top="'حذف'" @click="confirmDelete(data)" />
|
|
</PermissionGate>
|
|
</div>
|
|
</template>
|
|
</Column>
|
|
</DataTableWrapper>
|
|
|
|
<ConfirmDeleteDialog
|
|
v-model="deleteDialogVisible"
|
|
:loading="isDeleting"
|
|
@confirm="handleDelete"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue';
|
|
import { useDataTable } from '@/composables/useDataTable';
|
|
import { usePersianDate } from '@/composables/usePersianDate';
|
|
import { useToast } from '@/composables/useToast';
|
|
import { professorApi } from '@/api/professorApi';
|
|
import PageHeader from '@/components/common/PageHeader.vue';
|
|
import DataTableWrapper from '@/components/common/DataTableWrapper.vue';
|
|
import ConfirmDeleteDialog from '@/components/common/ConfirmDeleteDialog.vue';
|
|
import PermissionGate from '@/components/common/PermissionGate.vue';
|
|
import Button from 'primevue/button';
|
|
import Column from 'primevue/column';
|
|
import Tag from 'primevue/tag';
|
|
|
|
const { toPersianDigits } = usePersianDate();
|
|
const { showSuccess, showError } = useToast();
|
|
|
|
const {
|
|
items,
|
|
totalCount,
|
|
isLoading,
|
|
queryParams,
|
|
loadData,
|
|
onPageChange,
|
|
onSort,
|
|
onSearch
|
|
} = useDataTable(professorApi.getAll);
|
|
|
|
const deleteDialogVisible = ref(false);
|
|
const selectedProf = ref(null);
|
|
const isDeleting = ref(false);
|
|
|
|
const confirmDelete = (prof) => {
|
|
selectedProf.value = prof;
|
|
deleteDialogVisible.value = true;
|
|
};
|
|
|
|
const handleDelete = async () => {
|
|
if (!selectedProf.value) return;
|
|
isDeleting.value = true;
|
|
try {
|
|
await professorApi.delete(selectedProf.value._id || selectedProf.value.id);
|
|
showSuccess('استاد با موفقیت حذف شد');
|
|
deleteDialogVisible.value = false;
|
|
loadData();
|
|
} catch (err) {
|
|
showError(err);
|
|
} finally {
|
|
isDeleting.value = false;
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
loadData();
|
|
});
|
|
</script>
|