Add sessionHolding template configuration and update session slot definitions
This commit is contained in:
@@ -3,10 +3,21 @@
|
|||||||
<div class="settings-view w-full max-w-4xl mx-auto">
|
<div class="settings-view w-full max-w-4xl mx-auto">
|
||||||
<PageHeader
|
<PageHeader
|
||||||
title="تنظیمات سیستم"
|
title="تنظیمات سیستم"
|
||||||
subtitle="کانالهای اطلاعرسانی، قالبهای پیامک، راهاندازی پایگاه داده و وارد کردن دادهها"
|
subtitle="کانالهای اطلاعرسانی، تنظیمات اعلان، قالبهای پیامک، راهاندازی و وارد کردن دادهها"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="surface-card p-4 sm:p-5 border-round-xl border-1 border-color shadow-sm mb-4">
|
<Tabs value="0" class="surface-card border-round-xl border-1 border-color shadow-sm">
|
||||||
|
<TabList>
|
||||||
|
<Tab value="0">کانالها</Tab>
|
||||||
|
<Tab value="1">اطلاعرسانی</Tab>
|
||||||
|
<Tab value="2">قالبهای پیامک</Tab>
|
||||||
|
<Tab value="3">راهاندازی</Tab>
|
||||||
|
<Tab value="4">وارد کردن داده</Tab>
|
||||||
|
</TabList>
|
||||||
|
|
||||||
|
<TabPanels>
|
||||||
|
<TabPanel value="0">
|
||||||
|
<div class="p-4 sm:p-5">
|
||||||
<div class="flex align-items-start gap-3 mb-4">
|
<div class="flex align-items-start gap-3 mb-4">
|
||||||
<div class="w-3rem h-3rem border-round-xl flex align-items-center justify-content-center flex-shrink-0 bg-primary-light text-primary">
|
<div class="w-3rem h-3rem border-round-xl flex align-items-center justify-content-center flex-shrink-0 bg-primary-light text-primary">
|
||||||
<i class="pi pi-bell text-xl"></i>
|
<i class="pi pi-bell text-xl"></i>
|
||||||
@@ -71,9 +82,85 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
<div class="surface-card p-4 sm:p-5 border-round-xl border-1 border-color shadow-sm mb-4">
|
<TabPanel value="1">
|
||||||
|
<div class="p-4 sm:p-5">
|
||||||
|
<div class="flex align-items-start gap-3 mb-4">
|
||||||
|
<div class="w-3rem h-3rem border-round-xl flex align-items-center justify-content-center flex-shrink-0 bg-primary-light text-primary">
|
||||||
|
<i class="pi pi-sliders-h text-xl"></i>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow-1">
|
||||||
|
<h2 class="text-lg font-bold text-color m-0 mb-1">تنظیمات اطلاعرسانی</h2>
|
||||||
|
<p class="text-sm text-muted m-0 line-height-3">
|
||||||
|
برای هر نوع رویداد، کانالهای پیامک، ایمیل و ربات را جداگانه فعال یا غیرفعال کنید. اگر رکوردی در پایگاه داده نباشد، هنگام بارگذاری مقادیر پیشفرض اعمال میشود.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="isSettingsLoading" class="flex align-items-center gap-2 text-muted text-sm">
|
||||||
|
<i class="pi pi-spin pi-spinner"></i>
|
||||||
|
<span>در حال بارگذاری تنظیمات اطلاعرسانی…</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else class="flex flex-column gap-4">
|
||||||
|
<div
|
||||||
|
v-for="group in notificationSettings"
|
||||||
|
:key="group.key"
|
||||||
|
class="flex flex-column gap-3"
|
||||||
|
>
|
||||||
|
<h3 class="text-base font-bold text-color m-0 pb-2 border-bottom-1 border-color">{{ group.label }}</h3>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-for="action in group.actions"
|
||||||
|
:key="action.key"
|
||||||
|
class="p-4 border-round-lg surface-ground border-1 border-color flex flex-column gap-3"
|
||||||
|
>
|
||||||
|
<div class="flex flex-column sm:flex-row sm:align-items-start justify-content-between gap-2">
|
||||||
|
<div>
|
||||||
|
<div class="font-bold text-color">{{ action.label }}</div>
|
||||||
|
<p class="text-xs text-muted m-0 mt-1 line-height-3">{{ action.description }}</p>
|
||||||
|
<span class="text-xs text-muted font-mono">{{ action.key }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div
|
||||||
|
v-for="channel in notificationChannelDefs"
|
||||||
|
:key="`${action.key}-${channel.key}`"
|
||||||
|
class="col-12 md:col-4"
|
||||||
|
>
|
||||||
|
<div class="flex align-items-center justify-content-between p-3 border-round surface-card border-1 border-color h-full">
|
||||||
|
<div class="flex align-items-center gap-2">
|
||||||
|
<i :class="channel.icon" class="text-primary"></i>
|
||||||
|
<span class="text-sm font-semibold">{{ channel.label }}</span>
|
||||||
|
</div>
|
||||||
|
<InputSwitch
|
||||||
|
v-model="notificationForm[action.key][channel.key]"
|
||||||
|
:inputId="`notify-${action.key}-${channel.key}`"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-content-end">
|
||||||
|
<Button
|
||||||
|
label="ذخیره تنظیمات اطلاعرسانی"
|
||||||
|
icon="pi pi-save"
|
||||||
|
class="font-bold"
|
||||||
|
:loading="isSavingNotifications"
|
||||||
|
@click="saveNotificationSettings"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
|
<TabPanel value="2">
|
||||||
|
<div class="p-4 sm:p-5">
|
||||||
<div class="flex align-items-start gap-3 mb-4">
|
<div class="flex align-items-start gap-3 mb-4">
|
||||||
<div class="w-3rem h-3rem border-round-xl flex align-items-center justify-content-center flex-shrink-0 bg-primary-light text-primary">
|
<div class="w-3rem h-3rem border-round-xl flex align-items-center justify-content-center flex-shrink-0 bg-primary-light text-primary">
|
||||||
<i class="pi pi-send text-xl"></i>
|
<i class="pi pi-send text-xl"></i>
|
||||||
@@ -211,9 +298,11 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
<div class="surface-card p-4 sm:p-5 border-round-xl border-1 border-color shadow-sm mb-4">
|
<TabPanel value="3">
|
||||||
|
<div class="p-4 sm:p-5">
|
||||||
<div class="flex align-items-start gap-3 mb-4">
|
<div class="flex align-items-start gap-3 mb-4">
|
||||||
<div class="w-3rem h-3rem border-round-xl flex align-items-center justify-content-center flex-shrink-0 bg-primary-light text-primary">
|
<div class="w-3rem h-3rem border-round-xl flex align-items-center justify-content-center flex-shrink-0 bg-primary-light text-primary">
|
||||||
<i class="pi pi-database text-xl"></i>
|
<i class="pi pi-database text-xl"></i>
|
||||||
@@ -251,9 +340,11 @@
|
|||||||
این عملیات فقط یکبار قابل اجرا است.
|
این عملیات فقط یکبار قابل اجرا است.
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</TabPanel>
|
||||||
|
|
||||||
<div class="surface-card p-4 sm:p-5 border-round-xl border-1 border-color shadow-sm">
|
<TabPanel value="4">
|
||||||
|
<div class="p-4 sm:p-5">
|
||||||
<div class="flex align-items-start gap-3 mb-4">
|
<div class="flex align-items-start gap-3 mb-4">
|
||||||
<div class="w-3rem h-3rem border-round-xl flex align-items-center justify-content-center flex-shrink-0 bg-primary-light text-primary">
|
<div class="w-3rem h-3rem border-round-xl flex align-items-center justify-content-center flex-shrink-0 bg-primary-light text-primary">
|
||||||
<i class="pi pi-upload text-xl"></i>
|
<i class="pi pi-upload text-xl"></i>
|
||||||
@@ -318,7 +409,10 @@
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</TabPanel>
|
||||||
|
</TabPanels>
|
||||||
|
</Tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -330,6 +424,11 @@ import InputSwitch from 'primevue/toggleswitch';
|
|||||||
import InputText from 'primevue/inputtext';
|
import InputText from 'primevue/inputtext';
|
||||||
import Select from 'primevue/select';
|
import Select from 'primevue/select';
|
||||||
import Tag from 'primevue/tag';
|
import Tag from 'primevue/tag';
|
||||||
|
import Tabs from 'primevue/tabs';
|
||||||
|
import TabList from 'primevue/tablist';
|
||||||
|
import Tab from 'primevue/tab';
|
||||||
|
import TabPanels from 'primevue/tabpanels';
|
||||||
|
import TabPanel from 'primevue/tabpanel';
|
||||||
import PageHeader from '@/components/common/PageHeader.vue';
|
import PageHeader from '@/components/common/PageHeader.vue';
|
||||||
import { seedApi } from '@/api/seedApi';
|
import { seedApi } from '@/api/seedApi';
|
||||||
import { settingsApi } from '@/api/settingsApi';
|
import { settingsApi } from '@/api/settingsApi';
|
||||||
@@ -341,8 +440,11 @@ const { showSuccess, showError } = useToast();
|
|||||||
const isSettingsLoading = ref(true);
|
const isSettingsLoading = ref(true);
|
||||||
const isSavingSettings = ref(false);
|
const isSavingSettings = ref(false);
|
||||||
const isSavingMessaging = ref(false);
|
const isSavingMessaging = ref(false);
|
||||||
|
const isSavingNotifications = ref(false);
|
||||||
const smsTemplates = ref([]);
|
const smsTemplates = ref([]);
|
||||||
const templateForm = ref({});
|
const templateForm = ref({});
|
||||||
|
const notificationSettings = ref([]);
|
||||||
|
const notificationForm = ref({});
|
||||||
const messagingForm = ref({
|
const messagingForm = ref({
|
||||||
smsEnabled: true,
|
smsEnabled: true,
|
||||||
emailEnabled: true,
|
emailEnabled: true,
|
||||||
@@ -360,6 +462,12 @@ const messagingChannels = [
|
|||||||
{ key: 'bot', flag: 'botEnabled', label: 'پیام ربات', icon: 'pi pi-comments', envName: 'BOT_ENABLED' }
|
{ key: 'bot', flag: 'botEnabled', label: 'پیام ربات', icon: 'pi pi-comments', envName: 'BOT_ENABLED' }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const notificationChannelDefs = [
|
||||||
|
{ key: 'sms', label: 'پیامک', icon: 'pi pi-mobile' },
|
||||||
|
{ key: 'email', label: 'ایمیل', icon: 'pi pi-envelope' },
|
||||||
|
{ key: 'bot', label: 'ربات', icon: 'pi pi-comments' }
|
||||||
|
];
|
||||||
|
|
||||||
const channelStatus = (channelKey) => {
|
const channelStatus = (channelKey) => {
|
||||||
const flag = `${channelKey}Enabled`;
|
const flag = `${channelKey}Enabled`;
|
||||||
const dbOn = messagingForm.value[flag] !== false;
|
const dbOn = messagingForm.value[flag] !== false;
|
||||||
@@ -385,7 +493,15 @@ const TEMPLATE_SLOT_DEFS = {
|
|||||||
{ value: 'username', label: 'نام کاربری', defaultName: 'user' },
|
{ value: 'username', label: 'نام کاربری', defaultName: 'user' },
|
||||||
{ value: 'password', label: 'رمز عبور', defaultName: 'password' },
|
{ value: 'password', label: 'رمز عبور', defaultName: 'password' },
|
||||||
{ value: 'fullName', label: 'نام و نام خانوادگی', defaultName: 'name' },
|
{ value: 'fullName', label: 'نام و نام خانوادگی', defaultName: 'name' },
|
||||||
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' },
|
||||||
|
{ value: 'userCode', label: 'کد کاربری', defaultName: 'userCode' }
|
||||||
|
],
|
||||||
|
passwordReset: [
|
||||||
|
{ value: 'username', label: 'نام کاربری', defaultName: 'user' },
|
||||||
|
{ value: 'password', label: 'رمز عبور', defaultName: 'password' },
|
||||||
|
{ value: 'fullName', label: 'نام کاربر', defaultName: 'name' },
|
||||||
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' },
|
||||||
|
{ value: 'userCode', label: 'کد کاربری', defaultName: 'userCode' }
|
||||||
],
|
],
|
||||||
classRegistered: [
|
classRegistered: [
|
||||||
{ value: 'className', label: 'نام کلاس', defaultName: 'className' },
|
{ value: 'className', label: 'نام کلاس', defaultName: 'className' },
|
||||||
@@ -393,19 +509,24 @@ const TEMPLATE_SLOT_DEFS = {
|
|||||||
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||||
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' },
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' },
|
||||||
{ value: 'classStartDate', label: 'تاریخ شروع کلاس', defaultName: 'classStartDate' },
|
{ value: 'classStartDate', label: 'تاریخ شروع کلاس', defaultName: 'classStartDate' },
|
||||||
{ value: 'classDays', label: 'روزهای برگزاری (مثلاً شنبه و دوشنبه)', defaultName: 'classDays' },
|
{ value: 'classDays', label: 'روزهای برگزاری', defaultName: 'classDays' },
|
||||||
{ value: 'courseTime', label: 'ساعت دوره (مثلاً از ۱۹ تا ۲۱)', defaultName: 'courseTime' }
|
{ value: 'courseTime', label: 'ساعت دوره', defaultName: 'courseTime' },
|
||||||
|
{ value: 'classCode', label: 'کد کلاس', defaultName: 'classCode' }
|
||||||
],
|
],
|
||||||
classReminder: [
|
classReminder: [
|
||||||
{ value: 'className', label: 'نام کلاس', defaultName: 'className' },
|
{ value: 'className', label: 'نام کلاس', defaultName: 'className' },
|
||||||
{ value: 'time', label: 'ساعت برگزاری', defaultName: 'time' },
|
|
||||||
{ value: 'place', label: 'مکان برگزاری', defaultName: 'place' },
|
|
||||||
{ value: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
|
{ value: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
|
||||||
|
{ value: 'topic', label: 'موضوع جلسه', defaultName: 'topic' },
|
||||||
|
{ value: 'time', label: 'ساعت برگزاری', defaultName: 'time' },
|
||||||
|
{ value: 'classTime', label: 'ساعت کلاس', defaultName: 'classTime' },
|
||||||
|
{ value: 'sessionDate', label: 'تاریخ جلسه', defaultName: 'sessionDate' },
|
||||||
|
{ value: 'place', label: 'مکان برگزاری', defaultName: 'place' },
|
||||||
{ value: 'fullName', label: 'نام کاربر', defaultName: 'fullName' },
|
{ value: 'fullName', label: 'نام کاربر', defaultName: 'fullName' },
|
||||||
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' },
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' },
|
||||||
{ value: 'classStartDate', label: 'تاریخ شروع کلاس', defaultName: 'classStartDate' },
|
{ value: 'classStartDate', label: 'تاریخ شروع کلاس', defaultName: 'classStartDate' },
|
||||||
{ value: 'classDays', label: 'روزهای برگزاری (مثلاً شنبه و دوشنبه)', defaultName: 'classDays' },
|
{ value: 'classDays', label: 'روزهای برگزاری', defaultName: 'classDays' },
|
||||||
{ value: 'courseTime', label: 'ساعت دوره (مثلاً از ۱۹ تا ۲۱)', defaultName: 'courseTime' }
|
{ value: 'courseTime', label: 'ساعت دوره', defaultName: 'courseTime' },
|
||||||
|
{ value: 'classCode', label: 'کد کلاس', defaultName: 'classCode' }
|
||||||
],
|
],
|
||||||
invoiceCreated: [
|
invoiceCreated: [
|
||||||
{ value: 'amount', label: 'مبلغ صورتحساب (تومان)', defaultName: 'PAYMENT_PRICE' },
|
{ value: 'amount', label: 'مبلغ صورتحساب (تومان)', defaultName: 'PAYMENT_PRICE' },
|
||||||
@@ -413,8 +534,79 @@ const TEMPLATE_SLOT_DEFS = {
|
|||||||
{ value: 'course', label: 'نام دوره / کلاس', defaultName: 'COURSE' },
|
{ value: 'course', label: 'نام دوره / کلاس', defaultName: 'COURSE' },
|
||||||
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'MOBILE' },
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'MOBILE' },
|
||||||
{ value: 'classStartDate', label: 'تاریخ شروع کلاس', defaultName: 'classStartDate' },
|
{ value: 'classStartDate', label: 'تاریخ شروع کلاس', defaultName: 'classStartDate' },
|
||||||
{ value: 'classDays', label: 'روزهای برگزاری (مثلاً شنبه و دوشنبه)', defaultName: 'classDays' },
|
{ value: 'classDays', label: 'روزهای برگزاری', defaultName: 'classDays' },
|
||||||
{ value: 'courseTime', label: 'ساعت دوره (مثلاً از ۱۹ تا ۲۱)', defaultName: 'courseTime' }
|
{ value: 'courseTime', label: 'ساعت دوره', defaultName: 'courseTime' },
|
||||||
|
{ value: 'invoiceCode', label: 'کد صورتحساب', defaultName: 'invoiceCode' }
|
||||||
|
],
|
||||||
|
paymentStatusChanged: [
|
||||||
|
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||||
|
{ value: 'status', label: 'وضعیت', defaultName: 'status' },
|
||||||
|
{ value: 'amount', label: 'مبلغ', defaultName: 'amount' },
|
||||||
|
{ value: 'invoiceCode', label: 'کد صورتحساب', defaultName: 'invoiceCode' },
|
||||||
|
{ value: 'course', label: 'نام دوره', defaultName: 'course' },
|
||||||
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||||
|
],
|
||||||
|
paymentReminder: [
|
||||||
|
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||||
|
{ value: 'amount', label: 'مبلغ باقیمانده', defaultName: 'amount' },
|
||||||
|
{ value: 'dueDate', label: 'تاریخ سررسید', defaultName: 'dueDate' },
|
||||||
|
{ value: 'invoiceCode', label: 'کد صورتحساب', defaultName: 'invoiceCode' },
|
||||||
|
{ value: 'course', label: 'نام دوره', defaultName: 'course' },
|
||||||
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||||
|
],
|
||||||
|
transactionRecorded: [
|
||||||
|
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||||
|
{ value: 'amount', label: 'مبلغ', defaultName: 'amount' },
|
||||||
|
{ value: 'invoiceCode', label: 'کد صورتحساب', defaultName: 'invoiceCode' },
|
||||||
|
{ value: 'transactionCode', label: 'کد تراکنش', defaultName: 'transactionCode' },
|
||||||
|
{ value: 'receiptNumber', label: 'شماره رسید', defaultName: 'receiptNumber' },
|
||||||
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||||
|
],
|
||||||
|
sessionCancelled: [
|
||||||
|
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||||
|
{ value: 'className', label: 'نام کلاس', defaultName: 'className' },
|
||||||
|
{ value: 'topic', label: 'موضوع جلسه', defaultName: 'topic' },
|
||||||
|
{ value: 'sessionDate', label: 'تاریخ جلسه', defaultName: 'sessionDate' },
|
||||||
|
{ value: 'reason', label: 'دلیل لغو', defaultName: 'reason' },
|
||||||
|
{ value: 'classCode', label: 'کد کلاس', defaultName: 'classCode' },
|
||||||
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||||
|
],
|
||||||
|
sessionHolding: [
|
||||||
|
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'FULLNAME' },
|
||||||
|
{ value: 'topic', label: 'موضوع جلسه', defaultName: 'TOPIC' },
|
||||||
|
{ value: 'className', label: 'نام کلاس', defaultName: 'CLASSNAME' },
|
||||||
|
{ value: 'sessionDate', label: 'تاریخ جلسه', defaultName: 'SESSIONDATE' },
|
||||||
|
{ value: 'classTime', label: 'ساعت کلاس', defaultName: 'CLASSTIME' },
|
||||||
|
{ value: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
|
||||||
|
{ value: 'classCode', label: 'کد کلاس', defaultName: 'classCode' },
|
||||||
|
{ value: 'place', label: 'مکان', defaultName: 'place' },
|
||||||
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||||
|
],
|
||||||
|
classRequestApproved: [
|
||||||
|
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||||
|
{ value: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
|
||||||
|
{ value: 'classCode', label: 'کد کلاس', defaultName: 'classCode' },
|
||||||
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||||
|
],
|
||||||
|
classRequestRejected: [
|
||||||
|
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||||
|
{ value: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
|
||||||
|
{ value: 'reason', label: 'دلیل', defaultName: 'reason' },
|
||||||
|
{ value: 'registrationCode', label: 'کد درخواست', defaultName: 'registrationCode' },
|
||||||
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||||
|
],
|
||||||
|
pendingRegistration: [
|
||||||
|
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||||
|
{ value: 'className', label: 'نام کلاس', defaultName: 'className' },
|
||||||
|
{ value: 'registrationCode', label: 'کد درخواست', defaultName: 'registrationCode' },
|
||||||
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||||
|
],
|
||||||
|
certificateIssued: [
|
||||||
|
{ value: 'fullName', label: 'نام کارآموز', defaultName: 'fullName' },
|
||||||
|
{ value: 'certificateTitle', label: 'عنوان گواهینامه', defaultName: 'certificateTitle' },
|
||||||
|
{ value: 'certificateCode', label: 'کد گواهینامه', defaultName: 'certificateCode' },
|
||||||
|
{ value: 'courseName', label: 'نام دوره', defaultName: 'courseName' },
|
||||||
|
{ value: 'phoneNumber', label: 'شماره همراه', defaultName: 'mobile' }
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -600,9 +792,28 @@ const applyMessaging = (payload) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const applyNotificationSettings = (payload) => {
|
||||||
|
const data = payload?.data?.data || payload?.data || payload || {};
|
||||||
|
const groups = Array.isArray(data.notificationSettings) ? data.notificationSettings : [];
|
||||||
|
notificationSettings.value = groups;
|
||||||
|
|
||||||
|
const form = {};
|
||||||
|
groups.forEach((group) => {
|
||||||
|
(group.actions || []).forEach((action) => {
|
||||||
|
form[action.key] = {
|
||||||
|
sms: action.channels?.sms !== false,
|
||||||
|
email: action.channels?.email === true,
|
||||||
|
bot: action.channels?.bot === true
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
notificationForm.value = form;
|
||||||
|
};
|
||||||
|
|
||||||
const applySettings = (payload) => {
|
const applySettings = (payload) => {
|
||||||
applySmsTemplates(payload);
|
applySmsTemplates(payload);
|
||||||
applyMessaging(payload);
|
applyMessaging(payload);
|
||||||
|
applyNotificationSettings(payload);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadSettings = async () => {
|
const loadSettings = async () => {
|
||||||
@@ -636,6 +847,30 @@ const saveMessaging = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const saveNotificationSettings = async () => {
|
||||||
|
isSavingNotifications.value = true;
|
||||||
|
try {
|
||||||
|
const payload = {};
|
||||||
|
notificationSettings.value.forEach((group) => {
|
||||||
|
(group.actions || []).forEach((action) => {
|
||||||
|
const channels = notificationForm.value[action.key] || {};
|
||||||
|
payload[action.key] = {
|
||||||
|
sms: Boolean(channels.sms),
|
||||||
|
email: Boolean(channels.email),
|
||||||
|
bot: Boolean(channels.bot)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const response = await settingsApi.save({ notificationSettings: payload });
|
||||||
|
applySettings(response);
|
||||||
|
showSuccess('تنظیمات اطلاعرسانی با موفقیت ذخیره شد.');
|
||||||
|
} catch (err) {
|
||||||
|
showError(err);
|
||||||
|
} finally {
|
||||||
|
isSavingNotifications.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const saveSmsTemplates = async () => {
|
const saveSmsTemplates = async () => {
|
||||||
isSavingSettings.value = true;
|
isSavingSettings.value = true;
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user