diff --git a/src/api/professorApi.js b/src/api/professorApi.js
index fdd4eda..90328a4 100644
--- a/src/api/professorApi.js
+++ b/src/api/professorApi.js
@@ -6,6 +6,7 @@ export const professorApi = {
search: (params) => axiosInstance.get('/professors/admin/search', { params }),
getOne: (id) => axiosInstance.get(`/professors/admin/get-one/${id}`),
create: (data) => axiosInstance.post('/professors/admin/create', data),
+ createFromUser: (data) => axiosInstance.post('/professors/admin/create-from-user', data),
update: (id, data) => axiosInstance.put(`/professors/admin/update/${id}`, data),
delete: (id) => axiosInstance.delete(`/professors/admin/delete/${id}`)
};
diff --git a/src/api/userApi.js b/src/api/userApi.js
index aaacdf3..eee33bb 100644
--- a/src/api/userApi.js
+++ b/src/api/userApi.js
@@ -5,8 +5,10 @@ export const userApi = {
getAll: (params) => axiosInstance.get('/users/admin/get-all', { params }),
search: (params) => axiosInstance.get('/users/admin/search', { params }),
getOne: (id) => axiosInstance.get(`/users/admin/get-one/${id}`),
+ getFullProfile: (id) => axiosInstance.get(`/users/admin/${id}/full-profile`),
create: (data) => axiosInstance.post('/users/admin/create', data),
update: (id, data) => axiosInstance.put(`/users/admin/update/${id}`, data),
+ promoteToProfessor: (id, data) => axiosInstance.post(`/users/admin/${id}/promote-to-professor`, data),
resetPasswordAndSms: (id) => axiosInstance.post(
`/users/admin/${id}/reset-password-sms`,
{},
diff --git a/src/components/professors/AddProfessorFromUserDialog.vue b/src/components/professors/AddProfessorFromUserDialog.vue
new file mode 100644
index 0000000..06ec428
--- /dev/null
+++ b/src/components/professors/AddProfessorFromUserDialog.vue
@@ -0,0 +1,257 @@
+
+
+
+
+
+
diff --git a/src/components/users/charts/StudentAttendanceChart.vue b/src/components/users/charts/StudentAttendanceChart.vue
new file mode 100644
index 0000000..7768c95
--- /dev/null
+++ b/src/components/users/charts/StudentAttendanceChart.vue
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+ اطلاعات حضور و غیابی برای این دانشجو ثبت نشده است
+
+
+
+
+
+
+
diff --git a/src/components/users/charts/StudentPaymentStatusChart.vue b/src/components/users/charts/StudentPaymentStatusChart.vue
new file mode 100644
index 0000000..3d739d4
--- /dev/null
+++ b/src/components/users/charts/StudentPaymentStatusChart.vue
@@ -0,0 +1,86 @@
+
+
+
+
+
+
+
+
+ صورتحساب یا پرداختی برای این دانشجو یافت نشد
+
+
+
+
+
+
+
diff --git a/src/components/users/charts/StudentPaymentTimelineChart.vue b/src/components/users/charts/StudentPaymentTimelineChart.vue
new file mode 100644
index 0000000..ed779a7
--- /dev/null
+++ b/src/components/users/charts/StudentPaymentTimelineChart.vue
@@ -0,0 +1,88 @@
+
+
+
+
+
+
+
+
+ تراکنش مالی ثبت شدهای در طول زمان یافت نشد
+
+
+
+
+
+
+
diff --git a/src/views/professors/ProfessorListView.vue b/src/views/professors/ProfessorListView.vue
index 9fd34e3..ddf8baa 100644
--- a/src/views/professors/ProfessorListView.vue
+++ b/src/views/professors/ProfessorListView.vue
@@ -3,7 +3,10 @@
-
+
+
+
+
@@ -33,7 +36,13 @@
-
+
+
+
+
+
+
+
@@ -75,6 +84,11 @@
:loading="isDeleting"
@confirm="handleDelete"
/>
+
+
@@ -88,6 +102,7 @@ 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 AddProfessorFromUserDialog from '@/components/professors/AddProfessorFromUserDialog.vue';
import Button from 'primevue/button';
import Column from 'primevue/column';
import Tag from 'primevue/tag';
@@ -109,6 +124,7 @@ const {
const deleteDialogVisible = ref(false);
const selectedProf = ref(null);
const isDeleting = ref(false);
+const showAddFromUserDialog = ref(false);
const confirmDelete = (prof) => {
selectedProf.value = prof;
diff --git a/src/views/users/UserDetailView.vue b/src/views/users/UserDetailView.vue
index e29e418..1fd9491 100644
--- a/src/views/users/UserDetailView.vue
+++ b/src/views/users/UserDetailView.vue
@@ -1,180 +1,449 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+ {{ getInitials(user.name) }}
+
+
+
+
{{ user.name }}
+
+
+
+
+ کد کاربری: {{ user.uniqueCode }}
+ کد ملی: {{ toPersianDigits(user.nationalIdCode || user.nationalId || '-') }}
+ شماره همراه: {{ toPersianDigits(user.phoneNumber || user.phone || '-') }}
+ نام کاربری: @{{ user.username }}
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ کل صورتحسابها
+ {{ toPersianDigits(financialSummary.totalPayable?.toLocaleString()) }} تومان
+
+
+
+
+
+
+
+
+
+
+ مجموع پرداختیها
+ {{ toPersianDigits(financialSummary.totalPaid?.toLocaleString()) }} تومان
+
+
+
+
+
+
+
+
+
+
+ مانده بدهی
+
+ {{ toPersianDigits(financialSummary.remainingDebt?.toLocaleString()) }} تومان
+
+
+
+
+
+
+
+
+
+
+
+ درصد حضور در جلسات
+ {{ toPersianDigits(attendanceSummary.attendanceRate || 0) }}٪
+
+
+
+
+
+
+
+
+
+
+
- {{ $t('users.tabInfo') }}
- {{ $t('users.tabCourses') }}
- {{ $t('users.tabSessions') }}
- {{ $t('users.tabPayments') }}
- گواهینامهها و اسناد
+ داشبورد و تحلیل نموداری
+ اطلاعات کاربری
+ کلاسها و دورهها ({{ toPersianDigits(classes.length) }})
+ حضور و غیاب ({{ toPersianDigits(attendances.length) }})
+ امور مالی و فاکتورها ({{ toPersianDigits(payments.length) }})
+ اسناد و مدارک
+ لیست انتظار ({{ toPersianDigits(waitlist.length) }})
+ سوابق فعالیت و پیامکها
+
-
+
-
-
- نام
- {{ user.name }}
-
-
- جنسیت
- {{ user.gender === 'male' ? 'مرد' : user.gender === 'female' ? 'زن' : '-' }}
-
-
- کد ملی
- {{ toPersianDigits(user.nationalIdCode || user.nationalId) }}
-
-
- شماره همراه
- {{ toPersianDigits(user.phoneNumber || user.phone) }}
-
-
- پست الکترونیکی
- {{ user.email || '-' }}
-
-
-
پیامرسان ترجیحی
-
-
+
+
+
+
+
+
+
تحلیل وضعیت حضور و غیاب
+
+
+
+
+
+
+
حاضر{{ toPersianDigits(attendanceSummary.present || 0) }}
+
تاخیر{{ toPersianDigits(attendanceSummary.late || 0) }}
+
موجه{{ toPersianDigits(attendanceSummary.excused || 0) }}
+
غایب{{ toPersianDigits(attendanceSummary.absent || 0) }}
+
+
+
+
+
+
+
+
+
وضعیت صورتحسابها و بدهی
+
+
+
+
+
+
+
کل شهریه{{ toPersianDigits(financialSummary.totalTuition?.toLocaleString()) }}
+
تخفیف کل{{ toPersianDigits(financialSummary.totalDiscount?.toLocaleString()) }}
+
مانده بدهی{{ toPersianDigits(financialSummary.remainingDebt?.toLocaleString()) }}
+
+
+
+
+
+
+
+
+
روند پرداختها و تراکنشهای مالی
+ مبالغ بر حسب ماه تراکنش
+
+
+
+
+
+
+
+
+
وضعیت پیشرفت در کلاسهای ثبتنامی
+
+
+
+
+ {{ cls.name }}
+ {{ cls.course?.title || '-' }}
+
+
+ مدرس: {{ cls.professor ? `${cls.professor.name} ${cls.professor.surname}` : 'تعیین نشده' }}
+ شهریه: {{ toPersianDigits(cls.tuitionFee?.toLocaleString()) }} تومان
+
+
+
+ برنامه: {{ cls.days?.length ? `${cls.days.length} روز در هفته` : '-' }} {{ cls.startTime || '' }}
+ {{ toPersianDigits(cls.numberOfSessions) }} جلسه
+
+
+
+
+
-
-
- نقش سیستم
-
-
-
- نام پدر
- {{ user.fatherName || '-' }}
-
-
- تاریخ تولد
- {{ user.birthDate ? new Date(user.birthDate).toLocaleDateString('fa-IR') : '-' }}
-
-
- شماره شناسنامه
- {{ user.birthCertificateNumber || '-' }}
-
-
- محل صدور
- {{ user.placeOfIssue || '-' }}
-
-
- کد پستی
- {{ user.postalCode || '-' }}
-
-
- تحصیلات
- {{ user.education || '-' }}
-
-
- شماره کارت
- {{ user.cardNumber || '-' }}
-
-
- شماره شبا (IBAN)
- {{ user.shabaNumber || user.iban || '-' }}
-
-
- آدرس سکونت
- {{ user.address || '-' }}
-
-
-
+
+
+
اطلاعات هویتی و شناسنامهای
+
+
+ نام و نام خانوادگی
+ {{ user.name }}
+
+
+ جنسیت
+ {{ user.gender === 'male' ? 'مرد' : user.gender === 'female' ? 'زن' : '-' }}
+
+
+ کد ملی
+ {{ toPersianDigits(user.nationalIdCode || user.nationalId) }}
+
+
+ شماره شناسنامه
+ {{ user.birthCertificateNumber || '-' }}
+
+
+ تاریخ تولد
+ {{ user.birthDate ? formatJalali(user.birthDate) : '-' }}
+
+
+ نام پدر
+ {{ user.fatherName || '-' }}
+
+
+ محل صدور شناسنامه
+ {{ user.placeOfIssue || '-' }}
+
+
+
+
اطلاعات تماس و پیامرسانها
+
+
+ شماره همراه
+ {{ toPersianDigits(user.phoneNumber || user.phone) }}
+
+
+ پست الکترونیکی (ایمیل)
+ {{ user.email || '-' }}
+
+
+ تلفن همراه والدین
+ {{ toPersianDigits(user.parentPhoneNumber || '-') }}
+
+
+
پیامرسانهای ترجیحی
+
+
+
+
+
+ کد پستی
+ {{ user.postalCode || '-' }}
+
+
+ آدرس سکونت
+ {{ user.address || '-' }}
+
+
+
+
اطلاعات مالی و تحصیلی
+
+
+ تحصیلات و رشته
+ {{ user.education || '-' }}
+
+
+ شماره کارت بانکی
+ {{ user.cardNumber || '-' }}
+
+
+ شماره شبا (IBAN)
+ {{ user.shabaNumber || user.iban || '-' }}
+
+
+
+
+
+
+
+
+
-
دورههای ثبتنام شده
+
کلاسهای ثبتنام شده دانشجو
-
-
-
+
+
+ دانشجو در کلاسی ثبتنام نکرده است.
+
+
-
+ {{ data.name }}
-
+
- {{ toPersianDigits(data.price?.toLocaleString()) }} تومان
+ {{ data.course?.title || '-' }}
-
+
- {{ formatJalali(data.enrollDate || data.createdAt) }}
+ {{ data.professor ? `${data.professor.name} ${data.professor.surname}` : '-' }}
+
+
+
+
+ {{ toPersianDigits((data.tuitionFee || 0).toLocaleString()) }} تومان
+
+
+
+
+ {{ toPersianDigits(data.numberOfSessions || '-') }}
+
+
+
+
+ {{ data.startDate ? formatJalali(data.startDate) : '-' }}
+
+
+
+
+
-
-
-
-
تاریخچه حضور و غیاب دانشجو
-
-
-
-
- {{ formatJalali(data.date) }}
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
صورتحسابها و پرداختها
-
+ سوابق حضور و غیاب دانشجو در جلسات
+
+
+
+
+
+
+
+
+
+
+ هیچ سابقه حضوری برای این دانشجو یافت نشد.
+
+
+
+ {{ data.topic || data.class?.name || 'جلسه آموزشی' }}
+
+
+
+
+ {{ data.course?.title || data.class?.name || '-' }}
+
+
+
+
+ {{ formatJalali(data.day) }}
+ ({{ data.startTime }})
+
+
+
+
+
+
+
+
+
+ {{ data.attendanceNote || '-' }}
+
+
+
+
+
+
+
+
+
+
+
صورتحسابها و فاکتورهای آموزشی
+
-
+
+
+
+ هیچ صورتحسابی برای این دانشجو ثبت نشده است.
+
+
+
+ {{ data.uniqueCode || '-' }}
+
+
+
+
+ {{ data.course?.title || data.classes?.[0]?.name || 'شهریه دوره' }}
+
+
- {{ toPersianDigits(getPayableAmount(data).toLocaleString()) }} تومان
-
- تخفیف {{ toPersianDigits((data.discount || 0).toLocaleString()) }} تومان
-
+ {{ toPersianDigits(data.amount?.toLocaleString()) }} تومان
+
+
+
+
+ {{ toPersianDigits((data.discount || 0).toLocaleString()) }} تومان
- {{ toPersianDigits(data.paidAmount?.toLocaleString()) }} تومان
+ {{ toPersianDigits((data.paidAmount || 0).toLocaleString()) }} تومان
@@ -182,26 +451,166 @@
-
+
- {{ formatJalali(data.dueDate) }}
+ {{ data.dueDate ? formatJalali(data.dueDate) : '-' }}
+
+
+
+
+
+ تراکنشهای بانکی ثبت شده
+
+
+ هیچ تراکنش بانکی ثبت نشده است.
+
+
+
+ {{ formatJalali(data.date || data.createdAt) }}
+
+
+
+
+ {{ toPersianDigits((data.amount || 0).toLocaleString()) }} تومان
+
+
+
+
+
+
+
+
+
+ {{ toPersianDigits(data.receiptNumber || '-') }}
+
+
+
+
+
+
+
+
+
+ {{ data.notes || '-' }}
-
-
+
+
+
+
گواهینامههای رسمی صادر شده
+
+
+
+
+ {{ cert.title }}
+
+
+
دوره: {{ cert.course?.title || '-' }}
+
تاریخ صدور: {{ formatJalali(cert.issuedAt) }}
+
+ دانلود گواهینامه
+
+
+
+
+
+
+
مدارک و فایلهای پیوست دانشجو
+
+
+
+
+
سوابق ثبتنام در لیست انتظار
+
+
+ هیچ درخواستی در لیست انتظار ثبت نشده است.
+
+
+
+
+ {{ data.class?.name || 'هنوز تخصیص نیافته' }}
+
+
+
+
+ {{ formatJalali(data.registeredAt || data.createdAt) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
پیامکها و اطلاعیههای ارسالی به دانشجو
+
+
+ هیچ اطلاعیهای ارسال نشده است.
+
+
+
+
+
+
+
+
+
+ {{ data.body }}
+
+
+
+
+
+
+
+
+
+ {{ formatJalali(data.createdAt) }}
+
+
+
+
+
+
لاگهای فعالیتهای اخیر
+
+
+ هیچ لاگ فعالیتی یافت نشد.
+
+
+
+
+
+
+
+
+
+
+ {{ formatJalali(data.createdAt) }}
+
+
+
+
+
-
-