diff --git a/community/lms/doctype/lms_course/lms_course.json b/community/lms/doctype/lms_course/lms_course.json index 8b46e3ec..d35fa59f 100644 --- a/community/lms/doctype/lms_course/lms_course.json +++ b/community/lms/doctype/lms_course/lms_course.json @@ -21,12 +21,14 @@ "engine": "InnoDB", "field_order": [ "title", - "is_published", - "disable_self_learning", - "column_break_3", "short_code", "video_link", + "column_break_3", + "is_published", + "disable_self_learning", + "image", "section_break_5", + "tags", "short_introduction", "description" ], @@ -80,6 +82,17 @@ "fieldname": "disable_self_learning", "fieldtype": "Check", "label": "Disable Self Learning" + }, + { + "fieldname": "image", + "fieldtype": "Attach Image", + "label": "Preview Image", + "reqd": 1 + }, + { + "fieldname": "tags", + "fieldtype": "Data", + "label": "Tags" } ], "index_web_pages_for_search": 1, @@ -106,7 +119,7 @@ "link_fieldname": "course" } ], - "modified": "2021-06-21 11:34:04.552376", + "modified": "2021-06-28 12:04:21.524161", "modified_by": "Administrator", "module": "LMS", "name": "LMS Course", diff --git a/community/lms/doctype/lms_course/lms_course.py b/community/lms/doctype/lms_course/lms_course.py index a98a5e63..7889eb23 100644 --- a/community/lms/doctype/lms_course/lms_course.py +++ b/community/lms/doctype/lms_course/lms_course.py @@ -241,6 +241,9 @@ class LMSCourse(Document): member_names = [m['member'] for m in memberships] return find_all("User", name=["IN", member_names]) + def get_tags(self): + return self.tags.split(",") if self.tags else [] + def get_outline(self): return CourseOutline(self) diff --git a/community/lms/doctype/lms_course_review/__init__.py b/community/lms/doctype/lms_course_review/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/doctype/lms_course_review/lms_course_review.js b/community/lms/doctype/lms_course_review/lms_course_review.js new file mode 100644 index 00000000..8382eb52 --- /dev/null +++ b/community/lms/doctype/lms_course_review/lms_course_review.js @@ -0,0 +1,8 @@ +// Copyright (c) 2021, FOSS United and contributors +// For license information, please see license.txt + +frappe.ui.form.on('LMS Course Review', { + // refresh: function(frm) { + + // } +}); diff --git a/community/lms/doctype/lms_course_review/lms_course_review.json b/community/lms/doctype/lms_course_review/lms_course_review.json new file mode 100644 index 00000000..8db5bf63 --- /dev/null +++ b/community/lms/doctype/lms_course_review/lms_course_review.json @@ -0,0 +1,49 @@ +{ + "actions": [], + "creation": "2021-06-28 12:30:02.111289", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "review", + "rating" + ], + "fields": [ + { + "fieldname": "review", + "fieldtype": "Small Text", + "in_list_view": 1, + "label": "Review", + "reqd": 1 + }, + { + "fieldname": "rating", + "fieldtype": "Rating", + "label": "Rating" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2021-06-28 12:30:15.953008", + "modified_by": "Administrator", + "module": "LMS", + "name": "LMS Course Review", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/community/lms/doctype/lms_course_review/lms_course_review.py b/community/lms/doctype/lms_course_review/lms_course_review.py new file mode 100644 index 00000000..e2361ad0 --- /dev/null +++ b/community/lms/doctype/lms_course_review/lms_course_review.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class LMSCourseReview(Document): + pass diff --git a/community/lms/doctype/lms_course_review/test_lms_course_review.py b/community/lms/doctype/lms_course_review/test_lms_course_review.py new file mode 100644 index 00000000..da8a1450 --- /dev/null +++ b/community/lms/doctype/lms_course_review/test_lms_course_review.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, FOSS United and Contributors +# See license.txt + +# import frappe +import unittest + +class TestLMSCourseReview(unittest.TestCase): + pass diff --git a/community/public/css/style.css b/community/public/css/style.css index a3116517..4c8b8311 100644 --- a/community/public/css/style.css +++ b/community/public/css/style.css @@ -17,7 +17,7 @@ --h-color: var(--c2); - --text-color: #333; + --text-color: #192734; --text-color-light: #ccc; --cta-color: var(--c4); @@ -25,6 +25,8 @@ --received-message: var(--c8); --checkbox-size: 14px; --control-bg: var(--gray-100); + --muted-text: #4C5A67; + --button-background: #EEF0F2; } body { @@ -32,18 +34,6 @@ body { margin: 0px; } - -/* .course-details { - margin: 20px 0px; -} - -.course-details h2 { - color: var(--h-color); - font-size: 1.4em; - font-weight: bold; - margin: 20px 0px 10px 0px; -} */ - .chapter-plan { border-radius: 10px; margin: 20px 0px; @@ -57,21 +47,6 @@ body { font-weight: bold; } -/* .chapter-number { - background: var(--text-color); - color: white; - border-radius: 50%; - height: 24px; - min-width: 24px; - align-items: center; - padding: 2px 8px 2px 8px; - margin-right: 5px; -} - -.chapter-description { - margin: 20px 0px; -} */ - .lessons { padding-left: 20px; } @@ -265,3 +240,195 @@ input[type=checkbox] { border-radius: 50px; padding: 5px; } + +.course-image { + height: 168px; + width: 352px; + border-top-left-radius: 8px; + border-top-right-radius: 8px; + background-size: 352px 168px; +} + +@media (max-width: 768px) { + .course-image { + width: 336px; + } +} + +@media (max-width: 375px) { + .course-image { + width: 312px; + background-size: cover; + background-repeat: no-repeat; + } +} + +.course-tags { + display: flex; + position: relative; + top: 12px; + left: 12px; + height: 20px; +} + +.course-card-pills { + background: #ffffff; + margin: 0px 10px; + border-radius: 4px; + padding: 4px 6px; + font-size: 10px; + line-height: 120%; + text-align: center; + letter-spacing: 0.011em; + text-transform: uppercase; + color: #2C5477; + font-weight: bold; + box-shadow: 0px 5px 10px rgb(0 0 0 / 10%); +} + +.common-page-style { + background: #F4F5F6; +} + +.common-card-style { + display: flex; + flex-direction: column; + align-items: flex-start; + background: #FFFFFF; + border-radius: 8px; + width: 352px; + height: 380px; + margin: 0px 16px 32px; + box-shadow: 0px 5px 10px rgb(0 0 0 / 10%); +} + +@media (max-width: 768px) { + .common-card-style { + width: 336px; + } +} + +@media (max-width: 375px) { + .common-card-style { + width: 312px; + } +} + +.course-card-meta { + font-size: 12px; + line-height: 135%; + margin: 12px 16px 8px; + color: var(--muted-text); + height: 15px; +} + +.course-card-content { + width: 100%; +} + +.course-card-title { + font-weight: 600; + font-size: 18px; + line-height: 156%; + letter-spacing: -0.014em; + color: var(--text-color); + align-self: stretch; + margin: 0px 16px 16px; + height: 45px; +} + +.card-divider { + border: 1px solid #E2E6E9; + margin: 0px 16px 16px; +} + +.course-card-meta-2 { + margin: 0px 16px 16px; +} + +.course-instructor { + margin: 0px 8px; + font-size: 12px; + line-height: 135%; + color: var(--text-color); +} + +.course-student-count { + font-size: 12px; + line-height: 135%; + color: var(--muted-text); + float: right; +} + +.view-course-link { + height: 32px; + margin: 0px 16px 16px; + background: var(--button-background); + border-radius: 4px; + font-size: 12px; + padding: 8px 0px 8px; + text-align: center; + line-height: 135%; + color: var(--text-color); +} + +.course-cards-parent { + display: flex; + flex-wrap: wrap; +} + +@media (max-width: 375px) { + .course-cards-parent { + justify-content: center; + } +} + +.course-divider { + border: 1px solid #E2E6E9; + margin: 16px 0px 30px; +} + +.courses-header { + padding: 50px 0px 20px; + color: var(--text-color); + font-weight: 600; + font-size: 22px; + line-height: 145%; + letter-spacing: -0.0175em +} + +.course-top-section { + margin: 0px 140px 0px; +} + +@media (max-width: 768px) { + .course-top-section { + margin: 0px 40px 0px; + } +} + +@media (max-width: 375px) { + .course-top-section { + margin: 0px 24px 0px; + } +} + +.is-primary { + background: var(--primary-color); + color: #FFFFFF; +} + +.button-links:hover { + text-decoration: none; +} + +.icon-background { + border-radius: 50%; + padding: 3px; + width: 24px; + height: 24px; +} + +.small-margin { + margin-left: 10px; +} diff --git a/community/public/css/style.less b/community/public/css/style.less index 3de921c9..d7fdbb1c 100644 --- a/community/public/css/style.less +++ b/community/public/css/style.less @@ -138,39 +138,6 @@ section.lightgray { color: var(--tag-color); } -.course-header { - margin-top: 20px; -} - -/* -.course-header { - margin-top: 20px; - padding: 20px; - background: var(--header-bg); - color: var(--header-color); - border-radius: 9px; -} - -.course-author-avatar { - width: 20px; - height: 20px; - border-radius: 50%; - margin-right: 20px; -} - -.course-header h1 { - color: inherit; -} - -*/ - -// .gray-section { -// background:#F6F6F6; -// border: 1px solid #C4C4C4; -// padding: 20px; -// margin: 20px 0px; -// } - .instructor-title { color: black; } diff --git a/community/public/icons/black-arrow.svg b/community/public/icons/black-arrow.svg new file mode 100644 index 00000000..b242af38 --- /dev/null +++ b/community/public/icons/black-arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/community/public/icons/calendar.svg b/community/public/icons/calendar.svg new file mode 100644 index 00000000..fd4c50e4 --- /dev/null +++ b/community/public/icons/calendar.svg @@ -0,0 +1,3 @@ + + + diff --git a/community/public/icons/clock.svg b/community/public/icons/clock.svg new file mode 100644 index 00000000..fd6aed95 --- /dev/null +++ b/community/public/icons/clock.svg @@ -0,0 +1,3 @@ + + + diff --git a/community/public/icons/rating-filled.svg b/community/public/icons/rating-filled.svg new file mode 100644 index 00000000..260c7f4d --- /dev/null +++ b/community/public/icons/rating-filled.svg @@ -0,0 +1,3 @@ + + + diff --git a/community/public/icons/rating.svg b/community/public/icons/rating.svg new file mode 100644 index 00000000..dade2e61 --- /dev/null +++ b/community/public/icons/rating.svg @@ -0,0 +1,3 @@ + + + diff --git a/community/public/icons/user.svg b/community/public/icons/user.svg new file mode 100644 index 00000000..66b19fb9 --- /dev/null +++ b/community/public/icons/user.svg @@ -0,0 +1,4 @@ + + + + diff --git a/community/public/icons/white-arrow.svg b/community/public/icons/white-arrow.svg new file mode 100644 index 00000000..71bebd47 --- /dev/null +++ b/community/public/icons/white-arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/community/www/__init__.py b/community/www/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/__pycache__/__init__.py b/community/www/__pycache__/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/batch/__pycache__/__init__.py b/community/www/batch/__pycache__/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/courses/__init__.py b/community/www/courses/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/courses/__pycache__/__init__.py b/community/www/courses/__pycache__/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/courses/index.html b/community/www/courses/index.html index 89de4c19..253f9ade 100644 --- a/community/www/courses/index.html +++ b/community/www/courses/index.html @@ -9,37 +9,87 @@ {% endblock %} {% block content %} -
-
-

{{ 'All Courses' }}

-
- {% for course in courses %} - {{ course_card(course) }} - {% endfor %} - +
+
+
+
+ {{ 'All Courses' }} +
+
+
+ {% for course in courses %} + {{ course_card(course) }} + {% endfor %} +
-
+ {% endblock %} {% macro course_card(course) %} -
- -
-
-
{{ course.title }}
- {% if course.description %} -
- {{ frappe.utils.md_to_html(course.description[:200]) }} -
- {% endif %} -
+
+ +
+
+ {% if course.get_chapters() | length %} + + {{ course.get_chapters() | length }} Chapters + + {% endif %} + {% if course.get_chapters() | length and course.get_upcoming_batches() | length %} + . + {% endif %} + {% if course.get_upcoming_batches() | length %} + + {{ course.get_upcoming_batches() | length }} Open Batches + + {% endif %} +
+
{{ course.title }}
+
+
+ {{ widgets.Avatar(member=course.get_instructor(), avatar_class="avatar-small") }} + + {{ course.get_instructor().full_name }} + + {% if course.get_students() | length %} + + + {{ course.get_students() | length }} + + {% endif %} +
+ + {% if course.get_membership(frappe.session.user) %} + + {% else %} + + {% endif %} + +
{% endmacro %} + +{% block script %} + +{% endblock %} diff --git a/community/www/courses/index.py b/community/www/courses/index.py index 49b1864a..86d6acf2 100644 --- a/community/www/courses/index.py +++ b/community/www/courses/index.py @@ -5,8 +5,8 @@ def get_context(context): context.courses = get_courses() def get_courses(): - courses = frappe.get_all( - "LMS Course", - fields=['name', 'title', 'description'] - ) + course_names = frappe.get_all("LMS Course", pluck="name") + courses = [] + for course in course_names: + courses.append(frappe.get_doc("LMS Course", course)) return courses diff --git a/community/www/dashboard/__init__.py b/community/www/dashboard/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/dashboard/__pycache__/__init__.py b/community/www/dashboard/__pycache__/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/hackathons/__init__.py b/community/www/hackathons/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/hackathons/__pycache__/__init__.py b/community/www/hackathons/__pycache__/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/hackathons/macros/__init__.py b/community/www/hackathons/macros/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/home/__init__.py b/community/www/home/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/home/__pycache__/__init__.py b/community/www/home/__pycache__/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/macros/__init__.py b/community/www/macros/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/my-courses/__init__.py b/community/www/my-courses/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/my-courses/__pycache__/__init__.py b/community/www/my-courses/__pycache__/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/profiles/__init__.py b/community/www/profiles/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/profiles/__pycache__/__init__.py b/community/www/profiles/__pycache__/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/sketches/__init__.py b/community/www/sketches/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/www/sketches/__pycache__/__init__.py b/community/www/sketches/__pycache__/__init__.py new file mode 100644 index 00000000..e69de29b