Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add events section to hackathons #7316

Merged
merged 10 commits into from
Sep 30, 2020
4 changes: 3 additions & 1 deletion app/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -874,5 +874,7 @@ def callback(request):
PHONE_SALT = env('PHONE_SALT', default='THIS_IS_INSECURE_CHANGE_THIS_PLEASE')

HYPERCHARGE_BOUNTIES_PROFILE_HANDLE = env('HYPERCHARGE_BOUNTIES_PROFILE', default='gitcoinbot')
ADDEVENT_CLIENT_ID = env('ADDEVENT_CLIENT_ID', default='')
ADDEVENT_API_TOKEN = env('ADDEVENT_API_TOKEN', default='')

BRIGHTID_PRIVATE_KEY = env('BRIGHTID_PRIVATE_KEY', default='wrong-private-key')
BRIGHTID_PRIVATE_KEY = env('BRIGHTID_PRIVATE_KEY', default='wrong-private-key')
1 change: 1 addition & 0 deletions app/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@
path('api/v0.1/hackathon/<str:hackathon>/save/', dashboard.views.save_hackathon, name='save_hackathon'),
path('api/v1/hackathon/<str:hackathon>/prizes', dashboard.views.hackathon_prizes, name='hackathon_prizes_api'),
path('api/v0.1/hackathon/<str:hackathon>/showcase/', dashboard.views.showcase, name='hackathon_showcase'),
path('api/v0.1/hackathon/<str:hackathon>/events/', dashboard.views.events, name='hackathon_events'),
path('api/v0.1/projects/<int:project_id>', dashboard.views.get_project, name='project_context'),
# action URLs
url(r'^funder', retail.views.funder_bounties_redirect, name='funder_bounties_redirect'),
Expand Down
4 changes: 4 additions & 0 deletions app/assets/v2/images/hackathon/check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/v2/images/hackathon/demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions app/assets/v2/images/hackathon/demo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions app/assets/v2/images/hackathon/formation.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions app/assets/v2/images/hackathon/office.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions app/assets/v2/images/hackathon/pitch.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions app/assets/v2/images/hackathon/workshop.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions app/assets/v2/js/pages/dashboard-hackathon.js
Original file line number Diff line number Diff line change
Expand Up @@ -911,6 +911,9 @@
case 3:
newPathName = 'participants';
break;
case 4:
newPathName = 'events';
break;
case 5:
newPathName = 'showcase';
break;
Expand Down
62 changes: 62 additions & 0 deletions app/assets/v2/js/vue-components.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,68 @@ Vue.component('project-directory', {
});


Vue.component('events', {
delimiters: [ '[[', ']]' ],
props: [],
data: function() {
return {
events: []
};
},
methods: {
nth: function(d) {
if (d > 3 && d < 21)
return 'th';
switch (d % 10) {
case 1: return 'st';
case 2: return 'nd';
case 3: return 'rd';
default: return 'th';
}
},
fetchEvents: async function() {
const response = await fetchData(`/api/v0.1/hackathon/${document.hackathonObj.id}/events/`, 'GET');

this.$set(this, 'events', response.events.events);
},
formatDate: function(event) {
const monthNames = [
'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December'
];
const date = event.date_start.split('/');
const time = event.date_start_time;
const newDate = new Date(`${date[2]}-${date[0]}-${date[1]}T${time}`);
const month = monthNames[newDate.getMonth()];
const day = newDate.getDay();
const hours = newDate.getHours();
const ampm = event.date_start_ampm.toLowerCase();

return `${month} ${day}${this.nth(newDate.getDay())}, ${hours} ${ampm} ET`;
},
eventTag: function(event) {
const text = event.eventname;

if (text.includes('formation')) {
return 'formation';
} else if (text.includes('pitch')) {
return 'pitch';
} else if (text.includes('check')) {
return 'check';
} else if (text.includes('office')) {
return 'office';
} else if (text.includes('demo')) {
return 'demo';
}

return 'workshop';
}
},
mounted() {
this.fetchEvents();
}
});

Vue.component('showcase', {
delimiters: [ '[[', ']]' ],
props: [],
Expand Down
18 changes: 18 additions & 0 deletions app/dashboard/migrations/0151_hackathonevent_calendar_id.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.4 on 2020-09-30 05:21

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dashboard', '0150_auto_20200904_1505'),
]

operations = [
migrations.AddField(
model_name='hackathonevent',
name='calendar_id',
field=models.CharField(blank=True, max_length=255),
),
]
1 change: 1 addition & 0 deletions app/dashboard/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4921,6 +4921,7 @@ class HackathonEvent(SuperModel):
objects = HackathonEventQuerySet.as_manager()
display_showcase = models.BooleanField(default=False)
showcase = JSONField(default=dict, blank=True, null=True)
calendar_id = models.CharField(max_length=255, blank=True)

def __str__(self):
"""String representation for HackathonEvent.
Expand Down
55 changes: 55 additions & 0 deletions app/dashboard/templates/dashboard/index-vue.html
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,60 @@ <h6 class="font-weight-bold mb-3">Invite [[numUsers]] Users to the Bounty</h6>
</div>
</user-directory>
</b-tab>
<b-tab class="col-12" title-item-class="navigation">
<template v-slot:title>
<div class="mt-4">
{% trans "Events" %}
</div>
</template>
<div id="events">
<events inline-template>
<div style="background-color: white; padding: 5%;" class="container">
<div>
<h1 class="font-bigger-4 font-weight-bold">Events Schedule</h1>
{% if is_staff %}
<button class="btn btn-lg gc-border-blue">Add event</button>
{% endif %}
<hr style="color: black; height: 3px">
<div class="d-flex justify-content-between my-5" v-for="event in events">
<div class="d-flex col-8">
<div>
<img src="{% static 'v2/images/hackathon/formation.svg' %}" alt="" v-if="eventTag(event) == 'formation'">
<img src="{% static 'v2/images/hackathon/pitch.svg' %}" alt="" v-if="eventTag(event) == 'pitch'">
<img src="{% static 'v2/images/hackathon/check.svg' %}" alt="" v-if="eventTag(event) == 'check'">
<img src="{% static 'v2/images/hackathon/workshop.svg' %}" alt="" v-if="eventTag(event) == 'workshop'">
<img src="{% static 'v2/images/hackathon/office.svg' %}" alt="" v-if="eventTag(event) == 'office'">
<img src="{% static 'v2/images/hackathon/demo.svg' %}" alt="" v-if="eventTag(event) == 'demo'">
</div>
<div class="ml-4">
<p class="m-0" v-if="eventTag(event) == 'formation'" style="color: #1BD389">Team formation</p>
<p class="m-0" v-if="eventTag(event) == 'pitch'" style="color: #FF00B8">Pitch Day</p>
<p class="m-0" v-if="eventTag(event) == 'check'" style="color: #00DACD">Mid hack Check-In</p>
<p class="m-0" v-if="eventTag(event) == 'office'" style="color: #0090FF">Sponsor Office Hours</p>
<p class="m-0" v-if="eventTag(event) == 'workshop'" style="color: #D9AE00">Workshop</p>
<p class="m-0" v-if="eventTag(event) == 'demo'" style="color: #8948FF">Demo Day</p>
<p class="m-0 font-weight-bold">[[formatDate(event)]]</p>
<h3 class="font-title"><b>[[event.title]]</b> [[ event.organizer ? `with ${event.organizer}` : '']]</h3>
<p class="m-0" v-html="event.description" class="font-body"></p>
</div>
</div>
<div>
<div title="Add to Calendar" class="addeventatc">
Add to Calendar
<span class="start">[[event.date_start]] [[event.date_start_time]]</span>
<span class="end">[[event.date_end]] [[event.date_end_time]]</span>
<span class="timezone">[[event.timezone]]</span>
<span class="title">[[event.title]]</span>
<span class="description">[[event.description]]</span>
<span class="location">[[event.location]]</span>
</div>
</div>
</div>
</div>
</div>
</events>
</div>
</b-tab>
<b-tab class="col-12" title-item-class="navigation" v-if="hackHasEnded">
<template v-slot:title>
<div class="mt-4">
Expand Down Expand Up @@ -823,6 +877,7 @@ <h4 class="font-bigger-1 font-weight-bold mb-3">[[hackathon.name]] Wall of Fame<
{% include 'shared/analytics.html' %}
{% include 'shared/footer_scripts.html' %}
{% include 'shared/footer.html' %}
<script type="text/javascript" src="https://addevent.com/libs/atc/1.6.1/atc.min.js" async defer></script>
<script type="text/x-template" id="select2-template">
<select>
<slot></slot>
Expand Down
45 changes: 43 additions & 2 deletions app/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from datetime import datetime, timedelta
from decimal import Decimal

import requests
from django.conf import settings
from django.contrib import messages
from django.contrib.admin.views.decorators import staff_member_required
Expand Down Expand Up @@ -4102,9 +4103,9 @@ def hackathon(request, hackathon='', panel='prizes'):
active_tab = 1
elif panel == "projects":
active_tab = 2
elif panel == "chat":
active_tab = 3
elif panel == "participants":
active_tab = 3
elif panel == "events":
active_tab = 4
elif panel == "showcase":
active_tab = 5
Expand Down Expand Up @@ -6075,3 +6076,43 @@ def showcase(request, hackathon):
return JsonResponse({
'success': True,
})


def events(request, hackathon):
hackathon_event = HackathonEvent.objects.filter(pk=hackathon).first()

if not hackathon_event:
return JsonResponse({
'error': True,
'msg': f'No exists Hackathon Event with id {hackathon}'
}, status=404)

calendar_unique = hackathon_event.calendar_id
token = settings.ADDEVENT_API_TOKEN
endpoint = f'https://www.addevent.com/api/v1/oe/events/list/'
calendar_endpoint = 'https://www.addevent.com/api/v1/me/calendars/list/'

calendar_response = requests.get(calendar_endpoint, {
'token': token,
})

calendars = calendar_response.json()["calendars"]
calendar_id = None

for calendar in calendars:
if calendar['uniquekey'] == calendar_unique:
calendar_id = calendar['id']
break

upcoming = hackathon_event.start_date.strftime('%Y-%m-%d %H:%M:%S')
response = requests.get(endpoint, {
'token': token,
'calendar_id': calendar_id,
'upcoming': upcoming
})

events = response.json()

return JsonResponse({
'events': events,
})