Compare commits
161 Commits
discussion
...
rename-app
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5af07086b | ||
|
|
4d534db63f | ||
|
|
aec69e96cb | ||
|
|
6172b09aa3 | ||
|
|
98c386729c | ||
|
|
91ebcd8253 | ||
|
|
3a51299e8d | ||
|
|
eaa8876f4e | ||
|
|
7d80178b48 | ||
|
|
8090f2f397 | ||
|
|
bf986e26bc | ||
|
|
c95d957d2c | ||
|
|
b1aaddae59 | ||
|
|
8fe9bad2bb | ||
|
|
23dab6312d | ||
|
|
c91b1a7a23 | ||
|
|
d07dbcc50a | ||
|
|
49771a627d | ||
|
|
25ec4ae7c6 | ||
|
|
13022e0bcc | ||
|
|
cdc4b6992d | ||
|
|
f178f3806d | ||
|
|
d84f621813 | ||
|
|
7ba2ac1efd | ||
|
|
658a9e6172 | ||
|
|
0b44e78cc2 | ||
|
|
1c5766d022 | ||
|
|
3bff000cc9 | ||
|
|
30a8750f16 | ||
|
|
f3ad3f6d18 | ||
|
|
65a7dde47b | ||
|
|
38ebab59c7 | ||
|
|
b7f79b4832 | ||
|
|
876a2f562f | ||
|
|
5f4fc2fb59 | ||
|
|
44e8efd39b | ||
|
|
51c625da4d | ||
|
|
a795cd23a8 | ||
|
|
ebc3cf1cbf | ||
|
|
c717b3ba9d | ||
|
|
0ed3c87f79 | ||
|
|
9499700988 | ||
|
|
8366721643 | ||
|
|
66afd0fcdd | ||
|
|
a105a1d3b4 | ||
|
|
5488947922 | ||
|
|
aa466f9fb7 | ||
|
|
b3840e056f | ||
|
|
ddffc8372b | ||
|
|
dc877a9c09 | ||
|
|
04d2384283 | ||
|
|
50938afe77 | ||
|
|
ea6bd1f598 | ||
|
|
fb0f9885c1 | ||
|
|
4248a3af07 | ||
|
|
a3dc2402f7 | ||
|
|
153b439510 | ||
|
|
06b925435d | ||
|
|
93c2c3cc45 | ||
|
|
04a3d58028 | ||
|
|
8551cfa32e | ||
|
|
b19c7f2fac | ||
|
|
d135338088 | ||
|
|
b8fae5cd28 | ||
|
|
29fe75d807 | ||
|
|
1dbbf7c769 | ||
|
|
3be20b5658 | ||
|
|
73b6ddf365 | ||
|
|
64048a8a18 | ||
|
|
e245af57a8 | ||
|
|
0ab708396a | ||
|
|
29855a0cbc | ||
|
|
ff6457171f | ||
|
|
9fd59b5d38 | ||
|
|
c750c62993 | ||
|
|
a0d90ab16b | ||
|
|
af15d978c6 | ||
|
|
f4271e7c0e | ||
|
|
0440e1062d | ||
|
|
2bc30d696a | ||
|
|
6dcd210031 | ||
|
|
c78c4c92b7 | ||
|
|
6a2c749a86 | ||
|
|
56d738474a | ||
|
|
7721f31342 | ||
|
|
90e268ff2f | ||
|
|
69bdb75625 | ||
|
|
a0b77f5d08 | ||
|
|
77c4b53b71 | ||
|
|
035a674cff | ||
|
|
b9736cc6d6 | ||
|
|
f52e5067b6 | ||
|
|
d657525359 | ||
|
|
3a2ebd42a7 | ||
|
|
916e64d607 | ||
|
|
e0b25c1e6e | ||
|
|
13b968e18c | ||
|
|
9e1daf5062 | ||
|
|
941a34784c | ||
|
|
cd4ffa2eff | ||
|
|
17a7af74f2 | ||
|
|
ff22eaa606 | ||
|
|
417436d7b6 | ||
|
|
f228489173 | ||
|
|
a49563e23f | ||
|
|
b3403b78ee | ||
|
|
7a9039090d | ||
|
|
289195e6c9 | ||
|
|
e6502784ea | ||
|
|
54f301e8eb | ||
|
|
ed91801769 | ||
|
|
6965148e4e | ||
|
|
b5481e1dd5 | ||
|
|
4ec9b56366 | ||
|
|
530fcf9a39 | ||
|
|
ff1363b437 | ||
|
|
952e3a9906 | ||
|
|
9d530e35fb | ||
|
|
2c2ad78eb7 | ||
|
|
f61c5a2fa1 | ||
|
|
3e24ff9678 | ||
|
|
b0280c3be4 | ||
|
|
b10eb5c979 | ||
|
|
e2072c72da | ||
|
|
84a43912db | ||
|
|
841819436a | ||
|
|
14a984c75f | ||
|
|
445de61ce4 | ||
|
|
f83007788d | ||
|
|
aefee791ca | ||
|
|
00154d80df | ||
|
|
a1e12d29ac | ||
|
|
5069832165 | ||
|
|
e2cb003935 | ||
|
|
b83a10c282 | ||
|
|
c6fc0a22d2 | ||
|
|
c6d3994383 | ||
|
|
07f9721aeb | ||
|
|
dba956e473 | ||
|
|
2894a5e479 | ||
|
|
ad0913500c | ||
|
|
79a765b725 | ||
|
|
eaec991f47 | ||
|
|
e31b189045 | ||
|
|
eb58b1c149 | ||
|
|
af9760f944 | ||
|
|
21b2412362 | ||
|
|
7e5e167eec | ||
|
|
7bf254319b | ||
|
|
d7e1745c09 | ||
|
|
ef238c1b25 | ||
|
|
cb60d97bb7 | ||
|
|
7c3189e273 | ||
|
|
ace74febc7 | ||
|
|
8dbdabd52c | ||
|
|
f0ee8d7b88 | ||
|
|
7e5203f058 | ||
|
|
7017382451 | ||
|
|
3e2c6b3343 | ||
|
|
5ea744de5c | ||
|
|
aedb3d3d45 |
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@@ -53,19 +53,19 @@ jobs:
|
|||||||
then
|
then
|
||||||
(cd && tar xzf ~/bench-cache/bench.tgz)
|
(cd && tar xzf ~/bench-cache/bench.tgz)
|
||||||
else
|
else
|
||||||
bench init ~/frappe-bench --skip-redis-config-generation
|
bench init ~/frappe-bench --skip-redis-config-generation --skip-assets --python "$(which python)"
|
||||||
mkdir -p ~/bench-cache
|
mkdir -p ~/bench-cache
|
||||||
(cd && tar czf ~/bench-cache/bench.tgz frappe-bench)
|
(cd && tar czf ~/bench-cache/bench.tgz frappe-bench)
|
||||||
fi
|
fi
|
||||||
- name: add community app to bench
|
- name: add school app to bench
|
||||||
working-directory: /home/runner/frappe-bench
|
working-directory: /home/runner/frappe-bench
|
||||||
run: bench get-app community $GITHUB_WORKSPACE
|
run: bench get-app school $GITHUB_WORKSPACE
|
||||||
- name: create bench site
|
- name: create bench site
|
||||||
working-directory: /home/runner/frappe-bench
|
working-directory: /home/runner/frappe-bench
|
||||||
run: bench new-site --mariadb-root-password root --admin-password admin frappe.local
|
run: bench new-site --mariadb-root-password root --admin-password admin frappe.local
|
||||||
- name: install community app
|
- name: install school app
|
||||||
working-directory: /home/runner/frappe-bench
|
working-directory: /home/runner/frappe-bench
|
||||||
run: bench --verbose --site frappe.local install-app community
|
run: bench --verbose --site frappe.local install-app school
|
||||||
- name: allow tests
|
- name: allow tests
|
||||||
working-directory: /home/runner/frappe-bench
|
working-directory: /home/runner/frappe-bench
|
||||||
run: bench --site frappe.local set-config allow_tests true
|
run: bench --site frappe.local set-config allow_tests true
|
||||||
@@ -74,5 +74,5 @@ jobs:
|
|||||||
run: bench --site frappe.local build
|
run: bench --site frappe.local build
|
||||||
- name: run tests
|
- name: run tests
|
||||||
working-directory: /home/runner/frappe-bench
|
working-directory: /home/runner/frappe-bench
|
||||||
run: bench --site frappe.local run-tests --app community
|
run: bench --site frappe.local run-tests --app school
|
||||||
|
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,8 +3,8 @@
|
|||||||
*.egg-info
|
*.egg-info
|
||||||
*.swp
|
*.swp
|
||||||
tags
|
tags
|
||||||
community/docs/current
|
school/docs/current
|
||||||
community/public/dist
|
school/public/dist
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
*$py.class
|
*$py.class
|
||||||
|
|||||||
24
MANIFEST.in
24
MANIFEST.in
@@ -4,15 +4,15 @@ include *.json
|
|||||||
include *.md
|
include *.md
|
||||||
include *.py
|
include *.py
|
||||||
include *.txt
|
include *.txt
|
||||||
recursive-include community *.css
|
recursive-include school *.css
|
||||||
recursive-include community *.csv
|
recursive-include school *.csv
|
||||||
recursive-include community *.html
|
recursive-include school *.html
|
||||||
recursive-include community *.ico
|
recursive-include school *.ico
|
||||||
recursive-include community *.js
|
recursive-include school *.js
|
||||||
recursive-include community *.json
|
recursive-include school *.json
|
||||||
recursive-include community *.md
|
recursive-include school *.md
|
||||||
recursive-include community *.png
|
recursive-include school *.png
|
||||||
recursive-include community *.py
|
recursive-include school *.py
|
||||||
recursive-include community *.svg
|
recursive-include school *.svg
|
||||||
recursive-include community *.txt
|
recursive-include school *.txt
|
||||||
recursive-exclude community *.pyc
|
recursive-exclude school *.pyc
|
||||||
20
README.md
20
README.md
@@ -1,4 +1,4 @@
|
|||||||
## Community
|
## School
|
||||||
|
|
||||||
This app helps people organize and manage their own communities.
|
This app helps people organize and manage their own communities.
|
||||||
|
|
||||||
@@ -7,16 +7,16 @@ The App has following components:
|
|||||||
1. Hackathons
|
1. Hackathons
|
||||||
1. LMS
|
1. LMS
|
||||||
|
|
||||||
Community is built on the [Frappe Framework](https://github.com/frappe/frappe), a full-stack web app framework built with Python & JavaScript.
|
School is built on the [Frappe Framework](https://github.com/frappe/frappe), a full-stack web app framework built with Python & JavaScript.
|
||||||
|
|
||||||
## Development Setup
|
## Development Setup
|
||||||
|
|
||||||
**Step 1:** Clone the repo
|
**Step 1:** Clone the repo
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone https://github.com/fossunited/community.git
|
$ git clone https://github.com/frappe/school.git
|
||||||
|
|
||||||
$ cd community
|
$ cd school
|
||||||
```
|
```
|
||||||
|
|
||||||
**Step 2:** Run docker-compose
|
**Step 2:** Run docker-compose
|
||||||
@@ -59,15 +59,15 @@ To setup the repository locally follow the steps mentioned below:
|
|||||||
|
|
||||||
1. Install bench and setup a frappe-bench directory by following the [Installation Steps](https://frappeframework.com/docs/user/en/installation).
|
1. Install bench and setup a frappe-bench directory by following the [Installation Steps](https://frappeframework.com/docs/user/en/installation).
|
||||||
1. Start the server by running bench start.
|
1. Start the server by running bench start.
|
||||||
1. In a separate terminal window, create a new site by running bench new-site community.test.
|
1. In a separate terminal window, create a new site by running bench new-site school.test.
|
||||||
1. Run bench get-app https://github.com/fossunited/community.
|
1. Run bench get-app https://github.com/frappe/school.
|
||||||
1. Run bench --site community.test install-app community.
|
1. Run bench --site school.test install-app school.
|
||||||
1. Map your site to localhost with the command ```bench --site community.test add-to-hosts```
|
1. Map your site to localhost with the command ```bench --site school.test add-to-hosts```
|
||||||
1. Now open the URL http://community.test:8000/docs in your browser, you should see the app running.
|
1. Now open the URL http://school.test:8000/ in your browser, you should see the app running.
|
||||||
|
|
||||||
### Contribution Guidelines (for The Hard Way)
|
### Contribution Guidelines (for The Hard Way)
|
||||||
|
|
||||||
1. Go to the apps/community directory of your installation and execute git pull --unshallow to ensure that you have the full git repository. Also fork the fossunited/community repository on GitHub.
|
1. Go to the apps/school directory of your installation and execute git pull --unshallow to ensure that you have the full git repository. Also fork the frappe/school repository on GitHub.
|
||||||
1. Check out a working branch in git (e.g. git checkout -b my-new-branch).
|
1. Check out a working branch in git (e.g. git checkout -b my-new-branch).
|
||||||
1. Make your proposed changes to the source
|
1. Make your proposed changes to the source
|
||||||
1. Run your local version (e.g. bench start in your bench installation). Make sure that your changes work the way you want them to.
|
1. Run your local version (e.g. bench start in your bench installation). Make sure that your changes work the way you want them to.
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
# 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)
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
# 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)
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
<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>
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
{% 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>
|
|
||||||
@@ -1,207 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
from . import __version__ as app_version
|
|
||||||
|
|
||||||
app_name = "community"
|
|
||||||
app_title = "Community"
|
|
||||||
app_publisher = "FOSS United"
|
|
||||||
app_description = "Community App"
|
|
||||||
app_icon = "octicon octicon-file-directory"
|
|
||||||
app_color = "grey"
|
|
||||||
app_email = "jannat@erpnext.com"
|
|
||||||
app_license = "AGPL"
|
|
||||||
|
|
||||||
# Includes in <head>
|
|
||||||
# ------------------
|
|
||||||
|
|
||||||
# include js, css files in header of desk.html
|
|
||||||
# app_include_css = "/assets/community/css/community.css"
|
|
||||||
# app_include_js = "/assets/community/js/community.js"
|
|
||||||
|
|
||||||
# include js, css files in header of web template
|
|
||||||
web_include_css = "community.bundle.css"
|
|
||||||
# web_include_css = "/assets/community/css/community.css"
|
|
||||||
# web_include_js = "/assets/community/js/community.js"
|
|
||||||
|
|
||||||
# include custom scss in every website theme (without file extension ".scss")
|
|
||||||
# website_theme_scss = "community/public/scss/website"
|
|
||||||
|
|
||||||
# include js, css files in header of web form
|
|
||||||
# webform_include_js = {"doctype": "public/js/doctype.js"}
|
|
||||||
# webform_include_css = {"doctype": "public/css/doctype.css"}
|
|
||||||
|
|
||||||
# include js in page
|
|
||||||
# page_js = {"page" : "public/js/file.js"}
|
|
||||||
|
|
||||||
# include js in doctype views
|
|
||||||
# doctype_js = {"doctype" : "public/js/doctype.js"}
|
|
||||||
# doctype_list_js = {"doctype" : "public/js/doctype_list.js"}
|
|
||||||
# doctype_tree_js = {"doctype" : "public/js/doctype_tree.js"}
|
|
||||||
# doctype_calendar_js = {"doctype" : "public/js/doctype_calendar.js"}
|
|
||||||
|
|
||||||
# Home Pages
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
# application home page (will override Website Settings)
|
|
||||||
# home_page = "login"
|
|
||||||
|
|
||||||
# website user home page (by Role)
|
|
||||||
# role_home_page = {
|
|
||||||
# "Role": "home_page"
|
|
||||||
# }
|
|
||||||
|
|
||||||
# Generators
|
|
||||||
# ----------
|
|
||||||
|
|
||||||
# automatically create page for each record of this doctype
|
|
||||||
# website_generators = ["Web Page"]
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
# ------------
|
|
||||||
|
|
||||||
# before_install = "community.install.before_install"
|
|
||||||
# after_install = "community.install.after_install"
|
|
||||||
|
|
||||||
# Desk Notifications
|
|
||||||
# ------------------
|
|
||||||
# See frappe.core.notifications.get_notification_config
|
|
||||||
|
|
||||||
# notification_config = "community.notifications.get_notification_config"
|
|
||||||
|
|
||||||
# Permissions
|
|
||||||
# -----------
|
|
||||||
# Permissions evaluated in scripted ways
|
|
||||||
|
|
||||||
# permission_query_conditions = {
|
|
||||||
# "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions",
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# has_permission = {
|
|
||||||
# "Event": "frappe.desk.doctype.event.event.has_permission",
|
|
||||||
# }
|
|
||||||
|
|
||||||
# DocType Class
|
|
||||||
# ---------------
|
|
||||||
# Override standard doctype classes
|
|
||||||
|
|
||||||
override_doctype_class = {
|
|
||||||
"User": "community.overrides.user.CustomUser"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Document Events
|
|
||||||
# ---------------
|
|
||||||
# Hook on document methods and events
|
|
||||||
|
|
||||||
doc_events = {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
# Scheduled Tasks
|
|
||||||
# ---------------
|
|
||||||
#scheduler_events = {
|
|
||||||
# "daily": [
|
|
||||||
# "erpnext.stock.reorder_item.reorder_item"
|
|
||||||
# ]
|
|
||||||
#}
|
|
||||||
|
|
||||||
fixtures = ["Custom Field"]
|
|
||||||
|
|
||||||
# Testing
|
|
||||||
# -------
|
|
||||||
|
|
||||||
# before_tests = "community.install.before_tests"
|
|
||||||
|
|
||||||
# Overriding Methods
|
|
||||||
# ------------------------------
|
|
||||||
#
|
|
||||||
# override_whitelisted_methods = {
|
|
||||||
# "frappe.desk.doctype.event.event.get_events": "community.event.get_events"
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
# each overriding function accepts a `data` argument;
|
|
||||||
# generated from the base implementation of the doctype dashboard,
|
|
||||||
# along with any modifications made in other Frappe apps
|
|
||||||
# override_doctype_dashboards = {
|
|
||||||
# "Task": "community.task.get_dashboard_data"
|
|
||||||
# }
|
|
||||||
|
|
||||||
# exempt linked doctypes from being automatically cancelled
|
|
||||||
#
|
|
||||||
# auto_cancel_exempted_doctypes = ["Auto Repeat"]
|
|
||||||
|
|
||||||
# Add all simple route rules here
|
|
||||||
primary_rules = [
|
|
||||||
{"from_route": "/sketches/<sketch>", "to_route": "sketches/sketch"},
|
|
||||||
{"from_route": "/courses/<course>", "to_route": "courses/course"},
|
|
||||||
{"from_route": "/courses/<course>/<topic>", "to_route": "courses/topic"},
|
|
||||||
{"from_route": "/hackathons/<hackathon>", "to_route": "hackathons/hackathon"},
|
|
||||||
{"from_route": "/hackathons/<hackathon>/<project>", "to_route": "hackathons/project"},
|
|
||||||
{"from_route": "/add-a-new-batch", "to_route": "add-a-new-batch"},
|
|
||||||
{"from_route": "/courses/<course>/home", "to_route": "batch/home"},
|
|
||||||
{"from_route": "/courses/<course>/learn", "to_route": "batch/learn"},
|
|
||||||
{"from_route": "/courses/<course>/learn/<int:chapter>.<int:lesson>", "to_route": "batch/learn"},
|
|
||||||
{"from_route": "/courses/<course>/schedule", "to_route": "batch/schedule"},
|
|
||||||
{"from_route": "/courses/<course>/members", "to_route": "batch/members"},
|
|
||||||
{"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": "/discussions/<discussion>", "to_route": "discussions/discussion"}
|
|
||||||
]
|
|
||||||
|
|
||||||
# Any frappe default URL is blocked by profile-rules, add it here to unblock it
|
|
||||||
whitelist = [
|
|
||||||
"/home",
|
|
||||||
"/login",
|
|
||||||
"/update-password",
|
|
||||||
"/update-profile",
|
|
||||||
"/third-party-apps",
|
|
||||||
"/website_script.js",
|
|
||||||
"/courses",
|
|
||||||
"/sketches",
|
|
||||||
"/admin",
|
|
||||||
"/socket.io",
|
|
||||||
"/hackathons",
|
|
||||||
"/dashboard",
|
|
||||||
"/join-request",
|
|
||||||
"/add-a-new-batch",
|
|
||||||
"/new-sign-up",
|
|
||||||
"/message",
|
|
||||||
"/about",
|
|
||||||
"/edit-profile",
|
|
||||||
"/discussions"
|
|
||||||
]
|
|
||||||
whitelist_rules = [{"from_route": p, "to_route": p[1:]} for p in whitelist]
|
|
||||||
|
|
||||||
# regex rule to match all profiles
|
|
||||||
profile_rules = [
|
|
||||||
{"from_route": "/<string(minlength=4):username>", "to_route": "profiles/profile"},
|
|
||||||
]
|
|
||||||
|
|
||||||
website_route_rules = primary_rules + whitelist_rules + profile_rules
|
|
||||||
|
|
||||||
website_redirects = [
|
|
||||||
{"source": "/update-profile", "target": "/edit-profile"},
|
|
||||||
]
|
|
||||||
|
|
||||||
update_website_context = 'community.widgets.update_website_context'
|
|
||||||
|
|
||||||
## Specify the additional tabs to be included in the user profile page.
|
|
||||||
## Each entry must be a subclass of community.community.plugins.ProfileTab
|
|
||||||
# profile_tabs = []
|
|
||||||
|
|
||||||
## Specify the extension to be used to control what scripts and stylesheets
|
|
||||||
## to be included in lesson pages. The specified value must be be a
|
|
||||||
## subclass of community.community.plugins.PageExtension
|
|
||||||
# community_lesson_page_extension = None
|
|
||||||
|
|
||||||
community_lesson_page_extensions = [
|
|
||||||
"community.plugins.LiveCodeExtension"
|
|
||||||
]
|
|
||||||
|
|
||||||
## Markdown Macros for Lessons
|
|
||||||
community_markdown_macro_renderers = {
|
|
||||||
"Exercise": "community.plugins.exercise_renderer",
|
|
||||||
"Quiz": "community.plugins.quiz_renderer",
|
|
||||||
"YouTubeVideo": "community.plugins.youtube_video_renderer",
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# Copyright (c) 2021, FOSS United and contributors
|
|
||||||
# For license information, please see license.txt
|
|
||||||
|
|
||||||
import frappe
|
|
||||||
from frappe.model.document import Document
|
|
||||||
from ..lesson.lesson import update_progress
|
|
||||||
|
|
||||||
class ExerciseSubmission(Document):
|
|
||||||
|
|
||||||
def after_insert(self):
|
|
||||||
course_details = frappe.get_doc("LMS Course", self.course)
|
|
||||||
if not (course_details.is_mentor(frappe.session.user) or frappe.flags.in_test):
|
|
||||||
update_progress(self.lesson)
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<div class="p-5 batch-header">
|
|
||||||
<h3>{{batch_name}}</h3>
|
|
||||||
<div class="text-muted">{{member_count}} members</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<div class="breadcrumb">
|
|
||||||
|
|
||||||
|
|
||||||
{% 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">
|
|
||||||
<span class="muted-text"> {{ lesson.title }}</span>
|
|
||||||
{% else %}
|
|
||||||
<span class="muted-text">{{ course.title }}</span>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% 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>
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
<div class="common-card-style course-card">
|
|
||||||
<div class="course-image {% if not course.image %}default-image{% endif %}"
|
|
||||||
{% if course.image %} style="background-image: url( {{ course.image }} );" {% endif %}>
|
|
||||||
<div class="course-tags">
|
|
||||||
{% for tag in course.get_tags() %}
|
|
||||||
<div class="course-card-pills">{{ tag }}</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% if not course.image %}
|
|
||||||
<div class="default-image-text">{{ course.title[0] }}</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="course-card-content">
|
|
||||||
<div class="course-card-meta muted-text">
|
|
||||||
{% if course.get_chapters() | length %}
|
|
||||||
<span>
|
|
||||||
{{ course.get_chapters() | length }} Chapters
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
{% if course.get_chapters() | length and course.get_upcoming_batches() | length %}
|
|
||||||
<span class="font-weight-bold ml-3 mr-3"> . </span>
|
|
||||||
{% endif %}
|
|
||||||
{% if course.get_upcoming_batches() | length %}
|
|
||||||
<span class="">
|
|
||||||
{{ course.get_upcoming_batches() | length }} Open Batches
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="course-card-title">{{ course.title }}</div>
|
|
||||||
<div class="card-divider"></div>
|
|
||||||
<div class="course-card-meta-2">
|
|
||||||
{{ widgets.Avatar(member=course.get_instructor(), avatar_class="avatar-small") }}
|
|
||||||
<span class="course-instructor">
|
|
||||||
{{ course.get_instructor().full_name }}
|
|
||||||
</span>
|
|
||||||
<span class="course-student-count">
|
|
||||||
{% if course.get_students() | length %}
|
|
||||||
<span class="mr-4">
|
|
||||||
<img class="icon-background" src="/assets/community/icons/user.svg" />
|
|
||||||
{{ course.get_students() | length }}
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
{% set avg_rating = course.get_average_rating() %}
|
|
||||||
{% if avg_rating %}
|
|
||||||
<span>
|
|
||||||
<img class="icon-background" src="/assets/community/icons/rating.svg" />
|
|
||||||
{{ avg_rating }}
|
|
||||||
</span>
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{% set membership = course.get_membership(frappe.session.user) %}
|
|
||||||
|
|
||||||
{% set lesson_index = course.get_lesson_index(membership.current_lesson) if membership and
|
|
||||||
membership.current_lesson
|
|
||||||
else '1.1' %}
|
|
||||||
|
|
||||||
{% set query_parameter = "?batch=" + membership.batch if membership and membership.batch else "" %}
|
|
||||||
|
|
||||||
{% if course.upcoming %}
|
|
||||||
<div class="view-course-link is-secondary border">
|
|
||||||
Upcoming Course <img class="ml-3" src="/assets/community/icons/black-arrow.svg" />
|
|
||||||
</div>
|
|
||||||
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
|
||||||
|
|
||||||
{% elif membership %}
|
|
||||||
<div class="view-course-link is-primary">
|
|
||||||
Continue Course <img class="ml-3" src="/assets/community/icons/white-arrow.svg" />
|
|
||||||
</div>
|
|
||||||
<a class="stretched-link" href="{{ course.get_learn_url(lesson_index) }}{{ query_parameter }}"></a>
|
|
||||||
|
|
||||||
{% else %}
|
|
||||||
<div class="view-course-link">
|
|
||||||
View Course <img class="ml-3" src="/assets/community/icons/black-arrow.svg" />
|
|
||||||
</div>
|
|
||||||
<a class="stretched-link" href="/courses/{{ course.name }}"></a>
|
|
||||||
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script>
|
|
||||||
frappe.ready(() => {
|
|
||||||
$(".course-card-title").each((i, element) => {
|
|
||||||
var title = $(element).text();
|
|
||||||
var length = $(window).width() <= 375 ? 60 : 65;
|
|
||||||
var suffix = title.length > length ? "..." : "";
|
|
||||||
$(element).text(title.substring(0, length) + suffix);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<div class="instructor">
|
|
||||||
{{ widgets.Avatar(member=instructor, avatar_class="avatar-medium") }}
|
|
||||||
<a class="ml-1 instructor-title" href="/{{instructor.username}}">{{ instructor.full_name }}</a>
|
|
||||||
<div class="instructor-subtitle">Course Creator</div>
|
|
||||||
<!-- <div class="instructor-subtitle">Created {{instructor.get_course_count()}} courses</div> -->
|
|
||||||
</div>
|
|
||||||
@@ -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>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
Community
|
|
||||||
Hackathon
|
|
||||||
LMS
|
|
||||||
Conference
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
community.patches.set_email_preferences
|
|
||||||
community.patches.change_name_for_community_members
|
|
||||||
community.patches.save_abbr_for_community_members
|
|
||||||
community.patches.create_mentor_request_email_templates
|
|
||||||
community.patches.replace_member_with_user_in_batch_membership
|
|
||||||
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")
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<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>
|
|
||||||
|
Before Width: | Height: | Size: 763 B |
@@ -1,13 +0,0 @@
|
|||||||
<div class="discussion {% if message.is_author %} is-author {% endif %}">
|
|
||||||
<div class="d-flex justify-content-between">
|
|
||||||
<div class="font-weight-bold">
|
|
||||||
{{ message.author_name }}
|
|
||||||
</div>
|
|
||||||
<div class="text-muted">
|
|
||||||
{{ message.message_time }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="mt-5">
|
|
||||||
{{ message.message }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<div class="common-card-style thread-card mb-5">
|
|
||||||
<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 }}">
|
|
||||||
<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>
|
|
||||||
</div>
|
|
||||||
<div class="card-divider"></div>
|
|
||||||
<div>{{ message.message }}</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
{% extends "templates/base.html" %}
|
|
||||||
{% from "www/hackathons/macros/card.html" import null_card %}
|
|
||||||
{% block title %}{{ 'Courses' }}{% endblock %}
|
|
||||||
{% block head_include %}
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="common-page-style">
|
|
||||||
<div class="container">
|
|
||||||
<div class="courses-header">
|
|
||||||
{{ 'All Courses' }}
|
|
||||||
</div>
|
|
||||||
<div class="cards-parent">
|
|
||||||
{% for course in courses %}
|
|
||||||
{{ widgets.CourseCard(course=course) }}
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import frappe
|
|
||||||
|
|
||||||
def get_context(context):
|
|
||||||
context.no_cache = 1
|
|
||||||
context.courses = get_courses()
|
|
||||||
context.metatags = {
|
|
||||||
"title": "All Courses",
|
|
||||||
"image": frappe.db.get_single_value("Website Settings", "banner_image"),
|
|
||||||
"description": "This page lists all the courses published on our website",
|
|
||||||
"keywords": "All Courses, Courses, Learn"
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_courses():
|
|
||||||
course_names = frappe.get_all("LMS Course", filters={"is_published": True}, pluck="name")
|
|
||||||
courses = []
|
|
||||||
for course in course_names:
|
|
||||||
courses.append(frappe.get_doc("LMS Course", course))
|
|
||||||
return courses
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{% extends "templates/base.html" %}
|
|
||||||
{% block title %}{{ thread.title }}{% endblock %}
|
|
||||||
{% block head_include %}
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="common-page-style">
|
|
||||||
<div class="container">
|
|
||||||
{{ widgets.BreadCrumb(thread=thread) }}
|
|
||||||
<div class="course-home-headings">{{ thread.title }}</div>
|
|
||||||
{{ widgets.DiscussionMessage(thread=thread.name) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import frappe
|
|
||||||
|
|
||||||
def get_context(context):
|
|
||||||
context.no_cache = 1
|
|
||||||
|
|
||||||
try:
|
|
||||||
thread_name = frappe.form_dict["discussion"]
|
|
||||||
except KeyError:
|
|
||||||
redirect_to_discussions()
|
|
||||||
|
|
||||||
context.thread = frappe.db.get_value("Discussion Thread", thread_name, ["name", "title"], as_dict=True)
|
|
||||||
|
|
||||||
if not len(context.thread):
|
|
||||||
redirect_to_discussions
|
|
||||||
|
|
||||||
def redirect_to_discussions():
|
|
||||||
frappe.local.flags.redirect_location = "/discussions"
|
|
||||||
raise frappe.Redirect
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
{% extends "templates/base.html" %}
|
|
||||||
{% block title %}{{ 'Discussions' }}{% endblock %}
|
|
||||||
{% block head_include %}
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="common-page-style">
|
|
||||||
<div class="container">
|
|
||||||
<div class="courses-header">
|
|
||||||
<span>{{_('Discussions')}}</span>
|
|
||||||
<div id="new-topic" class="button is-primary pull-right">
|
|
||||||
<img src="/assets/community/icons/small-add.svg">
|
|
||||||
Start a Discussion</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-divider-dark"></div>
|
|
||||||
{% if threads | length %}
|
|
||||||
<div class="cards-parent">
|
|
||||||
{% for thread in threads %}
|
|
||||||
<div class="common-card-style thread-card">
|
|
||||||
<div class="course-card-title">{{ thread.title }}</div>
|
|
||||||
<div class="card-divider"></div>
|
|
||||||
<div>
|
|
||||||
<span class="course-student-count">
|
|
||||||
<span class="mr-4">
|
|
||||||
<img class="icon-background" src="/assets/community/icons/message.svg" />
|
|
||||||
{{ thread.message_count }}
|
|
||||||
</span>
|
|
||||||
<span class="mr-4">
|
|
||||||
<img class="icon-background" src="/assets/community/icons/user.svg" />
|
|
||||||
{{ thread.member_count }}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<a class="stretched-link" href="/discussions/{{ thread.name }}"></a>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="text-center font-weight-bold mt-5">
|
|
||||||
No discussions yet.
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- New Topic Modal -->
|
|
||||||
<div class="modal fade discussion-modal" id="discussion-modal" tabindex="-1" role="dialog" aria-hidden="true">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">
|
|
||||||
<div class="course-home-headings modal-headings">Start a Discussion</div>
|
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
{{ widgets.DiscussionComment() }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
frappe.ready(() => {
|
|
||||||
$("#new-topic").click((e) => {
|
|
||||||
show_new_topic_modal(e);
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
var show_new_topic_modal = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (frappe.session.user == "Guest") {
|
|
||||||
window.location.href = `/login?redirect-to=/discussions/`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$("#discussion-modal").modal("show");
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import frappe
|
|
||||||
|
|
||||||
def get_context(context):
|
|
||||||
context.threads = get_threads()
|
|
||||||
|
|
||||||
def get_threads():
|
|
||||||
threads = frappe.get_all("Discussion Thread", fields=["name", "title"])
|
|
||||||
for thread in threads:
|
|
||||||
messages = frappe.get_all("Discussion Message",
|
|
||||||
{
|
|
||||||
"thread": thread.name
|
|
||||||
},
|
|
||||||
["owner"],
|
|
||||||
as_list=True)
|
|
||||||
thread.message_count = len(messages)
|
|
||||||
thread.member_count = len(set(messages))
|
|
||||||
return threads
|
|
||||||
@@ -17,9 +17,9 @@ services:
|
|||||||
bench:
|
bench:
|
||||||
image: anandology/frappe-bench
|
image: anandology/frappe-bench
|
||||||
volumes:
|
volumes:
|
||||||
- .:/home/bench/frappe-bench/apps/community
|
- .:/home/bench/frappe-bench/apps/school
|
||||||
environment:
|
environment:
|
||||||
- FRAPPE_APPS=community
|
- FRAPPE_APPS=school
|
||||||
- FRAPPE_ALLOW_TESTS=true
|
- FRAPPE_ALLOW_TESTS=true
|
||||||
- FRAPPE_SITE_NAME=frappe.localhost
|
- FRAPPE_SITE_NAME=frappe.localhost
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
# Mockups
|
|
||||||
|
|
||||||
HTML Mockups using [Mockdown][].
|
|
||||||
|
|
||||||
[Mockdown]: https://github.com/anandology/mockdown
|
|
||||||
|
|
||||||
## How to use
|
|
||||||
|
|
||||||
**Step 1:** Get into `mockups` directory
|
|
||||||
|
|
||||||
```
|
|
||||||
$ cd mockups
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 2:** Instal `mockdown`
|
|
||||||
|
|
||||||
```
|
|
||||||
$ pip install mockdown
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 3:** Start mockdown server
|
|
||||||
|
|
||||||
```
|
|
||||||
$ mockdown
|
|
||||||
...
|
|
||||||
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
|
|
||||||
...
|
|
||||||
```
|
|
||||||
|
|
||||||
**Step 4:** See the mockups at <http://localhost:5000/>.
|
|
||||||
|
|
||||||
## How does it work?
|
|
||||||
|
|
||||||
Mockdown uses [Jinja][] templates for writing HTML.
|
|
||||||
|
|
||||||
[Jinja]: https://jinja.palletsprojects.com/
|
|
||||||
|
|
||||||
To make is easy to provide test data, Mockdown looks for YAML file with the same name as the template. For example, `home.html` template uses the data from `home.yml`.
|
|
||||||
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<!-- Required meta tags -->
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
|
|
||||||
<!-- Bootstrap CSS -->
|
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
|
|
||||||
<link href="/static/style.css" rel="stylesheet">
|
|
||||||
|
|
||||||
<title>{% block title %}FOSS United{% endblock %}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<nav class="navbar navbar-light navbar-expand-lg">
|
|
||||||
<div class="container">
|
|
||||||
<a class="navbar-brand" href="/"><span>Home</span></a>
|
|
||||||
<button aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler" data-target="#navbarSupportedContent" data-toggle="collapse" type="button">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
||||||
<ul class="mr-auto navbar-nav">
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link" href="/sketches.html">
|
|
||||||
Sketches
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="ml-auto navbar-nav">
|
|
||||||
<!-- post login tools -->
|
|
||||||
<li class="nav-item">
|
|
||||||
<a class="nav-link btn-login-area" href="/login.html">Login</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
{% block content %}
|
|
||||||
<h1>Lorem ipsum...</h1>
|
|
||||||
{% endblock %}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="container">
|
|
||||||
<div class="course-header">
|
|
||||||
<div class="course-type">course</div>
|
|
||||||
<h1>{{title}}</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-9 col-md-12">
|
|
||||||
<div class="course-details">
|
|
||||||
|
|
||||||
<h2>Course Description</h2>
|
|
||||||
|
|
||||||
<div class="course-description">
|
|
||||||
{{ description }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="preview-video">
|
|
||||||
<iframe
|
|
||||||
width="560"
|
|
||||||
height="315"
|
|
||||||
src="{{youtube_embed_url}}"
|
|
||||||
title="YouTube video player"
|
|
||||||
frameborder="0"
|
|
||||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
||||||
allowfullscreen></iframe>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h2>Upcoming Batches</h2>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
{% for batch in batches %}
|
|
||||||
<div class="col-lg-4 col-md-6">
|
|
||||||
<div class="batch">
|
|
||||||
<div class="batch-details">
|
|
||||||
<div>Session every {{batch.weekdays}}</div>
|
|
||||||
<div>{{batch.timeslot}}</div>
|
|
||||||
<div>Starting from {{batch.start_date}}</div>
|
|
||||||
|
|
||||||
<div class="course-type" style="color: #888; padding: 10px 0px;">mentors</div>
|
|
||||||
|
|
||||||
{% for m in batch.mentors %}
|
|
||||||
<div>
|
|
||||||
<img class="profile-photo" src="{{m.photo_url}}">
|
|
||||||
<span class="instructor-title">{{m.name}}</span>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
<div class="cta">
|
|
||||||
<div class="">
|
|
||||||
<button type="button">Join this Batch</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<h2>Course Outline</h2>
|
|
||||||
|
|
||||||
{% for chapter in chapters %}
|
|
||||||
<div class="chapter-plan">
|
|
||||||
<h3><span class="chapter-number">{{loop.index}}</span> {{chapter.title}}</h3>
|
|
||||||
<div class="chapter-description">
|
|
||||||
{{chapter.description}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="lessons">
|
|
||||||
{% for lesson in chapter.lessons %}
|
|
||||||
<div class="lesson">
|
|
||||||
<span class="lesson-type"><i class="{{lesson.icon}}"></i></span>
|
|
||||||
<span class="lesson-title">{{lesson.title}}</span>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-lg-3 col-md-12">
|
|
||||||
<div class="sidebar">
|
|
||||||
<h3>Instructor</h3>
|
|
||||||
<div class="instructor">
|
|
||||||
<div class="instructor-title">{{instructor.name}}</div>
|
|
||||||
<div class="instructor-subtitle">Created {{instructor.num_courses}} courses</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="sidebar">
|
|
||||||
<h3>Mentors</h3>
|
|
||||||
{% for m in mentors %}
|
|
||||||
<div class="instructor">
|
|
||||||
<div class="instructor-title">{{m.name}}</div>
|
|
||||||
<div class="instructor-subtitle">Mentored {{m.num_courses}} batches</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<div class="notice">
|
|
||||||
Interested to become a mentor?
|
|
||||||
|
|
||||||
<div><a href="#">Apply Now!</a></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
title: The Joy of Programming
|
|
||||||
description: |
|
|
||||||
Learn the joy of programming by turning the computer into a canvas.
|
|
||||||
youtube_embed_url: "https://www.youtube.com/embed/IFWAYnUeHR8?start=149"
|
|
||||||
stats:
|
|
||||||
chapters: 4
|
|
||||||
lessons: 25
|
|
||||||
videos: 6
|
|
||||||
completed: 287
|
|
||||||
|
|
||||||
instructor:
|
|
||||||
name: Anand Chitipothu
|
|
||||||
num_courses: 4
|
|
||||||
|
|
||||||
mentors:
|
|
||||||
- name: Anand Chitipothu
|
|
||||||
num_courses: 4
|
|
||||||
- name: Rushabh Mehta
|
|
||||||
num_courses: 3
|
|
||||||
- name: Jannat Patel
|
|
||||||
num_courses: 3
|
|
||||||
|
|
||||||
batches:
|
|
||||||
- id: jp01
|
|
||||||
status: scheduled
|
|
||||||
mentors:
|
|
||||||
- name: Anand Chitipothu
|
|
||||||
photo_url: https://pbs.twimg.com/profile_images/2599066714/igu5hx4wlg3mxucodinl.jpeg
|
|
||||||
num_batches: 4
|
|
||||||
start_date: May 3, 2021
|
|
||||||
weekdays: Mon, Thu
|
|
||||||
timeslot: 5:00-6:00 PM
|
|
||||||
|
|
||||||
- id: jp02
|
|
||||||
status: scheduled
|
|
||||||
mentors:
|
|
||||||
- name: Anand Chitipothu
|
|
||||||
photo_url: https://pbs.twimg.com/profile_images/2599066714/igu5hx4wlg3mxucodinl.jpeg
|
|
||||||
num_batches: 4
|
|
||||||
start_date: May 4, 2021
|
|
||||||
weekdays: Tue, Fri
|
|
||||||
timeslot: 5:00-6:00 PM
|
|
||||||
|
|
||||||
- id: jp03
|
|
||||||
status: scheduled
|
|
||||||
mentors:
|
|
||||||
- name: Rusbhabh Mehta
|
|
||||||
photo_url: https://pbs.twimg.com/profile_images/2599066714/igu5hx4wlg3mxucodinl.jpeg
|
|
||||||
num_batches: 4
|
|
||||||
start_date: May 15, 2021
|
|
||||||
weekdays: Sat
|
|
||||||
timeslot: 5:00-6:00 PM
|
|
||||||
|
|
||||||
|
|
||||||
chapters:
|
|
||||||
- title: Getting Started
|
|
||||||
description: |
|
|
||||||
Getting started with programming by turning the computer into a canvas.
|
|
||||||
lessons:
|
|
||||||
- index: 1
|
|
||||||
type: video
|
|
||||||
icon: bi bi-play-circle
|
|
||||||
title: Introduction to Programming
|
|
||||||
- index: 2
|
|
||||||
type: practice
|
|
||||||
icon: bi bi-code-square
|
|
||||||
title: Drawing Shapes
|
|
||||||
|
|
||||||
- title: Repeating Things
|
|
||||||
description: |
|
|
||||||
Isn't it very boring to do the same thing again and again?
|
|
||||||
Well, that is for humans. Computers love to do the same thing again and again.
|
|
||||||
Learn how to tell the computer to repeat multiple times the same task, or
|
|
||||||
with slight change every time.
|
|
||||||
|
|
||||||
lessons:
|
|
||||||
- index: 1
|
|
||||||
type: video
|
|
||||||
icon: bi bi-play-circle
|
|
||||||
title: Rinse and Repeat
|
|
||||||
- index: 2
|
|
||||||
type: practice
|
|
||||||
title: many circles
|
|
||||||
icon: bi bi-check2-circle
|
|
||||||
- index: 3
|
|
||||||
type: practice
|
|
||||||
icon: bi bi-code-square
|
|
||||||
title: print, print, print!
|
|
||||||
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="container">
|
|
||||||
<div class="course-header">
|
|
||||||
<h1>Sketches</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row sketches-gallery">
|
|
||||||
{% for s in sketches %}
|
|
||||||
<div class="col-md-3">
|
|
||||||
<div class="sketch-card">
|
|
||||||
<div class="sketch-image">
|
|
||||||
<a href="#">
|
|
||||||
<svg width="300" height="300" viewBox="0 0 300 300" fill="none" stroke="black" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<circle cx="150" cy="150" r="150.0"></circle>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="sketch-footer">
|
|
||||||
<div class="sketch-title">
|
|
||||||
<a href="#">{{s.title}}</a>
|
|
||||||
</div>
|
|
||||||
<div class="sketch-author">
|
|
||||||
by {{s.author}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
sketches:
|
|
||||||
- id: 20
|
|
||||||
title: Big Circle
|
|
||||||
author: Anand Chitipothu
|
|
||||||
- id: 19
|
|
||||||
title: Small Circle
|
|
||||||
author: Anand Chitipothu
|
|
||||||
- id: 18
|
|
||||||
title: Circles in Queue
|
|
||||||
author: Chaitanya
|
|
||||||
- id: 17
|
|
||||||
title: Random Bottom Circles
|
|
||||||
author: Anand Chitipothu
|
|
||||||
- id: 16
|
|
||||||
title: Pipes
|
|
||||||
author: Vishal
|
|
||||||
- id: 15
|
|
||||||
title: New Sketch
|
|
||||||
author: Malleshwari
|
|
||||||
|
|
||||||
- id: 20
|
|
||||||
title: Big Circle
|
|
||||||
author: Anand Chitipothu
|
|
||||||
- id: 19
|
|
||||||
title: Small Circle
|
|
||||||
author: Anand Chitipothu
|
|
||||||
- id: 18
|
|
||||||
title: Circles in Queue
|
|
||||||
author: Chaitanya
|
|
||||||
- id: 17
|
|
||||||
title: Random Bottom Circles
|
|
||||||
author: Anand Chitipothu
|
|
||||||
- id: 16
|
|
||||||
title: Pipes
|
|
||||||
author: Vishal
|
|
||||||
- id: 15
|
|
||||||
title: New Sketch
|
|
||||||
author: Malleshwari
|
|
||||||
@@ -1,221 +0,0 @@
|
|||||||
@import url("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.4.1/font/bootstrap-icons.css");
|
|
||||||
|
|
||||||
:root {
|
|
||||||
--c1: #fefae0;
|
|
||||||
--c2: #264653;
|
|
||||||
--c3: #e9c46a;
|
|
||||||
--c4: #2a9d8f;
|
|
||||||
--c5: #f4a261;
|
|
||||||
--c6: #e76f51;
|
|
||||||
|
|
||||||
--c7: #ccd5ae;
|
|
||||||
|
|
||||||
--bg: var(--c1);
|
|
||||||
--header-bg: var(--c2);
|
|
||||||
--header-color: var(--c3);
|
|
||||||
--tag-color: var(--c7);
|
|
||||||
--sidebar-bg: var(--c7);
|
|
||||||
|
|
||||||
--h-color: var(--c2);
|
|
||||||
|
|
||||||
--text-color: #333;
|
|
||||||
--text-color-light: #ccc;
|
|
||||||
|
|
||||||
--cta-color: var(--c4);
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.navbar-light {
|
|
||||||
border-bottom: 1px solid #E2E6E9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-header {
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-header .page-header{
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 20px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.course-header {
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 20px;
|
|
||||||
background: var(--header-bg);
|
|
||||||
color: var(--header-color);
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.course-header h1 {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.course-type {
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-size: 1.0em;
|
|
||||||
color: var(--tag-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar {
|
|
||||||
background: var(--sidebar-bg);
|
|
||||||
margin: 20px 0px;
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 1px 20px 20px 20px;
|
|
||||||
color: var(--text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar h3 {
|
|
||||||
margin-top: 20px;
|
|
||||||
color: var(--c2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.instructor {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instructor-title {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instructor-subtitle {
|
|
||||||
font-size: 0.8em;
|
|
||||||
color: var(--text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar .notice {
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px dashed var(--text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar .notice a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.course-details {
|
|
||||||
margin: 20px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.course-details h2 {
|
|
||||||
color: var(--h-color);
|
|
||||||
font-size: 1.4em;
|
|
||||||
font-weight: bold;
|
|
||||||
margin: 20px 0px 10px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapter-plan {
|
|
||||||
border-radius: 10px;
|
|
||||||
margin: 20px 0px;
|
|
||||||
padding: 20px;
|
|
||||||
border: 1px solid #ddc;
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapter-plan h3 {
|
|
||||||
font-size: 1.1em;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapter-number {
|
|
||||||
background: var(--text-color);
|
|
||||||
color: white;
|
|
||||||
border-radius: 50%;
|
|
||||||
height: 24px;
|
|
||||||
min-width: 24px;
|
|
||||||
align-items: center;
|
|
||||||
padding: 2px 8px 2px 8px;
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chapter-description {
|
|
||||||
margin: 20px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lessons {
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
.lesson {
|
|
||||||
margin: 5px 0px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.batch {
|
|
||||||
border-radius: 10px;
|
|
||||||
margin: 10px 0px;
|
|
||||||
background: white;
|
|
||||||
border: 1px solid #ddc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.batch-details {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.batch .cta {
|
|
||||||
margin-top: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
min-height: 28px;
|
|
||||||
text-align: right;
|
|
||||||
border-top: 1px solid #ddc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.batch .cta button {
|
|
||||||
background: var(--cta-color);
|
|
||||||
color: white;
|
|
||||||
border: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 5px 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.batch .right {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
img.profile-photo {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lesson-type {
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-video {
|
|
||||||
text-align: center;
|
|
||||||
margin: 20px 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-video iframe {
|
|
||||||
max-width: 100%
|
|
||||||
}
|
|
||||||
|
|
||||||
.sketches-gallery svg {
|
|
||||||
width: 200px;
|
|
||||||
height: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sketch-card {
|
|
||||||
background: white;
|
|
||||||
border-radius: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sketch-card .sketch-image {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sketch-footer {
|
|
||||||
padding: 10px;
|
|
||||||
background: #eee;
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{% set color = member.get_palette() %}
|
{% set color = member.get_palette() %}
|
||||||
<a class="button-links" href="/{{member.username}}">
|
<a class="button-links" href="{{ get_profile_url(member.username) }}">
|
||||||
<span class="avatar {{ avatar_class }}" title="{{ member.full_name }}">
|
<span class="avatar {{ avatar_class }}" title="{{ member.full_name }}">
|
||||||
{% if member.user_image %}
|
{% if member.user_image %}
|
||||||
<img class="avatar-frame standard-image" style="object-fit: cover;" src="{{ member.user_image }}" title="{{ member.full_name }}">
|
<img class="avatar-frame standard-image" style="object-fit: cover;" src="{{ member.user_image }}" title="{{ member.full_name }}">
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user