This commit is contained in:
pateljannat
2021-06-10 13:41:11 +05:30
parent d90a1247f1
commit 1e3152e303
22 changed files with 120 additions and 105 deletions

View File

@@ -136,15 +136,15 @@ primary_rules = [
{"from_route": "/hackathons/<hackathon>/<project>", "to_route": "hackathons/project"}, {"from_route": "/hackathons/<hackathon>/<project>", "to_route": "hackathons/project"},
{"from_route": "/dashboard", "to_route": ""}, {"from_route": "/dashboard", "to_route": ""},
{"from_route": "/add-a-new-batch", "to_route": "add-a-new-batch"}, {"from_route": "/add-a-new-batch", "to_route": "add-a-new-batch"},
{"from_route": "/courses/<course>/<batch>/home", "to_route": "batch/home"}, {"from_route": "/courses/<course>/home", "to_route": "batch/home"},
{"from_route": "/courses/<course>/<batch>/learn", "to_route": "batch/learn"}, {"from_route": "/courses/<course>/learn", "to_route": "batch/learn"},
{"from_route": "/courses/<course>/<batch>/learn/<int:chapter>.<int:lesson>", "to_route": "batch/learn"}, {"from_route": "/courses/<course>/learn/<int:chapter>.<int:lesson>", "to_route": "batch/learn"},
{"from_route": "/courses/<course>/<batch>/schedule", "to_route": "batch/schedule"}, {"from_route": "/courses/<course>/schedule", "to_route": "batch/schedule"},
{"from_route": "/courses/<course>/<batch>/members", "to_route": "batch/members"}, {"from_route": "/courses/<course>/members", "to_route": "batch/members"},
{"from_route": "/courses/<course>/<batch>/discuss", "to_route": "batch/discuss"}, {"from_route": "/courses/<course>/discuss", "to_route": "batch/discuss"},
{"from_route": "/courses/<course>/<batch>/about", "to_route": "batch/about"}, {"from_route": "/courses/<course>/about", "to_route": "batch/about"},
{"from_route": "/courses/<course>/<batch>/progress", "to_route": "batch/progress"}, {"from_route": "/courses/<course>/progress", "to_route": "batch/progress"},
{"from_route": "/courses/<course>/<batch>/join", "to_route": "batch/join"} {"from_route": "/courses/<course>/join", "to_route": "batch/join"}
] ]
# Any frappe default URL is blocked by profile-rules, add it here to unblock it # Any frappe default URL is blocked by profile-rules, add it here to unblock it

View File

@@ -12,4 +12,5 @@ class Chapter(Document):
filters={"chapter": self.name}, filters={"chapter": self.name},
fields='name', fields='name',
order_by="index_") order_by="index_")
print("rows", rows)
return [frappe.get_doc('Lesson', row['name']) for row in rows] return [frappe.get_doc('Lesson', row['name']) for row in rows]

View File

@@ -12,7 +12,8 @@
"index_", "index_",
"index_label", "index_label",
"body", "body",
"sections" "sections",
"include_in_preview"
], ],
"fields": [ "fields": [
{ {
@@ -59,11 +60,17 @@
"in_list_view": 1, "in_list_view": 1,
"label": "Index Label", "label": "Index Label",
"read_only": 1 "read_only": 1
},
{
"default": "0",
"fieldname": "include_in_preview",
"fieldtype": "Check",
"label": "Include In Preview"
} }
], ],
"index_web_pages_for_search": 1, "index_web_pages_for_search": 1,
"links": [], "links": [],
"modified": "2021-06-01 05:30:48.127494", "modified": "2021-06-10 10:06:39.176891",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "LMS", "module": "LMS",
"name": "Lesson", "name": "Lesson",

View File

@@ -83,7 +83,7 @@ class LMSBatch(Document):
def get_learn_url(self, lesson_number): def get_learn_url(self, lesson_number):
if not lesson_number: if not lesson_number:
return return
return f"/courses/{self.course}/{self.name}/learn/{lesson_number}" return f"/courses/{self.course}/learn/{lesson_number}"
@frappe.whitelist() @frappe.whitelist()
def save_message(message, batch): def save_message(message, batch):

View File

@@ -43,6 +43,9 @@ class LMSBatchMembership(Document):
member_name = frappe.db.get_value("User", self.member, "full_name") member_name = frappe.db.get_value("User", self.member, "full_name")
frappe.throw(_("{0} is already a {1} of {2} course through {3} batch").format(member_name, membership.member_type, course, membership.batch)) frappe.throw(_("{0} is already a {1} of {2} course through {3} batch").format(member_name, membership.member_type, course, membership.batch))
def get_user_batch(course, user=frappe.session.user):
return frappe.db.get_value("LMS Batch Membership", {"member": user, "course": course}, "batch")
@frappe.whitelist() @frappe.whitelist()
def create_membership(batch, member=None, member_type="Student", role="Member"): def create_membership(batch, member=None, member_type="Student", role="Member"):
frappe.get_doc({ frappe.get_doc({

View File

@@ -8,6 +8,7 @@ from frappe.model.document import Document
import json import json
from ...utils import slugify from ...utils import slugify
from community.query import find, find_all from community.query import find, find_all
from frappe.utils import flt
class LMSCourse(Document): class LMSCourse(Document):
@staticmethod @staticmethod
@@ -112,7 +113,7 @@ class LMSCourse(Document):
"""Returns all chapters of this course. """Returns all chapters of this course.
""" """
# TODO: chapters should have a way to specify the order # TODO: chapters should have a way to specify the order
return find_all("Chapter", course=self.name, order_by="creation") return find_all("Chapter", course=self.name, order_by="index_")
def get_batch(self, batch_name): def get_batch(self, batch_name):
return find("LMS Batch", name=batch_name, course=self.name) return find("LMS Batch", name=batch_name, course=self.name)
@@ -197,6 +198,7 @@ class CourseOutline:
self.lessons = self.get_lessons() self.lessons = self.get_lessons()
def get_next(self, current): def get_next(self, current):
current = flt(current)
numbers = sorted(lesson['number'] for lesson in self.lessons) numbers = sorted(lesson['number'] for lesson in self.lessons)
try: try:
index = numbers.index(current) index = numbers.index(current)
@@ -205,6 +207,7 @@ class CourseOutline:
return None return None
def get_prev(self, current): def get_prev(self, current):
current = flt(current)
numbers = sorted(lesson['number'] for lesson in self.lessons) numbers = sorted(lesson['number'] for lesson in self.lessons)
try: try:
index = numbers.index(current) index = numbers.index(current)
@@ -228,7 +231,7 @@ class CourseOutline:
chapter_numbers = {c['name']: c['index_'] for c in self.chapters} chapter_numbers = {c['name']: c['index_'] for c in self.chapters}
for lesson in lessons: for lesson in lessons:
lesson['number'] = "{}.{}".format(chapter_numbers[lesson['chapter']], lesson['index_']) lesson['number'] = flt("{}.{}".format(chapter_numbers[lesson['chapter']], lesson['index_']))
return lessons return lessons
@frappe.whitelist() @frappe.whitelist()

View File

@@ -2,4 +2,4 @@
""" """
from .doctype.lms_course.lms_course import LMSCourse as Course from .doctype.lms_course.lms_course import LMSCourse as Course
from .doctype.lms_sketch.lms_sketch import LMSSketch as Sketch from .doctype.lms_sketch.lms_sketch import LMSSketch as Sketch
from .doctype.lms_batch_membership.lms_batch_membership import LMSBatchMembership as Membership

View File

@@ -1,28 +1,30 @@
<div class="mt-5"> <div class="mt-5">
<a class="anchor_style" href="/courses">Courses</a> /{% if course.is_mentor(frappe.session.user) %} <a class="anchor_style" href="/courses/{{ course.name }}"> {{ course.title }}</a> {% else %} <span class="text-muted"> {{ course.title }}</span> {% endif %} <a class="anchor_style" href="/courses">Courses</a> /{% if course.is_mentor(frappe.session.user) %} <a
class="anchor_style" href="/courses/{{ course.name }}"> {{ course.title }}</a> {% else %} <span class="text-muted">
{{ course.title }}</span> {% endif %}
</div> </div>
<ul class="nav nav-tabs mt-4"> <ul class="nav nav-tabs mt-4">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="home" href="/courses/{{course.name}}/{{batch.name}}/home">Home</a> <a class="nav-link" id="home" href="/courses/{{course.name}}/home">Home</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="learn" href="/courses/{{course.name}}/{{batch.name}}/learn">Learn</a> <a class="nav-link" id="learn" href="/courses/{{course.name}}/learn">Lessons</a>
</li> </li>
<!-- <li class="nav-item"> <!-- <li class="nav-item">
<a class="nav-link" id="schedule" href="/courses/{{course.name}}/{{batch.name}}/schedule">Schedule</a> <a class="nav-link" id="schedule" href="/courses/{{course.name}}/schedule">Schedule</a>
</li> --> </li> -->
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="members" href="/courses/{{course.name}}/{{batch.name}}/members">Members</a> <a class="nav-link" id="members" href="/courses/{{course.name}}/members">Members</a>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="discussion" href="/courses/{{course.name}}/{{batch.name}}/discuss">Discussion</a> <a class="nav-link" id="discussion" href="/courses/{{course.name}}/discuss">Discussion</a>
</li> </li>
<!-- <li class="nav-item"> <!-- <li class="nav-item">
<a class="nav-link" id="about" href="/courses/{{course.name}}/{{batch.name}}/about">About</a> <a class="nav-link" id="about" href="/courses/{{course.name}}/about">About</a>
</li> --> </li> -->
{% if batch.is_member(frappe.session.user, member_type="Mentor") %} {% if batch.is_member(frappe.session.user, member_type="Mentor") %}
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" id="progress" href="/courses/{{course.name}}/{{batch.name}}/progress">Progress</a> <a class="nav-link" id="progress" href="/courses/{{course.name}}/progress">Progress</a>
</li> </li>
{% endif %} {% endif %}
</ul> </ul>

View File

@@ -1,15 +1,15 @@
<div class="chapter-teaser"> <div class="chapter-teaser">
<div class="teaser-body"> <div class="teaser-body">
<h3 class="chapter-title"><span class="mr-1">{{index}}.</span> {{ chapter.title }}</h3> <div class="chapter-title mb-5 font-weight-bold"><span class="mr-1">{{index}}.</span> {{ chapter.title }}</div>
<div class="chapter-description"> <div class="chapter-description">
{{ chapter.description or "" }} {{ chapter.description or "" }}
</div> </div>
<div class="chapter-lessons"> <div class="chapter-lessons">
{% for lesson in chapter.get_lessons() %} {% for lesson in chapter.get_lessons() %}
<div class="lesson-teaser"> <div class="lesson-teaser">
<a {% if show_link %} class="anchor_style" href="{{ batch.get_learn_url(course.get_lesson_index(lesson.name)) }}" {% endif %}>{{ lesson.title }}</a> <a {% if show_link %} href="{{ batch.get_learn_url(course.get_lesson_index(lesson.name)) }}" {% endif %}>{{ lesson.title }}</a>
{% if show_progress and not course.is_mentor(frappe.session.user) and lesson.get_progress() %} {% if show_progress and not course.is_mentor(frappe.session.user) and lesson.get_progress() %}
<a class="pull-right badge p-1 {{ lesson.get_slugified_class() }}"> <img class="progress-image" src="/assets/community/images/Vector.png"> {{ lesson.get_progress() }}</a> <a class="ml-5 badge p-1 {{ lesson.get_slugified_class() }}"> <img class="progress-image" src="/assets/community/images/Vector.png"> {{ lesson.get_progress() }}</a>
{% endif %} {% endif %}
</div> </div>
{% endfor %} {% endfor %}

View File

@@ -1,5 +1,7 @@
<h2>Course Outline</h2> <div class="mt-5">
<h3> Course Outline </h3>
{% for chapter in course.get_chapters() %} {% for chapter in course.get_chapters() %}
{{ widgets.ChapterTeaser(index=loop.index, chapter=chapter, course=course, batch=batch, show_link=show_link, show_progress=show_progress)}} {{ widgets.ChapterTeaser(index=loop.index, chapter=chapter, course=course, batch=batch, show_link=show_link, show_progress=show_progress)}}
{% endfor %} {% endfor %}
</div>

View File

@@ -1,5 +1,6 @@
<h3>Instructor</h3>
<div class="instructor"> <div class="instructor">
<div class="instructor-title">{{instructor.full_name}}</div> {{ widgets.Avatar(member=instructor, avatar_class="avatar-medium") }}
<div class="instructor-subtitle">Created {{instructor.get_course_count()}} courses</div> <a class="ml-1 instructor-title" href="/{{instructor.username}}">{{ instructor.full_name }}</a>
<div class="instructor-subtitle">Course Creator</div>
<!-- <div class="instructor-subtitle">Created {{instructor.get_course_count()}} courses</div> -->
</div> </div>

View File

@@ -82,6 +82,7 @@ body {
border-radius: 10px; border-radius: 10px;
margin: 10px 0px; margin: 10px 0px;
background: white; background: white;
box-shadow: 0px 5px 10px rgb(0 0 0 / 10%);
border: 1px solid #ddc; border: 1px solid #ddc;
} }

View File

@@ -10,6 +10,7 @@ h2 {
.teaser-body { .teaser-body {
padding: 20px; padding: 20px;
box-shadow: 0px 5px 10px rgb(0 0 0 / 10%)
} }
.teaser-footer { .teaser-footer {
padding: 20px; padding: 20px;
@@ -162,7 +163,6 @@ section.lightgray {
// } // }
.instructor-title { .instructor-title {
font-weight: bold;
color: black; color: black;
} }

View File

@@ -11,26 +11,28 @@
{% set invite_link = frappe.utils.get_url() + "/courses/" + course.name + "/" + batch.name + "/join" %} {% set invite_link = frappe.utils.get_url() + "/courses/" + course.name + "/" + batch.name + "/join" %}
<div class="container mt-5"> <div class="container mt-5">
{{ widgets.BatchTabs(course=course, batch=batch) }} {{ widgets.BatchTabs(course=course, batch=batch) }}
<div> <!-- <div>
<h1 class="mt-5">{{ batch.title }}</h1> <h1 class="mt-5">{{ batch.title }}</h1>
</div> </div> -->
<div class="course-details"> <div class="course-details mt-5">
{{ widgets.CourseOutline(course=course, batch=batch, show_link=True, show_progress=True) }} {{ widgets.CourseOutline(course=course, batch=batch, show_link=True, show_progress=True) }}
</div> </div>
<div class="w-25"> <div class="w-25">
<h2>Batch Schedule</h2> <h3>Batch Schedule</h3>
{{ widgets.RenderBatch(course=course, batch=batch) }} {{ widgets.RenderBatch(course=course, batch=batch) }}
</div> </div>
{% if batch.description %} {% if batch.description %}
<h2>Batch Details</h2> <div class="mt-5">
<h3>Batch Details</h3>
{{ frappe.utils.md_to_html(batch.description) }} {{ frappe.utils.md_to_html(batch.description) }}
</div>
{% endif %} {% endif %}
{% if course.is_mentor(frappe.session.user) %} {% if course.is_mentor(frappe.session.user) %}
<div class=""> <div class="">
<h2> Invite Members </h2> <h3> Invite Members </h3>
<a href="" class="anchor_style mr-5" id="invite-link" data-link="{{ invite_link }}">Get Batch Invitation <a href="" class="" id="invite-link" data-link="{{ invite_link }}">Get Batch Invitation
Link</a> Link</a>
<small id="copy-message" class="text-muted pull-right" style="display: none;">Copied to Clipboard.</small> <small id="copy-message" class="text-muted pull-right" style="display: none;">Copied to Clipboard.</small>
</div> </div>

View File

@@ -1,6 +1,7 @@
from re import I from re import I
import frappe import frappe
from . import utils from . import utils
from frappe.utils import cstr
def get_context(context): def get_context(context):
utils.get_common_context(context) utils.get_common_context(context)
@@ -10,9 +11,10 @@ def get_context(context):
lesson_number = f"{chapter_index}.{lesson_index}" lesson_number = f"{chapter_index}.{lesson_index}"
course_name = context.course.name course_name = context.course.name
print(chapter_index, lesson_index)
if not chapter_index or not lesson_index: if not chapter_index or not lesson_index:
index_ = get_lesson_index(context.course, context.batch, frappe.session.user) or "1.1" index_ = get_lesson_index(context.course, context.batch, frappe.session.user) or "1.1"
print(index_)
frappe.local.flags.redirect_location = context.batch.get_learn_url(index_) frappe.local.flags.redirect_location = context.batch.get_learn_url(index_)
raise frappe.Redirect raise frappe.Redirect
@@ -33,8 +35,9 @@ def get_context(context):
def get_chapter_title(course_name, lesson_number): def get_chapter_title(course_name, lesson_number):
if not lesson_number: if not lesson_number:
return return
chapter_index = lesson_number.split(".")[0] lesson_split = cstr(lesson_number).split(".")
lesson_index = lesson_number.split(".")[1] chapter_index = lesson_split[0]
lesson_index = lesson_split[1]
chapter_name = frappe.db.get_value("Chapter", {"course": course_name, "index_": chapter_index}, "name") chapter_name = frappe.db.get_value("Chapter", {"course": course_name, "index_": chapter_index}, "name")
return frappe.db.get_value("Lesson", {"chapter": chapter_name, "index_": lesson_index}, "title") return frappe.db.get_value("Lesson", {"chapter": chapter_name, "index_": lesson_index}, "title")

View File

@@ -19,23 +19,19 @@
{% macro MembersList(members) %} {% macro MembersList(members) %}
<div class="mt-5"> <div class="mt-5">
{% for member in members %} {% for member in members %}
<div class="row mb-5"> <div class="d-flex align-items-center">
<div>
{{ widgets.Avatar(member=member, avatar_class="avatar-large") }} {{ widgets.Avatar(member=member, avatar_class="avatar-large") }}
</div> <div class="d-flex flex-column ml-2">
<div class="col"> <div class="d-flex">
<div class="row ml-1"> <a class="anchor_style ml-2" href="/{{member.username}}">
<a class="anchor_style" href="/{{member.username}}">
<h3>{{ member.full_name }}</h3> <h3>{{ member.full_name }}</h3>
</a> </a>
{% if course.is_mentor(member.name) %} {% if course.is_mentor(member.name) %}
<div class="ml-2"> <div class="badge badge-success ml-2 align-self-start">Mentor</div>
<div class="badge badge-success">Mentor</div>
</div>
{% endif %} {% endif %}
</div> </div>
{% if member.bio %} {% if member.bio %}
<i>{{member.bio}}</i> <i class="ml-2">{{member.bio}}</i>
{% endif %} {% endif %}
</div> </div>
</div> </div>

View File

@@ -26,7 +26,7 @@
<div class="container"> <div class="container">
{{ widgets.BatchTabs(course=course, batch=batch) }} {{ widgets.BatchTabs(course=course, batch=batch) }}
<div class="mentor-dashboard"> <div class="mentor-dashboard">
<h1>Batch Progress</h1> <h3>Batch Progress</h3>
{% for exercise in report.exercises %} {% for exercise in report.exercises %}
<div class="exercise-submissions"> <div class="exercise-submissions">
<h2>Exercise {{exercise.index_label}}: {{exercise.title}}</h2> <h2>Exercise {{exercise.index_label}}: {{exercise.title}}</h2>

View File

@@ -14,12 +14,13 @@ def get_context(context):
context.exercise = exercise context.exercise = exercise
context.report = BatchReport(context.course, context.batch) context.report = BatchReport(context.course, context.batch)
print(context.report)
class BatchReport: class BatchReport:
def __init__(self, course, batch): def __init__(self, course, batch):
self.submissions = get_submissions(batch) self.submissions = get_submissions(batch)
self.exercises = self.get_exercises(course.name) self.exercises = self.get_exercises(course.name)
print(self.submissions)
self.submissions_by_exercise = defaultdict(list) self.submissions_by_exercise = defaultdict(list)
for s in self.submissions: for s in self.submissions:
self.submissions_by_exercise[s.exercise].append(s) self.submissions_by_exercise[s.exercise].append(s)
@@ -34,7 +35,7 @@ def get_submissions(batch):
students = batch.get_students() students = batch.get_students()
students_map = {s.email: s for s in students} students_map = {s.email: s for s in students}
names, values = nparams("s", students_map.keys()) names, values = nparams("s", students_map.keys())
print(students, names, values)
sql = """ sql = """
select owner, exercise, name, solution, creation, image select owner, exercise, name, solution, creation, image
from ( from (
@@ -45,7 +46,7 @@ def get_submissions(batch):
""".format(names) """.format(names)
data = frappe.db.sql(sql, values=values, as_dict=True) data = frappe.db.sql(sql, values=values, as_dict=True)
print(data)
for row in data: for row in data:
row['owner'] = students_map[row['owner']] row['owner'] = students_map[row['owner']]
return data return data

View File

@@ -1,21 +1,20 @@
import frappe import frappe
from community.lms.models import Course from community.lms.models import Course, Membership
def get_common_context(context): def get_common_context(context):
context.no_cache = 1 context.no_cache = 1
course_name = frappe.form_dict["course"] course_name = frappe.form_dict["course"]
batch_name = frappe.form_dict["batch"]
course = Course.find(course_name) course = Course.find(course_name)
if not course: if not course:
context.template = "www/404.html" context.template = "www/404.html"
return return
batch_name = Membership.get_user_batch(course_name)
batch = course.get_batch(batch_name) batch = course.get_batch(batch_name)
if not batch or not batch.is_member(frappe.session.user): """ if not batch or not batch.is_member(frappe.session.user):
frappe.local.flags.redirect_location = "/courses/" + course_name frappe.local.flags.redirect_location = "/courses/" + course_name
raise frappe.Redirect raise frappe.Redirect """
context.course = course context.course = course
context.batch = batch context.batch = batch

View File

@@ -12,28 +12,20 @@
<div class="mb-5"> <div class="mb-5">
<a class="anchor_style" href="/courses">Courses</a> / <span class="text-muted">{{ course.title }}</span> <a class="anchor_style" href="/courses">Courses</a> / <span class="text-muted">{{ course.title }}</span>
</div> </div>
<h1 id="course-title" data-course="{{course.name}}">{{course.title}}</h1> <h2 id="course-title" data-course="{{course.name}}">{{course.title}}</h2>
<div class="course-short-intro">{{ course.short_introduction }}</div> <div class="course-short-intro">{{ course.short_introduction }}</div>
</div> </div>
<div class="row"> <div class="">
<div class="col-lg-8 col-md-12"> <div class="">
<div class="course-details"> <div class="course-details">
{{ CourseVideo(course) }} {{ CourseVideo(course) }}
{{ CourseDescription(course) }} {{ CourseDescription(course) }}
{{ widgets.InstructorSection(instructor=course.get_instructor()) }}
{{ BatchSection(course) }} {{ BatchSection(course) }}
{{ widgets.CourseOutline(course=course, show_link=False) }} {{ widgets.CourseOutline(course=course, show_link=False) }}
</div> </div>
</div> </div>
<div class="col-lg-4 col-md-12">
<div class="sidebar">
{{ widgets.InstructorSection(instructor=course.get_instructor()) }}
</div>
<div class="sidebar">
{{ MentorsSection(course.get_mentors(), course.is_mentor(frappe.session.user), course.name) }}
</div>
</div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
@@ -49,28 +41,31 @@
{% endmacro %} {% endmacro %}
{% macro CourseDescription(course) %} {% macro CourseDescription(course) %}
<h2>Course Description</h2> <div class="mt-5">
<h3>Course Description</h3>
<div class="course-description"> <div class="course-description text-justify">
{{ frappe.utils.md_to_html(course.description) }} {{ frappe.utils.md_to_html(course.description) }}
</div>
</div> </div>
{% endmacro %} {% endmacro %}
{% macro BatchSection(course) %} {% macro BatchSection(course) %}
{% if course.is_mentor(frappe.session.user) %} <div class="row">
{{ BatchSectionForMentors(course, course.get_batches(mentor=frappe.session.user)) }} <div class="col-lg-8 col-md-12">
{% else %} {% if course.is_mentor(frappe.session.user) %}
{{ BatchSectionForStudents(course, course.get_upcoming_batches()) }} {{ BatchSectionForMentors(course, course.get_batches(mentor=frappe.session.user)) }}
{% endif %} {% else %}
{{ BatchSectionForStudents(course, course.get_upcoming_batches()) }}
{% endif %}
</div>
</div>
{% endmacro %} {% endmacro %}
{% macro BatchSectionForMentors(course, mentor_batches) %} {% macro BatchSectionForMentors(course, mentor_batches) %}
<h2>Your Batches</h2> <h2>Your Batches</h2>
{% if mentor_batches %} {% if mentor_batches %}
<!-- <div class="alert alert-secondary">
You are a mentor for this course. Manage your batches or create a new batch from here.
</div> -->
<div class="row"> <div class="row">
{% for batch in mentor_batches %} {% for batch in mentor_batches %}
@@ -92,14 +87,15 @@
{% macro BatchSectionForStudents(course, upcoming_batches) %} {% macro BatchSectionForStudents(course, upcoming_batches) %}
{% if upcoming_batches %} {% if upcoming_batches %}
<h2>Upcoming Batches</h2> <div class="mt-5">
<h3>Upcoming Batches</h3>
<div class="row"> <div class="row">
{% for batch in upcoming_batches %} {% for batch in upcoming_batches %}
<div class="col-lg-4 col-md-6"> <div class="col-lg-4 col-md-6">
{{ widgets.RenderBatch(course=course, batch=batch, can_join=True) }} {{ widgets.RenderBatch(course=course, batch=batch, can_join=True) }}
</div> </div>
{% endfor %} {% endfor %}
</div>
{% endif %}
</div> </div>
{% endif %}
{% endmacro %} {% endmacro %}

View File

@@ -10,19 +10,17 @@
{% block content %} {% block content %}
<section class="top-section" style="padding: 1rem 0rem;"> <section class="top-section" style="padding: 1rem 0rem;">
<div class='container pb-5'>
<h1>{{ 'Courses' }}</h1>
</div>
<div class='container'> <div class='container'>
<h4 class="mt-5">{{ 'All Courses' }}</h4>
<div class="row mt-5"> <div class="row mt-5">
{% for course in courses %} {% for course in courses %}
{{ course_card(course) }} {{ course_card(course) }}
{% endfor %} {% endfor %}
{% if courses %} <!-- {% if courses %}
{% for n in range( (3 - (courses|length)) %3) %} {% for n in range( (3 - (courses|length)) %3) %}
{{ null_card() }} {{ null_card() }}
{% endfor %} {% endfor %}
{% endif %} {% endif %} -->
</div> </div>
</div> </div>
</section> </section>
@@ -32,7 +30,7 @@
{% macro course_card(course) %} {% macro course_card(course) %}
<div class="col-sm-4 mb-4 text-left"> <div class="col-sm-4 mb-4 text-left">
<a class="card-links" style="color: inherit;" href="/courses/{{course.name}}"> <a class="card-links" style="color: inherit;" href="/courses/{{course.name}}">
<div class="card h-100"> <div class="card h-100" style="box-shadow: 0px 5px 10px rgb(0 0 0 / 10%);">
<div class='card-body'> <div class='card-body'>
<h5 class='card-title'>{{ course.title }}</h5> <h5 class='card-title'>{{ course.title }}</h5>
{% if course.description %} {% if course.description %}

View File

@@ -1,7 +1,7 @@
{% macro hackathon_card(hackathon) %} {% macro hackathon_card(hackathon) %}
<div class="col-sm-4 mb-4 text-left"> <div class="col-sm-4 mb-4 text-left">
<a href="/hackathons/{{ hackathon.name }}" class="no-decoration no-underline"> <a href="/hackathons/{{ hackathon.name }}" class="no-decoration no-underline">
<div class="card h-100"> <div class="card h-100" style="box-shadow: 0px 5px 10px rgb(0 0 0 / 10%);">
<div class='card-body'> <div class='card-body'>
<h5 class='card-title'>{{ hackathon.name }}</h5> <h5 class='card-title'>{{ hackathon.name }}</h5>
</div> </div>
@@ -12,7 +12,7 @@
{% macro null_card() %} {% macro null_card() %}
<div class="col-sm-4 mb-4 text-left"> <div class="col-sm-4 mb-4 text-left">
<div class="h-100 d-none d-sm-block" style="border: 1px solid rgba(209,216,221,0.5);border-radius: 0.25rem;background-color: rgb(250, 251, 252);"> <div class="h-100 d-none d-sm-block" style="box-shadow: 0px 5px 10px rgb(0 0 0 / 10%);border-radius: 0.25rem;background-color: rgb(250, 251, 252);">
</div> </div>
</div> </div>
{% endmacro %} {% endmacro %}