Compare commits

..

28 Commits

Author SHA1 Message Date
pateljannat
f83007788d fix: web form redirects 2021-08-23 10:22:40 +05:30
Jannat Patel
5069832165 Merge pull request #183 from fossunited/event-doctype-fixes
fix: event doctypes and templates
2021-08-20 17:41:56 +05:30
pateljannat
e2cb003935 fix: doctypes and templates 2021-08-20 17:35:13 +05:30
Jannat Patel
b83a10c282 Merge pull request #180 from sumaiya2908/event-management
Create web templates for event management
2021-08-20 15:34:48 +05:30
Summayya
c6fc0a22d2 fix: add user to exhibitor doctype 2021-08-20 15:26:47 +05:30
Summayya
07f9721aeb fix: remove speaker-registration 2021-08-20 13:45:40 +05:30
Summayya
dba956e473 fix: remove speaker-registration 2021-08-20 13:41:11 +05:30
Summayya
2894a5e479 fix: change date format 2021-08-19 17:22:01 +05:30
Summayya
ad0913500c fix: link user to speaker/attendee 2021-08-19 16:08:54 +05:30
Jannat Patel
79a765b725 Merge pull request #182 from fossunited/profile-urls
fix: profile urls
2021-08-19 12:05:59 +05:30
pateljannat
e31b189045 fix: profile urls 2021-08-19 09:35:02 +05:30
Summayya
eb58b1c149 fix: remove hover 2021-08-18 23:53:02 +05:30
Summayya
af9760f944 fix: remove div in schedule template 2021-08-18 19:49:12 +05:30
Summayya
21b2412362 fix: remove dummy data 2021-08-18 19:41:37 +05:30
Summayya
7e5e167eec fix: remove dummy data 2021-08-18 19:40:35 +05:30
Jannat Patel
7bf254319b Merge pull request #181 from fossunited/certification
feat: certification
2021-08-18 18:39:12 +05:30
pateljannat
d7e1745c09 fix: added back update progress code 2021-08-18 18:17:40 +05:30
pateljannat
ef238c1b25 fix: export label 2021-08-18 18:08:33 +05:30
pateljannat
cb60d97bb7 feat: certification 2021-08-18 18:04:47 +05:30
Summayya
7c3189e273 fix:conflict 2021-08-18 11:41:09 +05:30
Summayya
ace74febc7 Template for Previous content 2021-08-18 11:37:04 +05:30
Summayya
8dbdabd52c Create web templates for event management 2021-08-17 22:31:15 +05:30
Jannat Patel
f0ee8d7b88 Merge pull request #173 from fossunited/sketch-redesign
fix: sketch cards
2021-08-16 13:47:05 +05:30
Jannat Patel
7e5203f058 Merge pull request #179 from fossunited/discussions
feat: Discussions
2021-08-16 13:45:00 +05:30
pateljannat
7017382451 fix: removed sketch card 2021-08-11 11:40:57 +05:30
pateljannat
3e2c6b3343 fix: sketch image call 2021-08-10 17:08:32 +05:30
pateljannat
5ea744de5c fix: removed unused file 2021-08-10 16:46:48 +05:30
pateljannat
aedb3d3d45 fix: sketch cards 2021-08-10 16:39:17 +05:30
101 changed files with 9855 additions and 35 deletions

View File

@@ -1,5 +1,5 @@
{% set color = member.get_palette() %}
<a class="button-links" href="/{{member.username}}">
<a class="button-links" href="/user/{{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 }}">

View File

View File

@@ -0,0 +1,14 @@
// Copyright (c) 2021, FOSS United and contributors
// For license information, please see license.txt
frappe.ui.form.on('Attendee', {
onload: function (frm) {
frm.set_query('user', function (doc) {
return {
filters: {
"ignore_user_type": 1,
}
};
});
}
});

View File

@@ -0,0 +1,80 @@
{
"actions": [],
"creation": "2021-08-11 10:07:53.262504",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"user",
"full_name",
"column_break_3",
"company",
"is_paid",
"section_break_6",
"what_are_you_hoping_to_learn"
],
"fields": [
{
"fieldname": "company",
"fieldtype": "Data",
"label": "Company"
},
{
"fieldname": "what_are_you_hoping_to_learn",
"fieldtype": "Text",
"label": "What are you hoping to learn?"
},
{
"fieldname": "user",
"fieldtype": "Link",
"label": "User",
"options": "User"
},
{
"fetch_from": "user.full_name",
"fieldname": "full_name",
"fieldtype": "Data",
"label": "Full Name",
"read_only": 1
},
{
"default": "0",
"fieldname": "is_paid",
"fieldtype": "Check",
"label": "Is Paid"
},
{
"fieldname": "column_break_3",
"fieldtype": "Column Break"
},
{
"fieldname": "section_break_6",
"fieldtype": "Section Break"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-20 17:03:09.741997",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Attendee",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "user",
"track_changes": 1
}

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class Attendee(Document):
pass

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestAttendee(unittest.TestCase):
pass

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2021, FOSS United and contributors
// For license information, please see license.txt
frappe.ui.form.on('Event Details', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,68 @@
{
"actions": [],
"autoname": "field:event_name",
"creation": "2021-08-11 10:05:41.072432",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"event_name",
"start_date",
"end_date",
"event_description"
],
"fields": [
{
"fieldname": "event_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Event Name",
"reqd": 1,
"unique": 1
},
{
"fieldname": "start_date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Start Date",
"reqd": 1
},
{
"fieldname": "end_date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "End Date",
"reqd": 1
},
{
"fieldname": "event_description",
"fieldtype": "Markdown Editor",
"in_list_view": 1,
"label": "Event Description"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-18 23:51:30.432691",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Event Details",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class EventDetails(Document):
pass

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestEventDetails(unittest.TestCase):
pass

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2021, FOSS United and contributors
// For license information, please see license.txt
frappe.ui.form.on('Event Ticket', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,55 @@
{
"actions": [],
"creation": "2021-08-11 11:17:28.452289",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"event",
"ticket",
"attendee"
],
"fields": [
{
"fieldname": "ticket",
"fieldtype": "Data",
"label": "Ticket"
},
{
"fieldname": "attendee",
"fieldtype": "Link",
"label": "attendee",
"options": "Attendee"
},
{
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-20 13:38:28.688115",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Event Ticket",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class EventTicket(Document):
pass

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestEventTicket(unittest.TestCase):
pass

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2021, FOSS United and contributors
// For license information, please see license.txt
frappe.ui.form.on('Exhibitor', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,87 @@
{
"actions": [],
"creation": "2021-08-16 16:26:46.189119",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"event",
"is_paid",
"column_break_3",
"user",
"full_name",
"company",
"section_break_7",
"description"
],
"fields": [
{
"fetch_from": "user.full_name",
"fieldname": "full_name",
"fieldtype": "Data",
"label": "Full Name",
"read_only": 1
},
{
"fieldname": "company",
"fieldtype": "Data",
"label": "Company "
},
{
"fieldname": "description",
"fieldtype": "Text Editor",
"label": "Description"
},
{
"default": "0",
"fieldname": "is_paid",
"fieldtype": "Check",
"label": "Is Paid"
},
{
"fieldname": "user",
"fieldtype": "Link",
"label": "User",
"options": "User"
},
{
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details"
},
{
"fieldname": "column_break_3",
"fieldtype": "Column Break"
},
{
"fieldname": "section_break_7",
"fieldtype": "Section Break"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-20 16:32:58.031324",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Exhibitor",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "user",
"track_changes": 1
}

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class Exhibitor(Document):
pass

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestExhibitor(unittest.TestCase):
pass

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2021, FOSS United and contributors
// For license information, please see license.txt
frappe.ui.form.on('Host', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,57 @@
{
"actions": [],
"creation": "2021-08-11 10:51:47.234690",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"event",
"user",
"full_name"
],
"fields": [
{
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details"
},
{
"fieldname": "full_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Full Name",
"unique": 1
},
{
"fieldname": "user",
"fieldtype": "Data",
"label": "User"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-20 17:03:26.733195",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Host",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "user",
"track_changes": 1
}

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class Host(Document):
pass

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestHost(unittest.TestCase):
pass

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2021, FOSS United and contributors
// For license information, please see license.txt
frappe.ui.form.on('Speaker', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,72 @@
{
"actions": [],
"creation": "2021-08-11 10:37:32.124651",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"event",
"company",
"column_break_8",
"user",
"full_name"
],
"fields": [
{
"fieldname": "user",
"fieldtype": "Link",
"in_list_view": 1,
"label": "User",
"options": "User"
},
{
"fetch_from": "user.full_name",
"fieldname": "full_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Full Name",
"read_only": 1
},
{
"fieldname": "company",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Company"
},
{
"fieldname": "column_break_8",
"fieldtype": "Column Break"
},
{
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-20 16:53:43.968260",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Speaker",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "user",
"track_changes": 1
}

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class Speaker(Document):
pass

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestSpeaker(unittest.TestCase):
pass

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2021, FOSS United and contributors
// For license information, please see license.txt
frappe.ui.form.on('Talk', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,139 @@
{
"actions": [],
"creation": "2021-08-18 08:42:58.711932",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"event",
"title",
"url",
"column_break_5",
"speaker",
"category",
"thumbnail",
"schedule_section",
"date",
"status",
"column_break_11",
"start_time",
"end_time",
"section_break_9",
"about",
"attachment",
"name_of_the_speaker"
],
"fields": [
{
"fieldname": "title",
"fieldtype": "Data",
"label": "Title"
},
{
"fieldname": "name_of_the_speaker",
"fieldtype": "Data",
"label": "Name of the Speaker"
},
{
"fieldname": "url",
"fieldtype": "Data",
"label": "Video Embed Link"
},
{
"fieldname": "thumbnail",
"fieldtype": "Data",
"label": "Preview Image (Link)"
},
{
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details"
},
{
"fieldname": "about",
"fieldtype": "Text",
"label": "About the Talk"
},
{
"fieldname": "attachment",
"fieldtype": "Attach",
"label": "Attachment"
},
{
"fieldname": "speaker",
"fieldtype": "Link",
"label": "Speaker",
"options": "Speaker"
},
{
"default": "Pending",
"fieldname": "status",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Status",
"options": "Pending\nApproved\nRejected"
},
{
"fieldname": "column_break_5",
"fieldtype": "Column Break"
},
{
"fieldname": "section_break_9",
"fieldtype": "Section Break"
},
{
"fieldname": "category",
"fieldtype": "Data",
"label": "Category"
},
{
"fieldname": "schedule_section",
"fieldtype": "Section Break"
},
{
"fieldname": "date",
"fieldtype": "Date",
"label": "Date"
},
{
"fieldname": "column_break_11",
"fieldtype": "Column Break"
},
{
"fieldname": "start_time",
"fieldtype": "Time",
"label": "Start Time"
},
{
"fieldname": "end_time",
"fieldtype": "Time",
"label": "End Time"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-20 17:02:51.609288",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Talk",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title",
"track_changes": 1
}

View File

@@ -0,0 +1,29 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
class Talk(Document):
def before_save(self):
if not self.speaker:
self.save_speaker()
def save_speaker(self):
exists = frappe.db.exists({
'doctype': 'Speaker',
'user': frappe.session.user
})
if exists:
self.speaker = frappe.db.get_value(
'Speaker', {'user': frappe.session.user}, ["name"])
else:
speaker = frappe.get_doc({
"doctype": "Speaker",
"event": self.event,
"user": frappe.session.user
}).save(ignore_permissions=True)
self.speaker = speaker

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestTalk(unittest.TestCase):
pass

View File

@@ -0,0 +1,7 @@
frappe.ready(function () {
frappe.web_form.after_save = () => {
setTimeout(function () {
window.location.href = '/event/conference2021/about';
}, 2000);
}
})

View File

@@ -0,0 +1,76 @@
{
"accept_payment": 0,
"allow_comments": 0,
"allow_delete": 0,
"allow_edit": 0,
"allow_incomplete": 0,
"allow_multiple": 0,
"allow_print": 0,
"amount": 0.0,
"amount_based_on_field": 0,
"apply_document_permissions": 0,
"button_label": "",
"creation": "2021-08-19 15:26:56.594526",
"custom_css": "[data-doctype=\"Web Form\"] {\n max-width: 720px;\n margin: 6rem auto;\n}",
"doc_type": "Attendee",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2021-08-23 10:13:19.224367",
"modified_by": "Administrator",
"module": "Event Management",
"name": "attendee-registration",
"owner": "Administrator",
"payment_button_label": "Buy Now",
"published": 1,
"route": "event/conference2021/attendee-registration",
"route_to_success_link": 1,
"show_attachments": 0,
"show_in_grid": 0,
"show_sidebar": 0,
"sidebar_items": [],
"success_url": "/event/conference2021/about",
"title": "Attendee Registration",
"web_form_fields": [
{
"allow_read_on_all_link_options": 0,
"fieldname": "user",
"fieldtype": "Data",
"hidden": 0,
"label": "User",
"max_length": 0,
"max_value": 0,
"options": "User",
"read_only": 1,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "company",
"fieldtype": "Data",
"hidden": 0,
"label": "Company",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "what_are_you_hoping_to_learn",
"fieldtype": "Text",
"hidden": 0,
"label": "What are you hoping to learn",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
}
]
}

View File

@@ -0,0 +1,5 @@
import frappe
def get_context(context):
# do your magic here
pass

View File

@@ -0,0 +1,7 @@
frappe.ready(function () {
frappe.web_form.after_save = () => {
setTimeout(function () {
window.location.href = '/event/conference2021/about';
}, 2000);
}
})

View File

@@ -0,0 +1,76 @@
{
"accept_payment": 0,
"allow_comments": 0,
"allow_delete": 0,
"allow_edit": 0,
"allow_incomplete": 0,
"allow_multiple": 0,
"allow_print": 0,
"amount": 0.0,
"amount_based_on_field": 0,
"apply_document_permissions": 0,
"button_label": "Save",
"creation": "2021-08-16 16:27:06.566564",
"custom_css": "[data-doctype=\"Web Form\"] {\n max-width: 720px;\n margin: 6rem auto;\n}",
"doc_type": "Exhibitor",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2021-08-23 10:12:24.038572",
"modified_by": "Administrator",
"module": "Event Management",
"name": "exhibitor-registration",
"owner": "Administrator",
"payment_button_label": "Buy Now",
"published": 1,
"route": "exhibitor-registration",
"route_to_success_link": 0,
"show_attachments": 0,
"show_in_grid": 0,
"show_sidebar": 0,
"sidebar_items": [],
"success_url": "",
"title": "Exhibitor Registration",
"web_form_fields": [
{
"allow_read_on_all_link_options": 0,
"fieldname": "user",
"fieldtype": "Data",
"hidden": 0,
"label": "User",
"max_length": 0,
"max_value": 0,
"options": "User",
"read_only": 1,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "company",
"fieldtype": "Data",
"hidden": 0,
"label": "Company ",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "description",
"fieldtype": "Text Editor",
"hidden": 0,
"label": "Description",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
}
]
}

View File

@@ -0,0 +1,5 @@
import frappe
def get_context(context):
# do your magic here
pass

View File

@@ -0,0 +1,7 @@
frappe.ready(function () {
frappe.web_form.after_save = () => {
setTimeout(function () {
window.location.href = '/event/conference2021/about';
}, 2000);
}
})

View File

@@ -0,0 +1,102 @@
{
"accept_payment": 0,
"allow_comments": 0,
"allow_delete": 0,
"allow_edit": 0,
"allow_incomplete": 0,
"allow_multiple": 0,
"allow_print": 0,
"amount": 0.0,
"amount_based_on_field": 0,
"apply_document_permissions": 0,
"button_label": "Submit",
"client_script": "",
"creation": "2021-08-19 15:16:22.341723",
"custom_css": "[data-doctype=\"Web Form\"] {\n max-width: 720px;\n margin: 6rem auto;\n}",
"doc_type": "Talk",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2021-08-23 10:18:17.486228",
"modified_by": "Administrator",
"module": "Event Management",
"name": "purpose-a-talk",
"owner": "Administrator",
"payment_button_label": "Buy Now",
"published": 1,
"route": "propose-talk",
"route_to_success_link": 0,
"show_attachments": 0,
"show_in_grid": 0,
"show_sidebar": 0,
"sidebar_items": [],
"success_message": "Talk Submitted!",
"success_url": "/purpose-a-talk",
"title": "Propose a Talk",
"web_form_fields": [
{
"allow_read_on_all_link_options": 0,
"fieldname": "title",
"fieldtype": "Data",
"hidden": 0,
"label": "Title",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "category",
"fieldtype": "Data",
"hidden": 0,
"label": "Category",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "event",
"fieldtype": "Data",
"hidden": 0,
"label": "Event",
"max_length": 0,
"max_value": 0,
"options": "Event Details",
"read_only": 1,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "about",
"fieldtype": "Text Editor",
"hidden": 0,
"label": "About",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "attachment",
"fieldtype": "Attach",
"hidden": 0,
"label": "Attachment",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
}
]
}

View File

@@ -0,0 +1,5 @@
import frappe
def get_context(context):
# do your magic here
pass

View File

@@ -0,0 +1,7 @@
frappe.ready(function () {
frappe.web_form.after_save = () => {
setTimeout(function () {
window.location.href = '/event/conference2021/propose-talk';
}, 2000);
}
})

View File

@@ -0,0 +1,89 @@
{
"accept_payment": 0,
"allow_comments": 0,
"allow_delete": 0,
"allow_edit": 0,
"allow_incomplete": 0,
"allow_multiple": 0,
"allow_print": 0,
"amount": 0.0,
"amount_based_on_field": 0,
"apply_document_permissions": 0,
"button_label": "Register",
"creation": "2021-08-19 15:29:01.167930",
"custom_css": "[data-doctype=\"Web Form\"] {\n max-width: 720px;\n margin: 6rem auto;\n}",
"doc_type": "Speaker",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2021-08-20 16:16:51.107177",
"modified_by": "Administrator",
"module": "Event Management",
"name": "speaker-registration",
"owner": "Administrator",
"payment_button_label": "Buy Now",
"published": 1,
"route": "speaker-registration",
"route_to_success_link": 1,
"show_attachments": 0,
"show_in_grid": 0,
"show_sidebar": 0,
"sidebar_items": [],
"success_url": "/speaker-registration",
"title": "Speaker Registration",
"web_form_fields": [
{
"allow_read_on_all_link_options": 0,
"fieldname": "event",
"fieldtype": "Link",
"hidden": 0,
"label": "Event",
"max_length": 0,
"max_value": 0,
"options": "Event Details",
"read_only": 1,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "user",
"fieldtype": "Link",
"hidden": 0,
"label": "User",
"max_length": 0,
"max_value": 0,
"options": "User",
"read_only": 1,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "full_name",
"fieldtype": "Data",
"hidden": 0,
"label": "Full Name",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "company",
"fieldtype": "Data",
"hidden": 0,
"label": "Company",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
}
]
}

View File

@@ -0,0 +1,5 @@
import frappe
def get_context(context):
# do your magic here
pass

View File

@@ -0,0 +1,43 @@
<div class="section-with-cards">
<h1 class="course-home-headings">{{title}}</h1>
{%- if subtitle -%}
<p class="section-description">{{ subtitle }}</p>
{%- endif -%}
<div>
<div class="mentors-section">
{% for exhibitor in exhibitor_details %}
{% set exhibitor_doc = frappe.db.get_value("Exhibitor", exhibitor.exhibitor, ["user", "company"], as_dict= True)
%}
{% set member = frappe.get_doc("User", exhibitor_doc.user) %}
<div class="common-card-style member-card">
{% set color = member.get_palette() %}
<a class="button-links" href="/user/{{member.username}}">
<span class="avatar avatar-large" 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 }}">
</img>
{% else %}
<span class="avatar-frame standard-image" title="{{ member.full_name }}"
style="background-color: var({{color[0]}}); color: var({{color[1]}});">
{{ frappe.utils.get_abbr(member.full_name) }}
</span>
{% endif %}
</span>
</a>
<div class="small-title member-card-title">
{{ member.full_name }}
</div>
<div class="small-title">
{{exhibitor_doc.company}}
</div>
<a class="stretched-link" href=""></a>
</div>
{% endfor %}
</div>
<div class="event-btn"><a href="/exhibitor-registration?new=1&user={{ frappe.session.user }}&event={{ event }}"
class="btn btn-primary ">Become an Exhibitor</a></div>
</div>
</div>

View File

@@ -0,0 +1,49 @@
{
"__unsaved": 1,
"creation": "2021-08-13 15:05:41.606772",
"docstatus": 0,
"doctype": "Web Template",
"fields": [
{
"fieldname": "title",
"fieldtype": "Data",
"label": "Title",
"reqd": 0
},
{
"fieldname": "subtitle",
"fieldtype": "Data",
"label": "Subtitle",
"reqd": 0
},
{
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details",
"reqd": 0
},
{
"fieldname": "exhibitor_details",
"fieldtype": "Table Break",
"label": "Exhibitor Details",
"reqd": 0
},
{
"fieldname": "exhibitor",
"fieldtype": "Link",
"label": "Exhibitor",
"options": "Exhibitor",
"reqd": 0
}
],
"idx": 1,
"modified": "2021-08-20 16:28:22.779057",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Exhibitor Section",
"owner": "Administrator",
"standard": 1,
"template": "",
"type": "Section"
}

View File

@@ -0,0 +1,3 @@
<div class="section-with-cards">
<h1 class="course-home-headings">{{title}}</h1>
</div>

View File

@@ -0,0 +1,43 @@
{
"__unsaved": 1,
"creation": "2021-08-20 08:12:29.549625",
"docstatus": 0,
"doctype": "Web Template",
"fields": [
{
"fieldname": "title",
"fieldtype": "Data",
"label": "Title",
"reqd": 0
},
{
"fieldname": "subtitle",
"fieldtype": "Data",
"label": "Subtitle",
"reqd": 0
},
{
"__unsaved": 1,
"fieldname": "hosts",
"fieldtype": "Table Break",
"label": "Hosts",
"reqd": 0
},
{
"fieldname": "host",
"fieldtype": "Link",
"label": "Host",
"options": "Host",
"reqd": 0
}
],
"idx": 0,
"modified": "2021-08-20 08:16:25.805456",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Host Section",
"owner": "Administrator",
"standard": 1,
"template": "",
"type": "Section"
}

View File

@@ -0,0 +1,44 @@
<div class="section-with-cards">
<h1 class="course-home-headings">{{section_title}}</h1>
{%- if subtitle -%}
<p class="section-description">{{ subtitle }}</p>
{%- endif -%}
<div class="mentors-section">
{% for speaker in speaker_details %}
{% set speaker_doc = frappe.db.get_value("Speaker", speaker.speaker, ["user", "company"], as_dict= True)
%}
{% set member = frappe.get_doc("User", speaker_doc.user) %}
<div class="common-card-style member-card">
{% set color = member.get_palette() %}
<a class="button-links" href="/user/{{member.username}}">
<span class="avatar avatar-large" 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 }}">
</img>
{% else %}
<span class="avatar-frame standard-image" title="{{ member.full_name }}"
style="background-color: var({{color[0]}}); color: var({{color[1]}});">
{{ frappe.utils.get_abbr(member.full_name) }}
</span>
{% endif %}
</span>
</a>
<div class="small-title member-card-title">
{{ member.full_name }}
</div>
<div class="small-title">
{{speaker_doc.company}}
</div>
<a class="stretched-link" href=""></a>
</div>
{% endfor %}
</div>
<div class="event-btn">
<a href='/propose-talk?new=1&event={{ event }}' class="btn btn-primary ">Propose a Talk</a>
</div>
</div>

View File

@@ -0,0 +1,49 @@
{
"__unsaved": 1,
"creation": "2021-08-12 21:15:14.492000",
"docstatus": 0,
"doctype": "Web Template",
"fields": [
{
"fieldname": "section_title",
"fieldtype": "Data",
"label": "Section Title",
"reqd": 1
},
{
"fieldname": "subtitle",
"fieldtype": "Data",
"label": "Subtitle",
"reqd": 0
},
{
"fieldname": "event_",
"fieldtype": "Link",
"label": "Event ",
"options": "Event Details",
"reqd": 0
},
{
"fieldname": "speaker_details",
"fieldtype": "Table Break",
"label": "Speaker Details",
"reqd": 0
},
{
"fieldname": "speaker",
"fieldtype": "Link",
"label": "Speaker",
"options": "Speaker",
"reqd": 0
}
],
"idx": 1,
"modified": "2021-08-20 10:59:54.965714",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Speaker Section",
"owner": "Administrator",
"standard": 1,
"template": "",
"type": "Section"
}

View File

@@ -0,0 +1,53 @@
<div class="section-with-cards">
<div class="course-home-headings">{{title}}</div>
{%- if subtitle -%}
<p class="section-description">{{ subtitle }}</p>
{%- endif -%}
<div class="cards-parent">
{% for talk in talk_details %}
{% set talk_doc = frappe.db.get_value('Talk', talk.talk, ["title", "category", "speaker", "url", "thumbnail"], as_dict=True) %}
{% set speaker_info = frappe.db.get_value("Speaker", talk_doc.speaker, ["user"], as_dict=True) %}
{% set member = frappe.get_doc("User", speaker_info.user) %}
<div class="common-card-style flex-column">
<div class="course-image" style="background-image: url({{talk_doc.thumbnail}})">
<div class="course-tags"></div>
</div>
<div class="course-card-content">
<div class="course-card-meta muted-text">
<span> {{talk_doc.category}} </span>
</div>
<div class="course-card-title">{{talk_doc.title}}</div>
<div class="card-divider"></div>
<div class="course-card-meta-2">
{% set color = member.get_palette() %}
<a class="button-links" href="/user/{{member.username}}">
<span class="avatar avatar-small" 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 }}">
</img>
{% else %}
<span class="avatar-frame standard-image" title="{{ member.full_name }}"
style="background-color: var({{color[0]}}); color: var({{color[1]}});">
{{ frappe.utils.get_abbr(member.full_name) }}
</span>
{% endif %}
</span>
</a>
<span class="course-instructor"> {{ member.full_name }} </span>
<span class="small-title company-name"></span>
</div>
<div class="view-talk-link">
Vew Talk
<img class="ml-3" src="/assets/community/icons/black-arrow.svg" />
</div>
<a class="stretched-link" href="{{talk_doc.url}}"></a>
</div>
</div>
{% endfor %}
</div>
</div>

View File

@@ -0,0 +1,49 @@
{
"__unsaved": 1,
"creation": "2021-08-13 11:34:07.611034",
"docstatus": 0,
"doctype": "Web Template",
"fields": [
{
"fieldname": "title",
"fieldtype": "Data",
"label": "Title",
"reqd": 1
},
{
"fieldname": "subtitle",
"fieldtype": "Data",
"label": "Subtitle",
"reqd": 0
},
{
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details",
"reqd": 1
},
{
"fieldname": "talk_details",
"fieldtype": "Table Break",
"label": "Talk Details",
"reqd": 0
},
{
"fieldname": "talk",
"fieldtype": "Link",
"label": "Talk",
"options": "Talk",
"reqd": 0
}
],
"idx": 1,
"modified": "2021-08-20 10:58:45.556636",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Talk Section",
"owner": "Administrator",
"standard": 1,
"template": "",
"type": "Section"
}

View File

@@ -146,7 +146,7 @@ primary_rules = [
{"from_route": "/courses/<course>/about", "to_route": "batch/about"},
{"from_route": "/courses/<course>/progress", "to_route": "batch/progress"},
{"from_route": "/courses/<course>/join", "to_route": "batch/join"},
{"from_route": "/discussions/<discussion>", "to_route": "discussions/discussion"}
{"from_route": "/discussions/<discussion>", "to_route": "discussions/discussion"},
]
# Any frappe default URL is blocked by profile-rules, add it here to unblock it
@@ -169,7 +169,14 @@ whitelist = [
"/message",
"/about",
"/edit-profile",
"/discussions"
"/attendee-registration",
"/speaker-registration",
"/event",
"/hello",
"/exhibitor-registration",
"/discussions",
"/propose-talk",
]
whitelist_rules = [{"from_route": p, "to_route": p[1:]} for p in whitelist]

View File

@@ -91,7 +91,8 @@ def save_progress(lesson, course, status):
"lesson": lesson,
"status": status,
}).save(ignore_permissions=True)
return "OK"
course_details = frappe.get_doc("LMS Course", course)
return course_details.get_course_progress()
def update_progress(lesson):
user = frappe.session.user

View File

@@ -0,0 +1,14 @@
// Copyright (c) 2021, FOSS United and contributors
// For license information, please see license.txt
frappe.ui.form.on('LMS Certification', {
onload: function (frm) {
frm.set_query("student", function (doc) {
return {
filters: {
"ignore_user_type": 1,
}
};
});
}
});

View File

@@ -0,0 +1,70 @@
{
"actions": [],
"creation": "2021-08-16 15:47:19.494055",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"student",
"issue_date",
"column_break_3",
"course",
"expiry_date"
],
"fields": [
{
"fieldname": "student",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Student",
"options": "User"
},
{
"fieldname": "issue_date",
"fieldtype": "Date",
"label": "Issue Date"
},
{
"fieldname": "column_break_3",
"fieldtype": "Column Break"
},
{
"fieldname": "course",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Course",
"options": "LMS Course"
},
{
"fieldname": "expiry_date",
"fieldtype": "Date",
"label": "Expiry Date"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-16 15:47:19.494055",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Certification",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -0,0 +1,41 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
from frappe.utils import nowdate, add_years
from frappe import _
from frappe.utils.pdf import get_pdf
class LMSCertification(Document):
def validate(self):
certificates = frappe.get_all("LMS Certification", {
"student": self.student,
"course": self.course,
"expiry_date": [">", nowdate()]
})
if len(certificates):
full_name = frappe.db.get_value("User", self.student, "full_name")
course_name = frappe.db.get_value("LMS Course", self.course, "title")
frappe.throw(_("There is already a valid certificate for user {0} for the course {1}").format(full_name, course_name))
@frappe.whitelist()
def create_certificate(course):
course_details = frappe.get_doc("LMS Course", course)
certificate = course_details.is_certified()
if certificate:
return certificate
else:
expires_after_yrs = course_details.expiry
certificate = frappe.get_doc({
"doctype": "LMS Certification",
"student": frappe.session.user,
"course": course,
"issue_date": nowdate(),
"expiry_date": add_years(nowdate(), int(expires_after_yrs))
})
certificate.save(ignore_permissions=True)
return certificate.name

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestLMSCertification(unittest.TestCase):
pass

View File

@@ -25,7 +25,10 @@
"section_break_5",
"short_introduction",
"description",
"chapters"
"chapters",
"certification_section",
"enable_certification",
"expiry"
],
"fields": [
{
@@ -94,6 +97,25 @@
"fieldtype": "Table",
"label": "Chapters",
"options": "Chapters"
},
{
"fieldname": "certification_section",
"fieldtype": "Section Break",
"label": "Certification"
},
{
"default": "0",
"fieldname": "enable_certification",
"fieldtype": "Check",
"label": "Enable Certification"
},
{
"default": "0",
"depends_on": "enable_certification",
"fieldname": "expiry",
"fieldtype": "Select",
"label": "Certification Expires After Years",
"options": "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"
}
],
"index_web_pages_for_search": 1,
@@ -115,7 +137,7 @@
"link_fieldname": "course"
}
],
"modified": "2021-07-28 19:01:50.677445",
"modified": "2021-08-18 18:02:12.623807",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Course",

View File

@@ -347,6 +347,16 @@ class LMSCourse(Document):
"next": numbers[index+1] if index+1 < len(numbers) else None
}
def is_certified(self):
certificate = frappe.get_all("LMS Certification",
{
"student": frappe.session.user,
"course": self.name
})
if len(certificate):
return certificate[0].name
return
@frappe.whitelist()
def reindex_exercises(doc):
course_data = json.loads(doc)

View File

@@ -8,7 +8,7 @@ frappe.ready(function () {
frappe.web_form.after_save = () => {
setTimeout(() => {
window.location.href = `/${frappe.web_form.get_value(["username"])}`;
window.location.href = `/user/${frappe.web_form.get_value(["username"])}`;
})
}
})

View File

@@ -12,7 +12,7 @@
{% endif %}
<div class="course-author">
{% with author = course.get_instructor() %}
{{ widgets.Avatar(member=author, avatar_class="avatar-medium") }} <a href="/{{author.username}}">{{ author.full_name }}</a>
{{ widgets.Avatar(member=author, avatar_class="avatar-medium") }} <a href="/user/{{author.username}}">{{ author.full_name }}</a>
{% endwith %}
</div>
</div>

View File

@@ -1,6 +1,6 @@
<div class="instructor">
{{ widgets.Avatar(member=instructor, avatar_class="avatar-medium") }}
<a class="ml-1 instructor-title" href="/{{instructor.username}}">{{ instructor.full_name }}</a>
<a class="ml-1 instructor-title" href="/user/{{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>

View File

@@ -11,5 +11,5 @@
Created {{ course_count }} {{ suffix }}
</div>
{% endif %}
<a class="stretched-link" href="/{{ member.username }}"></a>
<a class="stretched-link" href="/user/{{ member.username }}"></a>
</div>

View File

@@ -18,7 +18,7 @@
<div class="review-card-footer">
<div>
{{ widgets.Avatar(member=review.owner_details, avatar_class="avatar-medium") }}
<a class="button-links" href="/{{review.owner_details.username}}">
<a class="button-links" href="/user/{{review.owner_details.username}}">
<span class="course-instructor">
{{ review.owner_details.full_name }}
</span>

View File

@@ -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>

View File

@@ -1,4 +1,5 @@
Community
Hackathon
LMS
Conference
Conference
Event Management

View File

@@ -279,6 +279,16 @@ input[type=checkbox] {
line-height: 135%;
color: var(--text-color);
}
.view-talk-link {
background: var(--button-background);
border-radius: 4px;
font-size: 14px;
padding: 8px 22px 8px;
text-align: center;
line-height: 135%;
color: var(--text-color);
}
.cards-parent {
display: grid;
@@ -749,6 +759,10 @@ input[type=checkbox] {
padding: 20px 0px 16px;
}
.member-card .talk-title{
font-weight: bold;
}
.member-card-large {
width: 256px;
height: 188px;
@@ -774,6 +788,7 @@ input[type=checkbox] {
font-weight: bold;
}
.member-card-xl .member-card-title {
font-weight: bold;
}
@@ -828,6 +843,11 @@ input[type=checkbox] {
margin: 0;
}
.avatar-medium-schedule{
width: 70px;
height: 70px;
}
.avatar-large {
width: 88px;
height: 88px;
@@ -1263,6 +1283,103 @@ pre {
font-size: 1rem;
}
.talk-title {
border-bottom: 1px solid #cecdcd;
}
.mt-5 {
margin-top: 5px;
}
.company-name {
font-weight: bold;
}
a.talk-link {
text-decoration: none;
}
.speaker-cards-parent {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
-moz-column-gap: 32px;
column-gap: 14px;
row-gap: 32px;
}
.avatar img {
object-fit: cover;
}
.section-with-cards .course-home-headings {
margin: 0px 0px 1rem;
}
.schedule-container {
padding-bottom: 16px;
}
.schedule-inner-container {
display: grid;
grid-template-columns: 1.2fr 2fr 1fr 0.2fr;
padding: 0 20px 0;
}
.schedule-slot {
font-weight: bolder;
}
.schedule-title {
font-size: 20px;
}
.schedule-info{
padding: 20px;
}
.drop-down-icon {
padding : 5px 0 0 5px;
}
.event-btn {
display: flex;
align-items: center;
justify-content: center;
margin-top: 3rem;
}
.exhibitor-card {
text-align: center;
padding-bottom: 30px;
}
.exhibitor-card .company-name{
font-size: 25px;
margin-top: 30px;
}
.exhibitor-card .company-logo{
height: 158px;
width: 252px;
object-fit: contain;
}
.info-speaker-avatar {
display: flex;
text-align: left;
}
.info-speaker {
margin-left: 1rem;
padding-bottom: 0;
margin-top: 6px;
}
.info-avatar img{
object-fit: contain;
}
.thread-card {
flex-direction: column;
padding: 1.5rem;
@@ -1295,3 +1412,40 @@ textarea.form-control {
color: #192734;
margin-left: 0.5rem;
}
.certificate-page .common-card-style {
flex-direction: column;
font-family: Inter;
color: black;
font-size: 2rem;
text-align: center;
padding: 5rem;
background-image: url(/assets/community/images/certificate-background.png);
}
.certificate-heading {
font-size: 4rem;
margin-bottom: 3rem;
font-weight: bold;
}
.certificate-para {
margin-bottom: 3rem;
}
@media (max-width: 768px) {
.certificate-page .common-card-style {
padding: 2rem;
font-size: 1.5rem;
}
.certificate-heading {
font-size: 3rem;
}
}
@media (max-width: 360px) {
.certificate-heading {
font-size: 2rem;
}
}

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z"/>
</svg>

After

Width:  |  Height:  |  Size: 293 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M6 9l6 6 6-6"/>
</svg>

After

Width:  |  Height:  |  Size: 206 B

View 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

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="25" height="25" fill="none" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path fill-rule="evenodd" d="M7.646 4.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1-.708.708L8 5.707l-5.646 5.647a.5.5 0 0 1-.708-.708l6-6z"/>
</svg>

After

Width:  |  Height:  |  Size: 296 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,32 @@
<div class="common-card-style">
<div class="certificate-heading">
Certificate of Completion
</div>
<div class="certificate-para">
This is to certify that <span class="font-weight-bold">{{ student.full_name }}</span> has successfully completed
<span class="font-weight-bold">{{ course.title }}</span> online course on
<span class="font-weight-bold">{{ frappe.utils.format_date(certificate.issue_date, "medium") }}</span>
</div>
<div style="display: flex; justify-content: space-between;" class="certificate-footer">
<div>
<div class="font-weight-bold">
Instructor:
</div>
<div>
{{ instructor.full_name }}
</div>
</div>
<div>
<div class="font-weight-bold">
Expiry Date:
</div>
<div>
{{ frappe.utils.format_date(certificate.expiry_date, "medium") }}
</div>
</div>
</div>
<div>
<img src="{{ logo }}" style="height: 50px;">
</div>
</div>
<script src="/assets/community/js/html2canvas.js"></script>

View File

@@ -2,7 +2,7 @@
<div class="mb-4">
{% set member = frappe.get_doc("User", message.owner) %}
{{ widgets.Avatar(member=member, avatar_class="avatar-small")}}
<a class="button-links" href="/{{ member.username }}">
<a class="button-links" href="/user/{{ member.username }}">
<span class="message-author">{{ member.full_name }}</span>
</a>
<span class="muted-text pull-right">{{ frappe.utils.format_datetime(message.creation, "dd MMM hh:mm") }}</span>

View File

@@ -63,7 +63,7 @@
<div>
{% if prev_url %}
<a class="button is-secondary dark-links" href="{{ prev_url }}">
<a class="button is-secondary dark-links prev" href="{{ prev_url }}">
<img class="mr-2" src="/assets/community/icons/left-arrow.svg">
Prev
</a>
@@ -87,10 +87,14 @@
<div>
{% if next_url %}
<a class="button is-primary" href="{{ next_url }}">
<a class="button is-primary next" href="{{ next_url }}">
Next
<img class="ml-2" src="/assets/community/icons/side-arrow-white.svg">
</a>
{% elif course.enable_certification %}
<div class="button is-primary {% if course.get_course_progress() != 100 %} hide {% endif %}" id="certification">
Get Certificate
</div>
{% endif %}
</div>

View File

@@ -28,6 +28,10 @@ frappe.ready(() => {
try_quiz_again(e);
});
$("#certification").click((e) => {
create_certificate(e);
})
})
var save_current_lesson = () => {
@@ -71,8 +75,9 @@ var mark_progress = (e) => {
status: status
},
callback: (data) => {
if (data.message == "OK") {
change_progress_indicators(status, e);
change_progress_indicators(status, e);
if (data.message == 100 && !$(".next").length && $("#certification").hasClass("hide")) {
$("#certification").removeClass("hide");
}
}
})
@@ -166,3 +171,17 @@ var add_to_local_storage = (quiz_name, current_index, answer, is_correct) => {
quiz_stored ? quiz_stored.push(quiz_obj) : quiz_stored = [quiz_obj]
localStorage.setItem(quiz_name, JSON.stringify(quiz_stored))
}
var create_certificate = (e) => {
e.preventDefault();
course = $(".title").attr("data-course");
frappe.call({
method: "community.lms.doctype.lms_certification.lms_certification.create_certificate",
args: {
"course": course
},
callback: (data) => {
window.location.href = `/courses/${course}/${data.message}`;
}
})
}

View File

@@ -0,0 +1,25 @@
{% extends "templates/base.html" %}
{% from "www/macros/common_macro.html" import MentorsSection %}
{% block title %} {{ student.full_name }} - {{ course.title }} {% endblock %}
{% block content %}
<div class="common-page-style">
<div class="container certificate-page">
<div class="breadcrumb">
<a class="dark-links" href="/courses">All Courses</a>
<img class="ml-1 mr-1" src="/assets/community/icons/chevron-right.svg">
<a class="dark-links" href="/courses/{{ course.name }}">{{ course.title }}</a>
</div>
{% if certificate.student == frappe.session.user %}
<div class="comment-footer mb-5">
<div class="button is-secondary pull-right" id="export-as-pdf" data-certificate="{{ certificate.name }}"
data-certificate-name="{{ student.full_name }} - {{ course.title }}">Export</div>
</div>
{% endif %}
{% include "community/templates/certificate.html" %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,29 @@
frappe.ready(() => {
if ($(document).width() <= 550) {
$(".certificate-footer").css("flex-direction", "column");
$(".certificate-footer").children().addClass("mb-5");
}
$("#export-as-pdf").click((e) => {
export_as_pdf(e);
})
})
var export_as_pdf = (e) => {
var button = $(e.currentTarget);
button.text(__("Exporting..."));
html2canvas(document.querySelector('.common-card-style'), {
scrollY: -window.scrollY,
scrollX: 0
}).then(function(canvas) {
let dataURL = canvas.toDataURL('image/png');
let a = document.createElement('a');
a.href = dataURL;
a.download = button.attr("data-certificate-name");
a.click();
}).finally(() => {
button.text(__("Export"))
});
}

View File

@@ -0,0 +1,31 @@
import frappe
def get_context(context):
context.no_cache = 1
try:
course_name = frappe.form_dict["course"]
certificate_name = frappe.form_dict["certificate"]
except KeyError:
redirect_to_course_list()
context.certificate = frappe.db.get_value("LMS Certification", certificate_name,
["name", "student", "issue_date", "expiry_date", "course"], as_dict=True)
if context.certificate.course != course_name:
redirect_to_course_list()
context.course = frappe.db.get_value("LMS Course", course_name,
["owner", "title", "name"], as_dict=True)
context.instructor = frappe.db.get_value("User", context.course.owner,
["full_name", "username"], as_dict=True)
context.student = frappe.db.get_value("User", context.certificate.student,
["full_name"], as_dict=True)
context.logo = frappe.db.get_single_value("Website Settings", "banner_image")
def redirect_to_course_list():
frappe.local.flags.redirect_location = "/courses"
raise frappe.Redirect

View File

@@ -70,6 +70,10 @@
<img class="ml-2" src="/assets/community/images/play.png" />
</div>
{% endif %}
{% set certificate = course.is_certified() %}
{% if certificate %}
<a class="button wide-button is-secondary dark-links" href="/courses/{{ course.name }}/{{ certificate }}">Get Certificate</a>
{% endif %}
</div>
</div>
</div>
@@ -119,7 +123,7 @@
{% if progress != 100 %}
Great work so far!
{% else %}
Excellent Work on completing this course 👏
Excellent work on completing this course 👏
{% endif %}
</p>
<p class="progress-text">

View File

@@ -67,4 +67,4 @@
})
</script>
{% endblock %}
{% endblock %}

Some files were not shown because too many files have changed in this diff Show More