Skip to content

Commit fdcb665

Browse files
Colby Galluppeterkos
andauthored
Added dynamic schedule (#1139)
* Schedule is now pulled from HackathonManager * Schedule is now pulled from HackathonManager * Switched schedule JS to use correct data format * Scaffolded API fetch code * Added date/time background fade * Added time progress indicator * Event marker now extends outside event div * Second-day events can be shown automatically * CSS code style fixes * Event border works for any size events * Fix second day click * More CSS code style fixes * Removed fake API data * fix url for testing * fix now, change url, change section description Co-authored-by: Peter Kos <[email protected]>
1 parent 6554286 commit fdcb665

File tree

3 files changed

+133
-54
lines changed

3 files changed

+133
-54
lines changed

index.html

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@ <h1>What is a Hackathon?</h1>
163163
</section>
164164
<section id="schedule" class="section-pad">
165165
<h1>Schedule</h1>
166-
<p>More events coming soon!</p>
167166
<p>All times are in EST.</p>
168167
<div id="schedule-block">
169168
<div id="schedule-tapes">
@@ -181,42 +180,8 @@ <h2 class="number">21</h2>
181180
<h6 class="name">SUNDAY</h6>
182181
</div>
183182
</div>
184-
<div class="events day-first-events">
185-
<div class="event">
186-
<p class="time">10-10:30am</p>
187-
<p class="title">Opening Ceremony</p>
188-
</div>
189-
<div class="event">
190-
<p class="time">12pm</p>
191-
<p class="title">Lunch (on your own!)</p>
192-
</div>
193-
<div class="event">
194-
<p class="time">2pm-3pm</p>
195-
<p class="title">Mystery Workshop</p>
196-
</div>
197-
<div class="event">
198-
<p class="time">5pm-6pm</p>
199-
<p class="title">Mystery Event</p>
200-
</div>
201-
</div>
202-
<div class="events day-second-events">
203-
<div class="event">
204-
<p class="time">10am</p>
205-
<p class="title">Devpost submission</p>
206-
</div>
207-
<div class="event">
208-
<p class="time">1pm-2pm</p>
209-
<p class="title">Mystery Workshop 2</p>
210-
</div>
211-
<div class="event">
212-
<p class="time">12:30pm-2pm</p>
213-
<p class="title">Coding stops / Judging begins</p>
214-
</div>
215-
<div class="event">
216-
<p class="time">2pm-4pm</p>
217-
<p class="title">Closing Ceremony</p>
218-
</div>
219-
</div>
183+
<div class="events day-first-events"></div>
184+
<div class="events day-second-events"></div>
220185
</div>
221186
</div>
222187
</section>

index.js

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,18 +128,105 @@ for (let i = 0; i < card.length; i++) {
128128
});
129129
}
130130

131-
132131
// Schedule toggle code
132+
133+
// Created as named function so that we can show the correct day
134+
function showSecondDayEvents() {
135+
$('.day-first-events').hide();
136+
$('.day-first').removeClass('day-active');
137+
$('.day-second-events').show();
138+
$('.day-second').addClass('day-active');
139+
}
140+
133141
$('.day-second-events').hide();
134142
$('.day-first').click(function() {
135143
$('.day-first-events').show();
136144
$('.day-first').addClass('day-active');
137145
$('.day-second-events').hide();
138146
$('.day-second').removeClass('day-active');
139147
});
140-
$('.day-second').click(function() {
141-
$('.day-first-events').hide();
142-
$('.day-first').removeClass('day-active');
143-
$('.day-second-events').show();
144-
$('.day-second').addClass('day-active');
145-
});
148+
$('.day-second').click(showSecondDayEvents);
149+
150+
// Dynamic schedule code (sample API data)
151+
152+
function convertDate(date) {
153+
let output = '';
154+
155+
// hour
156+
if (date.getUTCHours() > 12) {
157+
output = String(date.getUTCHours() - 12);
158+
} else {
159+
output = String(date.getUTCHours());
160+
}
161+
162+
// minute
163+
if (date.getMinutes() !== 0) {
164+
output += ':' + String(date.getUTCMinutes()).padStart(2, '0');
165+
}
166+
167+
// AM/PM
168+
if (date.getUTCHours() >= 12) {
169+
output += 'pm';
170+
} else {
171+
output += 'am';
172+
}
173+
174+
return output;
175+
}
176+
177+
function handleEventData(events) {
178+
let now = new Date()
179+
180+
// needed to handle overlapping events
181+
let timeMarkerAdded = false;
182+
183+
// show second day page
184+
if (now > new Date(1613865600 * 1000)) { // start of Feb 21
185+
showSecondDayEvents();
186+
}
187+
188+
events.forEach(event => {
189+
let startDate = new Date(event.start); // convert ISO 8601 -> Date object
190+
let finishDate = undefined;
191+
192+
let dateString = convertDate(startDate);
193+
if (event.finish) { // finish === null for instantaneous events
194+
finishDate = new Date(event.finish);
195+
let finishString = convertDate(finishDate);
196+
if (dateString.slice(-2) === finishString.slice(-2)) { // hide "am/pm" of first time if both are identical
197+
dateString = dateString.slice(0, -2);
198+
}
199+
dateString += "-" + convertDate(finishDate);
200+
}
201+
202+
// calculate event container classes
203+
let divClasses = 'event';
204+
if ((finishDate || startDate) < now) {
205+
divClasses += ' past';
206+
}
207+
208+
// add event to DOM
209+
let eventContainer = $('.day-first-events');
210+
if (startDate.getDate() === 21) {
211+
eventContainer = $('.day-second-events');
212+
}
213+
const eventDiv = eventContainer.append(`<div class="${divClasses}"><p class="time">${dateString}</p><p class="title">${event.title}</p></div>`);
214+
215+
// add time indicator for the current event
216+
if (!timeMarkerAdded && startDate < now && finishDate > now) {
217+
timeMarkerAdded = true;
218+
219+
// calculate percent
220+
const eventLength = finishDate - startDate;
221+
const percent = ((now - startDate) / eventLength) * 100;
222+
223+
eventDiv.children('div:last-child').css('background-image', `linear-gradient(0deg, white, white ${100-percent}%, #bfbfbf 0)`);
224+
eventDiv.children('div:last-child').append(`<div class="marker" style="top: ${percent}%;"></div>`);
225+
}
226+
});
227+
}
228+
229+
fetch('https://apply.brickhack.io/events.json')
230+
.then(res => res.json())
231+
.then(events => handleEventData(events))
232+
.catch(err => console.log(err));

sass/main.scss

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ $font-regular: 400;
3131
// Size for all titles on page
3232
$title-size: 3em;
3333

34-
// MAX events (across either day)
35-
// TODO: Make this more dynamic via JS?
36-
$event-count: 6;
37-
3834
// Import carousel
3935
@import '../node_modules/slick-carousel/slick/slick.css';
4036
@import '../node_modules/slick-carousel/slick/slick-theme.css';
@@ -745,26 +741,57 @@ nav {
745741
width: 60%;
746742

747743
// Sequentially assign colors to all elements
748-
$colors: $red, $orange, $light-gray;
749-
@for $i from 1 through $event-count {
750-
.event:nth-child(#{$i}) {
751-
border-top: 10px solid nth($colors, $i % length($colors) + 1);
752-
}
744+
.event:nth-child(3n) {
745+
border-top: 10px solid $red;
746+
}
747+
.event:nth-child(3n + 1) {
748+
border-top: 10px solid $orange;
749+
}
750+
.event:nth-child(3n + 2) {
751+
border-top: 10px solid $light-gray;
753752
}
754753

755754
.event {
756-
background-color: white;
755+
background: white;
757756
border-radius: 15px;
758757
margin: 10px 0px;
759758
padding: 10px;
759+
position: relative;
760+
761+
&.past {
762+
background-color: #bfbfbf;
763+
}
760764

761765
.time {
762766
color: $light-blue;
763767
}
768+
764769
.title {
765770
color: black;
766771
font-size: 1.3em;
767772
}
773+
774+
.marker {
775+
$marker-width: 20px;
776+
777+
border-bottom: 2px solid $red;
778+
border-top: 2px solid $red;
779+
position: absolute;
780+
left: -25px;
781+
right: 0;
782+
top: 0;
783+
784+
&::before {
785+
content: "";
786+
background-color: $red;
787+
border-radius: 50%;
788+
position: absolute;
789+
bottom: -($marker-width / 2);
790+
left: -($marker-width / 2);
791+
height: $marker-width;
792+
width: $marker-width;
793+
}
794+
}
768795
}
769796
}
770797

0 commit comments

Comments
 (0)