Compare commits

..

22 Commits

Author SHA1 Message Date
pateljannat
4c55f1f71c fix: exhibitor template 2021-08-19 12:16:05 +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
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
a3672e9d91 feat: discussions 2021-08-16 13:33:08 +05:30
pateljannat
7017382451 fix: removed sketch card 2021-08-11 11:40:57 +05:30
pateljannat
6c9d49bf8c discussion doctypes 2021-08-11 11:14:40 +05:30
pateljannat
2de058246b Merge branch 'main' of https://github.com/frappe/community into main 2021-08-11 10:46:11 +05:30
pateljannat
798ea30382 fix: chapter teaser jerk issue 2021-08-11 10:46:01 +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
Jannat Patel
83a2f42df9 Merge pull request #171 from fossunited/username-fixes
fix: username issues
2021-08-10 13:19:29 +05:30
pateljannat
66aace247c fix: conditions and tests 2021-08-10 10:28:59 +05:30
pateljannat
bc3db06960 fix: username issues 2021-08-09 16:54:02 +05:30
Jannat Patel
ddaa063587 Merge pull request #170 from fossunited/upcoming-course-notify
feat: notify me
2021-08-09 15:39:04 +05:30
113 changed files with 2414 additions and 393 deletions

View File

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

View File

@@ -1,67 +1,53 @@
{
"actions": [],
"creation": "2021-03-19 12:19:32.355307",
"creation": "2021-08-11 10:59:38.597046",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"author",
"batch",
"column_break_3",
"author_name",
"pin",
"section_break_6",
"thread",
"column_break_2",
"parent_message",
"section_break_4",
"message"
],
"fields": [
{
"fieldname": "batch",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Batch",
"options": "LMS Batch"
},
{
"fieldname": "author",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Author",
"options": "User"
},
{
"fieldname": "message",
"fieldtype": "Markdown Editor",
"fieldtype": "Long Text",
"in_list_view": 1,
"label": "Message"
},
{
"default": "0",
"fieldname": "pin",
"fieldtype": "Check",
"label": "Pin"
"fieldname": "thread",
"fieldtype": "Link",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Thread",
"options": "Discussion Thread"
},
{
"fetch_from": "author.full_name",
"fieldname": "author_name",
"fieldtype": "Data",
"label": "Author Name",
"read_only": 1
},
{
"fieldname": "column_break_3",
"fieldname": "column_break_2",
"fieldtype": "Column Break"
},
{
"fieldname": "section_break_6",
"fieldname": "parent_message",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Parent Message",
"options": "Discussion Message"
},
{
"fieldname": "section_break_4",
"fieldtype": "Section Break"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-05-21 11:49:34.911479",
"modified": "2021-08-12 15:59:04.811286",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Message",
"module": "Community",
"name": "Discussion Message",
"owner": "Administrator",
"permissions": [
{
@@ -77,9 +63,7 @@
"write": 1
}
],
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "author",
"track_changes": 1
}
}

View File

@@ -0,0 +1,22 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
from community.widgets import Widget, Widgets
class DiscussionMessage(Document):
def after_insert(self):
data = {
"message": self,
"widgets": Widgets()
}
template = frappe.render_template("community/templates/message_card.html", data)
thread_info = frappe.db.get_value("Discussion Thread", self.thread, ["reference_doctype", "reference_docname"], as_dict=True)
frappe.publish_realtime(event="publish_message",
message = {
"thread": self.thread,
"template": template,
"thread_info": thread_info
},
after_commit=True)

View File

@@ -1,10 +1,8 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
from __future__ import unicode_literals
# import frappe
import unittest
class TestLMSMessage(unittest.TestCase):
class TestDiscussionMessage(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('Discussion Thread', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,57 @@
{
"actions": [],
"creation": "2021-08-11 10:55:29.341674",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"title",
"reference_doctype",
"reference_docname"
],
"fields": [
{
"fieldname": "title",
"fieldtype": "Data",
"label": "Title"
},
{
"fieldname": "reference_doctype",
"fieldtype": "Link",
"label": "Reference Doctype",
"options": "DocType"
},
{
"fieldname": "reference_docname",
"fieldtype": "Dynamic Link",
"label": "Reference Docname",
"options": "reference_doctype"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-11 12:29:43.564123",
"modified_by": "Administrator",
"module": "Community",
"name": "Discussion Thread",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"search_fields": "title",
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "title",
"track_changes": 1
}

View File

@@ -0,0 +1,48 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
class DiscussionThread(Document):
pass
@frappe.whitelist()
def submit_discussion(doctype, docname, message, title=None, thread_name=None):
thread = []
filters = {}
if doctype and docname:
filters = {
"reference_doctype": doctype,
"reference_docname": docname
}
elif thread_name:
filters = {
"name": thread_name
}
if filters:
thread = frappe.get_all("Discussion Thread",filters)
if len(thread):
thread = thread[0]
save_message(message, thread)
else:
thread = frappe.get_doc({
"doctype": "Discussion Thread",
"title": title,
"reference_doctype": doctype,
"reference_docname": docname
})
thread.save(ignore_permissions=True)
save_message(message, thread)
return thread.name
def save_message(message, thread):
frappe.get_doc({
"doctype": "Discussion Message",
"message": message,
"thread": thread.name
}).save(ignore_permissions=True)

View File

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

View File

@@ -0,0 +1,70 @@
<div class="discussions">
<form class="discussion-form {% if doctype or thread %} discussion-on-page {% endif %}" id="discussion-form">
<div class="form-group" {% if title or thread %} style="display: none;" {% endif %}>
<div class="control-input-wrapper">
<div class="control-input">
<input type="text" autocomplete="off" class="input-with-feedback form-control thread-title"
data-fieldtype="Data" data-fieldname="feedback_comments" placeholder="Title" spellcheck="false" {% if title
%} value="{{ title }}" {% endif %}></input>
</div>
</div>
</div>
<div class="form-group">
<div class="control-input-wrapper">
<div class="control-input">
<textarea type="text" autocomplete="off" class="input-with-feedback form-control comment-field"
data-fieldtype="Text" data-fieldname="feedback_comments" placeholder="Enter a comment..."
spellcheck="false"></textarea>
</div>
</div>
</div>
<div class="comment-footer">
<div class="button is-secondary pull-right" id="submit-discussion"
{% if doctype %} data-doctype="{{ doctype | urlencode}}" {% endif %}
{% if docname %} data-docname="{{ docname | urlencode}}" {% endif %}
{% if thread %} data-thread="{{ thread }}" {% endif %}>
Post</div>
</div>
</form>
</div>
<script>
frappe.ready(() => {
$("#submit-discussion").click((e) => {
submit_discussion(e);
})
})
var submit_discussion = (e) => {
var message = $(".comment-field").val().trim();
if (message) {
var doctype = $(e.currentTarget).attr("data-doctype");
doctype = doctype ? decodeURIComponent(doctype) : doctype;
var docname = $(e.currentTarget).attr("data-docname");
docname = docname ? decodeURIComponent(docname) : docname;
frappe.call({
method: "community.community.doctype.discussion_thread.discussion_thread.submit_discussion",
args: {
"doctype": doctype ? doctype : "",
"docname": docname ? docname : "",
"message": $(".comment-field").val(),
"title": $(".thread-title").val(),
"thread_name": $(e.currentTarget).attr("data-thread")
},
callback: (data) => {
if (! $(".discussion-on-page").length) {
$("#discussion-modal").modal("hide");
window.location.href = `/discussions/${data.message}`;
}
}
})
}
}
</script>

View File

@@ -0,0 +1,80 @@
{% if doctype and docname and not thread %}
{% set thread_info = frappe.get_all("Discussion Thread", {"reference_doctype": doctype, "reference_docname": docname},
["name"]) %}
{% if thread_info | length %}
{% set thread = thread_info[0].name %}
{% endif %}
{% endif %}
{% if thread %}
{% set messages = frappe.get_all("Discussion Message", {"thread": thread}, ["name", "message", "owner", "creation"],
order_by="creation") %}
{% endif %}
{% if doctype %}
<div class="course-home-headings mt-5"> Discussions </div>
{% endif %}
<div class="messages mt-5">
{% for message in messages %}
{% include "community/templates/message_card.html" %}
{% endfor %}
</div>
{% if frappe.session.user == "Guest" or (condition is defined and not condition) %}
<div class="d-flex flex-column align-items-center font-weight-bold">
Want to join the discussion?
{% if frappe.session.user == "Guest" %}
<div class="button is-primary" id="login-from-discussion">Log In</div>
{% elif not condition %}
<div class="button is-primary" id="login-from-discussion" data-redirect="{{ redirect_to }}">{{ button_name }}</div>
{% endif %}
</div>
{% else %}
{{ widgets.DiscussionComment(doctype=doctype, docname=docname, title=title, thread=thread ) }}
{% endif %}
<script>
frappe.ready(() => {
setup_socket_io();
$("#login-from-discussion").click((e) => {
login_from_discussion(e);
})
})
var setup_socket_io = () => {
const assets = [
"/assets/frappe/js/lib/socket.io.min.js",
"/assets/frappe/js/frappe/socketio_client.js",
]
frappe.require(assets, () => {
if (window.dev_server) {
frappe.boot.socketio_port = "9000";
}
frappe.socketio.init(9000);
var target = $("#submit-discussion");
frappe.socketio.socket.on("publish_message", (data) => {
if (target.attr("data-thread") == data.thread
|| (decodeURIComponent(target.attr("data-doctype")) == data.thread_info.reference_doctype
&& decodeURIComponent(target.attr("data-docname")) == data.thread_info.reference_docname)) {
$(".comment-field").val("");
$(".messages").append(data.template);
}
})
})
}
var login_from_discussion = (e) => {
var redirect = $(e.currentTarget).attr("data-redirect") || window.location.href;
window.location.href = `/login?redirect-to=${redirect}`;
}
</script>

View File

View File

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

View File

@@ -0,0 +1,77 @@
{
"actions": [],
"creation": "2021-08-11 10:07:53.262504",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"attendee_info_section",
"name1",
"email",
"phone_number",
"occupation",
"company",
"what_are_you_hoping_to_learn"
],
"fields": [
{
"fieldname": "attendee_info_section",
"fieldtype": "Section Break",
"label": "Attendee Info"
},
{
"fieldname": "name1",
"fieldtype": "Data",
"label": "Name"
},
{
"fieldname": "email",
"fieldtype": "Data",
"label": "Email"
},
{
"fieldname": "phone_number",
"fieldtype": "Data",
"label": "Phone Number"
},
{
"fieldname": "occupation",
"fieldtype": "Data",
"label": "Occupation"
},
{
"fieldname": "company",
"fieldtype": "Data",
"label": "Company"
},
{
"fieldname": "what_are_you_hoping_to_learn",
"fieldtype": "Text",
"label": "What are you hoping to learn"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-11 10:07:53.262504",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Attendee Registration",
"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 AttendeeRegistration(Document):
pass

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestAttendeeRegistration(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 Registration"
},
{
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-18 09:51:14.654098",
"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 Registration', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,54 @@
{
"actions": [],
"autoname": "Exhibitor-Regis-.####.",
"creation": "2021-08-16 16:26:46.189119",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"full_name",
"company",
"logo"
],
"fields": [
{
"fieldname": "full_name",
"fieldtype": "Data",
"label": "Full Name"
},
{
"fieldname": "company",
"fieldtype": "Data",
"label": "Company "
},
{
"fieldname": "logo",
"fieldtype": "Attach Image",
"label": "Logo"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-18 20:08:31.591935",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Exhibitor Registration",
"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 ExhibitorRegistration(Document):
pass

View File

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

View File

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

View File

@@ -0,0 +1,65 @@
{
"actions": [],
"autoname": "field:full_name",
"creation": "2021-08-11 10:51:47.234690",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"event",
"full_name",
"user_image",
"title"
],
"fields": [
{
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details"
},
{
"fieldname": "title",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Title"
},
{
"fieldname": "full_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Full Name",
"reqd": 1,
"unique": 1
},
{
"fieldname": "user_image",
"fieldtype": "Attach Image",
"label": "Image"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-11 23:54:17.790263",
"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",
"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('Previous Content', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,67 @@
{
"actions": [],
"autoname": "format:PRE-VID-BY-{name_of_the_speaker}-{####}",
"creation": "2021-08-18 08:42:58.711932",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"event",
"title",
"name_of_the_speaker",
"url",
"thumbnail"
],
"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"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-18 09:37:03.278439",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Previous Content",
"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 PreviousContent(Document):
pass

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestPreviousContent(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('Schedule', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,63 @@
{
"actions": [],
"autoname": "Schedule-.####",
"creation": "2021-08-11 10:50:23.522178",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"event",
"speaker",
"slot"
],
"fields": [
{
"fieldname": "speaker",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Speaker",
"options": "Speaker Registration",
"reqd": 1
},
{
"fieldname": "slot",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Slot",
"options": "Slot",
"reqd": 1
},
{
"fieldname": "event",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Event",
"options": "Event Details",
"reqd": 1
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-18 09:46:18.694910",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Schedule",
"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,18 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
class Schedule(Document):
def before_save(self):
exists = frappe.db.exists(
"Schedule",
{
"Event": self.event,
"slot": self.slot
},
)
if exists:
frappe.throw("Slot already Assigned")

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestSchedule(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('Slot', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,69 @@
{
"actions": [],
"autoname": "format:SLOT-{date}-{start_time}",
"creation": "2021-08-11 11:19:50.276917",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"event",
"date",
"start_time",
"end_time"
],
"fields": [
{
"fieldname": "event",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Event",
"options": "Event Details",
"reqd": 1
},
{
"fieldname": "date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Date",
"reqd": 1
},
{
"fieldname": "start_time",
"fieldtype": "Time",
"in_list_view": 1,
"label": "Start Time",
"reqd": 1
},
{
"fieldname": "end_time",
"fieldtype": "Time",
"in_list_view": 1,
"label": "End Time",
"reqd": 1
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-18 23:51:47.850435",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Slot",
"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,14 @@
# 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 getdate
class Slot(Document):
def before_save(self):
event = frappe.get_doc("Event Details", self.event)
if getdate(self.date) < event.start_date or getdate(self.date) > event.end_date:
frappe.throw("Slot should be in Event's span")

View File

@@ -0,0 +1,8 @@
# Copyright (c) 2021, FOSS United and Contributors
# See license.txt
# import frappe
import unittest
class TestSlot(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 Registration', {
// refresh: function(frm) {
// }
});

View File

@@ -0,0 +1,149 @@
{
"actions": [],
"autoname": "SPEAKER-REGIS.####.",
"creation": "2021-08-11 10:37:32.124651",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"speaker_info_section",
"full_name",
"email",
"phone_number",
"job_title",
"company",
"column_break_8",
"picture",
"bio",
"talk_info_section",
"topic",
"title",
"column_break_13",
"about",
"attachment",
"status"
],
"fields": [
{
"fieldname": "speaker_info_section",
"fieldtype": "Section Break",
"label": "Speaker Info"
},
{
"fieldname": "email",
"fieldtype": "Data",
"label": "Email",
"reqd": 1,
"unique": 1
},
{
"fieldname": "phone_number",
"fieldtype": "Data",
"label": "Phone Number",
"unique": 1
},
{
"fieldname": "job_title",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Job Title",
"reqd": 1
},
{
"fieldname": "company",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Company",
"reqd": 1
},
{
"fieldname": "picture",
"fieldtype": "Attach Image",
"label": "Profile Image",
"reqd": 1
},
{
"fieldname": "bio",
"fieldtype": "Text",
"label": "Bio"
},
{
"fieldname": "talk_info_section",
"fieldtype": "Section Break",
"label": "Talk Info"
},
{
"fieldname": "topic",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Topic",
"options": "Delivery\nCloud\nCustomer Success\nMarketing\nDevelopment\nHR\nCustomer Stories",
"reqd": 1
},
{
"fieldname": "title",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Title",
"reqd": 1
},
{
"fieldname": "about",
"fieldtype": "Text",
"label": "About",
"reqd": 1
},
{
"fieldname": "attachment",
"fieldtype": "Attach",
"label": "Attachment"
},
{
"fieldname": "column_break_8",
"fieldtype": "Column Break"
},
{
"fieldname": "column_break_13",
"fieldtype": "Column Break"
},
{
"default": "Applied",
"fieldname": "status",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Status",
"options": "Applied\nPending\nApproved\nRejected"
},
{
"fieldname": "full_name",
"fieldtype": "Data",
"in_list_view": 1,
"label": "Full Name",
"reqd": 1
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-08-18 09:48:19.602309",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Speaker Registration",
"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,10 @@
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
class SpeakerRegistration(Document):
def on_update(self):
pass

View File

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

View File

@@ -0,0 +1,3 @@
frappe.ready(function() {
// bind events here
})

View File

@@ -0,0 +1,122 @@
{
"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-11 10:08:24.418743",
"doc_type": "Attendee Registration",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2021-08-18 11:35:06.067390",
"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": 0,
"show_attachments": 0,
"show_in_grid": 0,
"show_sidebar": 0,
"sidebar_items": [],
"success_url": "/event/conference20221",
"title": "Attendee Registration",
"web_form_fields": [
{
"allow_read_on_all_link_options": 0,
"fieldname": "attendee_info_section",
"fieldtype": "Section Break",
"hidden": 0,
"label": "Attendee Info",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "name1",
"fieldtype": "Data",
"hidden": 0,
"label": "Name",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "email",
"fieldtype": "Data",
"hidden": 0,
"label": "Email",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "phone_number",
"fieldtype": "Data",
"hidden": 0,
"label": "Phone Number",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "occupation",
"fieldtype": "Data",
"hidden": 0,
"label": "Occupation",
"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": 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,3 @@
frappe.ready(function() {
// bind events here
})

View File

@@ -0,0 +1,74 @@
{
"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",
"doc_type": "Exhibitor Registration",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2021-08-17 11:51:02.929819",
"modified_by": "Administrator",
"module": "Event Management",
"name": "exhibitor-registration",
"owner": "Administrator",
"payment_button_label": "Buy Now",
"published": 1,
"route": "event/conference2021/exhibitor-registration",
"route_to_success_link": 0,
"show_attachments": 0,
"show_in_grid": 0,
"show_sidebar": 0,
"sidebar_items": [],
"success_url": "/exhibitor-registration",
"title": "Exhibitor Registration",
"web_form_fields": [
{
"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": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "logo",
"fieldtype": "Attach Image",
"hidden": 0,
"label": "Logo",
"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,3 @@
frappe.ready(function() {
// bind events here
})

View File

@@ -0,0 +1,218 @@
{
"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",
"creation": "2021-08-11 20:52:20.308925",
"doc_type": "Speaker Registration",
"docstatus": 0,
"doctype": "Web Form",
"idx": 0,
"introduction_text": "<div class=\"ql-editor read-mode\"><p><br></p></div>",
"is_standard": 1,
"login_required": 1,
"max_attachment_size": 0,
"modified": "2021-08-18 20:00:46.756407",
"modified_by": "Administrator",
"module": "Event Management",
"name": "speaker-registration",
"owner": "Administrator",
"payment_button_label": "Buy Now",
"published": 1,
"route": "event/conference2021/speaker-registration",
"route_to_success_link": 1,
"show_attachments": 0,
"show_in_grid": 0,
"show_sidebar": 0,
"sidebar_items": [],
"success_url": "/event/conference2021/about",
"title": "Speaker Registration",
"web_form_fields": [
{
"allow_read_on_all_link_options": 0,
"fieldname": "speaker_info_section",
"fieldtype": "Section Break",
"hidden": 0,
"label": "Speaker Info",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"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": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "email",
"fieldtype": "Data",
"hidden": 0,
"label": "Email",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "phone_number",
"fieldtype": "Data",
"hidden": 0,
"label": "Phone Number",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "job_title",
"fieldtype": "Data",
"hidden": 0,
"label": "Job Title",
"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": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "column_break_8",
"fieldtype": "Column Break",
"hidden": 0,
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "picture",
"fieldtype": "Attach Image",
"hidden": 0,
"label": "Picture",
"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": "Text",
"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": "talk_info_section",
"fieldtype": "Section Break",
"hidden": 0,
"label": "Talk Info",
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "topic",
"fieldtype": "Select",
"hidden": 0,
"label": "Topic",
"max_length": 0,
"max_value": 0,
"options": "Delivery\nCloud\nCustomer Success\nMarketing\nDevelopment\nHR\nCustomer Stories",
"read_only": 0,
"reqd": 1,
"show_in_filter": 0
},
{
"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": "column_break_13",
"fieldtype": "Column Break",
"hidden": 0,
"max_length": 0,
"max_value": 0,
"read_only": 0,
"reqd": 0,
"show_in_filter": 0
},
{
"allow_read_on_all_link_options": 0,
"fieldname": "about",
"fieldtype": "Data",
"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,20 @@
<div class="section-with-cards">
<div class="courses-header">
<span>{{ title }}</span>
{% set cta_link = "/exhibitor-registration" if frappe.session.user != "Guest" else
"/login?redirect_to=exhibitor-registration" %}
<a href={{cta_link}} class="button is-primary pull-right">Become an Exhibitor</a>
</div>
<div class="speaker-cards-parent">
{% for exhibitor in exhibitor_details %}
{% set exhibitor_doc = frappe.db.get_value("Exhibitor Registration", exhibitor.exhibitor, ["logo", "company"],
as_dict=True) %}
<div class="common-card-style flex-column exhibitor-card">
<span>
<img class="standard-image company-logo" src="{{exhibitor_doc.logo}}" />
</span>
<div class="font-weight-bold mt-5">{{exhibitor_doc.company}}</div>
</div>
{% endfor %}
</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 Registration",
"reqd": 0
}
],
"idx": 1,
"modified": "2021-08-19 10:57:20.815230",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Exhibitor Section",
"owner": "Administrator",
"standard": 1,
"template": "",
"type": "Section"
}

View File

@@ -0,0 +1,38 @@
<div class="section-with-cards">
<div class="course-home-headings">{{title}}</div>
<div class="speaker-cards-parent">
{% for video in talk_details %}
{% set video_details = frappe.get_doc('Previous Content', video.previous_content, filters={
'event': event
}) %}
<div class="common-card-style talk-card">
<div class="course-image" style="background-image: url({{video_details.thumbnail}})">
<div class="course-tags"></div>
</div>
<div class="course-card-content">
<div class="course-card-meta muted-text">
<span> ERPNext </span>
</div>
<div class="course-card-title">{{video_details.title}}</div>
<div class="card-divider"></div>
<div class="course-card-meta-2">
<a class="button-links" href="/rushabh">
<span class="avatar avatar-small" title="Rushabh Mehta">
<img class="avatar-frame standard-image" style="object-fit: cover"
src="{{video_details.thumbnail}}"
title={{video_details.name_of_the_speaker}} />
</span>
</a>
<span class="course-instructor"> {{video_details.name_of_the_speaker}} </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="{{video_details.url}}"></a>
</div>
</div>
{% endfor %}
</div>
</div>

View File

@@ -0,0 +1,52 @@
{
"__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
},
{
"__unsaved": 1,
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details",
"reqd": 1
},
{
"fieldname": "talk_details",
"fieldtype": "Table Break",
"label": "Talk Details",
"reqd": 0
},
{
"__islocal": 1,
"__unsaved": 1,
"fieldname": "previous_content",
"fieldtype": "Link",
"label": "Previous Content",
"options": "Previous Content",
"reqd": 0
}
],
"idx": 1,
"modified": "2021-08-18 10:03:50.193908",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Previous Talk",
"owner": "Administrator",
"standard": 1,
"template": "",
"type": "Section"
}

View File

@@ -0,0 +1,78 @@
{% set schedule_docs = frappe.get_all("Schedule", fields =["speaker", "slot"], filters={
'event': event
},) %}
{% set slot_data = {} %}
{% for schedule in schedule_docs %}
{% set speaker = frappe.get_doc("Speaker Registration", schedule.speaker) %}
{% set slot = frappe.get_doc("Slot", schedule.slot) %}
{% set slot_data = slot_data.setdefault(slot.date, []).append({
"slot": slot.name|string,
"start_time": slot.start_time,
"end_time": slot.end_time,
"speaker": speaker.name,
"picture": speaker.picture,
"about": speaker.about,
"title": speaker.title,
"full_name": speaker.full_name,
"email": speaker.email
}) %}
{% endfor %}
<div class="courses-header">{{title}}</div>
<div class="common-page-style">
<div class="container">
<div class="course-content-parent">
<div class="course-details-outline">
<div class="course-home-outline">
<div class="coure-outline">
<div>
{% for day in slot_data %}
<div class="small-title chapter-title" data-target="#apps-sites-and-bench"
data-toggle="collapse" aria-expanded="false">
<img class="chapter-icon" src="/assets/community/icons/chevron-right.svg" />
{{day}}
</div>
<div class="card-divider"></div>
</div>
{% endfor %}
</div>
</div>
<div>
{% for day in slot_data %}
{% set outer_loop = loop %}
<div class="course-details-outline">
<div class="course-home-headings">{{day}}</div>
<div class="coure-outline">
{% for slot in slot_data[day] %}
<div class="schedule-container">
<div class="schedule-inner-container">
<span class="info-speaker-avatar">
<span class="info-avatar avatar avatar-small">
<img class="avatar-frame standard-image" src="{{slot.picture}}" />
</span>
<h6 class="info-speaker">{{slot.full_name}}</h6>
</span>
<div class="schedule-title">{{slot.title}}</div>
<div class="schedule-slot">
{{ frappe.format(slot.start_time, {'fieldtype': 'Time'})}} - {{
frappe.format(slot.end_time, {'fieldtype': 'Time'}) }}
</div>
<div class="chapter-title small-title" data-toggle="collapse" data-target="#slot-{{loop.index}}-{{outer_loop.index}}" aria-expanded="false" aria-controls="collapseExample">
<img class="chapter-icon" src="/assets/community/icons/chevron-right.svg">
</div>
</div>
<div class="collapse" id="slot-{{loop.index}}-{{outer_loop.index}}">
<p class="schedule-info">{{slot.about}}</p>
</div>
<div class="card-divider"></div>
{% endfor %}
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,37 @@
{
"__unsaved": 1,
"creation": "2021-08-17 16:43:49.506200",
"docstatus": 0,
"doctype": "Web Template",
"fields": [
{
"fieldname": "title",
"fieldtype": "Data",
"label": "Title",
"reqd": 1
},
{
"fieldname": "subtitle",
"fieldtype": "Data",
"label": "Subtitle",
"reqd": 0
},
{
"__unsaved": 1,
"fieldname": "event",
"fieldtype": "Link",
"label": "Event",
"options": "Event Details",
"reqd": 1
}
],
"idx": 0,
"modified": "2021-08-18 10:13:49.300196",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Schedule Section",
"owner": "Administrator",
"standard": 1,
"template": "",
"type": "Section"
}

View File

@@ -0,0 +1,23 @@
<div class="section-with-cards">
<h1 class="course-home-headings">{{section_title}}</h1>
<div class="speaker-cards-parent">
{% for speaker in speaker_details %}
{% set speaker_doc = frappe.get_doc("Speaker Registration", speaker.speaker) %}
<div class="common-card-style member-card">
<span class="avatar avatar-large">
<img class="avatar-frame" src="{{speaker_doc.picture}}" />
</span>
<div class="small-title talk-title mt-5">
{{ speaker_doc.full_name }}
</div>
<div class="small-title mt-5 bb">{{speaker_doc.job_title}}</div>
<div class="small-title company-name">{{speaker_doc.company}}</div>
</div>
{% endfor %}
</div>
{%- if cta_link -%}
<div class="event-btn"><a href={{cta_link}} class="btn btn-primary ">Become a Speaker</a></div>
{%- endif -%}
</div>

View File

@@ -0,0 +1,56 @@
{
"__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
},
{
"__unsaved": 1,
"fieldname": "event_",
"fieldtype": "Link",
"label": "Event ",
"options": "Event Details",
"reqd": 0
},
{
"fieldname": "cta_link",
"fieldtype": "Data",
"label": "CTA Link",
"reqd": 0
},
{
"fieldname": "speaker_details",
"fieldtype": "Table Break",
"label": "Speaker Details",
"reqd": 0
},
{
"fieldname": "speaker",
"fieldtype": "Link",
"label": "Speaker",
"options": "Speaker Registration",
"reqd": 0
}
],
"idx": 1,
"modified": "2021-08-18 10:06:03.032441",
"modified_by": "Administrator",
"module": "Event Management",
"name": "Speaker Section",
"owner": "Administrator",
"standard": 1,
"template": "",
"type": "Section"
}

View File

@@ -145,7 +145,8 @@ primary_rules = [
{"from_route": "/courses/<course>/discuss", "to_route": "batch/discuss"},
{"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": "/courses/<course>/join", "to_route": "batch/join"},
{"from_route": "/discussions/<discussion>", "to_route": "discussions/discussion"}
]
# Any frappe default URL is blocked by profile-rules, add it here to unblock it
@@ -167,7 +168,13 @@ whitelist = [
"/new-sign-up",
"/message",
"/about",
"/edit-profile"
"/edit-profile",
"/attendee-registration",
"/speaker-registration",
"/event",
"/hello",
"/exhibitor-registration",
"/discussions"
]
whitelist_rules = [{"from_route": p, "to_route": p[1:]} for p in whitelist]

View File

@@ -1,110 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2021, FOSS United and contributors
# For license information, please see license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.document import Document
from frappe import _
from frappe.utils import add_days, nowdate
class LMSMessage(Document):
def after_insert(self):
self.publish_message()
#Todo: Adding email preference field for users
#self.send_email()
def publish_message(self):
template = self.get_message_template()
message = frappe._dict({
"author_name": self.author_name,
"message_time": frappe.utils.format_datetime(self.creation, "dd-mm-yyyy HH:mm"),
"message": frappe.utils.md_to_html(self.message)
})
js = """
$(".msger-input").val("");
var template = `{0}`;
var message = {1};
var session_user = ("{2}" == frappe.session.user) ? true : false;
message.author_name = session_user ? "You" : message.author_name
message.is_author = session_user;
template = frappe.render_template(template, {{
"message": message
}})
$(".messages").append(template);
var message_element = document.getElementsByClassName("messages")[0]
message_element.scrollTo(0, message_element.scrollHeight);
""".format(template, message, self.owner)
frappe.publish_realtime(event="eval_js", message=js, after_commit=True)
def get_message_template(self):
return """
<li class="{% if message.is_author %} ours {% endif %}">
<div class="d-flex justify-content-between">
<div class="font-weight-bold">
{{ message.author_name }}
</div>
<small class="">
{{ message.message_time }}
</small>
</div>
<div class="message-para">
{{ message.message }}
</div>
</li>
"""
def send_email(self):
membership = frappe.get_all("LMS Batch Membership", {"batch": self.batch}, ["member"])
for entry in membership:
member = frappe.get_doc("User", entry.member)
if member.name != self.author:
#Todo: wrap sendmail in frappe.enqueue, else messages takes long to display.
frappe.sendmail(
recipients = member.email,
subject = _("New Message on ") + self.batch,
header = _("New Message on ") + self.batch,
template = "lms_message",
args = {
"author": self.author,
"message": frappe.utils.md_to_html(self.message),
"creation": frappe.utils.format_datetime(self.creation, "medium"),
"course": frappe.db.get_value("LMS Batch", self.batch, ["course"])
}
)
def send_daily_digest():
#Todo: Optimize this
emails = frappe._dict()
messages = frappe.get_all("LMS Message", {"creation": [">=", add_days(nowdate(), -1)]}, ["message", "batch", "author", "creation"])
for message in messages:
membership = frappe.get_all("LMS Batch Membership", {"batch": message.batch}, ["member"])
for entry in membership:
member = frappe.db.get_value("User", entry.member, ["name", "email"], as_dict=1)
if member.name != message.author:
if member.name in emails.keys():
emails[member.name]["messages"].append(message)
else:
emails[member.name] = frappe._dict({
"email": member.email,
"messages": [message]
})
for email in emails:
group_by_batch = frappe._dict()
for message in emails[email]["messages"]:
if message.batch in group_by_batch.keys():
group_by_batch[message.batch].append(message)
else:
group_by_batch[message.batch] = [message]
frappe.sendmail(
recipients = frappe.db.get_value("User", email, "email"),
subject = _("Message Digest"),
header = _("Message Digest"),
template = "lms_daily_digest",
args = {
"batches": group_by_batch
},
delayed = False
)

View File

@@ -1,8 +1,9 @@
<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">
{% if course %}
<a class="dark-links" href="/courses">All Courses</a>
<img class="ml-1 mr-1" src="/assets/community/icons/chevron-right.svg">
{% if lesson %}
<a class="dark-links" href="/courses/{{ course.name }}">{{ course.title }}</a>
<img class="ml-1 mr-1" src="/assets/community/icons/chevron-right.svg">
@@ -12,8 +13,9 @@
{% endif %}
{% endif %}
{% if member_name %}
<span class="muted-text">{{ member_name }}</span>
{% if thread %}
<a class="dark-links" href="/discussions">Discussions</a>
<img class="ml-1 mr-1" src="/assets/community/icons/chevron-right.svg">
<span class="muted-text">{{ thread.title }}</span>
{% endif %}
</div>

View File

@@ -1,6 +1,6 @@
<div>
<div class="small-title chapter-title" data-target="#{{ course.get_slugified_chapter_title(chapter.title) }}"
<div class="chapter-title small-title" data-target="#{{ course.get_slugified_chapter_title(chapter.title) }}"
data-toggle="collapse" aria-expanded="false">
<img class="chapter-icon" src="/assets/community/icons/chevron-right.svg">
{{ index }}. {{ chapter.title }}

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

@@ -34,14 +34,22 @@ class TestCustomUser(unittest.TestCase):
}).insert()
self.assertEqual(new_user.username[:8], "username")
def test_with_hyphen_at_end(self):
def test_with_underscore_at_end(self):
new_user = frappe.get_doc({
"doctype": "User",
"email": "test_with_hyphen_at_end@example.com",
"first_name": "Username---"
"email": "test_with_underscore_at_end@example.com",
"first_name": "Username___"
}).insert()
length = len(new_user.username)
self.assertNotEqual(new_user.username[length-1], "-")
self.assertNotEqual(new_user.username[-1], "_")
def test_with_short_first_name(self):
new_user = frappe.get_doc({
"doctype": "User",
"email": "test_with_short_first_name@example.com",
"first_name": "USN"
}).insert()
self.assertGreaterEqual(len(new_user.username), 4)
@classmethod
def tearDownClass(cls) -> None:
@@ -49,6 +57,7 @@ class TestCustomUser(unittest.TestCase):
"test_with_basic_username@example.com",
"test-without-username@example.com",
"test_with_illegal_characters@example.com",
"test_with_hyphen_at_end@example.com"
"test_with_underscore_at_end@example.com",
"test_with_short_first_name@example.com"
]
frappe.db.delete("User", {"name": ["in", users]})

View File

@@ -13,38 +13,45 @@ class CustomUser(User):
self.validate_username_characters()
def validate_username_characters(self):
if len(self.username):
underscore_condition = self.username[0] == "_" or self.username[-1] == "_"
else:
underscore_condition = ''
if self.is_new():
if not self.username:
self.username = self.get_username_from_first_name()
if self.username.find(" "):
self.username.replace(" ", "")
if not re.match("^[A-Za-z0-9_]*$", self.username):
if not re.match("^[A-Za-z0-9_]*$", self.username) or underscore_condition:
self.username = self.remove_illegal_characters()
if not self.username:
self.username = self.get_username_from_first_name()
if len(self.username) < 4:
self.username = self.email.replace("@", "").replace(".", "")
if self.username_exists():
while self.username_exists():
self.username = self.remove_illegal_characters() + str(random.randint(0, 99))
else:
if not re.match("^[A-Za-z0-9_-]*$", self.username):
frappe.throw(_("Username can only contain alphabets, numbers, hyphen and underscore."))
if not self.username:
frappe.throw(_("Username already exists."))
if self.username[0] == "-" or self.username[len(self.username) - 1] == "-":
frappe.throw(_("First and Last character of username cannot be Hyphen(-)."))
if not re.match("^[A-Za-z0-9_]*$", self.username):
frappe.throw(_("Username can only contain alphabets, numbers and unedrscore."))
if underscore_condition:
frappe.throw(_("First and Last character of username cannot be Underscore(_)."))
if len(self.username) < 4:
frappe.throw(_("Username cannot be less than 4 characters"))
def get_username_from_first_name(self):
return frappe.scrub(self.first_name) + str(random.randint(0, 99))
def remove_illegal_characters(self):
username = ''.join([c for c in self.username if c.isalnum() or c in ['-', '_']])
while username[0] == "-" or username[len(username) - 1] == "-":
if username[0] == "-":
username = username[1:]
if username[len(username) - 1]:
username = username[:1]
return username
return re.sub("[^\w]+", "", self.username).strip("_")
def get_authored_courses(self) -> int:
"""Returns the number of courses authored by this user.

View File

@@ -7,3 +7,4 @@ community.patches.replace_member_with_user_in_course_mentor_mapping
community.patches.replace_member_with_user_in_lms_message
community.patches.replace_member_with_user_in_mentor_request
community.patches.v0_0.chapter_lesson_index_table
execute:frappe.delete_doc("DocType", "LMS Message")

View File

@@ -22,6 +22,14 @@
--control-bg: var(--gray-100);
--muted-text: #4C5A67;
--button-background: #EEF0F2;
--text-xs: 11px;
--text-sm: 12px;
--text-md: 13px;
--text-base: 14px;
--text-lg: 16px;
--text-xl: 18px;
--text-2xl: 20px;
--text-3xl: 22px;
}
body {
@@ -76,82 +84,10 @@ img.profile-photo {
padding-right: 5px;
}
.message {
border: 1px dashed var(--text-color);
padding: 20px;
border-radius: 10px;
}
.msger-inputarea {
width: 100%;
display: flex;
padding: 10px;
border-top: 2px solid #ddd;
background: #eee;
z-index: 1;
}
.msger-inputarea * {
padding: 10px;
border: none;
border-radius: 3px;
font-size: 1em;
}
.msger-input {
flex: 1;
background: #ddd;
}
.message-section {
margin-left: 3%;
display: inline-block;
width: 95%;
}
.display-4 {
color: #2D005A;
font-weight: 600;
line-height: 51px;
}
section {
padding: 5rem 0 5rem 0;
}
.messages-container {
margin: 0 auto;
border: 1px solid black;
}
.messages {
height: 450px;
display: flex;
flex-direction: column;
align-items: flex-start;
padding: 8px;
list-style-type: none;
}
.messages li {
background: #F7F5F5;
border-radius: 8px;
padding: 8px;
margin: 2px 8px 2px 0;
width: 40%;
}
.messages li.ours {
align-self: flex-end;
margin: 2px 0 2px 8px;
background: var(--primary-color);
color: #fff
}
.message-para {
font-size: 20px;
}
.batch-header {
background: #eee;
border: 2px solid #ddd;
@@ -191,33 +127,6 @@ input[type=checkbox] {
appearance: auto;
}
.partiallycomplete {
background: #FEF4E2;
color: #976417;
}
.partiallycomplete img {
background: #976417;
}
.complete {
background: #EAF5EE;
color: #38A160;
}
.complete img {
background: #38A160;
}
.incomplete {
background: #FEECEC;
color: #E24C4C;
}
.incomplete img {
background: #E24C4C;
}
.progress-image {
margin-right: 3px;
border-radius: 50px;
@@ -276,6 +185,7 @@ input[type=checkbox] {
.common-page-style {
background: #F4F5F6;
padding-bottom: 2rem;
min-height: 60vh;
}
.common-card-style {
@@ -369,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;
@@ -696,16 +616,18 @@ input[type=checkbox] {
.chapter-title {
font-weight: bold;
margin: 0 .25rem .5rem;
margin: 0 .25rem 0;
cursor: pointer;
display: flex;
align-items: center;
padding-bottom: 0.5rem;
}
.chapter-description {
height: fit-content;
padding-left: 1rem;
padding-right: 1rem;
margin-bottom: 0.75rem;
}
.chapter-icon {
@@ -817,7 +739,7 @@ input[type=checkbox] {
}
.lessons {
margin: 12px 0px 16px;
margin-bottom: 1rem;
}
.course-buttons {
@@ -837,6 +759,10 @@ input[type=checkbox] {
padding: 20px 0px 16px;
}
.member-card .talk-title{
font-weight: bold;
}
.member-card-large {
width: 256px;
height: 188px;
@@ -862,6 +788,7 @@ input[type=checkbox] {
font-weight: bold;
}
.member-card-xl .member-card-title {
font-weight: bold;
}
@@ -916,6 +843,11 @@ input[type=checkbox] {
margin: 0;
}
.avatar-medium-schedule{
width: 70px;
height: 70px;
}
.avatar-large {
width: 88px;
height: 88px;
@@ -1350,3 +1282,143 @@ pre {
.markdown-source h4 {
font-size: 1rem;
}
.talk-card {
width: 16rem;
}
.talk-title {
border-bottom: 1px solid #cecdcd;
}
.mt-5 {
margin-top: 5px;
}
.company-name {
font-weight: bold;
}
a.talk-link {
text-decoration: none;
}
.talk-card {
flex-direction: column;
}
.speaker-cards-parent {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
-moz-column-gap: 2rem;
column-gap: 2rem;
row-gap: 2rem;
}
.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{
/* display: none; */
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-logo{
height: 158px;
}
/* .schedule-container:hover > .schedule-info {
display: block;
transition: all 0.3s ease-in-out;
} */
.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;
}
.hide{
display: none;
}
.thread-card {
flex-direction: column;
padding: 1.5rem;
}
textarea.form-control {
height: 300px;
}
.discussion-on-page textarea.form-control {
background-color: #FFFFFF;
color: inherit;
height: 160px;
}
.comment-footer {
display: flex;
justify-content: flex-end;
}
.comment-field {
font-size: inherit;
}
.thread-title {
font-size: inherit;
}
.message-author {
color: #192734;
margin-left: 0.5rem;
}

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,5 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.00001 3.00001H12L15.5 3C16.6046 3 17.5 3.89543 17.5 5V9.78889V12.2556C17.5 13.3601 16.6046 14.2556 15.5 14.2556H14.5C14.2239 14.2556 14 14.4794 14 14.7556V16.4507C14 16.8715 13.5119 17.1041 13.185 16.839L10.2754 14.4789C10.0972 14.3344 9.87483 14.2556 9.64544 14.2556H4.49997C3.39539 14.2556 2.49995 13.3601 2.49997 12.2555L2.50001 9.78889V5.00001C2.50001 3.89544 3.39544 3.00001 4.50001 3.00001L6.00001 3.00001Z" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="square"/>
<path d="M6 6.5H13" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round"/>
<path d="M6 9H10" stroke="#1F272E" stroke-miterlimit="10" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 763 B

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 4V12" stroke="white" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4 8H12" stroke="white" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 313 B

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