@@ -38,7 +38,7 @@
|
|||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<Button @click="openFileSelector" :loading="uploading">
|
<Button @click="openFileSelector" :loading="uploading">
|
||||||
{{
|
{{
|
||||||
uploading ? `Uploading ${progress}%` : 'Upload an zip file'
|
uploading ? `Uploading ${progress}%` : 'Upload an ZIP file'
|
||||||
}}
|
}}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,98 +8,109 @@
|
|||||||
{{ __('Save') }}
|
{{ __('Save') }}
|
||||||
</Button>
|
</Button>
|
||||||
</header>
|
</header>
|
||||||
<div class="w-1/2 mx-auto py-5">
|
<div class="w-3/4 mx-auto py-5">
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="text-lg font-semibold mb-4">
|
<div class="text-lg font-semibold mb-4">
|
||||||
{{ __('Details') }}
|
{{ __('Details') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-4 mb-4">
|
<div class="space-y-10 mb-4">
|
||||||
<FormControl
|
<div class="grid grid-cols-2 gap-10">
|
||||||
v-model="batch.title"
|
|
||||||
:label="__('Title')"
|
|
||||||
:required="true"
|
|
||||||
class="w-full"
|
|
||||||
/>
|
|
||||||
<div class="flex items-center space-x-5">
|
|
||||||
<FormControl
|
<FormControl
|
||||||
v-model="batch.published"
|
v-model="batch.title"
|
||||||
type="checkbox"
|
:label="__('Title')"
|
||||||
:label="__('Published')"
|
:required="true"
|
||||||
|
class="w-full"
|
||||||
/>
|
/>
|
||||||
<FormControl
|
<MultiSelect
|
||||||
v-model="batch.allow_self_enrollment"
|
v-model="instructors"
|
||||||
type="checkbox"
|
doctype="User"
|
||||||
:label="__('Allow self enrollment')"
|
:label="__('Instructors')"
|
||||||
/>
|
:required="true"
|
||||||
<FormControl
|
:filters="{ ignore_user_type: 1 }"
|
||||||
v-model="batch.certification"
|
|
||||||
type="checkbox"
|
|
||||||
:label="__('Certification')"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
<div class="grid grid-cols-2 gap-10">
|
||||||
<div class="mb-4">
|
<div class="flex flex-col space-y-5">
|
||||||
<div class="text-xs text-ink-gray-5 mb-2">
|
<FormControl
|
||||||
{{ __('Meta Image') }}
|
v-model="batch.published"
|
||||||
</div>
|
type="checkbox"
|
||||||
<FileUploader
|
:label="__('Published')"
|
||||||
v-if="!batch.image"
|
/>
|
||||||
:fileTypes="['image/*']"
|
<FormControl
|
||||||
:validateFile="validateFile"
|
v-model="batch.allow_self_enrollment"
|
||||||
@success="(file) => saveImage(file)"
|
type="checkbox"
|
||||||
>
|
:label="__('Allow self enrollment')"
|
||||||
<template v-slot="{ file, progress, uploading, openFileSelector }">
|
/>
|
||||||
<div class="flex items-center">
|
<FormControl
|
||||||
<div class="border rounded-md w-fit py-5 px-20">
|
v-model="batch.certification"
|
||||||
<Image class="size-5 stroke-1 text-ink-gray-7" />
|
type="checkbox"
|
||||||
|
:label="__('Certification')"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="text-xs text-ink-gray-5 mb-2">
|
||||||
|
{{ __('Meta Image') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<FileUploader
|
||||||
<Button @click="openFileSelector">
|
v-if="!batch.image"
|
||||||
{{ __('Upload') }}
|
:fileTypes="['image/*']"
|
||||||
</Button>
|
:validateFile="validateFile"
|
||||||
<div class="mt-2 text-ink-gray-5 text-sm">
|
@success="(file) => saveImage(file)"
|
||||||
{{
|
>
|
||||||
__(
|
<template
|
||||||
'Appears when the batch URL is shared on any online platform'
|
v-slot="{ file, progress, uploading, openFileSelector }"
|
||||||
)
|
>
|
||||||
}}
|
<div class="flex items-center">
|
||||||
|
<div class="border rounded-md w-fit py-5 px-20">
|
||||||
|
<Image class="size-5 stroke-1 text-ink-gray-7" />
|
||||||
|
</div>
|
||||||
|
<div class="ml-4">
|
||||||
|
<Button @click="openFileSelector">
|
||||||
|
{{ __('Upload') }}
|
||||||
|
</Button>
|
||||||
|
<div class="mt-2 text-ink-gray-5 text-sm">
|
||||||
|
{{
|
||||||
|
__(
|
||||||
|
'Appears when the batch URL is shared on any online platform'
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</FileUploader>
|
||||||
|
<div v-else class="mb-4">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<img
|
||||||
|
:src="batch.image.file_url"
|
||||||
|
class="border rounded-md w-40"
|
||||||
|
/>
|
||||||
|
<div class="ml-4">
|
||||||
|
<Button @click="removeImage()">
|
||||||
|
{{ __('Remove') }}
|
||||||
|
</Button>
|
||||||
|
<div class="mt-2 text-ink-gray-5 text-sm">
|
||||||
|
{{
|
||||||
|
__(
|
||||||
|
'Appears when the batch URL is shared on any online platform'
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
</FileUploader>
|
|
||||||
<div v-else class="mb-4">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<img :src="batch.image.file_url" class="border rounded-md w-40" />
|
|
||||||
<div class="ml-4">
|
|
||||||
<Button @click="removeImage()">
|
|
||||||
{{ __('Remove') }}
|
|
||||||
</Button>
|
|
||||||
<div class="mt-2 text-ink-gray-5 text-sm">
|
|
||||||
{{
|
|
||||||
__(
|
|
||||||
'Appears when the batch URL is shared on any online platform'
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<MultiSelect
|
|
||||||
v-model="instructors"
|
|
||||||
doctype="User"
|
|
||||||
:label="__('Instructors')"
|
|
||||||
:required="true"
|
|
||||||
:filters="{ ignore_user_type: 1 }"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div class="my-10">
|
<div class="my-10">
|
||||||
<div class="text-lg font-semibold mb-4">
|
<div class="text-lg font-semibold mb-4">
|
||||||
{{ __('Date and Time') }}
|
{{ __('Date and Time') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-10">
|
<div class="grid grid-cols-3 gap-10">
|
||||||
<div>
|
<div>
|
||||||
<FormControl
|
<FormControl
|
||||||
v-model="batch.start_date"
|
v-model="batch.start_date"
|
||||||
@@ -115,14 +126,6 @@
|
|||||||
class="mb-4"
|
class="mb-4"
|
||||||
:required="true"
|
:required="true"
|
||||||
/>
|
/>
|
||||||
<FormControl
|
|
||||||
v-model="batch.timezone"
|
|
||||||
:label="__('Timezone')"
|
|
||||||
type="text"
|
|
||||||
:placeholder="__('Example: IST (+5:30)')"
|
|
||||||
class="mb-4"
|
|
||||||
:required="true"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<FormControl
|
<FormControl
|
||||||
@@ -140,6 +143,16 @@
|
|||||||
:required="true"
|
:required="true"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<FormControl
|
||||||
|
v-model="batch.timezone"
|
||||||
|
:label="__('Timezone')"
|
||||||
|
type="text"
|
||||||
|
:placeholder="__('Example: IST (+5:30)')"
|
||||||
|
class="mb-4"
|
||||||
|
:required="true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -147,7 +160,7 @@
|
|||||||
<div class="text-lg font-semibold mb-4">
|
<div class="text-lg font-semibold mb-4">
|
||||||
{{ __('Settings') }}
|
{{ __('Settings') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-10">
|
<div class="grid grid-cols-3 gap-10">
|
||||||
<div>
|
<div>
|
||||||
<FormControl
|
<FormControl
|
||||||
v-model="batch.seat_count"
|
v-model="batch.seat_count"
|
||||||
@@ -162,11 +175,6 @@
|
|||||||
type="date"
|
type="date"
|
||||||
class="mb-4"
|
class="mb-4"
|
||||||
/>
|
/>
|
||||||
<Link
|
|
||||||
doctype="Email Template"
|
|
||||||
:label="__('Email Template')"
|
|
||||||
v-model="batch.confirmation_email_template"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<FormControl
|
<FormControl
|
||||||
@@ -191,6 +199,13 @@
|
|||||||
v-model="batch.category"
|
v-model="batch.category"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<Link
|
||||||
|
doctype="Email Template"
|
||||||
|
:label="__('Email Template')"
|
||||||
|
v-model="batch.confirmation_email_template"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -198,17 +213,16 @@
|
|||||||
<div class="text-lg font-semibold mb-4">
|
<div class="text-lg font-semibold mb-4">
|
||||||
{{ __('Payment') }}
|
{{ __('Payment') }}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<FormControl
|
||||||
<FormControl
|
v-model="batch.paid_batch"
|
||||||
v-model="batch.paid_batch"
|
type="checkbox"
|
||||||
type="checkbox"
|
:label="__('Paid Batch')"
|
||||||
:label="__('Paid Batch')"
|
/>
|
||||||
/>
|
<div class="grid grid-cols-3 gap-10 mt-4">
|
||||||
<FormControl
|
<FormControl
|
||||||
v-model="batch.amount"
|
v-model="batch.amount"
|
||||||
:label="__('Amount')"
|
:label="__('Amount')"
|
||||||
type="number"
|
type="number"
|
||||||
class="my-4"
|
|
||||||
/>
|
/>
|
||||||
<Link
|
<Link
|
||||||
doctype="Currency"
|
doctype="Currency"
|
||||||
@@ -445,7 +459,7 @@ const createNewBatch = () => {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
onError(err) {
|
onError(err) {
|
||||||
showToast('Error', err.messages?.[0] || err, 'x')
|
showToast('Message', err.messages?.[0] || err, 'alert-circle')
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -464,7 +478,7 @@ const editBatchDetails = () => {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
onError(err) {
|
onError(err) {
|
||||||
showToast('Error', err.messages?.[0] || err, 'x')
|
showToast('Message', err.messages?.[0] || err, 'alert-circle')
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -50,8 +50,7 @@ export const sessionStore = defineStore('lms-session', () => {
|
|||||||
brand.name = data.app_name
|
brand.name = data.app_name
|
||||||
brand.logo = data.app_logo
|
brand.logo = data.app_logo
|
||||||
brand.favicon =
|
brand.favicon =
|
||||||
data.favicon?.file_url ||
|
data.favicon?.file_url || '/assets/lms/frontend/learning.svg'
|
||||||
'/assets/lms/frontend/public/learning.svg'
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ export function showToast(title, text, icon, iconClasses = null) {
|
|||||||
icon: icon,
|
icon: icon,
|
||||||
iconClasses: iconClasses,
|
iconClasses: iconClasses,
|
||||||
position: icon == 'check' ? 'bottom-right' : 'top-center',
|
position: icon == 'check' ? 'bottom-right' : 'top-center',
|
||||||
timeout: 5,
|
timeout: icon != 'check' ? 10 : 5,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ on_login = "lms.lms.user.on_login"
|
|||||||
add_to_apps_screen = [
|
add_to_apps_screen = [
|
||||||
{
|
{
|
||||||
"name": "lms",
|
"name": "lms",
|
||||||
"logo": "/assets/lms/images/lms-logo.png",
|
"logo": "/assets/lms/frontend/learning.svg",
|
||||||
"title": "Learning",
|
"title": "Learning",
|
||||||
"route": "/lms",
|
"route": "/lms",
|
||||||
"has_permission": "lms.lms.api.check_app_permission",
|
"has_permission": "lms.lms.api.check_app_permission",
|
||||||
|
|||||||
@@ -53,7 +53,12 @@ class LMSBatch(Document):
|
|||||||
if self.paid_batch:
|
if self.paid_batch:
|
||||||
installed_apps = frappe.get_installed_apps()
|
installed_apps = frappe.get_installed_apps()
|
||||||
if "payments" not in installed_apps:
|
if "payments" not in installed_apps:
|
||||||
frappe.throw(_("Please install the Payments app to create a paid batches."))
|
documentation_link = "https://docs.frappe.io/learning/setting-up-payment-gateway"
|
||||||
|
frappe.throw(
|
||||||
|
_(
|
||||||
|
"Please install the Payments App to create a paid batch. Refer to the documentation for more details. {0}"
|
||||||
|
).format(documentation_link)
|
||||||
|
)
|
||||||
|
|
||||||
def validate_amount_and_currency(self):
|
def validate_amount_and_currency(self):
|
||||||
if self.paid_batch and (not self.amount or not self.currency):
|
if self.paid_batch and (not self.amount or not self.currency):
|
||||||
|
|||||||
@@ -50,7 +50,12 @@ class LMSCourse(Document):
|
|||||||
if self.paid_course:
|
if self.paid_course:
|
||||||
installed_apps = frappe.get_installed_apps()
|
installed_apps = frappe.get_installed_apps()
|
||||||
if "payments" not in installed_apps:
|
if "payments" not in installed_apps:
|
||||||
frappe.throw(_("Please install the Payments app to create a paid courses."))
|
documentation_link = "https://docs.frappe.io/learning/setting-up-payment-gateway"
|
||||||
|
frappe.throw(
|
||||||
|
_(
|
||||||
|
"Please install the Payments App to create a paid course. Refer to the documentation for more details. {0}"
|
||||||
|
).format(documentation_link)
|
||||||
|
)
|
||||||
|
|
||||||
def validate_certification(self):
|
def validate_certification(self):
|
||||||
if self.enable_certification and self.paid_certificate:
|
if self.enable_certification and self.paid_certificate:
|
||||||
|
|||||||
@@ -20,10 +20,11 @@ frappe.ui.form.on("LMS Settings", {
|
|||||||
frm.get_field("payments_app_is_not_installed").html(`
|
frm.get_field("payments_app_is_not_installed").html(`
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
Please install the
|
Please install the
|
||||||
<a target="_blank" style="color: var(--alert-text-warning); background: var(--alert-bg-warning);" href="https://frappecloud.com/marketplace/apps/payments">
|
<a target="_blank" style="text-decoration: underline; color: var(--alert-text-warning); background: var(--alert-bg-warning);" href="https://frappecloud.com/marketplace/apps/payments">Payments app</a>
|
||||||
Payments app
|
to enable payment gateway. Refer to the
|
||||||
</a>
|
<a target="_blank" style="text-decoration: underline; color: var(--alert-text-warning); background: var(--alert-bg-warning);" href="https://docs.frappe.io/learning/setting-up-payment-gateway">Documentation</a>
|
||||||
to enable payment gateway.
|
for more information.
|
||||||
|
</div>
|
||||||
`);
|
`);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user