fix: jalali date defaults, calendar arrow direction, payment status label, edit page load, and session holding notification
This commit is contained in:
@@ -74,7 +74,7 @@
|
||||
<StatusTag :status="data.status || 'scheduled'" type="session" />
|
||||
</template>
|
||||
</Column>
|
||||
<Column header="عملیات" style="width: 140px">
|
||||
<Column header="عملیات" style="width: 170px">
|
||||
<template #body="{ data }">
|
||||
<div class="flex align-items-center gap-1">
|
||||
<Button
|
||||
@@ -86,6 +86,16 @@
|
||||
v-tooltip.top="'حضور و غیاب'"
|
||||
@click="$router.push(`/sessions/attendance/${data._id || data.id}`)"
|
||||
/>
|
||||
<Button
|
||||
icon="pi pi-send"
|
||||
text
|
||||
rounded
|
||||
size="small"
|
||||
severity="info"
|
||||
v-tooltip.top="'اطلاعرسانی برگزاری جلسه'"
|
||||
:loading="notifyingSessionId === (data._id || data.id)"
|
||||
@click="openNotifyHoldingDialog(data)"
|
||||
/>
|
||||
<Button
|
||||
icon="pi pi-pencil"
|
||||
text
|
||||
@@ -118,6 +128,34 @@
|
||||
@confirm="handleDeleteConfirm"
|
||||
/>
|
||||
|
||||
<Dialog
|
||||
v-model:visible="notifyDialogVisible"
|
||||
header="اطلاعرسانی برگزاری جلسه"
|
||||
modal
|
||||
:style="{ width: '450px' }"
|
||||
>
|
||||
<div class="flex flex-column gap-3 py-2">
|
||||
<p class="m-0 line-height-3 text-sm">
|
||||
آیا از ارسال پیامک برگزاری جلسه طبق برنامه به تمامی دانشجویان این کلاس اطمینان دارید؟
|
||||
</p>
|
||||
<div v-if="selectedSessionForNotify" class="surface-100 p-3 border-round text-xs flex flex-column gap-1">
|
||||
<div><strong>موضوع جلسه:</strong> {{ selectedSessionForNotify.topic || 'طبق برنامه' }}</div>
|
||||
<div><strong>تاریخ:</strong> {{ formatJalali(selectedSessionForNotify.day || selectedSessionForNotify.date) }}</div>
|
||||
<div><strong>ساعت:</strong> {{ selectedSessionForNotify.startTime || '—' }} تا {{ selectedSessionForNotify.endTime || '—' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<template #footer>
|
||||
<Button label="انصراف" text severity="secondary" @click="notifyDialogVisible = false" />
|
||||
<Button
|
||||
label="ارسال پیامک"
|
||||
icon="pi pi-send"
|
||||
severity="info"
|
||||
:loading="isNotifying"
|
||||
@click="handleSendSessionHolding"
|
||||
/>
|
||||
</template>
|
||||
</Dialog>
|
||||
|
||||
<!-- Bulk auto-create: only when no sessions yet -->
|
||||
<div v-if="!hasSessions" class="surface-card p-4 sm:p-5 border-round border-1 border-color shadow-sm">
|
||||
<h2 class="text-lg font-bold text-color mb-1">ایجاد جلسات کلاس</h2>
|
||||
@@ -249,6 +287,7 @@ import SelectButton from 'primevue/selectbutton';
|
||||
import DatePicker from 'vue3-persian-datetime-picker';
|
||||
import DataTable from 'primevue/datatable';
|
||||
import Column from 'primevue/column';
|
||||
import Dialog from 'primevue/dialog';
|
||||
|
||||
const props = defineProps({
|
||||
classId: { type: [String, Object], required: true },
|
||||
@@ -260,7 +299,7 @@ const props = defineProps({
|
||||
endTime: { type: String, default: '' }
|
||||
});
|
||||
|
||||
const { toPersianDigits, toLatinDigits, formatJalali } = usePersianDate();
|
||||
const { toPersianDigits, toLatinDigits, formatJalali, getTodayJalali } = usePersianDate();
|
||||
const { showSuccess, showError } = useToast();
|
||||
|
||||
const todayJalali = () => moment().locale('fa').format('jYYYY/jMM/jDD');
|
||||
@@ -278,6 +317,35 @@ const bulkStatus = ref(null);
|
||||
const generatedSessions = ref([]);
|
||||
const manualSessions = ref([{ date: todayJalali(), startTime: '19:00', endTime: '20:30', topic: '' }]);
|
||||
|
||||
const notifyDialogVisible = ref(false);
|
||||
const selectedSessionForNotify = ref(null);
|
||||
const notifyingSessionId = ref(null);
|
||||
const isNotifying = ref(false);
|
||||
|
||||
const openNotifyHoldingDialog = (session) => {
|
||||
selectedSessionForNotify.value = session;
|
||||
notifyDialogVisible.value = true;
|
||||
};
|
||||
|
||||
const handleSendSessionHolding = async () => {
|
||||
if (!selectedSessionForNotify.value) return;
|
||||
const id = selectedSessionForNotify.value._id || selectedSessionForNotify.value.id;
|
||||
notifyingSessionId.value = id;
|
||||
isNotifying.value = true;
|
||||
try {
|
||||
const res = await sessionApi.notifyHolding(id);
|
||||
const count = res.data?.sentCount || res.data?.totalStudents || '';
|
||||
showSuccess(`پیامک برگزاری جلسه با موفقیت به ${count ? toPersianDigits(count) + ' نفر از ' : ''}دانشجویان ارسال شد`);
|
||||
notifyDialogVisible.value = false;
|
||||
selectedSessionForNotify.value = null;
|
||||
} catch (err) {
|
||||
showError(err);
|
||||
} finally {
|
||||
notifyingSessionId.value = null;
|
||||
isNotifying.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const statusOptions = [
|
||||
{ label: 'طبق برنامه', value: 'scheduled' },
|
||||
{ label: 'برگزار شده', value: 'held' },
|
||||
|
||||
@@ -44,7 +44,7 @@ const NOTIFICATION_LABELS = {
|
||||
|
||||
const PAYMENT_LABELS = {
|
||||
paid: 'تسویهشده',
|
||||
partial: 'پرداخت جزئی',
|
||||
partial: 'پیش پرداخت',
|
||||
pending: 'در انتظار پرداخت',
|
||||
overdue: 'معوق',
|
||||
cancelled: 'لغوشده'
|
||||
@@ -63,7 +63,7 @@ const severity = computed(() => {
|
||||
|
||||
if (props.type === 'payment') {
|
||||
if (val === 'paid' || val === 'تسویه شده' || val === 'تسویهشده') return 'success';
|
||||
if (val === 'partial' || val === 'پرداخت جزئی') return 'contrast';
|
||||
if (val === 'partial' || val === 'پرداخت جزئی' || val === 'پیش پرداخت') return 'contrast';
|
||||
if (val === 'pending' || val === 'در انتظار پرداخت') return 'info';
|
||||
if (val === 'overdue' || val === 'معوق شده' || val === 'معوق') return 'danger';
|
||||
if (val === 'cancelled' || val === 'canceled' || val === 'لغوشده') return 'secondary';
|
||||
|
||||
Reference in New Issue
Block a user