Compare commits
14 Commits
quiz-clean
...
sketch-red
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7017382451 | ||
|
|
3e2c6b3343 | ||
|
|
5ea744de5c | ||
|
|
aedb3d3d45 | ||
|
|
d5067a4bcd | ||
|
|
04d44510de | ||
|
|
844fcc9bca | ||
|
|
145b5efab0 | ||
|
|
4079ed97b9 | ||
|
|
63d70fc037 | ||
|
|
ce86b5deda | ||
|
|
037e946bbe | ||
|
|
a51c8de1eb | ||
|
|
53dc517180 |
@@ -1,5 +1,5 @@
|
||||
{% set color = member.get_palette() %}
|
||||
<a href="/{{member.username}}">
|
||||
<a class="button-links" href="/{{member.username}}">
|
||||
<span class="avatar {{ avatar_class }}" title="{{ member.full_name }}">
|
||||
{% if member.user_image %}
|
||||
<img class="avatar-frame standard-image" style="object-fit: cover;" src="{{ member.user_image }}" title="{{ member.full_name }}">
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
"fieldname": "member_type",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Member Type",
|
||||
"options": "\nStudent\nMentor\nStaff"
|
||||
},
|
||||
@@ -44,7 +45,6 @@
|
||||
"default": "Member",
|
||||
"fieldname": "role",
|
||||
"fieldtype": "Select",
|
||||
"in_standard_filter": 1,
|
||||
"label": "Role",
|
||||
"options": "\nMember\nAdmin"
|
||||
},
|
||||
@@ -63,9 +63,10 @@
|
||||
{
|
||||
"fetch_from": "batch.course",
|
||||
"fieldname": "course",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Course"
|
||||
"label": "Course",
|
||||
"options": "LMS Course"
|
||||
},
|
||||
{
|
||||
"fieldname": "current_lesson",
|
||||
@@ -83,7 +84,7 @@
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-07-06 20:50:46.885325",
|
||||
"modified": "2021-08-04 17:10:42.708479",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Batch Membership",
|
||||
|
||||
@@ -74,8 +74,11 @@ class LMSCourse(Document):
|
||||
mentors = frappe.get_all("LMS Course Mentor Mapping", {"course": self.name}, ["mentor"])
|
||||
for mentor in mentors:
|
||||
member = frappe.get_doc("User", mentor.mentor)
|
||||
# TODO: change this to count query
|
||||
member.batch_count = len(frappe.get_all("LMS Batch Membership", {"member": member.name, "member_type": "Mentor"}))
|
||||
member.batch_count = frappe.db.count("LMS Batch Membership",
|
||||
{
|
||||
"member": member.name,
|
||||
"member_type": "Mentor"
|
||||
})
|
||||
course_mentors.append(member)
|
||||
return course_mentors
|
||||
|
||||
@@ -191,7 +194,13 @@ class LMSCourse(Document):
|
||||
"""Returns the {chapter_index}.{lesson_index} for the lesson.
|
||||
"""
|
||||
lesson = frappe.db.get_value("Lessons", {"lesson": lesson_name}, ["idx", "parent"], as_dict=True)
|
||||
if not lesson:
|
||||
return None
|
||||
|
||||
chapter = frappe.db.get_value("Chapters", {"chapter": lesson.parent}, ["idx"], as_dict=True)
|
||||
if not chapter:
|
||||
return None
|
||||
|
||||
return f"{chapter.idx}.{lesson.idx}"
|
||||
|
||||
def reindex_exercises(self):
|
||||
@@ -238,21 +247,6 @@ class LMSCourse(Document):
|
||||
membership.batch_title = frappe.db.get_value("LMS Batch", membership.batch, "title")
|
||||
return all_memberships
|
||||
|
||||
def get_mentors(self, batch=None):
|
||||
filters = {
|
||||
"course": self.name,
|
||||
"member_type": "Mentor"
|
||||
}
|
||||
if batch:
|
||||
filters["batch"] = batch
|
||||
|
||||
memberships = frappe.get_all(
|
||||
"LMS Batch Membership",
|
||||
filters,
|
||||
["member"])
|
||||
member_names = [m['member'] for m in memberships]
|
||||
return find_all("User", name=["IN", member_names])
|
||||
|
||||
def get_students(self, batch=None):
|
||||
"""Returns (email, full_name, username) of all the students of this batch as a list of dict.
|
||||
"""
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
frappe.ready(function () {
|
||||
|
||||
frappe.web_form.after_load = () => {
|
||||
if (!frappe.utils.get_url_arg("name")) {
|
||||
window.location.href = `/edit-profile?name=${frappe.session.user}`;
|
||||
}
|
||||
}
|
||||
|
||||
frappe.web_form.after_save = () => {
|
||||
setTimeout(() => {
|
||||
window.location.href = `/${frappe.web_form.get_value(["username"])}`;
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"apply_document_permissions": 0,
|
||||
"breadcrumbs": "",
|
||||
"button_label": "Save",
|
||||
"client_script": "",
|
||||
"creation": "2021-06-30 13:48:13.682851",
|
||||
"custom_css": "[data-doctype=\"Web Form\"] {\n max-width: 720px;\n margin: 6rem auto;\n}",
|
||||
"doc_type": "User",
|
||||
@@ -20,7 +21,7 @@
|
||||
"is_standard": 1,
|
||||
"login_required": 1,
|
||||
"max_attachment_size": 0,
|
||||
"modified": "2021-07-14 17:15:15.424855",
|
||||
"modified": "2021-08-06 14:40:39.013776",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "profile",
|
||||
@@ -72,6 +73,18 @@
|
||||
"reqd": 0,
|
||||
"show_in_filter": 0
|
||||
},
|
||||
{
|
||||
"allow_read_on_all_link_options": 0,
|
||||
"fieldname": "username",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"label": "Username",
|
||||
"max_length": 0,
|
||||
"max_value": 0,
|
||||
"read_only": 0,
|
||||
"reqd": 0,
|
||||
"show_in_filter": 0
|
||||
},
|
||||
{
|
||||
"allow_read_on_all_link_options": 0,
|
||||
"description": "Get your globally recognized avatar from Gravatar.com",
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
{{ lesson.title }}
|
||||
|
||||
{% if membership %}
|
||||
<img class="lesson-progress-tick {{ course.get_progress(lesson.name) != 'Complete' and 'hide' }}"
|
||||
<img class="ml-1 lesson-progress-tick {{ course.get_progress(lesson.name) != 'Complete' and 'hide' }}"
|
||||
src="/assets/community/icons/check.svg">
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<div class="batch">
|
||||
<div class="batch-details">
|
||||
<div class="">Session every {{batch.sessions_on}}</div>
|
||||
<div>{{frappe.utils.format_time(batch.start_time, "short")}} -
|
||||
{{frappe.utils.format_time(batch.end_time, "short")}}
|
||||
</div>
|
||||
<div>Starting {{frappe.utils.format_date(batch.start_date, "medium")}}</div>
|
||||
<div class="course-type" style="color: #888; padding: 10px 0px;">mentors</div>
|
||||
|
||||
{% for m in course.get_mentors(batch.name) %}
|
||||
<div>
|
||||
{{ widgets.Avatar(member=m, avatar_class="avatar-medium" ) }}
|
||||
<span class="instructor-title">{{m.full_name}}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if can_manage or can_join %}
|
||||
<div class="cta">
|
||||
<div class="">
|
||||
{% if can_manage %}
|
||||
<a href="/courses/{{ course.name }}/home?batch={{ batch.name }}" class="btn btn-primary manage-batch" data-batch="{{ batch.name | urlencode }}"
|
||||
data-course="{{ course.name | urlencode }}">Manage</a>
|
||||
{% elif can_join %}
|
||||
<button class="join-batch btn btn-secondary" data-batch="{{ batch.name | urlencode }}"
|
||||
data-course="{{ course.name | urlencode }}">Join this Batch</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -18,9 +18,11 @@
|
||||
<div class="review-card-footer">
|
||||
<div>
|
||||
{{ widgets.Avatar(member=review.owner_details, avatar_class="avatar-medium") }}
|
||||
<span class="course-instructor">
|
||||
{{ review.owner_details.full_name }}
|
||||
</span>
|
||||
<a class="button-links" href="/{{review.owner_details.username}}">
|
||||
<span class="course-instructor">
|
||||
{{ review.owner_details.full_name }}
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="rating">
|
||||
{% for i in [1, 2, 3, 4, 5] %}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<div class="sketch-teaser">
|
||||
<div class="sketch-image">
|
||||
<a href="/sketches/{{sketch.sketch_id}}">
|
||||
{{ sketch.to_svg() }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="sketch-footer">
|
||||
<div class="sketch-title">
|
||||
<a href="sketches/{{sketch.sketch_id}}">{{sketch.title}}</a>
|
||||
</div>
|
||||
<div class="sketch-author">
|
||||
{% set owner = sketch.get_owner() %}
|
||||
by <a href="/{{owner.username}}">{{owner.full_name}}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
54
community/overrides/test_user.py
Normal file
54
community/overrides/test_user.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# Copyright (c) 2021, FOSS United and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
import unittest
|
||||
import frappe
|
||||
|
||||
class TestCustomUser(unittest.TestCase):
|
||||
|
||||
def test_with_basic_username(self):
|
||||
new_user = frappe.get_doc({
|
||||
"doctype": "User",
|
||||
"email": "test_with_basic_username@example.com",
|
||||
"first_name": "Username"
|
||||
}).insert()
|
||||
self.assertEqual(new_user.username, "username")
|
||||
|
||||
def test_without_username(self):
|
||||
""" The user in this test has the same first name as the user of the test test_with_basic_username.
|
||||
In such cases frappe makes the username of the second user empty.
|
||||
The condition in community app should override this and save a username. """
|
||||
new_user = frappe.get_doc({
|
||||
"doctype": "User",
|
||||
"email": "test-without-username@example.com",
|
||||
"first_name": "Username"
|
||||
}).insert()
|
||||
self.assertTrue(new_user.username)
|
||||
|
||||
def test_with_illegal_characters(self):
|
||||
new_user = frappe.get_doc({
|
||||
"doctype": "User",
|
||||
"email": "test_with_illegal_characters@example.com",
|
||||
"first_name": "Username$$"
|
||||
}).insert()
|
||||
self.assertEqual(new_user.username[:8], "username")
|
||||
|
||||
def test_with_hyphen_at_end(self):
|
||||
new_user = frappe.get_doc({
|
||||
"doctype": "User",
|
||||
"email": "test_with_hyphen_at_end@example.com",
|
||||
"first_name": "Username---"
|
||||
}).insert()
|
||||
length = len(new_user.username)
|
||||
self.assertNotEqual(new_user.username[length-1], "-")
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls) -> None:
|
||||
users = [
|
||||
"test_with_basic_username@example.com",
|
||||
"test-without-username@example.com",
|
||||
"test_with_illegal_characters@example.com",
|
||||
"test_with_hyphen_at_end@example.com"
|
||||
]
|
||||
frappe.db.delete("User", {"name": ["in", users]})
|
||||
@@ -2,9 +2,50 @@ import frappe
|
||||
from frappe.core.doctype.user.user import User
|
||||
from frappe.utils import cint
|
||||
import hashlib
|
||||
import random
|
||||
import re
|
||||
from frappe import _
|
||||
|
||||
class CustomUser(User):
|
||||
|
||||
def validate(self):
|
||||
super(CustomUser, self).validate()
|
||||
self.validate_username_characters()
|
||||
|
||||
def validate_username_characters(self):
|
||||
if self.is_new():
|
||||
|
||||
if self.username.find(" "):
|
||||
self.username.replace(" ", "")
|
||||
|
||||
if not re.match("^[A-Za-z0-9_]*$", self.username):
|
||||
self.username = self.remove_illegal_characters()
|
||||
|
||||
if not self.username:
|
||||
self.username = self.get_username_from_first_name()
|
||||
|
||||
if self.username_exists():
|
||||
self.username = self.remove_illegal_characters() + str(random.randint(0, 99))
|
||||
|
||||
else:
|
||||
if not re.match("^[A-Za-z0-9_-]*$", self.username):
|
||||
frappe.throw(_("Username can only contain alphabets, numbers, hyphen and underscore."))
|
||||
|
||||
if self.username[0] == "-" or self.username[len(self.username) - 1] == "-":
|
||||
frappe.throw(_("First and Last character of username cannot be Hyphen(-)."))
|
||||
|
||||
def get_username_from_first_name(self):
|
||||
return frappe.scrub(self.first_name) + str(random.randint(0, 99))
|
||||
|
||||
def remove_illegal_characters(self):
|
||||
username = ''.join([c for c in self.username if c.isalnum() or c in ['-', '_']])
|
||||
while username[0] == "-" or username[len(username) - 1] == "-":
|
||||
if username[0] == "-":
|
||||
username = username[1:]
|
||||
if username[len(username) - 1]:
|
||||
username = username[:1]
|
||||
return username
|
||||
|
||||
def get_authored_courses(self) -> int:
|
||||
"""Returns the number of courses authored by this user.
|
||||
"""
|
||||
|
||||
@@ -780,7 +780,7 @@ input[type=checkbox] {
|
||||
}
|
||||
|
||||
.lesson-links {
|
||||
display: flex;
|
||||
display: block;
|
||||
padding: 0 1rem;
|
||||
margin-bottom: .25rem;
|
||||
color: inherit;
|
||||
@@ -794,6 +794,13 @@ input[type=checkbox] {
|
||||
border-radius: .25rem;
|
||||
}
|
||||
|
||||
.course-content-parent .lesson-links {
|
||||
padding: 0 0 0 1rem;
|
||||
margin-bottom: 0.75rem;
|
||||
font-size: 0.85rem;
|
||||
line-height: 200%;
|
||||
}
|
||||
|
||||
.chapter-content {
|
||||
margin: 0;
|
||||
margin-left: .875rem;
|
||||
@@ -1214,7 +1221,19 @@ input[type=checkbox] {
|
||||
left: 174px;
|
||||
font-size: 12px;
|
||||
line-height: 165%;
|
||||
width: fit-content;
|
||||
width: 85%;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.profile-profession {
|
||||
width: 75%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.profile-profession {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
@@ -1228,6 +1247,7 @@ input[type=checkbox] {
|
||||
.profile-profession {
|
||||
top: 5px;
|
||||
left: 70px;
|
||||
width: 75%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
3
community/public/icons/like.svg
Normal file
3
community/public/icons/like.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13.0746 3.60967C12.7814 3.31071 12.4333 3.07355 12.0501 2.91174C11.6669 2.74994 11.2562 2.66666 10.8415 2.66666C10.4267 2.66666 10.016 2.74994 9.63283 2.91174C9.24966 3.07355 8.90152 3.31071 8.60831 3.60967L7.99979 4.22983L7.39126 3.60967C6.79899 3.00607 5.9957 2.66697 5.1581 2.66697C4.32051 2.66697 3.51721 3.00607 2.92494 3.60967C2.33267 4.21327 1.99994 5.03192 1.99994 5.88554C1.99994 6.73916 2.33267 7.55782 2.92494 8.16142L3.53347 8.78158L7.99979 13.3333L12.4661 8.78158L13.0746 8.16142C13.368 7.86259 13.6007 7.5078 13.7595 7.11729C13.9182 6.72679 13.9999 6.30824 13.9999 5.88554C13.9999 5.46284 13.9182 5.04429 13.7595 4.65379C13.6007 4.26329 13.368 3.90849 13.0746 3.60967V3.60967Z" stroke="#4C5A67" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 871 B |
@@ -7,8 +7,8 @@
|
||||
<div class="questions">
|
||||
{% for question in quiz.questions %}
|
||||
<div class="question {% if loop.index == 1 %} active-question {% else %} hide {% endif %}"
|
||||
data-question="{{ question.question }}"data-multi="{{ question.multiple}}" data-qt-index="{{ loop.index }}">
|
||||
<p>{{ question.question }}</p>
|
||||
data-question="{{ question.question }}" data-multi="{{ question.multiple}}" data-qt-index="{{ loop.index }}">
|
||||
<p>{{ frappe.utils.md_to_html(question.question) }}</p>
|
||||
|
||||
{% if question.multiple %}
|
||||
<small class="font-weight-bold">Choose all answers that apply:</small>
|
||||
|
||||
@@ -58,6 +58,7 @@ var mark_active_question = (e = undefined) => {
|
||||
$(".current-question").text(`${next_index}`);
|
||||
$("#check").removeClass("hide").attr("disabled", true);
|
||||
$("#next").addClass("hide");
|
||||
$(".explanation").addClass("hide");
|
||||
}
|
||||
|
||||
var mark_progress = (e) => {
|
||||
|
||||
@@ -17,10 +17,9 @@ def get_context(context):
|
||||
index_ = get_lesson_index(context.course, context.batch, frappe.session.user) or "1.1"
|
||||
else:
|
||||
index_ = "1.1"
|
||||
frappe.local.flags.redirect_location = context.course.get_learn_url(index_) + context.course.query_parameter
|
||||
raise frappe.Redirect
|
||||
utils.redirect_to_lesson(context.course, index_)
|
||||
|
||||
context.lesson = list(filter(lambda x: cstr(x.number) == lesson_number, context.lessons))[0]
|
||||
context.lesson = get_current_lesson_details(lesson_number, context)
|
||||
neighbours = context.course.get_neighbours(lesson_number, context.lessons)
|
||||
context.next_url = get_learn_url(neighbours["next"], context.course)
|
||||
context.prev_url = get_learn_url(neighbours["prev"], context.course)
|
||||
@@ -40,6 +39,12 @@ def get_context(context):
|
||||
"is_member": context.membership is not None
|
||||
}
|
||||
|
||||
def get_current_lesson_details(lesson_number, context):
|
||||
details_list = list(filter(lambda x: cstr(x.number) == lesson_number, context.lessons))
|
||||
if not len(details_list):
|
||||
utils.redirect_to_lesson(context.course)
|
||||
return details_list[0]
|
||||
|
||||
def get_learn_url(lesson_number, course):
|
||||
return course.get_learn_url(lesson_number) and course.get_learn_url(lesson_number) + course.query_parameter
|
||||
|
||||
|
||||
@@ -24,9 +24,6 @@ def get_common_context(context):
|
||||
if batch:
|
||||
context.batch = batch
|
||||
|
||||
context.members = course.get_mentors(membership.batch) + course.get_students(membership.batch)
|
||||
context.member_count = len(context.members)
|
||||
|
||||
context.course.query_parameter = "?batch=" + membership.batch if membership and membership.batch else ""
|
||||
context.livecode_url = get_livecode_url()
|
||||
|
||||
|
||||
@@ -102,24 +102,33 @@
|
||||
</div>
|
||||
{{ widgets.MemberCard(member=course.get_instructor(), show_course_count=True, dimension_class="member-card-large") }}
|
||||
</div>
|
||||
{% if course.get_course_progress() %}
|
||||
{% set progress = course.get_course_progress() %}
|
||||
{% if progress %}
|
||||
<div class="course-progress-section">
|
||||
<div class="course-home-headings">
|
||||
Your Progress
|
||||
</div>
|
||||
<div class="common-card-style progress-card">
|
||||
<p class="small-title">
|
||||
{% if progress != 100 %}
|
||||
Great work so far!
|
||||
{% else %}
|
||||
Excellent Work on completing this course 👏
|
||||
{% endif %}
|
||||
</p>
|
||||
<p class="progress-text">
|
||||
{% if progress != 100 %}
|
||||
Challenge yourself to complete the lessons and grow professionally.
|
||||
{% else %}
|
||||
You have reached a new level in your journey to success!
|
||||
{% endif %}
|
||||
</p>
|
||||
<div class="progress-percentage">
|
||||
{{ frappe.utils.rounded(course.get_course_progress()) }}%
|
||||
{{ frappe.utils.rounded(progress) }}%
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" style="width: {{ course.get_course_progress() }}%"
|
||||
aria-valuenow="{{ course.get_course_progress() }}" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
<div class="progress-bar" role="progressbar" style="width: {{ progress }}%"
|
||||
aria-valuenow="{{ progress }}" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -187,55 +196,3 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro BatchSection(course) %}
|
||||
<div class="row">
|
||||
<div class="col-lg-8 col-md-12">
|
||||
{% if course.is_mentor(frappe.session.user) %}
|
||||
{{ BatchSectionForMentors(course, course.get_batches(mentor=frappe.session.user)) }}
|
||||
{% else %}
|
||||
{{ BatchSectionForStudents(course, course.get_upcoming_batches()) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
{% macro BatchSectionForMentors(course, mentor_batches) %}
|
||||
<h2>Your Batches</h2>
|
||||
|
||||
{% if mentor_batches %}
|
||||
|
||||
<div class="row">
|
||||
{% for batch in mentor_batches %}
|
||||
<div class="col-lg-4 col-md-6">
|
||||
{{ widgets.RenderBatch(course=course, batch=batch, can_manage=True) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<a class="add-batch margin-bottom" href="/add-a-new-batch?new=1&course={{course.name}}">Add a new batch</a>
|
||||
{% else %}
|
||||
<div class="mentor_message">
|
||||
<p>
|
||||
You are a mentor for this course.
|
||||
</p>
|
||||
<a class="" href="/add-a-new-batch?new=1&course={{course.name}}">Create your first batch</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro BatchSectionForStudents(course, upcoming_batches) %}
|
||||
{% if upcoming_batches %}
|
||||
<div class="mt-5">
|
||||
<h3 class="upcoming">Upcoming Batches</h3>
|
||||
<div class="row">
|
||||
{% for batch in upcoming_batches %}
|
||||
<div class="col-lg-4 col-md-6">
|
||||
{{ widgets.RenderBatch(course=course, batch=batch, can_join=True) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="mt-5 upcoming">There are no Upcoming Batches for this course currently.</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
@@ -35,21 +35,24 @@
|
||||
{% endif %}
|
||||
<span class="social-icons">
|
||||
{% if member.linkedin %}
|
||||
<a class="linkedin" href="{{ member.linkedin }}">
|
||||
<a class="linkedin button-links" href="{{ member.linkedin }}">
|
||||
<img src="/assets/community/images/linkedin.png">
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if member.medium %}
|
||||
<a class="medium" href="{{ member.medium}}">
|
||||
<a class="medium button-links" href="{{ member.medium}}">
|
||||
<img src="/assets/community/icons/medium.svg">
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if member.github %}
|
||||
<a class="github" href="{{ member.github }}">
|
||||
<a class="github button-links" href="{{ member.github }}">
|
||||
<img src="/assets/community/icons/github.svg">
|
||||
</a>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% if frappe.session.user == member.email %}
|
||||
<a class="dark-links pull-right" href="edit-profile?name={{ member.email }}">Edit Profile</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user