Skip to content

Commit

Permalink
GITC-102: Hackathons landing page (developers) refresh (#9304)
Browse files Browse the repository at this point in the history
* GITC-102: Hackathons landing page (developers) refresh

* GITC-102: Tightens up spacing in the header and adjust top-hacks viewbox

* GITC-102: Updates the sponsor cta, fixes mautic error/success state and hack-list indentation

* GITC-232: Replace hackathon bubbles with sponsor avatars

* GITC-102: fixes > 6 sponsors circle positioning

* GITC-102: Fixes isort issues
  • Loading branch information
gdixon authored Jul 26, 2021
1 parent f8ede14 commit 4776e34
Show file tree
Hide file tree
Showing 15 changed files with 882 additions and 272 deletions.
349 changes: 274 additions & 75 deletions app/app/templates/shared/hackathon-list.html

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 108 additions & 0 deletions app/assets/v2/js/bubbles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
document.addEventListener('DOMContentLoaded', () => {
// configure the bubbles
const SCROLL_SPEED = 0.3;
const NOISE_SPEED = 0.004;
const NOISE_AMOUNT = 5;
const CANVAS_WIDTH = 2800;
const bubblesEl = document.querySelector('.bubbles');
const bubbleSpecs = [
{ s: .6, x: 1134, y: 45 },
{ s: .6, x: 1620, y: 271 },
{ s: .6, x: 1761, y: 372 },
{ s: .6, x: 2499, y: 79 },
{ s: .6, x: 2704, y: 334 },
{ s: .6, x: 2271, y: 356 },
{ s: .6, x: 795, y: 226 },
{ s: .6, x: 276, y: 256 },
{ s: .6, x: 1210, y: 365 },
{ s: .6, x: 444, y: 193 },
{ s: .6, x: 2545, y: 387 },
{ s: .8, x: 1303, y: 193 },
{ s: .8, x: 907, y: 88 },
{ s: .8, x: 633, y: 320 },
{ s: .8, x: 323, y: 60 },
{ s: .8, x: 129, y: 357 },
{ s: .8, x: 1440, y: 342 },
{ s: .8, x: 1929, y: 293 },
{ s: .8, x: 2135, y: 198 },
{ s: .8, x: 2276, y: 82 },
{ s: .8, x: 2654, y: 182 },
{ s: .8, x: 2783, y: 60 },
{ x: 1519, y: 118 },
{ x: 1071, y: 233 },
{ x: 1773, y: 148 },
{ x: 2098, y: 385 },
{ x: 2423, y: 244 },
{ x: 901, y: 385 },
{ x: 624, y: 111 },
{ x: 75, y: 103 },
{ x: 413, y: 367 },
{ x: 2895, y: 271 },
{ x: 1990, y: 75 }
];

class Bubbles {
constructor(specs) {
this.bubbles = [];

specs.forEach((spec, index) => {
this.bubbles.push(new Bubble(index, spec));
});

requestAnimationFrame(this.update.bind(this));
bubblesEl.style.opacity = 1;
}

update() {
this.bubbles.forEach(bubble => bubble.update());
this.raf = requestAnimationFrame(this.update.bind(this));
}
}

class Bubble {
constructor(index, {
x,
y,
s = 1
}) {
this.index = index;
this.x = x;
this.y = y;
this.scale = s;

this.noiseSeedX = Math.floor(Math.random() * 64000);
this.noiseSeedY = Math.floor(Math.random() * 64000);
this.el = bubblesEl.children[index];
if (!this.el) {
return;
}

this.el.classList.add(`logo${this.index + 1}`);
}

update() {
if (!this.el) {
return;
}
this.noiseSeedX += NOISE_SPEED;
this.noiseSeedY += NOISE_SPEED;
let randomX = noise.simplex2(this.noiseSeedX, 0);
let randomY = noise.simplex2(this.noiseSeedY, 0);

this.x -= SCROLL_SPEED;
this.xWithNoise = this.x + (randomX * NOISE_AMOUNT);
this.yWithNoise = this.y + (randomY * NOISE_AMOUNT);

if (this.x < -200) {
this.x = CANVAS_WIDTH;
}

this.el.style.transform = `translate(${this.xWithNoise}px, ${this.yWithNoise}px) scale(${this.scale})`;
}
}

noise.seed(Math.floor(Math.random() * 64000));

// init the bubbles
const bubbles = new Bubbles(bubbleSpecs);
});
54 changes: 41 additions & 13 deletions app/assets/v2/js/pages/hackathon-list.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,48 @@
$(document).ready(function() {
$(document).on('click', '#tabs a', function(e) {
e.preventDefault();
let target = $(this).data('href');
document.addEventListener('DOMContentLoaded', () => {

$('.hackathons-list').addClass('hidden');
$('.nav-link').removeClass('active');
$('.nav-link').css('font-weight', '');
$(this).addClass('active');
$(this).css('font-weight', '700');
const tabs = document.querySelectorAll('.hackathon-tabs a');
const hacks = document.querySelectorAll('.hackathon-list');

const loadTab = (target) => {
let hiddenRows = false;

$('.hackathon-list').addClass('hidden');
$('.hackathon-list.' + target).removeClass('hidden');
const hack = document.querySelector('.hackathon-list.' + target);
const rows = document.querySelectorAll('.hackathon-list.' + target + ' > .row');
const more = document.querySelector('.hackathon-list.' + target + ' > .view-more');

$('html,body').animate({
scrollTop: '+=1px'
tabs.forEach((t) => t.classList.remove('active'));
document.querySelector('.nav-link[data-href="' + target + '"]').classList.add('active');

hacks.forEach((hack) => hack.classList.add('hidden'));
hack.classList.remove('hidden');

rows.forEach((row, indx) => {
if (indx > 1 && more.classList.contains('d-none')) {
hiddenRows = true;
row.classList.add('d-none');
}
});

if (hiddenRows && more) {
const newMore = more.cloneNode(true);

more.parentNode.replaceChild(newMore, more);
newMore.classList.add('d-block');
newMore.classList.remove('d-none');
newMore.addEventListener('click', () => {
newMore.classList.add('d-none');
newMore.classList.remove('d-block');
rows.forEach((hack) => hack.classList.remove('d-none'));
});
}
};

tabs.forEach((tab) => {
tab.addEventListener('click', (e) => {
e.preventDefault();
loadTab(e.target.dataset.href);
});
});

loadTab(document.default_tab);
});
8 changes: 8 additions & 0 deletions app/assets/v2/scss/gc-utilities.scss
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@
background-color: $gc-grey-100;
}

.bg-violet-100 {
background-color: $gc-violet-100;
}

.bg-violet-300 {
background-color: $gc-violet-300;
}
Expand All @@ -90,6 +94,10 @@
background-color: $gc-violet-400;
}

.bg-teal-300 {
background-color: $gc-teal-300;
}

.bg-pink-300 {
background-color: $gc-pink-300;
}
Expand Down
2 changes: 1 addition & 1 deletion app/assets/v2/scss/gitcoin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,7 @@
}

.nav-tabs .nav-line {
color: #6F3FF5;
color: $gc-grey-500;
border-width: 0px 0px 3px 0;
}
.nav-tabs .nav-line.active {
Expand Down
12 changes: 9 additions & 3 deletions app/dashboard/gas_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,16 @@ def gas_history_view(request):
events = JSONStore.objects.get(key='hackathons', view='hackathons').data[1]
default_tab = 'current'

num_current = len([ele for ele in events if ele['type'] == 'current'])
num_upcoming = len([ele for ele in events if ele['type'] == 'upcoming'])
num_finished = len([ele for ele in events if ele['type'] == 'finished'])

tabs = [
('current', 'happening now'),
('upcoming', 'upcoming'),
('finished', 'completed'),
('current', 'happening now', num_current),
('upcoming', 'upcoming', num_upcoming),
('finished', 'completed', num_finished),
]

context = {
'title': _('Live Ethereum (ETH) Gas History'),
'card_desc': _('See and comment on the Ethereum (ETH) Gas - Hourly History Graph'),
Expand All @@ -262,6 +267,7 @@ def gas_history_view(request):
'granularity_options': granularity_options,
'events': events,
'tabs': tabs,
'types': ['current', 'upcoming', 'finished'],
'default_tab': default_tab
}
return TemplateResponse(request, 'gas_history.html', context)
18 changes: 18 additions & 0 deletions app/dashboard/migrations/0184_hackathonevent_total_prize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.24 on 2021-07-17 03:53

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dashboard', '0183_auto_20210701_1339'),
]

operations = [
migrations.AddField(
model_name='hackathonevent',
name='total_prize',
field=models.CharField(blank=True, help_text='extra text to display next the event dates on the hackathon list page', max_length=255, null=True),
),
]
1 change: 1 addition & 0 deletions app/dashboard/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5055,6 +5055,7 @@ class HackathonEvent(SuperModel):
chat_channel_id = models.CharField(max_length=255, blank=True, null=True)
use_circle = models.BooleanField(help_text=_('Use circle for the Hackathon'), default=False)
visible = models.BooleanField(help_text=_('Can this HackathonEvent be seeing on /hackathons ?'), default=True)
total_prize = models.CharField(max_length=255, null=True, blank=True, help_text='extra text to display next the event dates on the hackathon list page')

default_channels = ArrayField(models.CharField(max_length=255), blank=True, default=list)
objects = HackathonEventQuerySet.as_manager()
Expand Down
377 changes: 310 additions & 67 deletions app/dashboard/templates/dashboard/hackathon/hackathons.html

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions app/dashboard/templatetags/group_by_field.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
"""Define the add_url_schema template tag to allow cleaning up url in templates.
Copyright (C) 2021 Gitcoin Core
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
from django import template

register = template.Library()

@register.simple_tag
def group_by_field(list_input, fields, field):
"""Groups list_input into columns by pivotting on the given field (for each of the given fields)"""
output = []
for fields_val in fields:
# collect columns details into a dict ({field:fields_val, 'list':[...]})
group = {}
# eg group.type = "current"
group[field] = fields_val
# collate the list by pivotting only the matching elements
group['list'] = [ele for ele in list_input if ele[field] == fields_val]
# appending each dict to the output
output.append(group)

return output
36 changes: 36 additions & 0 deletions app/dashboard/templatetags/group_in_columns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
"""Define the add_url_schema template tag to allow cleaning up url in templates.
Copyright (C) 2021 Gitcoin Core
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
import itertools

from django import template

register = template.Library()

@register.filter
def group_in_columns(list_input, number_of_columns):
"""Groups list_input into columns based on the number_of_columns required (to be used in a loop)"""
columns = int(number_of_columns)
items = iter(list_input)
while True:
column = list(itertools.islice(items, columns))
if column:
yield column
else:
break
Loading

0 comments on commit 4776e34

Please sign in to comment.