lms: add activity child table and create frontend

Co-authored-by: Chinmay Pai <chinmaydpai@gmail.com>
This commit is contained in:
scmmishra 2018-10-08 15:26:05 +05:30 committed by Aditya Hase
parent b3b003f518
commit 836a4b5e54
14 changed files with 697 additions and 0 deletions

View File

@ -0,0 +1,208 @@
{
"allow_copy": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2018-10-08 10:59:58.325210",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "course_name",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Course Name",
"length": 0,
"no_copy": 0,
"options": "Course",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "",
"fieldname": "lesson_name",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Lesson Name",
"length": 0,
"no_copy": 0,
"options": "Content",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "quiz_score",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Quiz Score",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Unattempted",
"fieldname": "quiz_status",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Quiz Status",
"length": 0,
"no_copy": 0,
"options": "\nUnattempted\nPassed\nFailed",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "lesson_status",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Lesson Status",
"length": 0,
"no_copy": 0,
"options": "\nOngoing\nCompleted",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2018-10-08 12:48:34.394511",
"modified_by": "Administrator",
"module": "Education",
"name": "LMS Activity",
"name_case": "",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0,
"track_views": 0
}

View File

@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
class LMSActivity(Document):
pass

View File

View File

@ -0,0 +1,63 @@
{% extends "frappe_theme/templates/base.html" %}
{% block title %}ERPNext Academy{% endblock %}
{% from "templates/includes/media.html" import media %}
{% block head_include %}
<meta name="description" content="ERPNext Academy is a learnig platform to gain expertise in the world's top 100% open source ERP software." />
<meta name="keywords" content="ERP Software, Cloud ERP, Open Source ERP, Accounting Software, Online ERP, Online Accounting, ERP for small business, Learn ERP, ERPNext Academy, Learn ERPNext, Learn Accounting" />
{% endblock %}
{% macro video(id) %}
<div class="embed-responsive embed-responsive-16by9">
<iframe class="embed-responsive-item" src="https://www.youtube.com/embed/{{ lesson.video_url }}" allowfullscreen></iframe>
</div>
{% endmacro %}
{% block content %}
<section class='video-top-section video-section-bg'>
<div class='container'>
{% if lesson.video_url is defined %}
{{ video("lesson,video") }}
{% endif %}
<div class="mt-3 row">
<div class="col-md-8">
<h2>{{ lesson.name }}</h2>
<span class="text-muted">
<i class="octicon octicon-clock" title="Duration"></i> 49 Mins
&mdash; Published on 28th October 2018.
</span>
</div>
<div class="col-md-4 text-right">
<a class='btn btn-outline-secondary' href="/classrooms/module">Previous</a>
<a class='btn btn-primary' href="/learn?module={{ module }}&lesson={{ next_lesson }}">Next</a>
</div>
</div>
<hr>
</div>
</section>
{% for lesson in lesson_list %}
{{ lesson }}
{% endfor %}
<section class="video-description-section">
<div class='container'>
<div class="content">
{{ lesson.content }}
</div>
<div class="text-right hidden">
<a class='btn btn-outline-secondary' href="/classrooms/module">Previous</a>
<a class='btn btn-primary' href="/classrooms/module">Next</a>
</div>
<div class="mt-3 text-right">
<a class="text-muted" href="/report"><i class="octicon octicon-issue-opened" title="Report"></i> Report a Mistake</a>
</div>
</div>
</section>
<style>
.footer-message {
display: none;
}
</style>
{% endblock %}

View File

@ -0,0 +1,2 @@
# current_module = frappe.get_doc("Course", frappe.form_dict["lesson"])
# current_lesson = frappe.get_doc("Lesson", frappe.form_dict["lesson"])

101
erpnext/www/lms/index.css Normal file
View File

@ -0,0 +1,101 @@
.page-content {
padding-bottom: 0px !important;
}
.dashboard-section {
margin: auto;
max-width: 90%;
}
.dashboard-section h1 {
font-size: 1.5em;
}
@media(min-width: 768px) {
.dashboard-section {
max-width: 80%;
}
}
@media(min-width: 992px) {
.dashboard-section {
max-width: 65%;
}
}
.hero-content h1 {
font-size: 1.85em;
font-weight: 300;
}
.hero {
border-bottom: 0px;
}
.erp-hero {
border-bottom: 1px solid #e1e9f0;
}
.hero-content p {
margin-bottom: 100px;
}
.navbar {
border-bottom: 0px;
}
.main-illustration {
margin: -90px 0 -60px -32px;
min-height: 420px;
}
.hero-title {
font-size: 32px;
}
@media screen and (max-width: 750px) {
.main-illustration {
min-height: inherit;
}
}
@media screen and (max-width: 480px) {
.main-illustration {
margin: -60px 0 -20px -16px;
}
.hero-title {
font-size: 26px;
}
.hero-title+p {
font-size: 16px;
}
}
.modal-dialog {
max-width: 800px;
margin: 30px auto;
}
.modal-body {
position: relative;
padding: 0px;
background-color: black;
}
.close {
position: absolute;
right: -30px;
top: 0;
z-index: 999;
font-size: 2rem;
font-weight: normal;
color: #fff;
opacity: 1;
}
.video-btn {
color: white !important;
}

View File

@ -0,0 +1,87 @@
{% extends "frappe_theme/templates/base.html" %}
{% block title %}ERPNext Academy{% endblock %}
{% from "templates/includes/media.html" import media %}
{% block head_include %}
<meta name="description" content="ERPNext Academy is a learnig platform to gain expertise in the world's top 100% open source ERP software." />
<meta name="keywords" content="ERP Software, Cloud ERP, Open Source ERP, Accounting Software, Online ERP, Online Accounting, ERP for small business, Learn ERP, ERPNext Academy, Learn ERPNext, Learn Accounting" />
{% endblock %}
{% macro featured_card(program_name, description, hero_image, code) %}
<div class='card-deck mt-5'>
<div class="card">
<img src="{{ hero_image }}" style='height: 150px'>
<div class='card-body'>
<a href="/lms/program?code={{ code }}">
<h5 class='card-title'>{{ program_name }}</h5>
</a>
<div>{{ description }}</div>
</div>
<div class='card-footer text-right'>
<!-- <a class='video-btn btn btn-secondary btn-sm' data-toggle="modal" data-src=" insert jinja stuff here " data-target="#myModal">Watch -->
<!-- Intro</a>&nbsp;&nbsp; -->
<a class='btn btn-secondary btn-sm' href="/enroll?course=user">Enroll Now</a>
</div>
</div>
</div>
{% endmacro %}
{% block content %}
<section class='top-section'>
<div class='container'>
<div class='text-center'>
<!-- <img class="main-illustration" src='/assets/erpnext_com/img/erpnext_com_illustration.png'
style='width: 700px;'> -->
</div>
<h1>Become an ERPNext Expert</h1>
<ul class="list-group">
</ul>
<p class='lead'>
A platform for enterpreneurs, developers and implementors to learn the world's leading 100% Open
Source ERP</p>
<p class="mt-4">
<a class="btn btn-primary btn-lg" href="/enroll">
Enroll Now</a>
</p>
</section>
<section class='section-padding section-bg'>
<div class='container'>
<h3 class='text-center'>Featured Programs</h3>
<p class='lead text-center'>Master ERPNext with our Expert Learning Paths</p>
{% for program in featured %}
{{ featured_card(program.program_name, program.description, program.hero_image, program.program_code) }}
{% endfor %}
<div class='mt-4 text-center'>
<a class="btn btn-primary btn-lg" href="/program">View All</a>
</div>
</div>
</section>
{% include "www/lms/templates/includes/highlights.html" %}
<div class="container">
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<!-- 16:9 aspect ratio -->
<div class="embed-responsive embed-responsive-16by9">
<iframe id="ytplayer" type="text/html" class="embed-responsive-item" allowscriptaccess="always"></iframe>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
.footer-message {
display: none;
}
</style>
{% endblock %}

30
erpnext/www/lms/index.js Normal file
View File

@ -0,0 +1,30 @@
$(function () {
setTimeout(function () {
$(".later").fadeIn();
}, 1000);
});
$(document).ready(function () {
var $videoSrc;
// Gets the video src from the data-src on each button
$('.video-btn').click(function () {
$videoSrc = $(this).attr("data-src");
console.log($videoSrc);
});
console.log($videoSrc);
// when the modal is opened autoplay it
$('#myModal').on('shown.bs.modal', function (e) {
// set the video src to autoplay and not to show related video. Youtube related video is like a box of chocolates... you never know what you're gonna get
$("#ytplayer").attr('src', "https://www.youtube.com/embed/" + $videoSrc + "?autoplay=0");
})
// stop playing the youtube video when I close the modal
$('#myModal').on('hide.bs.modal', function (e) {
// a poor man's stop video
$("#ytplayer").attr('src', $videoSrc);
})
// document ready
});

5
erpnext/www/lms/index.py Normal file
View File

@ -0,0 +1,5 @@
from __future__ import unicode_literals
import frappe
def get_context(context):
context.featured = frappe.get_all('Program', filters={'is_featured': 1}, fields=['program_name', 'program_code', 'description', 'hero_image'])

View File

@ -0,0 +1,70 @@
{% extends "frappe_theme/templates/base.html" %}
{% block title %}ERPNext Academy{% endblock %}
{% block head_include %}
<meta name="description" content="ERPNext Academy is a learnig platform to gain expertise in the world's top 100% open source ERP software." />
<meta name="keywords" content="ERP Software, Cloud ERP, Open Source ERP, Accounting Software, Online ERP, Online Accounting, ERP for small business, Learn ERP, ERPNext Academy, Learn ERPNext, Learn Accounting" />
{% endblock %}
{% macro course_card(name) %}
<div class="card mt-3" data-list="getting-started">
<div class='card-body'>
<div class="row">
<div class="course-details col-xs-8 col-sm-9 col-md-10">
<h5>{{ name }}</h5>
<span class="course-list text-muted" id="getting-started">
Course Content
<ul class="mb-0 mt-1">
{% for content in course_data[name] %}
<li>{{ content }}</li>
{% endfor %}
</ul>
</span>
</div>
<div class='text-center col-xs-4 col-sm-3 col-md-2'>
<a class='btn btn-primary btn-sm btn-block' href="/course?course={{ name }}&content=Getting Started">Start Course</a>
</div>
</div>
</div>
</div>
{% endmacro %}
{% block content %}
<section class='top-section'>
<div class='container'>
<div class='text-center'>
<!-- <img class="main-illustration" src='/assets/academy/img/expert.png' style='width: 700px;'> -->
</div>
<h1>{{ program.program_name }}</h1>
<p class='lead'>{{ program.description }}</p>
<p class="mt-4">
<a class="btn btn-primary btn-lg" href="/program/course">
Continue with Course 2</a>
</p>
</section>
<section class='section-padding section-bg'>
<div class='container'>
<h3 class='text-center'>Courses</h3>
<p class='lead text-center'>Master ERPNext with our Expert Learning Paths</p>
{% for course_item in course_list %}
{{ course_card(course_item) }}
{% endfor %}
</div>
</section>
{% include "www/lms/templates/includes/highlights.html" %}
<style>
.footer-message {
display: none;
}
@media (max-width: 767px) {
.course-details {
margin-bottom: 1rem !important;
}
}
</style>
{% endblock %}

View File

@ -0,0 +1,20 @@
from __future__ import unicode_literals
import frappe
# Get the classroom's route parameter from the url
url_param = frappe.form_dict["code"]
# Get classroom from classroom_name
current_program = frappe.get_doc("Program", url_param)
def get_context(context):
context.program = current_program
context.course_list, context.course_data = get_courses()
def get_courses():
course_data = {}
course_names = [program.course_name for program in current_program.courses]
program_courses = [frappe.get_doc('Course', name) for name in course_names]
for course_item in program_courses:
course_data[course_item.name] = [content_item.content for content_item in course_item.course_content if content_item.content_type in ('Video', 'Article')]
return course_names, course_data

View File

@ -0,0 +1,60 @@
<footer class="bg-dark pt-4">
<div class="container">
<div class="row mt-4 mb-5">
<div class='col-sm-12 col-md-6 mb-4' style='display: flex; flex-direction: column; justify-content: space-between;'>
<img src="/assets/academy/img/graduation-cap.svg"
style='height: 50px; width: 50px;'>
<div class="text-muted">
<div style="line-height: 2">
&copy;<span id="year"></span> Frappe Technologies Pvt. Ltd.
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-3">
<h6 class='text-light'>Social</h6>
<ul class="list-unstyled">
<li class="py-2">
<a href="https://frappe.io/blog" class="text-muted">Blog</a>
</li>
<li class="py-2">
<a href="https://discuss.erpnext.com" class="text-muted">Forum</a>
</li>
<li class="py-2">
<a href="https://github.com/frappe" class="text-muted">GitHub</a>
</li>
<li class="py-2">
<a href="https://twitter.com/erpnext" class="text-muted">Twitter</a>
</li>
<li class="py-2">
<a href="https://medium.com/frapp%C3%A9-thoughts" class="text-muted">Medium</a>
</li>
<li class="py-2">
<a href="https://www.facebook.com/ERPNext" class="text-muted">Facebook</a>
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-6 col-md-3">
<h6 class='text-light'>Company</h6>
<ul class="list-unstyled">
<li class="py-2">
<a href="https://erpnext.com" class="text-muted">ERPNext</a>
</li>
<li class="py-2">
<a href="https://frappe.io/about" class="text-muted">Team</a>
</li>
<li class="py-2">
<a href="https://frappe.io/about" class="text-muted">Jobs</a>
</li>
<li class="py-2">
<a href="https://frappe.io/about#contact" class="text-muted">Contact</a>
</li>
</ul>
</div>
</div>
<div class='mt-4 text-muted text-center'>"Be the change, you wish to see in the world ~ M. K. Gandhi"
</div>
</footer>
<!--Javascript-->

View File

@ -0,0 +1,41 @@
<section class="section-padding">
<div class='container'>
<h3 class='text-center'>Highlights</h3>
<div class='card-deck mt-5'>
<div class="card">
<div class='card-body'>
<h5 class='card-title'>Curated Courses</h5>
<div>Learning paths specifically designed for the your use cases, whether you are a user, developer
or an
implementer</div>
</div>
<div class='card-footer'>
<a href="#" class='text-muted small'>Explore Learning Paths</a>
</div>
</div>
<div class="card">
<div class='card-body'>
<h5 class='card-title'>Comprehensive Content</h5>
<div>Content designed to cover all the fundamentals as well as expert tips and techniques to make
the most out of ERPNext.</div>
</div>
<div class='card-footer'>
<a href="#" class='text-muted small'>View Course List</a>
</div>
</div>
<div class="card">
<div class='card-body'>
<h5 class='card-title'>Certification</h5>
<div>ERPNext is open source and infinitely extensible. Customize it, build upon it, add your own
apps built with
<a href="https://frappe.io" class="underline">Frappe Framework</a>.</div>
</div>
<div class='card-footer'>
<a href="#" class='text-muted small'>Certification Benefits</a>
</div>
</div>
</div>
</div>
</section>