feat: data in course fields
This commit is contained in:
@@ -58,8 +58,14 @@
|
||||
|
||||
.field-input {
|
||||
border: 1px solid var(--gray-300);
|
||||
border-radius: var(--border-radius-sm);
|
||||
padding: 0.5rem;
|
||||
border-radius: var(--border-radius-md);
|
||||
padding: 0.5rem;
|
||||
width: 75%;
|
||||
margin: 0.25rem 0 1rem;
|
||||
}
|
||||
|
||||
.field-input:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.field-description {
|
||||
@@ -82,6 +88,10 @@
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
textarea.field-input {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,14 @@ import EditorJS from "@editorjs/editorjs";
|
||||
import Header from "@editorjs/header";
|
||||
import List from "@editorjs/list";
|
||||
|
||||
create_editor_for_short_description = () => {
|
||||
const create_editor_for_short_description = () => {
|
||||
let editor = new EditorJS({
|
||||
holder: "course-description",
|
||||
tools: {
|
||||
header: {
|
||||
class: Header,
|
||||
},
|
||||
list: List,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="page-title"> {{ _("Course Details") }} </div>
|
||||
<div class="mt-10">
|
||||
<div>
|
||||
<div class="course-title">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
{{ _("Title") }}
|
||||
</div>
|
||||
@@ -18,11 +18,26 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="">
|
||||
<input type="text" class="field-input">
|
||||
<input type="text" class="field-input" value="{{ course.title }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="course-title">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
{{ _("Preview Video") }}
|
||||
</div>
|
||||
<div class="field-description">
|
||||
{{ _("A feature video that provides a preview of the course") }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="">
|
||||
<input type="text" class="field-input" value="{{ course.video_link }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div class="field-label">
|
||||
{{ _("Short Introduction") }}
|
||||
</div>
|
||||
@@ -31,11 +46,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="">
|
||||
<div type="text" class="field-input"></div>
|
||||
<input type="text" class="field-input" value="{{ course.short_introduction }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="course-title">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
{{ _("Tags") }}
|
||||
</div>
|
||||
@@ -44,11 +60,22 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="tags field-input">
|
||||
{% for tag in get_tags(course.name) %}
|
||||
<button class="btn btn-secondary btn-sm mr-2 text-uppercase">
|
||||
{{ tag }}
|
||||
<span class="btn-remove">
|
||||
<svg class="icon icon-sm">
|
||||
<use class="" href="#icon-close"></use>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
{% endfor %}
|
||||
<input type="text" class="invisible-input" id="tags-input">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="course-title">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
{{ _("Course Image") }}
|
||||
</div>
|
||||
@@ -59,11 +86,11 @@
|
||||
<div class="">
|
||||
<input type="file" class="field-input" id="image">
|
||||
</div>
|
||||
<img>
|
||||
<img {% if course.image %} class="image-preview" src="{{ course.image }}" {% endif %}>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="course-title">
|
||||
<div>
|
||||
<div class="field-label">
|
||||
{{ _("Course Description") }}
|
||||
</div>
|
||||
@@ -71,9 +98,33 @@
|
||||
{{ _("Add a detailed description") }}
|
||||
</div>
|
||||
</div>
|
||||
<input id="course-description" class="field-input">
|
||||
<textarea id="course-description" class="field-input">{{ course.description }}</textarea>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="published" class="mb-0">
|
||||
<input type="checkbox" id="published" {% if course.published %} checked {% endif %}>
|
||||
{{ _("Published") }}
|
||||
</label>
|
||||
<label for="upcoming" class="mb-0 ml-20">
|
||||
<input type="checkbox" id="upcoming" {% if course.upcoming %} checked {% endif %}>
|
||||
{{ _("Upcoming") }}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="field-label">
|
||||
{{ _("Instructor") }}
|
||||
</div>
|
||||
<div>
|
||||
{{ widgets.Avatar(member=member, avatar_class="avatar-medium") }} {{ member.full_name }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary btn-sm btn-save-course">
|
||||
{{ _("Save") }}
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -19,6 +19,10 @@ frappe.ready(() => {
|
||||
.addClass("image-preview")
|
||||
.attr("src", URL.createObjectURL(e.target.files[0]));
|
||||
});
|
||||
|
||||
$(".btn-save-course").click((e) => {
|
||||
save_course(e);
|
||||
});
|
||||
});
|
||||
|
||||
const create_tag = (e) => {
|
||||
@@ -28,7 +32,7 @@ const create_tag = (e) => {
|
||||
let tag = `<button class="btn btn-secondary btn-sm mr-2 text-uppercase">
|
||||
${$(e.target).val()}
|
||||
<span class="btn-remove">
|
||||
<svg class="icon icon-sm" style="">
|
||||
<svg class="icon icon-sm">
|
||||
<use class="" href="#icon-close"></use>
|
||||
</svg>
|
||||
</span>
|
||||
@@ -36,3 +40,35 @@ const create_tag = (e) => {
|
||||
$(tag).insertBefore("#tags-input");
|
||||
$(e.target).val("");
|
||||
};
|
||||
|
||||
const save_course = (e) => {
|
||||
let tags = $(".tags button")
|
||||
.map((i, el) => $(el).text().trim())
|
||||
.get();
|
||||
|
||||
frappe.call({
|
||||
method: "lms.lms.doctype.lms_course.lms_course.save_course",
|
||||
args: {
|
||||
tags: tags.join(", "),
|
||||
title: $("#title").text(),
|
||||
short_introduction: $("#intro").text(),
|
||||
video_link: $("#video-link").text(),
|
||||
image: $("#image").attr("href"),
|
||||
description: this.code_field_group.fields_dict["code_md"].value,
|
||||
course: $("#title").data("course")
|
||||
? $("#title").data("course")
|
||||
: "",
|
||||
published: $("#published").prop("checked") ? 1 : 0,
|
||||
upcoming: $("#upcoming").prop("checked") ? 1 : 0,
|
||||
},
|
||||
callback: (data) => {
|
||||
frappe.show_alert({
|
||||
message: __("Saved"),
|
||||
indicator: "green",
|
||||
});
|
||||
setTimeout(() => {
|
||||
window.location.href = `/courses/${data.message}?edit=1`;
|
||||
}, 1000);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,5 +1,50 @@
|
||||
import frappe
|
||||
from lms.lms.utils import redirect_to_courses_list, can_create_courses
|
||||
from frappe import _
|
||||
|
||||
|
||||
def get_context(context):
|
||||
context.no_cache = 1
|
||||
try:
|
||||
course_name = frappe.form_dict["course"]
|
||||
except KeyError:
|
||||
redirect_to_courses_list()
|
||||
|
||||
if course_name == "new-course":
|
||||
if not can_create_courses():
|
||||
message = "You do not have permission to access this page."
|
||||
if frappe.session.user == "Guest":
|
||||
message = "Please login to access this page."
|
||||
|
||||
raise frappe.PermissionError(_(message))
|
||||
|
||||
context.course = frappe._dict()
|
||||
context.course.edit_mode = True
|
||||
context.membership = None
|
||||
else:
|
||||
set_course_context(context, course_name)
|
||||
context.member = frappe.db.get_value(
|
||||
"User", frappe.session.user, ["full_name", "username"], as_dict=True
|
||||
)
|
||||
|
||||
|
||||
def set_course_context(context, course_name):
|
||||
fields = [
|
||||
"name",
|
||||
"title",
|
||||
"short_introduction",
|
||||
"description",
|
||||
"image",
|
||||
"published",
|
||||
"upcoming",
|
||||
"disable_self_learning",
|
||||
"status",
|
||||
"video_link",
|
||||
"enable_certification",
|
||||
"grant_certificate_after",
|
||||
"paid_certificate",
|
||||
"price_certificate",
|
||||
"currency",
|
||||
"max_attempts",
|
||||
]
|
||||
context.course = frappe.db.get_value("LMS Course", course_name, fields, as_dict=True)
|
||||
|
||||
Reference in New Issue
Block a user