refactor: renamed app to school

This commit is contained in:
Jannat Patel
2021-10-11 20:31:27 +05:30
parent 13022e0bcc
commit d07dbcc50a
466 changed files with 2497 additions and 146 deletions

View File

View File

@@ -0,0 +1,129 @@
{% 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 %}
{% from "www/hackathons/macros/navbar.html" import navbar %}
{% from "www/hackathons/macros/user.html" import show_user %}
{% 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/{{ hackathon }}/{{ project.name }}" 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 %}
{% macro card_talk(talk) %}
<div class="col-sm-4 mb-4 text-left">
<a href="{{talk.video_link}}" class="no-decoration no-underline">
<div class="card h-100">
<div class='card-body'>
<h5 class='card-title'>{{ talk.topic }}</h5>
<div class="text-muted">{{ talk.speaker }}</div>
<div class="text-muted">{{ frappe.utils.format_datetime(talk.date_and_time, "medium") }}</div>
</div>
</div>
</a>
</div>
{% endmacro %}
{% macro card_update(update) %}
<div class="col-sm-4 mb-4 text-left">
<div class="card h-100">
<div class='card-body'>
<p>{{ frappe.utils.md_to_html(update.project_update) }}</p>
<div>
<a href="/hackathons/{{hackathon}}/{{update.project}}">{{ update.project}}</a>
by {{ show_user(update.owner) }}
<div class="text-muted">{{ frappe.utils.format_datetime(update.creation, "medium") }}</div>
</div>
</div>
</div>
</div>
{% endmacro %}
{% block content %}
<section class="section">
{{ hero(hackathon, {'name': 'Home', 'url': '/hackathons'}) }}
<div class='container'>
{{ navbar(hackathon) }}
<div class="tab-content">
<div class="tab-pane fade py-4 show active" role="tabpanel" id="home">
<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>
<div class="tab-pane fade py-4" role="tabpanel" id="talks">
<div class="row mt-5">
{% for talk in talks %}
{{ card_talk(talk) }}
{% endfor %}
{% if talks %}
{% for n in range( (3 - (talks|length)) %3) %}
{{ null_card() }}
{% endfor %}
{% endif %}
</div>
</div>
<div class="tab-pane fade py-4" role="tabpanel" id="updates">
<div class="row mt-5">
{% for update in updates %}
{{ card_update(update) }}
{% endfor %}
{% if updates %}
{% for n in range( (3 - (updates|length)) %3) %}
{{ null_card() }}
{% endfor %}
{% endif %}
</div>
</div>
</div>
</div>
</section>
{% endblock %}

View File

@@ -0,0 +1,25 @@
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
context.talks = get_hackathon_talks(hackathon)
context.updates = get_hackathon_updates(context.projects)
def get_hackathon_projects(hackathon):
return frappe.get_all("Community Project", filters={"hackathon":hackathon}, fields=["name", "project_short_intro"])
def get_hackathon_talks(hackathon):
return frappe.get_all("Community Talk", {"event": hackathon}, ["topic", "speaker", "date_and_time", "video_link"])
def get_hackathon_updates(projects):
project_list = [project.name for project in projects]
return frappe.get_all("Community Project Update", {"project": ["in", project_list]}, ["project", "`update` as project_update", "owner", "creation"])

View 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 %}

View 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 Hackathon")

View File

View File

@@ -0,0 +1,18 @@
{% macro hackathon_card(hackathon) %}
<div class="col-sm-4 mb-4 text-left">
<a href="/hackathons/{{ hackathon.name }}" class="no-decoration no-underline">
<div class="card h-100" style="box-shadow: 0px 5px 10px rgb(0 0 0 / 10%);">
<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="box-shadow: 0px 5px 10px rgb(0 0 0 / 10%);border-radius: 0.25rem;background-color: rgb(250, 251, 252);">
</div>
</div>
{% endmacro %}

View 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 %}

View File

@@ -0,0 +1,16 @@
{% macro navbar(hackathon) %}
<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">Projects</a>
</li>
<li class="nav-item">
<a class="nav-link" id="talks-tab" data-toggle="tab" href="#talks" role="tab" aria-controls="talks"
aria-selected="false">Talks</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</a>
</li>
</ul>
{% endmacro %}

View File

@@ -0,0 +1,3 @@
{% macro show_user(user) %}
{{ frappe.db.get_value("User", user, "full_name") }}
{% endmacro %}

View File

@@ -0,0 +1,174 @@
{% 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 %}
{% from "www/hackathons/macros/user.html" import show_user %}
{% 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="section">
{{ hero(project, {'name': hackathon, 'url': '/hackathons/' + 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" data-project={{project.name}}>👍</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="{{ member.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.utils.format_datetime(date, "medium") }}</div>
</div>
{% endmacro %}
{% if frappe.session.user != 'Guest' and (is_owner or is_member) %}
<p>
<a href="/project-update?new=1&project={{ project.name }}&hackathon={{ hackathon }}" 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) }}
{%
<!-- creation -->
{{ add_update("Project created by " + frappe.db.get_value('User', project.owner, 'full_name'),
project.creation) }}
</div>
</div>
</div>
{% endif %}
</div>
</section>
{% endblock %}

View File

@@ -0,0 +1,48 @@
$('#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');
likes ? $btn.text(`${likes} 👍`): $btn.text(`👍`);
if (liked) {
$btn.addClass('btn-dark').removeClass('btn-default');
} else {
$btn.addClass('btn-default').removeClass('btn-dark');
}
};
// set initial likes
frappe.ready(() => {
frappe.call('school.www.hackathons.project.like', { project: get_url_arg().get("project"), initial: true }, (data) => {
set_likes(data.message.action == "Liked", data.message.likes)
})
})
var get_url_arg = () => {
return new URLSearchParams(window.location.search);
}
// like - unlike
$('.btn-like').on('click', (e) => {
frappe.call('school.www.hackathons.project.like', { project: get_url_arg().get("project") }, (data) => {
set_likes(data.message.action == "Liked", data.message.likes);
});
});
// accept / reject
$('.btn-accept').on('click', (e) => {
frappe.call('school.www.hackathons.project.join_request', { id: $(e.target).attr('data-request-id'), action: 'Accept' }, (data) => {
window.location.reload();
});
});
$('.btn-reject').on('click', (ev) => {
frappe.call('school.www.hackathons.project.join_request', { id: $(ev.target).attr('data-request-id'), action: 'Reject' }, (data) => {
window.location.reload();
});
});
$('.btn-leave').on('click', (ev) => {
frappe.call('school.www.hackathons.project.join_request', { id: $(ev.target).attr('data-request-id'), action: 'Reject' }, (data) => {
window.location.reload();
});
});

View File

@@ -0,0 +1,90 @@
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.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_updates(project_name):
return frappe.get_all('Community Project Update', {"project": project_name}, ['owner', 'creation', '`update` as project_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):
return 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})
@frappe.whitelist()
def join_request(id, action):
if action == 'Accept':
project_member = frappe.get_doc('Community Project Member', id)
if len(frappe.db.get_all('Community Project Member',
dict(project = project_member.project, status = 'Accepted'))) > 2:
frappe.throw('A project cannot have more than 4 members')
frappe.db.set_value('Community Project Member', id, 'status', 'Accepted')
else:
frappe.db.set_value('Community Project Member', id, 'status', 'Rejected')
def has_already_liked(project):
likes = frappe.db.get_value('Community Project Like', {"owner": frappe.session.user, "project": project})
return likes
@frappe.whitelist()
def get_project_likes(project):
return len(frappe.get_all("Community Project Like", {"project": project}))
@frappe.whitelist()
def like(project, initial=False):
liked_project = has_already_liked(project)
action = "Liked" if (liked_project and initial) else "Unliked"
if not initial:
if liked_project:
action = "Unliked"
frappe.get_doc("Community Project Like", liked_project).delete()
else:
action = "Liked"
frappe.get_doc({"doctype": "Community Project Like","project": project}).save()
frappe.db.set_value("Community Project", project, "likes", get_project_likes(project))
return {
"action": action,
"likes": get_project_likes(project)
}