Merge pull request #314 from pateljannat/ui-cleanup

This commit is contained in:
Jannat Patel
2022-03-17 15:23:51 +05:30
committed by GitHub
12 changed files with 315 additions and 261 deletions

View File

@@ -1,7 +1,7 @@
import re
import frappe
from frappe.utils import flt, cint, cstr
from school.lms.md import markdown_to_html
from school.lms.md import markdown_to_html, find_macros
import string
from frappe import _
@@ -85,6 +85,13 @@ def get_lesson_details(chapter):
lesson_details = frappe.db.get_value("Course Lesson", row.lesson,
["name", "title", "include_in_preview", "body", "creation"], as_dict=True)
lesson_details.number = flt("{}.{}".format(chapter.idx, row.idx))
lesson_details.icon = "icon-list"
macros = find_macros(lesson_details.body)
for macro in macros:
if macro[0] == "YouTubeVideo":
lesson_details.icon = "icon-video"
elif macro[0] == "Quiz":
lesson_details.icon = "icon-quiz"
lessons.append(lesson_details)
return lessons

View File

@@ -17,10 +17,35 @@
<div class="course-card-content">
<div class="course-card-meta">
{% if get_lessons(course.name) | length %}
<span>
<div class="vertically-center">
<svg class="icon icon-md">
<use href="#icon-education"></use>
</svg>
{{ get_lessons(course.name) | length }} {{ _("Lessons") }}
</span>
</div>
{% endif %}
<div class="vertically-center">
{% set student_count = get_students(course.name) | length %}
{% if student_count %}
<div class="vertically-center">
<svg class="icon icon-md">
<use class="" href="#icon-users">
</svg>
{{ student_count }}
</div>
{% endif %}
{% set avg_rating = get_average_rating(course.name) %}
{% if avg_rating %}
<div class="vertically-center ml-3">
<svg class="icon icon-md">
<use href="#icon-star"></use>
</svg>
{{ frappe.utils.flt(avg_rating, frappe.get_system_settings("float_precision") or 3) }}
</div>
{% endif %}
</div>
</div>
<div class="course-card-title">{{ course.title }}</div>
@@ -59,22 +84,6 @@
</span>
</a>
</span>
{% set student_count = get_students(course.name) | length %}
<span class="course-student-count">
{% if student_count %}
<span class="vertically-center mr-3">
<img class="icon-background" src="/assets/school/icons/user.svg" />
{{ student_count }}
</span>
{% endif %}
{% set avg_rating = get_average_rating(course.name) %}
{% if avg_rating %}
<span class="vertically-center">
<img class="icon-background" src="/assets/school/icons/rating.svg" />
{{ frappe.utils.flt(avg_rating, frappe.get_system_settings("float_precision") or 3) }}
</span>
{% endif %}
</span>
</div>
{% if read_only %}

View File

@@ -23,12 +23,15 @@
<div class="lessons">
{% for lesson in get_lessons(course.name, chapter) %}
<div class="lesson-info {% if membership.current_lesson == lesson.name %} active-lesson {% endif %}">
{% set active = membership.current_lesson == lesson.name %}
<div class="lesson-info {% if active %} active-lesson {% endif %}">
{% if membership or lesson.include_in_preview %}
<a class="lesson-links" href="{{ get_lesson_url(course.name, lesson.number) }}{{course.query_parameter}}"
data-course="{{ course.name }}">
<svg class="icon icon-md mr-2">
<use class="" href="#{{ lesson.icon }}{% if active %}-blue{% endif %}">
</svg>
{{ lesson.title }}
{% if membership %}
@@ -43,14 +46,18 @@
title="This lesson is not available for preview. As you are the Instructor of the course only you can see it."
href="{{ get_lesson_url(course.name, lesson.number) }}{{course.query_parameter}}"
data-course="{{ course.name }}">
<img class="mr-3" src="/assets/school/icons/lock.svg">
<svg class="icon icon-md">
<use class="" href="#icon-lock">
</svg>
<div>{{ lesson.title }}</div>
</a>
{% else %}
<div class="no-preview" title="This lesson is not available for preview" data-course="{{ course.name }}">
<div class="lesson-links">
<img class="mr-3" src="/assets/school/icons/lock.svg">
<svg class="icon icon-md">
<use class="" href="#icon-lock">
</svg>
<div>{{ lesson.title }}</div>
</div>
</div>
@@ -83,7 +90,7 @@ frappe.ready(() => {
});
const expand_the_first_chapter = () => {
var elements = $(".course-outline .collapse");
let elements = $(".course-outline .collapse");
elements.each((i, element) => {
if (i < 1) {
show_section(element);
@@ -95,13 +102,21 @@ const expand_the_first_chapter = () => {
const expand_the_active_chapter = () => {
/* Find anchor matching the URL for course details page */
var selector = $(`a[href="${decodeURIComponent(window.location.pathname)}"]`).parent();
let selector = $(`a[href="${decodeURIComponent(window.location.pathname)}"]`).parent();
if (!selector.length) {
selector = $(`a[href^="${decodeURIComponent(window.location.pathname)}"]`).parent();
}
if (selector.length && $(".course-details-page").length) {
$(".lesson-info").removeClass("active-lesson")
$(".lesson-info").removeClass("active-lesson");
$(".lesson-info").each((i, elem) => {
let href = $(elem).find("use").attr("href");
href.endsWith("blue") && $(elem).find("use").attr("href", href.substring(0, href.length - 5));
})
selector.addClass("active-lesson");
let href = selector.find("use").attr("href");
!href.endsWith("blue") && selector.find("use").attr("href", `${href}-blue`);
show_section(selector.parent().parent());
}
@@ -124,7 +139,7 @@ const show_section = (element) => {
};
const rotate_chapter_icon = (e) => {
var icon = $(e.currentTarget).children(".chapter-icon");
let icon = $(e.currentTarget).children(".chapter-icon");
if (icon.css("transform") == "none") {
icon.css("transform", "rotate(90deg)");
} else {

View File

@@ -19,7 +19,7 @@
<div class="avg-rating-stars">
<div class="rating">
{% for i in [1, 2, 3, 4, 5] %}
<svg class="icon icon-md {% if i <= avg_rating %} star-click {% endif %}" data-rating="{{ i }}">
<svg class="icon icon-md {% if i <= frappe.utils.ceil(avg_rating) %} star-click {% endif %}" data-rating="{{ i }}">
<use href="#icon-star"></use>
</svg>
{% endfor %}
@@ -49,14 +49,16 @@
{% if reviews | length %}
<div class="mt-12">
{% for review in reviews %}
<div class="">
<div class="review-card-footer">
<div class="d-flex align-items-center">
<div class="mr-5">
{{ widgets.Avatar(member=review.owner_details, avatar_class="avatar-medium") }}
</div>
<div>
<a class="button-links" href="{{get_profile_url(review.owner_details.username) }}">
<div class="mb-4">
<div class="d-flex align-items-center">
<div class="mr-4">
{{ widgets.Avatar(member=review.owner_details, avatar_class="avatar-medium") }}
</div>
<div>
<div class="d-flex align-items-center">
<a class="button-links mr-2" href="{{get_profile_url(review.owner_details.username) }}">
<span class="bold-heading">
{{ review.owner_details.full_name }}
</span>
@@ -69,12 +71,12 @@
{% endfor %}
</div>
</div>
</div>
<div class="ml-16 mt-4">
<div> {{ review.review }} </div>
<div class="frappe-timestamp mt-2 mb-6 course-meta" data-timestamp="{{ review.creation }}"> frappe.utils.pretty_date(review.creation) </div>
<div class="frappe-timestamp course-meta" data-timestamp="{{ review.creation }}"> frappe.utils.pretty_date(review.creation) </div>
</div>
</div>
<div class="review-content"> {{ review.review }} </div>
</div>
{% if loop.index != reviews | length %}
<div class="card-divider"></div>

View File

@@ -58,7 +58,7 @@ input[type=checkbox] {
letter-spacing: 0.011em;
text-transform: uppercase;
font-weight: 600;
box-shadow: var(--popover-box-shadow);
box-shadow: var(--shadow-sm);
color: var(--gray-900);
width: fit-content;
}
@@ -76,6 +76,7 @@ input[type=checkbox] {
padding-bottom: 5rem;
min-height: 60vh;
padding-top: 3rem;
background-color: var(--bg-color);
}
.common-card-style {
@@ -99,47 +100,36 @@ input[type=checkbox] {
}
.course-card-meta {
margin: 0.75rem 0 0.5rem;
display: flex;
align-items: center;
justify-content: space-between;
font-size: var(--text-base);
color: var(--gray-600);
color: var(--gray-900);
margin-bottom: 0.5rem;
}
.course-card-meta-2 {
color: var(--gray-700);
.icon {
margin: 0;
margin-right: 0.25rem;
}
.lesson-links .icon {
stroke: none;
}
.course-card-content {
padding: 0 1.25rem 1.25rem;
padding: 1rem;
display: flex;
flex-direction: column;
flex: 1 1 auto;
}
@media (max-width: 400px) {
.course-card-content {
padding: 0 0.5rem 1.25rem;
}
}
@media (max-width: 350px) {
.course-card-content {
padding: 0px 10px 10px;
}
}
.course-card-title {
font-size: 1.125rem;
font-weight: 600;
color: var(--gray-800);
color: var(--gray-900);
margin-bottom: 1.25rem;
}
@media (max-width: 360px) {
.card-heading {
font-size: 0.875rem;
}
}
.card-divider {
border-top: 1px solid var(--gray-300);
margin-bottom: 1rem;
@@ -151,9 +141,8 @@ input[type=checkbox] {
}
.course-instructor {
margin-left: 0.625rem;
font-size: 0.875rem;
color: var(--gray-700);
margin-left: 0.5rem;
font-size: var(--text-base);
}
@media (max-width: 400px) {
@@ -164,9 +153,9 @@ input[type=checkbox] {
.course-student-count {
display: flex;
font-size: 12px;
font-size: var(--text-base);
float: right;
font-weight: 500;
color: var(--gray-900);
}
.course-card-footer {
@@ -222,12 +211,12 @@ input[type=checkbox] {
}
.button-links {
color: #4C5A67;
color: var(--gray-900);
}
.button-links:hover {
text-decoration: none;
color: #4C5A67;
color: var(--gray-900);
}
.icon-background {
@@ -243,14 +232,9 @@ input[type=checkbox] {
height: 100%;
}
.review-card-footer {
margin-top: 20px;
justify-content: space-between;
}
.review-content {
padding: 24px;
flex: 1;
margin: 1rem 0 0 3.5rem;
color: var(--gray-700);
}
.submit-review {
@@ -290,13 +274,25 @@ input[type=checkbox] {
}
.course-card-wide {
margin-top: 1rem;
width: 60%;
background-color: white;
padding: 0 1rem 1rem;
border-radius: var(--border-radius);
width: 50%;
box-shadow: var(--shadow-base);
font-size: var(--text-base);
}
@media (max-width: 1000px) {
.course-card-wide {
width: 75%;
margin: 0 auto;
}
}
@media (max-width: 768px) {
.course-card-wide {
width: 100%;
margin: 0;
}
}
@@ -378,18 +374,22 @@ input[type=checkbox] {
margin: 5rem 0 4rem;
}
.course-home-page {
background-color: #FFFFFF;
padding-top: 3.75rem;
}
.chapter-title {
font-weight: 500;
cursor: pointer;
border-radius: var(--border-radius-lg);
padding: 0.75rem 0;
padding: 0.5rem 0;
color: var(--gray-900);
display: flex;
align-items: center;
}
.chapter-description {
margin: 0.75rem 3rem 1rem;
margin: 0 2rem 0.5rem;
}
.course-content-parent .chapter-description {
@@ -397,25 +397,24 @@ input[type=checkbox] {
}
.chapter-icon {
margin-right: 1.25rem;
margin-right: 0.5rem;
}
.reviews-parent {
margin: 5rem 0;
}
.course-description-section {
margin-top: 3.75rem;
color: var(--gray-900);
}
.lesson-info {
font-size: 16px;
color: var(--gray-900);
letter-spacing: -0.011em;
}
.lesson-links {
display: flex;
padding: 0.75rem 1rem;
align-items: center;
padding: 0.5rem;
color: inherit;
}
@@ -426,14 +425,8 @@ input[type=checkbox] {
border-radius: var(--border-radius-md);
}
.course-content-parent .chapter-title {
font-size: var(--text-md);
}
.course-content-parent .lesson-links {
padding: 0.5rem 1rem;
font-size: var(--text-md);
line-height: 200%;
font-size: var(--text-base);
}
.course-outline {
@@ -442,7 +435,7 @@ input[type=checkbox] {
}
.lessons {
margin-left: 2.5rem;
margin-left: 2rem;
}
.member-card {
@@ -508,17 +501,17 @@ input[type=checkbox] {
.member-parent {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
-moz-column-gap: 1.25rem;
column-gap: 1.25rem;
row-gap: 1.25rem;
-moz-column-gap: 2rem;
column-gap: 2rem;
row-gap: 2rem;
}
@media (max-width: 600px) {
.member-parent {
grid-template-columns: repeat(auto-fill, minmax(125px, 1fr));
-moz-column-gap: 1.25rem;
column-gap: 1.25rem;
row-gap: 1.25rem;
-moz-column-gap: 2rem;
column-gap: 2rem;
row-gap: 2rem;
}
}
@@ -580,9 +573,10 @@ input[type=checkbox] {
.breadcrumb {
display: flex;
align-items: center;
font-size: var(--text-md);
font-size: var(--text-base);
line-height: 20px;
color: var(--gray-900);
padding: 1rem 0;
}
.course-details-outline {
@@ -817,8 +811,8 @@ input[type=checkbox] {
}
.progress-percent {
margin: 0.5rem 0 1.3rem;
font-size: 0.8rem;
margin: 0.5rem 0;
font-size: var(--text-base);
font-weight: 500;
}
@@ -955,15 +949,15 @@ pre {
background-image: url(/assets/frappe/icons/timeless/search.svg);
border: none;
border-radius: var(--border-radius-md);
font-size: var(--text-sm);
font-size: var(--text-base);
padding: 0.625rem 0.75rem;
height: 36px;
background-repeat: no-repeat;
text-indent: 1.5rem;
background-position: 1rem 0.6rem;
background-position: 1rem 0.7rem;
float: right;
width: 25%;
background-color: var(--gray-100);
box-shadow: var(--shadow-sm);
}
.section-heading {
@@ -1144,6 +1138,7 @@ pre {
flex-direction: column;
align-items: flex-end;
justify-content: space-between;
margin-left: auto;
}
.job-detail-card {
@@ -1151,11 +1146,6 @@ pre {
flex-direction: column;
}
.job-detail-card span::before {
content: "\00B7";
margin: 0 8px;
}
.job-subtitle {
font-size: var(--text-base);
margin-bottom: 1.875rem;
@@ -1171,34 +1161,6 @@ pre {
color: var(--gray-900);
}
.company-name {
font-size: var(--text-base);
}
.job-meta {
display: flex;
align-items: center;
color: var(--gray-700);
font-size: var(--text-base);
}
.job-type {
background-color: var(--dark-green-100);
color: var(--dark-green-500);
border-radius: var(--border-radius-md);
padding: 0.25rem 0.5rem;
font-weight: 600;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.6px;
margin-bottom: 0.5rem;
width: fit-content;
}
.job-description {
margin-top: 3.75rem;
}
.course-head-container {
color: var(--gray-900);
}
@@ -1206,16 +1168,16 @@ pre {
.course-intructor-rating-section {
display: flex;
align-items: center;
margin-top: 3.5rem;
justify-content: space-between;
margin-top: 2rem;
}
.course-intructor-rating-section .seperator::before {
content: "\00B7";
.seperator {
margin: 0 1rem;
}
.course-head-container .progress {
margin-top: 2.75rem;
margin-top: 1rem;
}
.course-overlay-card {
@@ -1225,32 +1187,31 @@ pre {
overflow: auto;
width: fit-content;
position: fixed;
top: 40%;
top: 50%;
right: 7%;
max-width: 400px;
z-index: 4;
}
@media (max-width: 768px) {
@media (max-width: 1000px) {
.course-overlay-card {
position: inherit;
margin-top: 1rem;
margin: 1rem auto;
}
.course-intructor-rating-section .seperator::before {
content: "\00B7";
.seperator {
margin: 0 0.25rem;
}
}
.video-in-overlay {
top: 30%;
top: 40%;
}
.course-overlay-content {
padding: 1.25rem;
font-size: var(--text-base);
color: var(--gray-700);
color: var(--gray-900);
}
.breadcrumb-destination {
@@ -1267,7 +1228,7 @@ pre {
width: 60%;
}
@media (max-width: 768px) {
@media (max-width: 1000px) {
.course-body-container {
width: 100%;
}
@@ -1293,15 +1254,9 @@ pre {
box-shadow: none;
}
.course-creator-name {
font-size: var(--text-xl);
font-weight: 500;
color: var(--gray-900);
}
.course-meta {
font-size: var(--text-base);
color: var(--gray-600);
color: var(--gray-900);
}
.avg-rating {
@@ -1341,6 +1296,7 @@ pre {
.star-click {
--star-fill: var(--yellow-500);
margin-right: 0;
}
.rating {
@@ -1360,6 +1316,7 @@ pre {
.reviews-parent .progress {
width: 200px;
color: var(--gray-900);
}
.reviews-parent .progress-bar {
@@ -1426,3 +1383,11 @@ pre {
.carousel-inner {
overflow: inherit;
}
.course-card-wide .breadcrumb {
margin-bottom: 0;
}
.course-content-parent .course-details-outline .course-home-headings {
display: none;
}

View File

@@ -1,3 +0,0 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.7114 3.0002H11.6325C10.4336 2.98895 9.27915 3.45397 8.42278 4.29322C7.5658 5.13306 7.07747 6.27888 7.06517 7.47871L7.06514 7.47871V7.48384V8.17399H5C3.89543 8.17399 3 9.06943 3 10.174V18.9996C3 20.1041 3.89543 20.9996 5 20.9996H18.2602C19.3647 20.9996 20.2602 20.1041 20.2602 18.9996V10.174C20.2602 9.06942 19.3647 8.17399 18.2602 8.17399H16.195V7.56755C16.2063 6.36863 15.7412 5.21421 14.902 4.35784C14.0622 3.50086 12.9163 3.01253 11.7165 3.00023V3.0002H11.7114ZM15.195 8.17399V7.56514V7.56016H15.195C15.2043 6.62548 14.842 5.72537 14.1878 5.05777C13.5341 4.39076 12.6425 4.01043 11.7087 4.0002H11.6301H11.6251V4.00017C10.6904 3.99087 9.79031 4.35318 9.12271 5.00743C8.4557 5.6611 8.07537 6.55271 8.06514 7.48649V8.17399H15.195ZM5 9.17399C4.44772 9.17399 4 9.62171 4 10.174V18.9996C4 19.5518 4.44772 19.9996 5 19.9996H18.2602C18.8124 19.9996 19.2602 19.5518 19.2602 18.9996V10.174C19.2602 9.62171 18.8124 9.17399 18.2602 9.17399H5ZM11.6303 15.804C12.3026 15.804 12.8476 15.259 12.8476 14.5867C12.8476 13.9145 12.3026 13.3694 11.6303 13.3694C10.958 13.3694 10.413 13.9145 10.413 14.5867C10.413 15.259 10.958 15.804 11.6303 15.804ZM13.8476 14.5867C13.8476 15.8113 12.8549 16.804 11.6303 16.804C10.4057 16.804 9.413 15.8113 9.413 14.5867C9.413 13.3622 10.4057 12.3694 11.6303 12.3694C12.8549 12.3694 13.8476 13.3622 13.8476 14.5867Z" fill="#4C5A67"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,31 @@
<svg id="frappe-symbols" aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" class="d-block" xmlns="http://www.w3.org/2000/svg">
<svg id="icon-video" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.91624 5.11694L6.91622 5.11695C6.47722 5.30953 6.16502 5.71991 6.11766 6.20522L6.11496 6.2329V6.26072V11.7393V11.7671L6.11766 11.7949C6.16503 12.2801 6.47727 12.6904 6.91613 12.883L6.91632 12.8831C7.35161 13.0739 7.85949 13.0294 8.25381 12.7616L12.3871 10.0312C12.7443 9.81338 12.9721 9.42718 12.9721 9C12.9721 8.57282 12.7443 8.18662 12.3871 7.96878L8.25382 5.23837C7.85957 4.97063 7.35166 4.92595 6.91624 5.11694ZM1 9C1 4.58171 4.58171 1 9 1C11.1217 1 13.1566 1.84286 14.6568 3.34314C16.1571 4.84344 17 6.87827 17 9C17 13.4183 13.4183 17 9 17C4.58171 17 1 13.4183 1 9Z" stroke="black"/>
</svg>
<svg id="icon-video-blue" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 9C1 4.58172 4.58172 1 9 1C11.1217 1 13.1566 1.84286 14.6569 3.34315C16.1571 4.84343 17 6.87827 17 9C17 13.4182 13.4182 17 9 17C4.58172 17 1 13.4182 1 9ZM8.00636 12.0679L11.8766 9.51133C12.0614 9.40191 12.174 9.2084 12.174 9C12.174 8.79161 12.0614 8.59809 11.8766 8.48867L8.00636 5.932C7.79102 5.78453 7.51 5.75869 7.2694 5.86422C7.0288 5.96977 6.86529 6.1906 6.84063 6.44334V11.5567C6.86529 11.8094 7.0288 12.0302 7.2694 12.1358C7.51 12.2413 7.79102 12.2155 8.00636 12.0679Z" fill="#2D95F0"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" id="icon-quiz" viewBox="0 0 1024 1024" stroke="#1F272E">
<path d="M512 0C229.232 0 0 229.232 0 512c0 282.784 229.232 512 512 512 282.784 0 512.017-229.216 512.017-512C1024.017 229.232 794.785 0 512 0zm0 961.008c-247.024 0-448-201.984-448-449.01 0-247.024 200.976-448 448-448s448.017 200.977 448.017 448S759.025 961.009 512 961.009zm-47.056-160.529h80.512v-81.248h-80.512zm46.112-576.944c-46.88 0-85.503 12.64-115.839 37.889-30.336 25.263-45.088 75.855-44.336 117.775l1.184 2.336h73.44c0-25.008 8.336-60.944 25.008-73.84 16.656-12.88 36.848-19.328 60.56-19.328 27.328 0 48.336 7.424 63.073 22.271 14.72 14.848 22.063 36.08 22.063 63.664 0 23.184-5.44 42.976-16.368 59.376-10.96 16.4-29.328 39.841-55.088 70.322-26.576 23.967-42.992 43.231-49.232 57.807-6.256 14.592-9.504 40.768-9.744 78.512h76.96c0-23.68 1.503-41.136 4.496-52.336 2.975-11.184 11.504-23.823 25.568-37.888 30.224-29.152 54.496-57.664 72.88-85.551 18.336-27.857 27.52-58.593 27.52-92.193 0-46.88-14.176-83.408-42.577-109.568-28.416-26.176-68.272-39.248-119.568-39.248z" fill="#1F272E"/>
</svg>
<svg id="icon-quiz-blue" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1511_749)">
<path d="M512 0C229.232 0 0 229.232 0 512C0 794.784 229.232 1024 512 1024C794.784 1024 1024.02 794.784 1024.02 512C1024.02 229.232 794.785 0 512 0ZM512 961.008C264.976 961.008 64 759.024 64 511.998C64 264.974 264.976 63.998 512 63.998C759.024 63.998 960.017 264.975 960.017 511.998C960.017 759.021 759.025 961.009 512 961.009V961.008ZM464.944 800.479H545.456V719.231H464.944V800.479ZM511.056 223.535C464.176 223.535 425.553 236.175 395.217 261.424C364.881 286.687 350.129 337.279 350.881 379.199L352.065 381.535H425.505C425.505 356.527 433.841 320.591 450.513 307.695C467.169 294.815 487.361 288.367 511.073 288.367C538.401 288.367 559.409 295.791 574.146 310.638C588.866 325.486 596.209 346.718 596.209 374.302C596.209 397.486 590.769 417.278 579.841 433.678C568.881 450.078 550.513 473.519 524.753 504C498.177 527.967 481.761 547.231 475.521 561.807C469.265 576.399 466.017 602.575 465.777 640.319H542.737C542.737 616.639 544.24 599.183 547.233 587.983C550.208 576.799 558.737 564.16 572.801 550.095C603.025 520.943 627.297 492.431 645.681 464.544C664.017 436.687 673.201 405.951 673.201 372.351C673.201 325.471 659.025 288.943 630.624 262.783C602.208 236.607 562.352 223.535 511.056 223.535V223.535Z" fill="#2D95F0" stroke="#2D95F0"/>
</g>
<defs>
<clipPath id="clip0_1511_749">
<rect width="1024" height="1024" fill="white"/>
</clipPath>
</defs>
</svg>
<svg id="icon-list-blue" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.66699 3.25C2.46808 3.25 2.27731 3.32902 2.13666 3.46967C1.99601 3.61032 1.91699 3.80109 1.91699 4C1.91699 4.19891 1.99601 4.38968 2.13666 4.53033C2.27731 4.67098 2.46808 4.75 2.66699 4.75H2.67399C2.8729 4.75 3.06367 4.67098 3.20432 4.53033C3.34497 4.38968 3.42399 4.19891 3.42399 4C3.42399 3.80109 3.34497 3.61032 3.20432 3.46967C3.06367 3.32902 2.8729 3.25 2.67399 3.25H2.66699ZM5.33299 3.5C5.20038 3.5 5.07321 3.55268 4.97944 3.64645C4.88567 3.74021 4.83299 3.86739 4.83299 4C4.83299 4.13261 4.88567 4.25979 4.97944 4.35355C5.07321 4.44732 5.20038 4.5 5.33299 4.5H14C14.1326 4.5 14.2598 4.44732 14.3535 4.35355C14.4473 4.25979 14.5 4.13261 14.5 4C14.5 3.86739 14.4473 3.74021 14.3535 3.64645C14.2598 3.55268 14.1326 3.5 14 3.5H5.33299ZM5.33299 7.5C5.20038 7.5 5.07321 7.55268 4.97944 7.64645C4.88567 7.74021 4.83299 7.86739 4.83299 8C4.83299 8.13261 4.88567 8.25979 4.97944 8.35355C5.07321 8.44732 5.20038 8.5 5.33299 8.5H14C14.1326 8.5 14.2598 8.44732 14.3535 8.35355C14.4473 8.25979 14.5 8.13261 14.5 8C14.5 7.86739 14.4473 7.74021 14.3535 7.64645C14.2598 7.55268 14.1326 7.5 14 7.5H5.33299ZM4.83299 12C4.83299 11.8674 4.88567 11.7402 4.97944 11.6464C5.07321 11.5527 5.20038 11.5 5.33299 11.5H14C14.1326 11.5 14.2598 11.5527 14.3535 11.6464C14.4473 11.7402 14.5 11.8674 14.5 12C14.5 12.1326 14.4473 12.2598 14.3535 12.3536C14.2598 12.4473 14.1326 12.5 14 12.5H5.33299C5.20038 12.5 5.07321 12.4473 4.97944 12.3536C4.88567 12.2598 4.83299 12.1326 4.83299 12ZM1.91699 8C1.91699 7.80109 1.99601 7.61032 2.13666 7.46967C2.27731 7.32902 2.46808 7.25 2.66699 7.25H2.67399C2.8729 7.25 3.06367 7.32902 3.20432 7.46967C3.34497 7.61032 3.42399 7.80109 3.42399 8C3.42399 8.19891 3.34497 8.38968 3.20432 8.53033C3.06367 8.67098 2.8729 8.75 2.67399 8.75H2.66699C2.46808 8.75 2.27731 8.67098 2.13666 8.53033C1.99601 8.38968 1.91699 8.19891 1.91699 8V8ZM2.66699 11.25C2.46808 11.25 2.27731 11.329 2.13666 11.4697C1.99601 11.6103 1.91699 11.8011 1.91699 12C1.91699 12.1989 1.99601 12.3897 2.13666 12.5303C2.27731 12.671 2.46808 12.75 2.66699 12.75H2.67399C2.8729 12.75 3.06367 12.671 3.20432 12.5303C3.34497 12.3897 3.42399 12.1989 3.42399 12C3.42399 11.8011 3.34497 11.6103 3.20432 11.4697C3.06367 11.329 2.8729 11.25 2.67399 11.25H2.66699Z" fill="#2D95F0"/>
</svg>
<svg id="icon-lock-blue" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.077 1.45H8.022C7.13244 1.44174 6.27599 1.78701 5.64088 2.40993C5.00577 3.03285 4.64397 3.88244 4.635 4.772V5.122H3.75C3.21957 5.122 2.71086 5.33271 2.33579 5.70779C1.96071 6.08286 1.75 6.59157 1.75 7.122V12.513C1.75 13.0434 1.96071 13.5521 2.33579 13.9272C2.71086 14.3023 3.21957 14.513 3.75 14.513H12.289C12.8194 14.513 13.3281 14.3023 13.7032 13.9272C14.0783 13.5521 14.289 13.0434 14.289 12.513V7.122C14.289 6.59157 14.0783 6.08286 13.7032 5.70779C13.3281 5.33271 12.8194 5.122 12.289 5.122H11.404V4.837C11.4123 3.94744 11.067 3.09099 10.4441 2.45588C9.82115 1.82077 8.97156 1.45898 8.082 1.45H8.077ZM10.404 5.122V4.83C10.4104 4.20548 10.1686 3.60398 9.73166 3.15769C9.29475 2.71141 8.69851 2.45686 8.074 2.45H8.014C7.38948 2.4436 6.78798 2.68543 6.34169 3.12234C5.89541 3.55925 5.64086 4.15549 5.634 4.78V5.122H10.404ZM3.75 6.122C3.48478 6.122 3.23043 6.22736 3.04289 6.41489C2.85536 6.60243 2.75 6.85678 2.75 7.122V12.513C2.75 12.7782 2.85536 13.0326 3.04289 13.2201C3.23043 13.4076 3.48478 13.513 3.75 13.513H12.289C12.5542 13.513 12.8086 13.4076 12.9961 13.2201C13.1836 13.0326 13.289 12.7782 13.289 12.513V7.122C13.289 6.85678 13.1836 6.60243 12.9961 6.41489C12.8086 6.22736 12.5542 6.122 12.289 6.122H3.75ZM8.02 10.391C8.1721 10.391 8.31797 10.3306 8.42553 10.223C8.53308 10.1155 8.5935 9.9696 8.5935 9.8175C8.5935 9.6654 8.53308 9.51953 8.42553 9.41197C8.31797 9.30442 8.1721 9.244 8.02 9.244C7.8679 9.244 7.72203 9.30442 7.61447 9.41197C7.50692 9.51953 7.4465 9.6654 7.4465 9.8175C7.4465 9.9696 7.50692 10.1155 7.61447 10.223C7.72203 10.3306 7.8679 10.391 8.02 10.391V10.391ZM9.593 9.817C9.593 10.2343 9.42722 10.6345 9.13213 10.9296C8.83704 11.2247 8.43682 11.3905 8.0195 11.3905C7.60218 11.3905 7.20196 11.2247 6.90687 10.9296C6.61178 10.6345 6.446 10.2343 6.446 9.817C6.446 9.39968 6.61178 8.99946 6.90687 8.70437C7.20196 8.40928 7.60218 8.2435 8.0195 8.2435C8.43682 8.2435 8.83704 8.40928 9.13213 8.70437C9.42722 8.99946 9.593 9.39968 9.593 9.817V9.817Z" fill="#2D95F0"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" id="icon-location" viewBox="0 0 24 24" fill="none" stroke="#1F272E" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather feather-map-pin">
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path>
<circle cx="12" cy="10" r="3"></circle>
</svg>
</svg>

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -1,4 +1,4 @@
<div id="quiz-title" class="course-home-headings">{{ quiz.title }}</div>
<div id="quiz-title" class="hide">{{ quiz.title }}</div>
<div class="common-card-style question-card">
<form id="quiz-form">

View File

@@ -3,6 +3,7 @@
{% block title %} {{ lesson.title }} - {{ course.title }} {% 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 %}
@@ -11,11 +12,10 @@
{% endblock %}
{% block content %}
<div class="common-page-style">
<div class="container course-details-page">
{{ widgets.BreadCrumb(course=course, lesson=lesson) }}
{{ BreadCrumb(course, lesson) }}
<div class="course-content-parent">
<div class="course-details-outline">
{{ widgets.CourseOutline(course=course, membership=membership) }}
@@ -32,6 +32,16 @@
</div>
{% endblock %}
{% macro BreadCrumb(course, lesson) %}
<div class="breadcrumb">
<a class="dark-links" href="/courses">{{ _("All Courses") }}</a>
<img class="ml-1 mr-1" src="/assets/school/icons/chevron-right.svg">
<a class="dark-links" href="/courses">{{ course.title }}</a>
<img class="ml-1 mr-1" src="/assets/school/icons/chevron-right.svg">
<span class="breadcrumb-destination">{{ lesson.title }}</span>
</div>
{% endmacro %}
{% macro LessonContent(lesson) %}
{% set instructors = get_instructors(course.name) %}
{% set is_instructor = is_instructor(course.name) %}
@@ -57,8 +67,8 @@
</div>
{% endif %}
{% endfor %}
<a class="button-links ml-2" href="{{ get_profile_url(instructors[0].username) }}">
<span class="course-creator-name">
<a class="button-links ml-1" href="{{ get_profile_url(instructors[0].username) }}">
<span class="course-meta">
{% if ins_len == 1 %}
{{ instructors[0].full_name }}
{% else %}
@@ -67,7 +77,7 @@
{% endif %}
</span>
</a>
<div class="ml-3 course-meta"> {{ frappe.utils.format_date(lesson.creation, "medium") }} </div>
<div class="ml-5 course-meta"> {{ frappe.utils.format_date(lesson.creation, "medium") }} </div>
</div>

View File

@@ -2,18 +2,21 @@
{% block title %}{{ course.title }}
{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
<link rel="stylesheet" href="/assets/frappe/css/font-awesome.css">
{% endblock %}
{% block content %}
<div class="common-page-style pt-0">
<div class="common-page-style pt-0 pb-0">
<div class="course-home-top-container">
{{ CourseHomeHeader(course) }}
{{ CourseHeaderOverlay(course) }}
<div class="container course-home-page">
<div class="course-body-container">
{{ Description(course) }}
{{ widgets.CourseOutline(course=course, membership=membership) }}
{{ widgets.Reviews(course=course, membership=membership) }}
<div class="course-home-page">
<div class="container">
<div class="course-body-container">
{{ CourseHeaderOverlay(course) }}
{{ Description(course) }}
{{ widgets.CourseOutline(course=course, membership=membership) }}
{{ widgets.Reviews(course=course, membership=membership) }}
</div>
</div>
</div>
</div>
@@ -23,28 +26,32 @@
{% macro CourseHomeHeader(course) %}
<div class="course-head-container"
style=" {% if course.image %} background-position: center; background-size: cover; background-image: url({{ course.image }});
style=" {% if course.image %}
background-position: center;
background-size: cover;
background-image: url({{ course.image }});
{% else %} background-color: var(--gray-200) {% endif %}">
<div class="container pt-10 pb-10">
{{ BreadCrumb(course) }}
{{ CourseCardWide(course) }}
<div class="container pt-5 pb-5">
<div class="course-card-wide" style="">
{{ BreadCrumb(course) }}
{{ CourseCardWide(course) }}
</div>
</div>
</div>
{% endmacro %}
<!-- BreadCrumb -->
{% macro BreadCrumb(course) %}
<div class="breadcrumb">
<a class="dark-links" href="/courses">{{ _("All Courses") }}</a>
<img class="ml-2 mr-2" src="/assets/school/icons/chevron-right.svg">
<img class="ml-1 mr-1" src="/assets/school/icons/chevron-right.svg">
<span class="breadcrumb-destination">{{ course.title }}</span>
</div>
{% endmacro %}
<!-- Course Card -->
{% macro CourseCardWide(course) %}
<div class="course-card-wide">
<div class="">
<div class="d-flex align-items-center">
{% for tag in get_tags(course.name) %}
<div class="course-card-pills">{{ tag }}</div>
@@ -58,32 +65,22 @@
</div>
<div class="course-intructor-rating-section">
<div class="d-flex align-items-center">
{% set instructors = get_instructors(course.name) %}
{% set ins_len = instructors | length %}
{% for instructor in instructors %}
{% if ins_len > 1 and loop.index == 1 %}
<div class="avatar-group overlap">
{% endif %}
{{ widgets.Avatar(member=instructor, avatar_class="avatar-small") }}
{% if ins_len > 1 and loop.index == ins_len %}
</div>
{% endif %}
{% endfor %}
<a class="button-links" href="{{ get_profile_url(instructors[0].username) }}">
<span class="course-instructor">
{% if ins_len == 1 %}
{{ instructors[0].full_name }}
{% else %}
{% set suffix = "other" if ins_len - 1 == 1 else "others" %}
{{ instructors[0].full_name.split(" ")[0] }} and {{ ins_len - 1 }} {{ suffix }}
{% endif %}
</span>
</a>
<div class="vertically-center">
<svg class="icon icon-md">
<use class="" href="#icon-users">
</svg>
{{ get_students(course.name) | length }} {{ _("Enrolled") }}
</div>
<span class="seperator"></span>
{% if get_lessons(course.name) | length %}
<div class="vertically-center">
<svg class="icon icon-md">
<use href="#icon-education"></use>
</svg>
{{ get_lessons(course.name) | length }} {{ _("Lessons") }}
</div>
{% endif %}
{% set avg_rating = get_average_rating(course.name) %}
{% if avg_rating %}
@@ -93,22 +90,33 @@
<use href="#icon-star"></use>
</svg>
{% endfor %}
<span> {{ avg_rating }} {{ _(" Rating ") }} </span>
</div>
<span> {{ avg_rating }} {{ _(" Rating ") }} </span>
{% endif %}
</div>
{% if membership %}
{% set progress = frappe.utils.cint(membership.progress) %}
<div class="progress">
<div class="progress" title="{{ progress }}% Completed">
<div class="progress-bar" role="progressbar" aria-valuenow="{{ progress }}"
aria-valuemin="0" aria-valuemax="100" style="width:{{ progress }}%">
<span class="sr-only"> {{ progress }} Complete</span>
</div>
</div>
<div class="progress-percent">{{ progress }}% Completed</div>
{% endif %}
<div class="mt-3">
<div class="bold-heading">Instructors:</div>
{% for instructor in get_instructors(course.name) %}
<div class="mt-1">
{{ widgets.Avatar(member=instructor, avatar_class="avatar-small") }}
<a class="button-links" href="{{ get_profile_url(instructor.username) }}">
<span class="course-instructor"> {{ instructor.full_name }} </span>
</a>
</div>
{% endfor %}
</div>
</div>
{% endmacro%}
@@ -127,31 +135,25 @@
You have opted to be notified for this course. You will receive an email when the course becomes available.
</div>
{% if get_lessons(course.name) | length %}
<div class="mt-3 mb-4">
<img class="mr-3" src="/assets/school/icons/book.svg">
{{ get_lessons(course.name) | length }} {{ _("Lessons") }}
</div>
{% endif %}
<div class="d-flex align-items-center mb-2">
<div class="">
<svg class="icon icon-md mr-1">
<use class="" href="#icon-users">
</svg>
{{ get_students(course.name) | length }} {{ _("Enrolled") }}
</div>
{% if get_students(course.name) | length %}
{% set initial_members = get_initial_members(course.name) %}
<div class="overlay-student-count">
{% for member in initial_members %}
{% if initial_members | length > 1 and loop.index == 1 %}
<div class="avatar-group overlap">
{% endif %}
{{ widgets.Avatar(member=member, avatar_class="avatar-small") }}
<span class="seperator"></span>
{% if initial_members | length > 1 and loop.index == initial_members | length %}
{% if get_lessons(course.name) | length %}
<div class="">
<svg class="icon icon-md mr-1">
<use href="#icon-education"></use>
</svg>
{{ get_lessons(course.name) | length }} {{ _("Lessons") }}
</div>
{% endif %}
{% endfor %}
<div class="course-meta ml-2">{{ get_students(course.name) | length }} {{ _("Enrolled") }} </div>
</div>
{% endif %}
{% if not course.disable_self_learning and not membership and not course.upcoming and not restriction.restrict %}
<div class="button wide-button start-learning is-primary join-batch" data-course="{{ course.name | urlencode }}">

View File

@@ -1,6 +1,10 @@
{% extends "templates/base.html" %}
{% block title %}{{ _('Job Openings') }}{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
{% endblock %}
{% block content %}
<div class="common-page-style">
@@ -16,20 +20,25 @@
<div class="common-card-style job-list-card">
{% for job in jobs %}
<div class="job-card">
<div class="avatar avatar-medium" title="{{ job.company_name}}">
<div class="avatar avatar-medium mr-3" title="{{ job.company_name}}">
<span class="avatar-frame company-logo" style="background-image: url( {{ job.company_logo | urlencode }} );"></span>
</div>
<div class="job-card-info col-8">
<div class="job-card-info">
<div class="job-card-heading">{{ _(job.job_title) }}</div>
<a class="dark-links company-name mt-1" href="{{ job.company_website }}">{{ job.company_name }}</a>
<div class="vertically-center course-meta">
<div class="mr-3">{{ job.company_name }}</div>
<div class="vertically-center">
<svg class="icon icon-sm">
<use class="" href="#icon-location">
</svg>
{{ job.location }}
</div>
</div>
</div>
<div class="job-meta col">
<img class="mr-2" src="/assets/school/icons/location.svg">
<div>{{ job.location }}</div>
</div>
<div class="job-card-logo-section">
<div class="job-type"> {{ job.type }} </div>
<div class="job-meta">{{ frappe.utils.format_date(job.creation, "medium") }}</div>
<div class="job-card-logo-section course-meta">
<div class="indicator-pill green ml-3"> {{ job.type }} </div>
<div class="">{{ frappe.utils.format_date(job.creation, "medium") }}</div>
</div>
<a class="stretched-link" href="/jobs/{{ job.name }}"></a>
</div>

View File

@@ -1,6 +1,10 @@
{% extends "templates/base.html" %}
{% block title %}{{ _(job.job_title) }}{% endblock %}
{% block head_include %}
{% include "public/icons/symbol-defs.svg" %}
{% endblock %}
{% block content %}
<div class="common-page-style">
@@ -8,27 +12,30 @@
{{ BreadCrumb(job) }}
<div class="common-card-style job-detail-card">
<div class="d-flex justify-content-between">
<div>
<div class="avatar avatar-medium mb-6" title="{{ job.company_name}}">
<div class="avatar-frame company-logo" style="background-image: url( {{ job.company_logo | urlencode }} );"></div>
<div class="d-flex">
<div class="avatar avatar-medium align-self-center" title="{{ job.company_name}}">
<div class="avatar-frame company-logo" style="
background-image: url( {{ job.company_logo | urlencode }} );"></div>
</div>
<div class="course-home-headings mb-2">{{ _(job.job_title) }}</div>
<div class="d-flex align-items-center mb-2">
<a class="dark-links company-name" href="{{ job.company_website }}">{{ job.company_name }}</a>
<span></span>
<div class="job-meta">
<img class="mr-2" src="/assets/school/icons/location.svg">
<div>{{ job.location }}</div>
<div class="ml-5">
<div class="vertically-center">
<div class="course-home-headings mb-0">{{ _(job.job_title) }}</div>
<div class="indicator-pill green ml-5"> {{ job.type }} </div>
</div>
<div class="d-flex align-items-center mb-2">
<a class="dark-links course-meta mr-5" href="{{ job.company_website }}">{{ job.company_name }}</a>
<div class="vertically-center course-meta mr-5">
<svg class="icon icon-sm">
<use class="" href="#icon-location">
</svg>
<div>{{ job.location }}</div>
</div>
<div class="course-meta"> {{ frappe.utils.format_date(job.creation, "medium") }} </div>
</div>
<span></span>
<div class="job-meta"> {{ frappe.utils.format_date(job.creation, "medium") }} </div>
</div>
<div class="job-type"> {{ job.type }} </div>
</div>
{% set application_link = job.application_link if frappe.session.user != 'Guest' else '/login?redirect-to=/jobs/' + job.name %}
<div class="d-flex align-items-start">
<div class="d-flex align-items-start ml-auto">
<a class="button is-primary mr-2"
href="{{ application_link }}">{{ _("Apply") }}</a>
<div class="button is-default mr-2" id="report" data-job="{{ job.name }}">{{ _("Report") }}</div>
@@ -38,7 +45,7 @@
</div>
</div>
<div class="job-description job-meta">{{ _(job.description) }}</div>
<div class="course-meta mt-10">{{ _(job.description) }}</div>
</div>
</div>
@@ -84,6 +91,6 @@
<div class="breadcrumb">
<a class="dark-links" href="/jobs">{{ _("Job Openings") }}</a>
<img class="ml-1 mr-1" src="/assets/school/icons/chevron-right.svg">
<span class="muted-text">{{ _(job.job_title) }}</span>
<span class="breadcrumb-destination">{{ job.job_title }}</span>
</div>
{% endmacro %}