feat: dashboard

This commit is contained in:
pateljannat
2021-04-12 14:05:02 +05:30
parent 767aaac913
commit 258ccb1642
6 changed files with 266 additions and 52 deletions

View File

@@ -2,7 +2,7 @@
"actions": [],
"allow_guest_to_view": 1,
"allow_rename": 1,
"autoname": "field:username",
"autoname": "field:email",
"creation": "2021-02-12 15:47:23.591567",
"doctype": "DocType",
"editable_grid": 1,
@@ -108,7 +108,7 @@
"has_web_view": 1,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-03-30 17:25:57.075151",
"modified": "2021-04-12 13:34:41.573486",
"modified_by": "Administrator",
"module": "Community",
"name": "Community Member",

View File

@@ -134,7 +134,8 @@ primary_rules = [
{"from_route": "/courses/<course>/<topic>", "to_route": "courses/topic"},
{"from_route": "/hackathons", "to_route": "hackathons"},
{"from_route": "/hackathons/<hackathon>", "to_route": "hackathons/hackathon"},
{"from_route": "/hackathons/<hackathon>/<project>", "to_route": "hackathons/project"}
{"from_route": "/hackathons/<hackathon>/<project>", "to_route": "hackathons/project"},
{"from_route": "/dashboard", "to_route": ""}
]
# Any frappe default URL is blocked by profile-rules, add it here to unblock it

View File

@@ -1,41 +0,0 @@
{% extends "templates/base.html" %}
{% block title %}{{ 'Hackathons' }}{% endblock %}
{% from "www/hackathons/macros/card.html" import hackathon_card %}
{% from "www/hackathons/macros/card.html" import null_card %}
{% block head_include %}
<meta name="description" content="{{ 'Conferences' }}" />
<meta name="keywords" content="An app that supports Communities." />
<style>
section {
padding: 5rem 0 5rem 0;
}
</style>
{% endblock %}
{% block content %}
<section class="top-section" style="padding: 6rem 0rem;">
<div class='container pb-5'>
<h1>{{ 'Conferences' }}</h1>
</div>
<div class='container'>
<div class="row mt-5">
{% for conference in conferences %}
<div class="col-sm-4 mb-4 text-left">
<a href="{{ conference.live_stream_url }}" class="no-decoration no-underline">
<div class="card h-100">
<div class='card-body'>
<h5 class='card-title'>{{ conference.name }}</h5>
</div>
</div>
</a>
</div>
{% endfor %}
{% if conferences %}
{% for n in range( (3 - (conferences|length)) %3) %}
{{ null_card() }}
{% endfor %}
{% endif %}
</div>
</div>
</section>
{% endblock %}

View File

@@ -1,8 +0,0 @@
import frappe
def get_context(context):
context.no_cache = 1
context.conferences = get_conferences()
def get_conferences():
return frappe.get_all("Community Conference", fields=["name", "live_stream_url"])

View File

@@ -0,0 +1,221 @@
{% extends "templates/base.html" %}
{% block title %}{{ _("Community") }}{% endblock %}
{% block head_include %}
<meta name="description" content="{{ 'Community' }}" />
<meta name="keywords" content="An app that supports Communities." />
<style>
section {
padding: 2rem;
color: #000000;
}
svg {
width: 200px;
height: 200px;
}
.dashboard__profile {
width: 150px;
height: 155px;
border-radius: 50%;
object-fit: contain;
}
.dashboard__profileSmall {
width: 59px;
height: 57px;
border-radius: 50%;
object-fit: contain;
}
.dashboard__abbr {
font-size: 50px;
width: 155px;
height: 155px;
border-radius: 50%;
}
.dashboard__abbrSmall {
font-size: 20px;
width: 59px;
height: 57px;
border-radius: 50%;
}
.dashboard__parent {
display: flex;
}
.dashboard__name {
font-weight: normal;
font-style: normal;
font-size: 36px;
line-height: 42px;
}
.dashboard__details {
padding-top: 2rem;
width: 80%;
}
.dashboard__course {
border: 1px solid black;
padding: 1rem;
margin: 0.5rem;
width: 48%;
}
.dashboard__courseHeader {
display: flex;
justify-content: space-between;
height: 50px;
margin-bottom: 3px;
}
.dashboard__badge {
background: #D6D6FF;
border-radius: 20px;
color: #1712FE;
padding: 0.5rem;
height: fit-content;
}
.dashboard__description {
height: 100px;
}
</style>
{% endblock %}
{% macro profile(photo, full_name, abbr, icon) %}
{% if photo %}
<img class="avatar rounded-circle img-fluid mr-5{% if icon == 'large' %} avatar-xl {% else %} avatar-large {% endif %}"
src="{{ photo }}" alt="{{ full_name }}">
{% else %}
<div class="col-sm-2">
<div class="standard-image {% if icon == 'large' %} dashboard__abbr {% else %} dashboard__abbrSmall {% endif %}">
{{ abbr }}
</div>
</div>
{% endif %}
{% endmacro %}
{% block content %}
<section>
<div class="dashboard__parent">
<div>
{{ profile(member.photo, member.full_name, abbr, "large")}}
</div>
<div class="dashboard__details">
<div class="dashboard__name">
{{member.full_name}}
</div>
<div>
<ul class="nav nav-tabs mt-4" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab"
aria-controls="home" aria-selected="true">Activity</a>
</li>
<li class="nav-item">
<a class="nav-link" id="sketches-tab" data-toggle="tab" href="#sketches" role="tab"
aria-controls="sketches" aria-selected="false">Sketches</a>
</li>
<li class="nav-item">
<a class="nav-link" id="courses-tab" data-toggle="tab" href="#courses" role="tab"
aria-controls="courses" aria-selected="false">Courses</a>
</li>
</ul>
</div>
<div>
<div class="tab-content">
<div class="tab-pane fade py-4 show active" role="tabpanel" id="home">
<div class='container'>
{% if activity %}
{% for message in activity %}
<div class="dashboard__message border m-5 p-3">
<div class="text-muted float-right">
{{ message.course }} ({{message.batch}})
</div>
<div class="d-flex align-items-center w-100">
<div>
{{ profile(message.profile, message.full_name, message.abbr, "small")}}
</div>
<div class="ml-5 mt-5">{{ frappe.utils.md_to_html(message.message) }}</div>
</div>
<div class="d-flex justify-content-between">
<div class="">
{{message.full_name}}
</div>
<div class="text-muted">
{{ frappe.utils.pretty_date(message.creation) }}
</div>
</div>
</div>
{% endfor %}
{% else %}
<p class="text-center">You have not received any messages yet.</p>
{% endif %}
</div>
</div>
<div class="tab-pane fade py-4" role="tabpanel" id="sketches">
<div class='container'>
<a href="/sketches/new">Create a New Sketch</a>
<div class="">
{% if sketches %}
{% for sketch in sketches %}
<div class="col mb-4">
<div class="card sketch-card" style="width: 200px;">
<div class="card-img-top">
<a href="/sketches/{{sketch.sketch_id}}">
{{ sketch.to_svg() }}
</a>
</div>
<div class="card-footer">
<div class="sketch-title">
<a href="sketches/{{sketch.sketch_id}}">{{sketch.title}}</a>
</div>
<div class="sketch-author">
by {{sketch.get_owner_name()}}
</div>
</div>
</div>
</div>
{% endfor %}
{% else %}
<p class="text-center">You have not created any sketches.</p>
{% endif %}
</div>
</div>
</div>
<div class="tab-pane fade py-4" role="tabpanel" id="courses">
{% if courses %}
<p class="ml-3">Your Courses</p>
<div class="d-flex flex-wrap">
{% for course in courses %}
<div class="dashboard__course">
<div class="dashboard__courseHeader">
<h5 class="w-75">{{ course.name }}</h5>
{% if course.member_type %}
<div class="dashboard__badge">
{{ course.member_type }}
</div>
{% endif %}
</div>
<div class="dashboard__description">
{{ frappe.utils.md_to_html(course.description) }}
</div>
<div class="text-muted"> Joined {{ frappe.utils.pretty_date(course.joining) }} </div>
</div>
{% endfor %}
{% else %}
<p class="text-center">You are not a member of any course yet. Checkout our <a
href="/courses" target="_blank">Courses</a>.</p>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
</section>
{% endblock %}

View File

@@ -0,0 +1,41 @@
import frappe
from ...lms.doctype.lms_sketch.lms_sketch import get_recent_sketches
def get_context(context):
context.no_cache = 1
context.member = frappe.get_all("Community Member", {"email": frappe.session.user}, ["name", "email", "photo", "full_name"])[0]
context.abbr = "".join([s[0] for s in context.member.full_name.split()])
context.memberships = get_memberships(context.member.name)
context.courses = get_courses(context.memberships)
context.activity = get_activity(context.memberships)
context.sketches = list(filter(lambda x: x.owner == frappe.session.user, get_recent_sketches()))
print(context)
def get_memberships(member):
return frappe.get_all("LMS Batch Membership", {"member": member}, ["batch", "member_type", "creation"])
def get_courses(memberships):
courses = []
for membership in memberships:
course = frappe.db.get_value("LMS Batch", membership.batch, "course")
course_details = frappe.get_doc("LMS Course", course)
course_in_list = list(filter(lambda x: x.name == course_details.name, courses))
if not len(course_in_list):
course_details.description = course_details.description[0:100] + "..."
course_details.joining = membership.creation
if membership.member_type != "Student":
course_details.member_type = membership.member_type
courses.append(course_details)
return courses
def get_activity(memberships):
messages, courses = [], {}
batches = [x.batch for x in memberships]
for batch in batches:
courses[batch] = frappe.db.get_value("LMS Batch", batch, "course")
messages = frappe.get_all("LMS Message", {"batch": ["in", ",".join(batches)]}, ["message", "author", "creation", "batch"], order_by='creation desc')
for message in messages:
message.course = courses[message.batch]
message.profile, message.full_name = frappe.db.get_value("Community Member", message.author, ["photo", "full_name"])
if not message.profile:
message.abbr = "".join([s[0] for s in message.full_name.split()])
return messages