Merge pull request #450 from pateljannat/onboarding-signup

This commit is contained in:
Jannat Patel
2022-12-21 12:04:49 +05:30
committed by GitHub
32 changed files with 247 additions and 171 deletions

View File

@@ -63,6 +63,8 @@ after_sync = "lms.install.after_sync"
after_uninstall = "lms.install.after_uninstall"
setup_wizard_requires = "assets/lms/js/setup_wizard.js"
# Desk Notifications
# ------------------
# See frappe.core.notifications.get_notification_config
@@ -285,4 +287,6 @@ profile_url_prefix = "/users/"
signup_form_template = "lms.plugins.show_custom_signup"
on_login = "lms.overrides.user.set_country_from_ip"
on_login = "lms.overrides.user.on_login"
on_session_creation = "lms.overrides.user.on_session_creation"

View File

@@ -1,7 +0,0 @@
// Copyright (c) 2021, FOSS United and contributors
// For license information, please see license.txt
frappe.ui.form.on("LMS Course Enrollment", {
// refresh: function(frm) {
// }
});

View File

@@ -1,61 +0,0 @@
{
"actions": [],
"creation": "2021-03-03 11:24:08.220185",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"course",
"user"
],
"fields": [
{
"fieldname": "course",
"fieldtype": "Link",
"label": "Course",
"options": "LMS Course"
},
{
"fieldname": "user",
"fieldtype": "Data",
"label": "User",
"options": "Email"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-03-05 12:59:22.973826",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Course Enrollment",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Student",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class LMSCourseEnrollment(Document):
pass

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestLMSCourseEnrollment(unittest.TestCase):
pass

View File

@@ -7,6 +7,7 @@
"field_order": [
"search_placeholder",
"portal_course_creation",
"is_onboarding_complete",
"column_break_2",
"custom_certificate_template",
"livecode_url",
@@ -137,12 +138,19 @@
"fieldtype": "Link",
"label": "Custom Certificate Template",
"options": "Web Template"
},
{
"default": "0",
"fieldname": "is_onboarding_complete",
"fieldtype": "Check",
"label": "Is Onboarding Complete",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2022-12-15 10:23:08.638117",
"modified": "2022-12-20 11:44:06.317159",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Settings",

View File

@@ -114,7 +114,7 @@ def sanitize_html(html, macro):
any broken tags. This makes sures that all those things are fixed
before passing to the etree parser.
"""
soup = BeautifulSoup(html, features="html5lib")
soup = BeautifulSoup(html, features="lxml")
nodes = soup.body.children
classname = ""
if macro == "YouTubeVideo":

View File

View File

@@ -0,0 +1,3 @@
frappe.pages["lms-home"].on_page_load = function (wrapper) {
window.location.href = "/courses";
};

View File

@@ -0,0 +1,19 @@
{
"content": null,
"creation": "2022-12-15 13:45:06.602567",
"docstatus": 0,
"doctype": "Page",
"idx": 0,
"modified": "2022-12-15 13:45:06.602567",
"modified_by": "Administrator",
"module": "LMS",
"name": "lms-home",
"owner": "Administrator",
"page_name": "lms-home",
"roles": [],
"script": null,
"standard": "Yes",
"style": null,
"system_page": 1,
"title": "LMS"
}

View File

@@ -1,5 +1,4 @@
<div>
{% include "public/icons/symbol-defs.svg" %}
<h3 class="section-title">{{ _(title) }}</h3>
{% if subtitle %}
<p> {{ _(subtitle) }} </p>

View File

@@ -8,7 +8,6 @@ from frappe import _
from frappe.core.doctype.user.user import User
from frappe.utils import cint, escape_html, random_string
from frappe.website.utils import is_signup_disabled
from lms.lms.utils import validate_image
from lms.widgets import Widgets
@@ -295,6 +294,14 @@ def get_country_code():
return
def on_login(login_manager):
set_country_from_ip()
def on_session_creation(login_manager):
frappe.local.response["home_page"] = "/courses"
@frappe.whitelist(allow_guest=True)
def search_users(start=0, text=""):
or_filters = get_or_filters(text)

View File

@@ -42,3 +42,4 @@ lms.patches.v0_0.quiz_submission_result
lms.patches.v0_0.skill_to_user_skill
lms.patches.v0_0.rename_instructor_role
lms.patches.v0_0.change_course_creation_settings #12-12-2022
lms.patches.v0_0.check_onboarding_status #21-12-2022

View File

@@ -0,0 +1,11 @@
import frappe
def execute():
if (
frappe.db.count("LMS Course")
and frappe.db.count("Course Chapter")
and frappe.db.count("Course Lesson")
and frappe.db.count("LMS Quiz")
):
frappe.db.set_value("LMS Settings", None, "is_onboarding_complete", True)

View File

@@ -130,6 +130,10 @@ input[type=checkbox] {
stroke: none;
}
.onboarding-parent .icon {
stroke: none;
}
.course-card-content {
padding: 1rem;
display: flex;
@@ -1883,3 +1887,34 @@ select {
.clickable-row {
cursor: pointer;
}
.onboarding-parent {
background-color: var(--primary-light);
padding: 2rem 0;
}
.onboarding-steps {
display: flex;
justify-content: space-between;
padding-top: 1.5rem;
font-weight: 500;
color: var(--gray-900);
}
.onboarding-steps-link {
display: flex;
align-items: center;
color: inherit;
}
.onboarding-steps-link:hover {
text-decoration: none;
color: inherit;
}
.onboarding-skip {
font-size: var(--text-sm);
float: right;
cursor: pointer;
margin-right: 1rem;
}

View File

@@ -64,4 +64,12 @@
<path d="M27.8837 15.1677V15.6677H28.3837H34.6997V29.4519H22.3877V13.7919C22.3877 7.77141 27.1738 2.82244 33.1317 2.55889V8.06527C30.1784 8.31947 27.8837 10.8044 27.8837 13.7919V15.1677Z" stroke="#1F272E"/>
<path d="M10.7958 15.1677V15.6677H11.2958H17.6118V29.4517L5.2998 29.4518V13.7919C5.2998 7.77141 10.0859 2.82244 16.0438 2.55889V8.06527C13.0905 8.31947 10.7958 10.8044 10.7958 13.7919V15.1677Z" stroke="#1F272E"/>
</svg>
<svg id="icon-disabled-check" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M20 10C20 15.5228 15.5228 20 10 20C4.47715 20 0 15.5228 0 10C0 4.47715 4.47715 0 10 0C15.5228 0 20 4.47715 20 10ZM14.8734 8.1402C15.264 7.74969 15.264 7.11652 14.8734 6.726C14.4829 6.33547 13.8498 6.33547 13.4592 6.726L12.6259 7.55933L10.9592 9.226L8.333 11.8522L7.37345 10.8927L6.54011 10.0593C6.14959 9.6688 5.51643 9.6688 5.1259 10.0593C4.73538 10.4499 4.73538 11.083 5.1259 11.4735L5.95923 12.3069L7.6259 13.9735C7.81344 14.1611 8.0678 14.2664 8.333 14.2664C8.5982 14.2664 8.8526 14.1611 9.0401 13.9735L12.3734 10.6402L14.0401 8.9735L14.8734 8.1402Z" fill="#A6B1B9"/>
</svg>
<svg id="icon-green-check-circled" width="24" height="24" viewBox="0 0 27 27" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12ZM16.8734 10.1402C17.264 9.74969 17.264 9.11652 16.8734 8.726C16.4829 8.33547 15.8498 8.33547 15.4592 8.726L14.6259 9.55933L12.9592 11.226L10.333 13.8522L9.37345 12.8927L8.54011 12.0593C8.14959 11.6688 7.51643 11.6688 7.1259 12.0593C6.73538 12.4499 6.73538 13.083 7.1259 13.4735L7.95923 14.3069L9.6259 15.9735C9.81344 16.1611 10.0678 16.2664 10.333 16.2664C10.5982 16.2664 10.8526 16.1611 11.0401 15.9735L14.3734 12.6402L16.0401 10.9735L16.8734 10.1402Z" fill="#68D391"/>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,5 @@
frappe.provide("lms.setup");
// redirect to desk page 'lms' after setup wizard is complete
// 'lms' desk page redirects to '/courses'
frappe.setup.welcome_page = "/app/lms-home";

View File

@@ -0,0 +1,10 @@
{% extends "templates/base.html" %}
{% block content %}
{% include "public/icons/symbol-defs.svg" %}
{% include "lms/templates/onboarding_header.html" %}
{% block page_content %}
Hello, world!
{% endblock %}
{% endblock %}

View File

@@ -0,0 +1,77 @@
{% set onboarding_settings = frappe.db.get_single_value("LMS Settings", "is_onboarding_complete") %}
{% set course_created = frappe.db.count("LMS Course") %}
{% set chapter_created = frappe.db.count("Course Chapter") %}
{% set lesson_created = frappe.db.count("Course Lesson") %}
{% set quiz_created = frappe.db.count("LMS Quiz") %}
{% set first_course = frappe.db.get_all("LMS Course", order_by="creation", pluck="name")[0] %}
{% set is_onboarding_complete = onboarding_settings or (course_created and chapter_created and lesson_created and quiz_created) %}
{% if has_course_moderator_role() and not is_onboarding_complete %}
<div class="onboarding-parent">
<div class="container">
<div class="onboarding-skip">{{ _("Skip") }}</div>
<h3 class="mt-0"> {{ _("Welcome") }} 🎉</h3>
<div class="onboarding-subtitle">
{{ _("Lets start setting up your content on the LMS so that you can reclaim time and focus on growth.") }}
</div>
<div class="onboarding-steps">
<a class="onboarding-steps-link" href="/courses/new-course">
<svg class="icon icon-md">
<use href="{% if course_created %} #icon-green-check-circled {% else %} #icon-disabled-check {% endif %}">
</use>
</svg>
{{ _("Create a Course") }}
</a>
<a class="onboarding-steps-link" {% if course_created %} href="/courses/{{ first_course }}?edit=1" {% else %} disabled {% endif %}>
<svg class="icon icon-md">
<use href="{% if chapter_created %} #icon-green-check-circled {% else %} #icon-disabled-check {% endif %}">
</use>
</svg>
{{ _("Add a Chapter") }}
</a>
<a class="onboarding-steps-link" {% if chapter_created %} href="/courses/{{ first_course }}?edit=1" {% endif %}>
<svg class="icon icon-md">
<use href="{% if lesson_created %} #icon-green-check-circled {% else %} #icon-disabled-check {% endif %}">
</use>
</svg>
{{ _("Add a Lesson") }}
</a>
<a class="onboarding-steps-link" {% if lesson_created %} href="/quizzes/new-quiz" {% endif %}>
<svg class="icon icon-md">
<use href="{% if quiz_created %} #icon-green-check-circled {% else %} #icon-disabled-check {% endif %}">
</use>
</svg>
{{ _("Create a Quiz") }}
</a>
</div>
</div>
</div>
{% endif %}
<script>
frappe.ready(() => {
$(".onboarding-skip").click((e) => {
skip_onboarding(e);
});
});
const skip_onboarding = (e) => {
frappe.call({
method: "frappe.client.set_value",
args: {
doctype: "LMS Settings",
name: "LMS Settings",
fieldname: "is_onboarding_complete",
value: 1,
},
freeze: true,
callback: function (data) {
window.location.reload();
}
});
}
</script>

View File

@@ -1,29 +1,26 @@
{% extends "templates/base.html" %}
{% extends "lms/templates/lms_base.html" %}
{% from "www/macros/livecode.html" import LiveCodeEditorJS, LiveCodeEditor with context %}
{% block title %}
{% block title %}
{% if lesson.title %}
{{ lesson.title }} - {{ course.title }}
{% else %}
{{ _("New Lesson") }}
{% endif %}
{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
<link rel="stylesheet" href="/assets/frappe/css/hljs-night-owl.css">
{% for ext in page_extensions %}
{{ ext.render_header() }}
{% endfor %}
{% endblock %}
{% block content %}
{% block page_content %}
<div class="common-page-style lesson-page">
<div class="container course-details-page">
{{ BreadCrumb(course, lesson) }}

View File

@@ -4,11 +4,6 @@
{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
{% endblock %}
{% block content %}
<div class="common-page-style" style="background-color: var(--fg-color);">
<div class="container">

View File

@@ -4,11 +4,6 @@
{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
{% endblock %}
{% block content %}
<div class="common-page-style">
<div class="container">

View File

@@ -1,10 +1,10 @@
{% extends "templates/base.html" %}
{% extends "lms/templates/lms_base.html" %}
{% block title %}
{{ _(class_info.title) }}
{% endblock %}
{% block content %}
{% block page_content %}
<div class="common-page-style">
<div class="container">
{{ BreadCrumb(class_info) }}

View File

@@ -1,9 +1,9 @@
{% extends "templates/base.html" %}
{% extends "lms/templates/lms_base.html" %}
{% block title %}
{{ _("All Classes") }}
{% endblock %}
{% block content %}
{% block page_content %}
<div class="common-page-style">
<div class="container">
{% if has_course_moderator_role() %}

View File

@@ -1,15 +1,10 @@
{% extends "templates/base.html" %}
{% extends "lms/templates/lms_base.html" %}
{% block title %}
{{ student.first_name }} 's {{ _("Progress") }}
{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
{% endblock %}
{% block content %}
{% block page_content %}
<div class="common-page-style">
<div class="container">
{{ BreadCrumb(class_info, student) }}

View File

@@ -1,35 +1,44 @@
{% extends "templates/base.html" %}
{% block title %}{{ _('Community') }}{% endblock %}
{% extends "lms/templates/lms_base.html" %}
{% block title %}
{{ _('Community') }}
{% endblock %}
{% block content %}
{% block page_content %}
<div class="common-page-style">
<div class="container">
<div class="container">
<input class="search pull-right" id="search-user" placeholder="{{ _('Search') }}">
<input class="search pull-right" id="search-user" placeholder="{{ _('Search') }}">
<div class="course-home-headings">{{ _("People") }} </div>
<div class="course-home-headings">{{ _("Community") }} </div>
<div class="empty-state alert alert-dismissible hide" id="search-empty-state">
<a href="#" class="close-search-empty-state" aria-label="close">&times;</a>
<div>
<img class="icon icon-xl" src="/assets/frappe/images/ui-states/search-empty-state.svg">
</div>
<div class="empty-state-text">
<div class="empty-state-heading">
{{ _("No results found") }}
</div>
<div class="course-meta">
{{ _("Try some other keyword or explore our community") }}
</div>
</div>
</div>
<div class="empty-state alert alert-dismissible hide" id="search-empty-state">
<a href="#" class="close-search-empty-state" aria-label="close">&times;</a>
<div>
<img class="icon icon-xl" src="/assets/frappe/images/ui-states/search-empty-state.svg">
</div>
<div class="empty-state-text">
<div class="empty-state-heading">{{ _("No results found") }}</div>
<div class="course-meta">{{ _("Try some other keyword or explore our community") }}</div>
</div>
</div>
<div class="member-parent">
{% for user in users %}
{{ widgets.MemberCard(member=user, show_course_count=False, avatar_class="avatar-large") }}
{% endfor %}
</div>
<div class="member-parent">
{% for user in users %}
{{ widgets.MemberCard(member=user, show_course_count=False, avatar_class="avatar-large") }}
{% endfor %}
</div>
{% if user_count > user_details | length %}
<div class="mt-10 d-flex justify-content-center">
<div class="button is-secondary" id="load-more" data-start="30" data-count="{{ user_count }}">{{ _("Load More") }}</div>
</div>
{% endif %}
</div>
{% if user_count > user_details | length %}
<div class="mt-10 d-flex justify-content-center">
<div class="btn btn-md btn-default" id="load-more" data-start="30" data-count="{{ user_count }}">
{{ _("Load More") }}
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -1,15 +1,10 @@
{% extends "templates/base.html" %}
{% extends "lms/templates/lms_base.html" %}
{% block title %}
{{ course.title if course.title else _("New Course") }}
{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
{% endblock %}
{% block content %}
{% block page_content %}
<div class="common-page-style pt-0 pb-0">
<div class="course-home-top-container">
{{ CourseHomeHeader(course) }}

View File

@@ -1,4 +1,4 @@
{% extends "templates/base.html" %}
{% extends "lms/templates/lms_base.html" %}
{% block title %}
@@ -6,12 +6,7 @@
{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
{% endblock %}
{% block content %}
{% block page_content %}
<div class="common-page-style">
<div class="container">
{% if restriction %}

View File

@@ -1,11 +1,8 @@
{% extends "templates/base.html" %}
{% extends "lms/templates/lms_base.html" %}
{% block title %}{{ _('Job Openings') }}{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
{% endblock %}
{% block content %}
{% block page_content %}
<div class="common-page-style">
<div class="container">

View File

@@ -1,11 +1,8 @@
{% extends "templates/base.html" %}
{% extends "lms/templates/lms_base.html" %}
{% block title %}{{ _(job.job_title) }}{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
{% endblock %}
{% block content %}
{% block page_content %}
<div class="common-page-style">
<div class="container">

View File

@@ -205,9 +205,9 @@
<div class="course-home-headings"> {{ _("Role Settings") }} </div>
<div class="medium">
<label class="role">
<input type="checkbox" id="instructor" data-role="Instructor"
<input type="checkbox" id="course-creator" data-role="Course Creator"
{% if has_course_instructor_role(member.name) %} checked {% endif %}>
{{ _("Instructor") }}
{{ _("Course Creator") }}
</label>
<label class="role">
<input type="checkbox" id="moderator" data-role="Moderator"