feat: hackathon and project web view
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
"engine": "InnoDB",
|
"engine": "InnoDB",
|
||||||
"field_order": [
|
"field_order": [
|
||||||
"year",
|
"year",
|
||||||
|
"is_hackathon",
|
||||||
"volunteers"
|
"volunteers"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
@@ -21,11 +22,17 @@
|
|||||||
"fieldtype": "Table",
|
"fieldtype": "Table",
|
||||||
"label": "Volunteers",
|
"label": "Volunteers",
|
||||||
"options": "Community Event Volunteer"
|
"options": "Community Event Volunteer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"default": "0",
|
||||||
|
"fieldname": "is_hackathon",
|
||||||
|
"fieldtype": "Check",
|
||||||
|
"label": "Is Hackathon"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-02-12 18:29:21.213257",
|
"modified": "2021-02-15 18:29:26.828720",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Community",
|
"module": "Community",
|
||||||
"name": "Community Event",
|
"name": "Community Event",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
{
|
{
|
||||||
"fieldname": "member",
|
"fieldname": "member",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
|
"in_list_view": 1,
|
||||||
"label": "Member",
|
"label": "Member",
|
||||||
"options": "Community Member"
|
"options": "Community Member"
|
||||||
}
|
}
|
||||||
@@ -18,7 +19,7 @@
|
|||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-02-12 15:55:58.252902",
|
"modified": "2021-02-15 12:03:31.153575",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Community",
|
"module": "Community",
|
||||||
"name": "Community Event Volunteer",
|
"name": "Community Event Volunteer",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"default": "0",
|
"default": "1",
|
||||||
"fieldname": "enabled",
|
"fieldname": "enabled",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Enabled"
|
"label": "Enabled"
|
||||||
@@ -29,12 +29,14 @@
|
|||||||
"unique": 1
|
"unique": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_in_quick_entry": 1,
|
||||||
"fieldname": "role",
|
"fieldname": "role",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Role",
|
"label": "Role",
|
||||||
"options": "\nBoard\nDirector\nVolunteer\nSpeaker"
|
"options": "\nBoard\nDirector\nVolunteer\nSpeaker"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_in_quick_entry": 1,
|
||||||
"fieldname": "photo",
|
"fieldname": "photo",
|
||||||
"fieldtype": "Attach Image",
|
"fieldtype": "Attach Image",
|
||||||
"label": "Photo"
|
"label": "Photo"
|
||||||
@@ -45,6 +47,7 @@
|
|||||||
"label": "Short Intro"
|
"label": "Short Intro"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"allow_in_quick_entry": 1,
|
||||||
"fieldname": "bio",
|
"fieldname": "bio",
|
||||||
"fieldtype": "HTML Editor",
|
"fieldtype": "HTML Editor",
|
||||||
"label": "Bio"
|
"label": "Bio"
|
||||||
@@ -52,7 +55,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-02-12 15:50:13.439527",
|
"modified": "2021-02-15 12:16:32.428546",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Community",
|
"module": "Community",
|
||||||
"name": "Community Member",
|
"name": "Community Member",
|
||||||
|
|||||||
@@ -27,10 +27,11 @@
|
|||||||
"reqd": 1
|
"reqd": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"default": "Pending",
|
||||||
"fieldname": "status",
|
"fieldname": "status",
|
||||||
"fieldtype": "Select",
|
"fieldtype": "Select",
|
||||||
"label": "Status",
|
"label": "Status",
|
||||||
"options": "\nPending\nAccepted\nRejected"
|
"options": "Pending\nAccepted\nRejected"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "project_owner",
|
"fieldname": "project_owner",
|
||||||
@@ -41,7 +42,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-02-12 18:36:33.600885",
|
"modified": "2021-02-16 19:27:30.842282",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Community",
|
"module": "Community",
|
||||||
"name": "Community Project Member",
|
"name": "Community Project Member",
|
||||||
|
|||||||
1
community/community/utils.py
Normal file
1
community/community/utils.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import frappe
|
||||||
69
community/www/hackathons/hackathon.html
Normal file
69
community/www/hackathons/hackathon.html
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{% extends "templates/base.html" %}
|
||||||
|
{% block title %}{{ hackathon }}{% endblock %}
|
||||||
|
{% from "www/hackathons/macros/hero.html" import hero %}
|
||||||
|
{% from "www/hackathons/macros/card.html" import null_card %}
|
||||||
|
|
||||||
|
{% block head_include %}
|
||||||
|
<style>
|
||||||
|
div.card-hero-img {
|
||||||
|
height: 220px;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-color: rgb(250, 251, 252);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-image-wrapper {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 220px;
|
||||||
|
background-color: rgb(250, 251, 252);
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-body {
|
||||||
|
align-self: center;
|
||||||
|
color: #d1d8dd;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
padding: 5rem 0 5rem 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% macro card(project) %}
|
||||||
|
<div class="col-sm-4 mb-4 text-left">
|
||||||
|
<a href="/hackathons/project?project={{ project.name }}&hackathon={{ hackathon }}" class="no-decoration no-underline">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class='card-body'>
|
||||||
|
<h5 class='card-title'>{{ project.name }}</h5>
|
||||||
|
<div class="text-muted">{{ project.project_short_intro }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<section class="section">
|
||||||
|
{{ hero(hackathon, {'name': 'Home', 'url': '/hackathons'}) }}
|
||||||
|
<div class='container'>
|
||||||
|
<div class="row mt-5">
|
||||||
|
{% for project in projects %}
|
||||||
|
{{ card(project) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% if projects %}
|
||||||
|
{% for n in range( (3 - (projects|length)) %3) %}
|
||||||
|
{{ null_card() }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
16
community/www/hackathons/hackathon.py
Normal file
16
community/www/hackathons/hackathon.py
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
def get_context(context):
|
||||||
|
context.no_cache = 1
|
||||||
|
try:
|
||||||
|
hackathon = frappe.form_dict['hackathon']
|
||||||
|
except KeyError:
|
||||||
|
frappe.local.flags.redirect_location = '/hackathons'
|
||||||
|
raise frappe.Redirect
|
||||||
|
context.projects = get_hackathon_projects(hackathon)
|
||||||
|
context.hackathon = hackathon
|
||||||
|
|
||||||
|
def get_hackathon_projects(hackathon):
|
||||||
|
return frappe.get_all("Community Project", filters={"event":hackathon}, fields=["name", "project_short_intro"])
|
||||||
63
community/www/hackathons/index.html
Normal file
63
community/www/hackathons/index.html
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
{% extends "templates/base.html" %}
|
||||||
|
{% block title %}{{ 'Hackathons' }}{% endblock %}
|
||||||
|
{% from "www/hackathons/macros/card.html" import hackathon_card %}
|
||||||
|
{% from "www/hackathons/macros/card.html" import null_card %}
|
||||||
|
{% block head_include %}
|
||||||
|
<meta name="description" content="{{ 'Hackathon' }}" />
|
||||||
|
<meta name="keywords" content="An app that supports Communities" />
|
||||||
|
<style>
|
||||||
|
div.card-hero-img {
|
||||||
|
height: 220px;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-color: rgb(250, 251, 252);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-image-wrapper {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 220px;
|
||||||
|
background-color: rgb(250, 251, 252);
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-body {
|
||||||
|
align-self: center;
|
||||||
|
color: #d1d8dd;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
padding: 5rem 0 5rem 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<section class="top-section" style="padding: 6rem 0rem;">
|
||||||
|
<div class='container pb-5'>
|
||||||
|
<h1>{{ 'Hackathon' }}</h1>
|
||||||
|
<p class="mt-4">
|
||||||
|
{% if frappe.session.user == 'Guest' %}
|
||||||
|
<a class="btn btn-primary btn-lg" href="/login#signup">{{_('Sign Up')}}</a>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class='container'>
|
||||||
|
<div class="row mt-5">
|
||||||
|
{% for hackathon in hackathons %}
|
||||||
|
{{ hackathon_card(hackathon) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% if hackathons %}
|
||||||
|
{% for n in range( (3 - (hackathons|length)) %3) %}
|
||||||
|
{{ null_card() }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
8
community/www/hackathons/index.py
Normal file
8
community/www/hackathons/index.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def get_context(context):
|
||||||
|
context.no_cache = 1
|
||||||
|
context.hackathons = get_hackathons()
|
||||||
|
|
||||||
|
def get_hackathons():
|
||||||
|
return frappe.get_all("Community Event", filters={"is_hackathon": True})
|
||||||
18
community/www/hackathons/macros/card.html
Normal file
18
community/www/hackathons/macros/card.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{% macro hackathon_card(hackathon) %}
|
||||||
|
<div class="col-sm-4 mb-4 text-left">
|
||||||
|
<a href="/hackathons/hackathon?hackathon={{ hackathon.name }}" class="no-decoration no-underline">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class='card-body'>
|
||||||
|
<h5 class='card-title'>{{ hackathon.name }}</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro null_card() %}
|
||||||
|
<div class="col-sm-4 mb-4 text-left">
|
||||||
|
<div class="h-100 d-none d-sm-block" style="border: 1px solid rgba(209,216,221,0.5);border-radius: 0.25rem;background-color: rgb(250, 251, 252);">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
15
community/www/hackathons/macros/hero.html
Normal file
15
community/www/hackathons/macros/hero.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{% macro hero(title, back) %}
|
||||||
|
<div class='container pb-5'>
|
||||||
|
<div class="mb-3">
|
||||||
|
<a href="{{ back.url }}" class="text-muted">
|
||||||
|
{{_('Back to')}} {{ _(back.name) }}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
<p class="mt-4">
|
||||||
|
{% if frappe.session.user == 'Guest' %}
|
||||||
|
<a id="signup" class="btn btn-primary btn-lg" href="/login#signup">{{_('Sign Up')}}</a>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
176
community/www/hackathons/project.html
Normal file
176
community/www/hackathons/project.html
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
{% extends "templates/base.html" %}
|
||||||
|
{% block title %}{{ hackathon }}{% endblock %}
|
||||||
|
{% from "www/hackathons/macros/hero.html" import hero %}
|
||||||
|
{% from "www/hackathons/macros/card.html" import null_card %}
|
||||||
|
{% block head_include %}
|
||||||
|
<meta name="description" content="{{ 'Hackathon' }}" />
|
||||||
|
<meta name="keywords" content="An app that supports Communities" />
|
||||||
|
<style>
|
||||||
|
div.card-hero-img {
|
||||||
|
height: 220px;
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-color: rgb(250, 251, 252);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-image-wrapper {
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 220px;
|
||||||
|
background-color: rgb(250, 251, 252);
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-body {
|
||||||
|
align-self: center;
|
||||||
|
color: #d1d8dd;
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
padding: 5rem 0 5rem 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% macro show_user(user) %}
|
||||||
|
{{ frappe.db.get_value("User", user, "full_name") }}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<section class="section">
|
||||||
|
{{ hero(project, {'name': hackathon, 'url': '/hackathons/hackathon?hackathon=' + hackathon}) }}
|
||||||
|
<div class='container'>
|
||||||
|
{% if project %}
|
||||||
|
<h1 class="mb-2">{{project.project_name}}</h1>
|
||||||
|
|
||||||
|
{% if frappe.session.user != "Guest" %}
|
||||||
|
{% if is_owner %}
|
||||||
|
<p>
|
||||||
|
<div class="badge badge-info">Owner</div>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if is_member %}
|
||||||
|
<p>
|
||||||
|
<div class="badge badge-info">Member</div>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p>{{ project.project_short_intro[:220] }}</p>
|
||||||
|
{% if project.repository_link %}
|
||||||
|
<a href="{{ project.repository_link }}" class="btn btn-default btn-sm" target="_blank">Respository</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if project.video_link %}
|
||||||
|
<a href="{{ project.video_link }}" class="btn btn-default btn-sm" target="_blank">Video ▶️</a>
|
||||||
|
{% endif %}
|
||||||
|
<button class="btn btn-default btn-sm btn-like">👍</button>
|
||||||
|
|
||||||
|
<ul class="nav nav-tabs mt-4" id="myTab" role="tablist">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home"
|
||||||
|
aria-selected="true">Readme</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" id="members-tab" data-toggle="tab" href="#members" role="tab"
|
||||||
|
aria-controls="members" aria-selected="false">Members ({{ confirmed_members|len + 1}})</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" id="updates-tab" data-toggle="tab" href="#updates" role="tab"
|
||||||
|
aria-controls="updates" aria-selected="false">Updates ({{ (updates|len) + 1 }})</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
|
|
||||||
|
<!-- readme -->
|
||||||
|
<div class="tab-pane fade show active py-4 markdown-style" id="home" role="tabpanel"
|
||||||
|
aria-labelledby="home-tab">
|
||||||
|
{{ frappe.utils.md_to_html(project.project_description or "No README created yet") }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="tab-pane fade py-4" id="members" role="tabpanel" aria-labelledby="members-tab">
|
||||||
|
|
||||||
|
<!-- members -->
|
||||||
|
<div class="list-group">
|
||||||
|
<!-- owner -->
|
||||||
|
<div class="list-group-item">{{ show_user(project.owner) }}</div>
|
||||||
|
<!-- all members -->
|
||||||
|
{% for member in members %}
|
||||||
|
{% set is_user = member.owner == frappe.session.user %}
|
||||||
|
{% set is_pending = is_user and member.status=="Pending" %}
|
||||||
|
{% if member.status == "Accepted" %}
|
||||||
|
<div class="list-group-item">
|
||||||
|
{{ show_user(member.owner) }}
|
||||||
|
{% if is_user %}
|
||||||
|
<button data-request-id="{{ m.name }}"
|
||||||
|
class="btn btn-sm btn-default btn-leave ml-4">Leave</button>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% elif member.status == "Pending" and is_owner %}
|
||||||
|
<div class="list-group-item">Join request from: <b>{{ show_user(member.owner) }}</b>
|
||||||
|
<p class="alert alert-warning mt-2">{{ member.intro }}</p>
|
||||||
|
<div class="my-3">
|
||||||
|
<button data-request-id="{{ member.name }}"
|
||||||
|
class="btn btn-sm btn-secondary btn-accept">Accept</button>
|
||||||
|
<button data-request-id="{{ member.name }}"
|
||||||
|
class="btn btn-sm btn-default btn-reject">Reject</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if frappe.session.user != 'Guest' %}
|
||||||
|
<!-- join / pending -->
|
||||||
|
{% if not (my_project or is_member or is_pending) and project.accepting_members %}
|
||||||
|
<a class="btn btn-sm btn-secondary mt-2"
|
||||||
|
href="/join-request?new=1&project={{ project.name }}&project_name={{ project.project_name }}">Join
|
||||||
|
{{ project.project_name }}</a>
|
||||||
|
{% elif is_pending %}
|
||||||
|
<p class="alert alert-warning mt-2">Your application is pending</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- updates -->
|
||||||
|
<div class="tab-pane fade py-4" id="updates" role="tabpanel" aria-labelledby="updates-tab">
|
||||||
|
|
||||||
|
{% macro add_update(update, date) %}
|
||||||
|
<div class='list-group-item'>
|
||||||
|
{{ frappe.utils.md_to_html(update or '') }}
|
||||||
|
<div class="small text-muted text-right">{{ frappe.format_date(date) }}</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% if frappe.session.user != 'Guest' and (is_owner or is_member) %}
|
||||||
|
<p>
|
||||||
|
<a href="/add-update?new=1&project={{ project.name }}" class="btn btn-secondary btn-sm">Add
|
||||||
|
Update</a>
|
||||||
|
</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
<div class='list-group'>
|
||||||
|
|
||||||
|
<!-- updates -->
|
||||||
|
{% for update in updates %}
|
||||||
|
{{ add_update(update.project_update, update.creation) }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<!-- creation -->
|
||||||
|
{{ add_update("Project created by " + frappe.db.get_value('User', project.owner, 'full_name'),
|
||||||
|
project.creation) }}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
41
community/www/hackathons/project.js
Normal file
41
community/www/hackathons/project.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
$('#req-evals').on('click', () => {
|
||||||
|
frappe.msgprint("The evaluations have been moved to <a href='https://t.me/fossunited'>Telegram</a>")
|
||||||
|
})
|
||||||
|
var set_likes = function(liked, likes) {
|
||||||
|
let $btn = $('.btn-like');
|
||||||
|
$btn.text(`${likes} 👍`);
|
||||||
|
if (liked) {
|
||||||
|
$btn.addClass('btn-secondary').removeClass('btn-default');
|
||||||
|
} else {
|
||||||
|
$btn.addClass('btn-default').removeClass('btn-secondary');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// set initial
|
||||||
|
//set_likes(liked, likes);
|
||||||
|
|
||||||
|
// like - unlike
|
||||||
|
$('.btn-like').on('click', () => {
|
||||||
|
frappe.call('like', {project: project}, (data) => {
|
||||||
|
set_likes(data.message.action =="Liked", data.message.likes);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// accept / reject
|
||||||
|
$('.btn-accept').on('click', (ev) => {
|
||||||
|
frappe.call('join_request', {id: $(ev.target).attr('data-request-id'), action: 'Accept'}, (data) => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btn-reject').on('click', (ev) => {
|
||||||
|
frappe.call('join_request', {id: $(ev.target).attr('data-request-id'), action: 'Reject'}, (data) => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.btn-leave').on('click', (ev) => {
|
||||||
|
frappe.call('join_request', {id: $(ev.target).attr('data-request-id'), action: 'Reject'}, (data) => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
57
community/www/hackathons/project.py
Normal file
57
community/www/hackathons/project.py
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
from frappe import _
|
||||||
|
|
||||||
|
def get_context(context):
|
||||||
|
context.no_cache = 1
|
||||||
|
try:
|
||||||
|
project = frappe.form_dict['project']
|
||||||
|
hackathon = frappe.form_dict['hackathon']
|
||||||
|
except KeyError:
|
||||||
|
frappe.local.flags.redirect_location = '/hackathons'
|
||||||
|
raise frappe.Redirect
|
||||||
|
context.project = get_project(project)
|
||||||
|
context.hackathon = hackathon
|
||||||
|
context.members = get_members(project)
|
||||||
|
context.confirmed_members = get_comfirmed_members(project)
|
||||||
|
context.likes = get_project_likes(project)
|
||||||
|
context.updates = get_updates(project)
|
||||||
|
if frappe.session.user != "Guest":
|
||||||
|
context.my_project = get_my_projects()
|
||||||
|
context.is_owner = context.project.owner == frappe.session.user
|
||||||
|
context.accepted_members = get_accepted_members(project)
|
||||||
|
context.is_member = check_is_member(project)
|
||||||
|
context.liked = get_liked_project(project)
|
||||||
|
|
||||||
|
def get_project(project_name):
|
||||||
|
try:
|
||||||
|
return frappe.get_doc('Community Project', project_name)
|
||||||
|
except frappe.DoesNotExistError:
|
||||||
|
frappe.throw(_("Project {0} does not exist.").format(project_name))
|
||||||
|
|
||||||
|
def get_members(project_name):
|
||||||
|
return frappe.get_all("Community Project Member", {"project": project_name, "status": ("!=", "Rejected") }, ['name', "owner", "status", 'intro'])
|
||||||
|
|
||||||
|
def get_comfirmed_members(project_name):
|
||||||
|
return frappe.get_all("Community Project Member", {"project": project_name, "status": ("=", "Accepted") }, ['name'])
|
||||||
|
|
||||||
|
def get_project_likes(project_name):
|
||||||
|
return frappe.get_all("Community Project Like", {"project": project_name})
|
||||||
|
|
||||||
|
def get_updates(project_name):
|
||||||
|
return frappe.get_all('Community Project Update', {"project": project_name}, ['owner', 'creation', 'update'])
|
||||||
|
|
||||||
|
def get_accepted_members(project_name):
|
||||||
|
return frappe.get_all("Community Project Member", {"project": project_name, "status": "Accepted" })
|
||||||
|
|
||||||
|
def get_my_projects():
|
||||||
|
my_project = frappe.db.get_value('Community Project', {"owner": frappe.session.user})
|
||||||
|
if not my_project:
|
||||||
|
my_project = frappe.db.get_value('Community Project Member', {"owner": frappe.session.user, "status": 'Accepted'}, 'project')
|
||||||
|
return my_project
|
||||||
|
|
||||||
|
def check_is_member(project_name):
|
||||||
|
frappe.get_all("Community Project Member", {"project": project_name, "status": "Accepted", "owner": frappe.session.user })
|
||||||
|
|
||||||
|
def get_liked_project(project_name):
|
||||||
|
return frappe.db.get_value("Community Project Like", {"owner": frappe.session.user, "project": project_name})
|
||||||
Reference in New Issue
Block a user