feat: community member for profile and edit profile form
This commit is contained in:
@@ -69,7 +69,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"is_published_field": "enabled",
|
"is_published_field": "enabled",
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-03-03 15:00:46.298535",
|
"modified": "2021-03-09 11:17:40.842666",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Community",
|
"module": "Community",
|
||||||
"name": "Community Course Member",
|
"name": "Community Course Member",
|
||||||
@@ -89,7 +89,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"quick_entry": 1,
|
"quick_entry": 1,
|
||||||
"route": "me",
|
|
||||||
"sort_field": "modified",
|
"sort_field": "modified",
|
||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class CommunityCourseMember(WebsiteGenerator):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
self.validate_user_name()
|
self.validate_user_name()
|
||||||
if not self.route:
|
if not self.route:
|
||||||
self.route = "me/" + self.user_name
|
self.route = self.user_name
|
||||||
|
|
||||||
def validate_user_name(self):
|
def validate_user_name(self):
|
||||||
if len(self.user_name) < 4:
|
if len(self.user_name) < 4:
|
||||||
@@ -60,7 +60,7 @@ class CommunityCourseMember(WebsiteGenerator):
|
|||||||
"username": self.user_name,
|
"username": self.user_name,
|
||||||
"send_welcome_email": 0,
|
"send_welcome_email": 0,
|
||||||
"user_type": 'Website User',
|
"user_type": 'Website User',
|
||||||
"redirect_url": "me/" + self.name
|
"redirect_url": self.name
|
||||||
})
|
})
|
||||||
user.save(ignore_permissions=True)
|
user.save(ignore_permissions=True)
|
||||||
update_password_link = user.reset_password()
|
update_password_link = user.reset_password()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"actions": [],
|
"actions": [],
|
||||||
"autoname": "field:user_name",
|
"allow_guest_to_view": 1,
|
||||||
"creation": "2021-02-12 15:47:23.591567",
|
"creation": "2021-02-12 15:47:23.591567",
|
||||||
"doctype": "DocType",
|
"doctype": "DocType",
|
||||||
"editable_grid": 1,
|
"editable_grid": 1,
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
"field_order": [
|
"field_order": [
|
||||||
"enabled",
|
"enabled",
|
||||||
"full_name",
|
"full_name",
|
||||||
|
"email",
|
||||||
"role",
|
"role",
|
||||||
"photo",
|
"photo",
|
||||||
"short_intro",
|
"short_intro",
|
||||||
@@ -64,11 +65,20 @@
|
|||||||
"fieldname": "route",
|
"fieldname": "route",
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"label": "Route"
|
"label": "Route"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "email",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"label": "Email",
|
||||||
|
"options": "Email",
|
||||||
|
"reqd": 1,
|
||||||
|
"unique": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"has_web_view": 1,
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-03-02 11:24:28.763348",
|
"modified": "2021-03-12 10:23:09.709669",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Community",
|
"module": "Community",
|
||||||
"name": "Community Member",
|
"name": "Community Member",
|
||||||
|
|||||||
@@ -3,8 +3,39 @@
|
|||||||
# For license information, please see license.txt
|
# For license information, please see license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
# import frappe
|
import frappe
|
||||||
from frappe.website.website_generator import WebsiteGenerator
|
from frappe.website.website_generator import WebsiteGenerator
|
||||||
|
import re
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
class CommunityMember(WebsiteGenerator):
|
class CommunityMember(WebsiteGenerator):
|
||||||
pass
|
def get_context(self, context):
|
||||||
|
context.abbr = ("").join([ s[0] for s in self.full_name.split() ])
|
||||||
|
return context
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
self.validate_user_name()
|
||||||
|
if self.route != self.user_name:
|
||||||
|
self.route = self.user_name
|
||||||
|
|
||||||
|
def validate_user_name(self):
|
||||||
|
if self.user_name:
|
||||||
|
if len(self.user_name) < 4:
|
||||||
|
frappe.throw(_("Username must be atleast 4 characters long."))
|
||||||
|
if not re.match("^[A-Za-z0-9]*$", self.user_name):
|
||||||
|
frappe.throw(_("Username can only contain alphabets, and numbers."))
|
||||||
|
self.user_name = self.user_name.lower()
|
||||||
|
|
||||||
|
def autoname(self):
|
||||||
|
self.name = self.user_name
|
||||||
|
|
||||||
|
def create_member_from_user(doc, method):
|
||||||
|
member = frappe.get_doc({
|
||||||
|
"doctype": "Community Member",
|
||||||
|
"full_name": doc.full_name,
|
||||||
|
"user_name": doc.username,
|
||||||
|
"email": doc.email,
|
||||||
|
"route": doc.username,
|
||||||
|
"owner": doc.email
|
||||||
|
})
|
||||||
|
member.save(ignore_permissions=True)
|
||||||
|
|||||||
@@ -1,17 +1,23 @@
|
|||||||
{% extends "templates/web.html" %}
|
{% extends "templates/web.html" %}
|
||||||
|
|
||||||
{% block page_content %}
|
{% block page_content %}
|
||||||
<div class="py-20 row">
|
<div class="py-20 row">
|
||||||
|
{% if photo %}
|
||||||
<div class="col-sm-2 border border-dark">
|
<div class="col-sm-2 border border-dark">
|
||||||
<img src="{{ photo }}" alt="{{ full_name }}">
|
<img src="{{ photo }}" alt="{{ full_name }}">
|
||||||
</div>
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="col-sm-2">
|
||||||
|
<div class="standard-image" style="font-size: 30px;">{{ abbr }}</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h1>{{ full_name }}</h1>
|
<h1>{{ full_name }}</h1>
|
||||||
<p class="lead"> {{ short_intro }}</p>
|
{% if short_intro %}
|
||||||
<div class="mt-4">
|
<p class="lead"> {{ short_intro }} </p>
|
||||||
<div>Role: <strong>{{ role }}</strong></div>
|
{% endif %}
|
||||||
</div>
|
{% if bio %}
|
||||||
<p class="markdown-style">{{ frappe.utils.md_to_html(bio) }}</p>
|
<p class="markdown-style"> {{ frappe.utils.md_to_html(bio) }} </p>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -2,37 +2,39 @@
|
|||||||
"accept_payment": 0,
|
"accept_payment": 0,
|
||||||
"allow_comments": 0,
|
"allow_comments": 0,
|
||||||
"allow_delete": 0,
|
"allow_delete": 0,
|
||||||
"allow_edit": 0,
|
"allow_edit": 1,
|
||||||
"allow_incomplete": 0,
|
"allow_incomplete": 0,
|
||||||
"allow_multiple": 0,
|
"allow_multiple": 0,
|
||||||
"allow_print": 0,
|
"allow_print": 0,
|
||||||
"amount": 0.0,
|
"amount": 0.0,
|
||||||
"amount_based_on_field": 0,
|
"amount_based_on_field": 0,
|
||||||
"apply_document_permissions": 0,
|
"apply_document_permissions": 0,
|
||||||
"button_label": "Submit",
|
"breadcrumbs": "",
|
||||||
"creation": "2021-03-02 11:31:39.072501",
|
"button_label": "Save",
|
||||||
"doc_type": "Community Course Member",
|
"creation": "2021-03-09 17:34:03.394301",
|
||||||
|
"doc_type": "Community Member",
|
||||||
"docstatus": 0,
|
"docstatus": 0,
|
||||||
"doctype": "Web Form",
|
"doctype": "Web Form",
|
||||||
"idx": 0,
|
"idx": 0,
|
||||||
"is_standard": 1,
|
"is_standard": 1,
|
||||||
"login_required": 0,
|
"login_required": 1,
|
||||||
"max_attachment_size": 0,
|
"max_attachment_size": 0,
|
||||||
"modified": "2021-03-03 11:02:33.907687",
|
"modified": "2021-03-12 10:23:37.625177",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Community",
|
"module": "Community",
|
||||||
"name": "community-course-membership",
|
"name": "update-profile",
|
||||||
"owner": "Administrator",
|
"owner": "Administrator",
|
||||||
"payment_button_label": "Buy Now",
|
"payment_button_label": "Buy Now",
|
||||||
"published": 1,
|
"published": 1,
|
||||||
"route": "community-course-membership",
|
"route": "edit-profile",
|
||||||
"route_to_success_link": 0,
|
"route_to_success_link": 0,
|
||||||
"show_attachments": 0,
|
"show_attachments": 0,
|
||||||
"show_in_grid": 0,
|
"show_in_grid": 0,
|
||||||
"show_sidebar": 0,
|
"show_sidebar": 0,
|
||||||
"sidebar_items": [],
|
"sidebar_items": [],
|
||||||
"success_url": "/community-course-membership",
|
"success_message": "Profile updated successfully.",
|
||||||
"title": "Community Course Membership",
|
"success_url": "/",
|
||||||
|
"title": "Update Profile",
|
||||||
"web_form_fields": [
|
"web_form_fields": [
|
||||||
{
|
{
|
||||||
"allow_read_on_all_link_options": 0,
|
"allow_read_on_all_link_options": 0,
|
||||||
@@ -55,7 +57,7 @@
|
|||||||
"max_length": 0,
|
"max_length": 0,
|
||||||
"max_value": 0,
|
"max_value": 0,
|
||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 1,
|
"reqd": 0,
|
||||||
"show_in_filter": 0
|
"show_in_filter": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -70,6 +72,42 @@
|
|||||||
"read_only": 0,
|
"read_only": 0,
|
||||||
"reqd": 0,
|
"reqd": 0,
|
||||||
"show_in_filter": 0
|
"show_in_filter": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
|
"fieldname": "short_intro",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"label": "Short Intro",
|
||||||
|
"max_length": 0,
|
||||||
|
"max_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
|
"fieldname": "bio",
|
||||||
|
"fieldtype": "Data",
|
||||||
|
"hidden": 0,
|
||||||
|
"label": "Bio",
|
||||||
|
"max_length": 0,
|
||||||
|
"max_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"allow_read_on_all_link_options": 0,
|
||||||
|
"fieldname": "photo",
|
||||||
|
"fieldtype": "Attach Image",
|
||||||
|
"hidden": 0,
|
||||||
|
"label": "Photo",
|
||||||
|
"max_length": 0,
|
||||||
|
"max_value": 0,
|
||||||
|
"read_only": 0,
|
||||||
|
"reqd": 0,
|
||||||
|
"show_in_filter": 0
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -90,13 +90,11 @@ app_include_js = "/assets/community/js/community.js"
|
|||||||
# ---------------
|
# ---------------
|
||||||
# Hook on document methods and events
|
# Hook on document methods and events
|
||||||
|
|
||||||
# doc_events = {
|
doc_events = {
|
||||||
# "*": {
|
"User": {
|
||||||
# "on_update": "method",
|
"after_insert": "community.community.doctype.community_member.community_member.create_member_from_user"
|
||||||
# "on_cancel": "method",
|
}
|
||||||
# "on_trash": "method"
|
}
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
# Scheduled Tasks
|
# Scheduled Tasks
|
||||||
# ---------------
|
# ---------------
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<div class="badge badge-info enrollment-badge hide">Enrolled</div>
|
<div class="badge badge-info enrollment-badge hide">Enrolled</div>
|
||||||
<div>
|
<div>
|
||||||
{% if not course_enrolled and frappe.session.user != "Guest" %}
|
{% if not course_enrolled and frappe.session.user != "Guest" %}
|
||||||
<button class="btn btn-dark btn-enroll float-right" data-course={{course.name}}>Enroll</button>
|
<button class="btn btn-dark btn-enroll float-right" data-course="{{ course.name }}">Enroll</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h1>{{ course.title }}</h1>
|
<h1>{{ course.title }}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
frappe.ready(() => {
|
frappe.ready(() => {
|
||||||
if(frappe.session.user != "Guest"){
|
if(frappe.session.user != "Guest"){
|
||||||
var url_params = new URLSearchParams(window.location.search);
|
frappe.call('community.www.courses.course.has_enrolled', { course: get_search_params().get("course") }, (data) => {
|
||||||
frappe.call('community.www.courses.course.has_enrolled', { course: url_params.get("course") }, (data) => {
|
|
||||||
if (data.message) {
|
if (data.message) {
|
||||||
show_enrollment_badge()
|
show_enrollment_badge()
|
||||||
}
|
}
|
||||||
@@ -14,8 +13,12 @@ var show_enrollment_badge = () => {
|
|||||||
$(".enrollment-badge").removeClass("hide");
|
$(".enrollment-badge").removeClass("hide");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var get_search_params = () => {
|
||||||
|
return new URLSearchParams(window.location.search)
|
||||||
|
}
|
||||||
|
|
||||||
$('.btn-enroll').on('click', (e) => {
|
$('.btn-enroll').on('click', (e) => {
|
||||||
frappe.call('community.www.courses.course.enroll', { course: $(e.target).attr("data-course") }, (data) => {
|
frappe.call('community.www.courses.course.enroll', { course: get_search_params().get("course") }, (data) => {
|
||||||
show_enrollment_badge()
|
show_enrollment_badge()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ def get_course(name):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def has_enrolled(course):
|
def has_enrolled(course):
|
||||||
|
print(frappe.db)
|
||||||
return frappe.db.get_value("LMS Course Enrollment", {"course": course, "owner": frappe.session.user})
|
return frappe.db.get_value("LMS Course Enrollment", {"course": course, "owner": frappe.session.user})
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ def get_context(context):
|
|||||||
|
|
||||||
def get_my_courses():
|
def get_my_courses():
|
||||||
my_courses = []
|
my_courses = []
|
||||||
courses = frappe.get_all("Community Course Enrollment", {"owner": frappe.session.user}, ["course"])
|
courses = frappe.get_all("LMS Course Enrollment", {"owner": frappe.session.user}, ["course"])
|
||||||
for course in courses:
|
for course in courses:
|
||||||
my_courses.append({
|
my_courses.append({
|
||||||
"name": course.course,
|
"name": course.course,
|
||||||
"title": frappe.db.get_value("Community Course", course.course, ["title"])
|
"title": frappe.db.get_value("LMS Course", course.course, ["title"])
|
||||||
})
|
})
|
||||||
return my_courses
|
return my_courses
|
||||||
Reference in New Issue
Block a user