diff --git a/_includes/events-page/right-col-content-check.html b/_includes/events-page/right-col-content-check.html new file mode 100644 index 0000000000..e122fb7d6b --- /dev/null +++ b/_includes/events-page/right-col-content-check.html @@ -0,0 +1,32 @@ +

+ + Online Project Team Meetings +

+
+
+
+ +
+
+

+ Please review the listing of project team meeting times to find a + project that fits your schedule. You are welcome to attend a project + team meeting after you have completed + Onboarding. +

+
+
+
+
+ {% assign days-of-week = + "Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday" | split: "," %} + {% for day in days-of-week %} +
+

{{day}}

+
    +
    + {% endfor %} +
    +
    + + diff --git a/assets/js/events-check.js b/assets/js/events-check.js new file mode 100644 index 0000000000..c96648fdff --- /dev/null +++ b/assets/js/events-check.js @@ -0,0 +1,45 @@ +const locationsDropDown = document.querySelector(".getting-started-mobile-page"); +const showingLocations = document.querySelector(".mobile-locations-dropdown"); +const showContent = document.querySelectorAll(".event-title"); +const showLocations = document.querySelector(".event-title-1"); + +showLocations.addEventListener("click", function () { + this.classList.toggle("active"); + if (showingLocations.style.display == "block") { + showingLocations.style.display = "none"; + } else { + showingLocations.style.display = "block"; + } +}); + +for (let i = 0; i < showContent.length; i++) { + showContent[i].addEventListener("click", showingDropDown); +} + +function showingDropDown() { + if(document.body.clientWidth<767){ + this.classList.toggle("active"); + let dropDown = this.nextElementSibling; + if (dropDown.style.display === "block") { + dropDown.style.display = "none"; + } else { + dropDown.style.display = "block"; + } + } +} +document.querySelector('.flex-page-card').addEventListener('resize',handleScreenResize) +function handleScreenResize(){ + if(document.body.clientWidth>767){ + const columns = document.querySelectorAll('.mobile-dropdown'); + for(let column of columns){ + column.style.display='block'; + column.previousElementSibling.classList.remove('active'); + } + } + else{ + const columns = document.querySelectorAll('.mobile-dropdown'); + for(let column of columns){ + column.style.display='none'; + } +} +} \ No newline at end of file diff --git a/assets/js/project.js b/assets/js/project.js index faf755d123..797fc008de 100644 --- a/assets/js/project.js +++ b/assets/js/project.js @@ -1,13 +1,14 @@ --- --- - /* - Fetch the correct project +Fetch the correct project */ {% assign projects = site.data.external.github-data %} // Escapes JSON for injections. See: #2134. If this is no longer the case, perform necessary edits, and remove this comment. let projects = JSON.parse(decodeURIComponent("{{ projects | jsonify | uri_escape }}")); +import { vrmsDataFetch, localeTimeIn12Format } from './utility/vrms-events.js'; + /* Passing script attributes from html script tag to JS file https://www.gun.io/blog/pass-arguments-to-embedded-javascript-tutorial-example @@ -18,6 +19,7 @@ const project = findProjectById(projectId); function findProjectById(identification){ // Starts at 1 now since the first element is a time stamp + for (let i = 1; i < projects.length; i++){ let itemId = projects[i].id.toString(); if(itemId == identification){ @@ -135,101 +137,31 @@ let meetingsHeader = document.querySelector('.meetingsHeader'); let projectTitle = scriptTag.getAttribute("projectTitle"); let meetingsFound = []; -// Grab the meeting time data from the vrms_data.json file -{% assign vrmsData = site.data.external.vrms_data %} -// Escapes JSON for injections. See: #2134. If this is no longer the case, perform necessary edits, and remove this comment. -const vrmsData = JSON.parse(decodeURIComponent("{{ vrmsData | jsonify | uri_escape }}")); - -// Helper function to sort VRMS data by day of the week from "date" key and meeting time from "startTime" key -function sortByDate(scheduleData) { - const map = { - 'Mon': 1, - 'Tue': 2, - 'Wed': 3, - 'Thu': 4, - 'Fri': 5, - 'Sat': 6, - 'Sun': 7 - }; - - scheduleData.sort(function(a, b) { - const day1 = new Date(a.date).toString().substring(0, 3); - const day2 = new Date(b.date).toString().substring(0, 3); - - return map[day1] - map[day2]; - }); - - scheduleData.sort(function(a, b) { - const day1 = new Date(a.date).toString().substring(0, 3); - const day2 = new Date(b.date).toString().substring(0, 3); - const time1 = new Date(a.startTime).toString().substring(16, 21); - const time2 = new Date(b.startTime).toString().substring(16, 21); - - if (day1 === day2) { - if (time1 > time2) { - return 1; - } else { - return -1; - } - } else { - return 1; - } - }); -} - // Loops through the VRMS data and inserts each meeting time into the HTML of the correct project page function appendMeetingTimes(scheduleData) { - - sortByDate(scheduleData); - for (const event of scheduleData) { try { - const startTime = timeFormat(new Date(event.startTime)); - const endTime = timeFormat(new Date(event.endTime)); + const startTime = localeTimeIn12Format(event.startTime); + const endTime = localeTimeIn12Format(event.endTime); const projectName = event.project.name; const name = event.name; const day = new Date(event.date).toString().substring(0,3); + // only append the meeting times to the correct project page if (projectTitle.toLowerCase() === projectName.toLowerCase()) { meetingsList.insertAdjacentHTML("beforeend", `
  • ${day} ${startTime} - ${endTime}
    ${name}
  • `); meetingsFound.push(day); } - } catch (e) { console.error(e); } } } -appendMeetingTimes(vrmsData); - +vrmsDataFetch("project", appendMeetingTimes) if (meetingsFound.length >= 1) { meetingsHeader.insertAdjacentHTML("beforeend", 'Meetings'); document.querySelector('#userTimeZone').insertAdjacentHTML('afterbegin', timeZoneText()); -} - -// Formats time to be readable -function timeFormat(time) { - let hours = time.getHours(); - let minutes = time.getMinutes(); - - if (minutes == 0) { - minutes = minutes + "0"; - } - - if (hours < 12) { - return `${hours}:${minutes} am`; - } - else if (hours > 12){ - hours = hours - 12; - return `${hours}:${minutes} pm`; - } - else if (hours = 12){ - return `${hours}:${minutes} pm`; - } else { - return `${hours}:${minutes} am`; - } - } \ No newline at end of file diff --git a/assets/js/right-col-content-check.js b/assets/js/right-col-content-check.js new file mode 100644 index 0000000000..372d790167 --- /dev/null +++ b/assets/js/right-col-content-check.js @@ -0,0 +1,25 @@ +import { getEventData, insertEventSchedule } from "./utility/api-events.js"; + +/** + * This type of function is called an IIFE function. The main function is the primarily controller that loads the recurring events on this page. + * Refer: https://developer.mozilla.org/en-US/docs/Glossary/IIFE + */ +(async function main() { + const eventData = await getEventData(); + + //Displays/Inserts event schedule to DOM + if (document.readyState === "loading") { + document.addEventListener( + "DOMContentLoaded", + () => { insertEventSchedule(eventData, "events"); } + ); + } + else { + insertEventSchedule(eventData, "events"); + } + + //Displays/Inserts the user's time zone in the DOM + document + .querySelector("#userTimeZone") + .insertAdjacentHTML("afterbegin", timeZoneText()); +})(); \ No newline at end of file diff --git a/assets/js/right-col-content.js b/assets/js/right-col-content.js index 372d790167..c74f03337a 100644 --- a/assets/js/right-col-content.js +++ b/assets/js/right-col-content.js @@ -1,11 +1,10 @@ -import { getEventData, insertEventSchedule } from "./utility/api-events.js"; - +import { vrmsDataFetch, localeTimeIn12Format } from "./utility/vrms-events.js" /** * This type of function is called an IIFE function. The main function is the primarily controller that loads the recurring events on this page. * Refer: https://developer.mozilla.org/en-US/docs/Glossary/IIFE */ -(async function main() { - const eventData = await getEventData(); +(function main() { + const eventData = vrmsDataFetch("events") //Displays/Inserts event schedule to DOM if (document.readyState === "loading") { @@ -22,4 +21,105 @@ import { getEventData, insertEventSchedule } from "./utility/api-events.js"; document .querySelector("#userTimeZone") .insertAdjacentHTML("afterbegin", timeZoneText()); -})(); \ No newline at end of file +})(); + +/** + * Inserts the recurring events into the html + * @param {Object} eventData - An array objects of the type returned by displayObject() + * @param {String} page - page that is using eventData ("events" or "project-meetings") + */ +function insertEventSchedule(eventData, page) { + + const formatedEvents = formatEventData(eventData) + + for (const [key, value] of Object.entries(formatedEvents)) { + let placeToInsert = document.querySelector(`#${key}-List`); + placeToInsert.innerHTML = ""; + // check if the day has any events + if (!value.length) { + placeToInsert.insertAdjacentHTML( + "beforeend", + `
  • There are no meetings scheduled.
  • ` + ); + } else { + value.forEach((event) => { + if (event) { + // If a project doesn't have an hflaWebsiteUrl, redirect to the project's Github page + if (event.hflaWebsiteUrl == "") { + event.hflaWebsiteUrl = event.githubUrl + } + let eventHtml; + // insert the correct html for the current page + if (page === "events") { + eventHtml = `
  • ${event.start} - ${event.end}
  • ${event.name} ${event.meetingName}
  • `; + } else { + if(event.dsc != "") event.meetingName += ", "; + eventHtml = `
  • ${event.start} - ${event.end} ${event.name} ${event.meetingName} ${event.dsc}
  • `; + } + placeToInsert.insertAdjacentHTML("beforeend", eventHtml); + } + }); + } + } + } + + /** + * Formats event data + * @param {Object} data - array of event objects + * @return {Object} filtered and sorted data + */ + function formatEventData(data) { + const filteredData = filterVrmsData(data); + return filteredData + + } + + /** + * Filters out the needed data from the vrmsData returned from vrmsDataFetch + */ + function filterVrmsData(responseData) { + const return_obj = { + Monday: [], + Tuesday: [], + Wednesday: [], + Thursday: [], + Friday: [], + Saturday: [], + Sunday: [], + }; + responseData.forEach((item) => { + let day_of_week = getDayString(item.date); + return_obj[day_of_week].push(display_object(item)); + }); + return return_obj; + } + + /** + * @param {Date} date - A valid javscript time string. Example: "2020-05-13T02:00:00.000Z" + * @return {String} - The name of the day represented by the time string. Example 2020-05-13 was a wednesday. I.e rv = 'Wednesday' + */ + function getDayString(date) { + let new_date = new Date(date); + let weekday = new_date.getDay(); + let options = { weekday: "long" }; + return new Intl.DateTimeFormat("en-US", options).format(new_date); + } + + /** + * Function that represent the individual object extracted from the api + */ + function display_object(item) { + if (item?.project?.name !== "Hack4LA" && !/^Test\b/i.test(item?.project?.name)) { + const rv_object = { + meetingName: item.name, + name: item.project.name, + dsc: item.description, + start: localeTimeIn12Format(item.startTime), + end: localeTimeIn12Format(item.endTime), + hflaWebsiteUrl: item.project.hflaWebsiteUrl, + githubUrl: item.project.githubUrl, + }; + return rv_object; + } + } + \ No newline at end of file diff --git a/assets/js/utility/api-events.js b/assets/js/utility/api-events.js index a77b7a4a52..2cf765f297 100644 --- a/assets/js/utility/api-events.js +++ b/assets/js/utility/api-events.js @@ -160,4 +160,4 @@ function display_object(item) { } } -export { getEventData, insertEventSchedule }; +export { getEventData, insertEventSchedule }; \ No newline at end of file diff --git a/assets/js/utility/vrms-events.js b/assets/js/utility/vrms-events.js new file mode 100644 index 0000000000..a44b710f3b --- /dev/null +++ b/assets/js/utility/vrms-events.js @@ -0,0 +1,73 @@ +--- +--- + +{% assign vrmsData = site.data.external.vrms_data %} +const vrmsData = JSON.parse(decodeURIComponent("{{ vrmsData | jsonify | uri_escape }}")); + +/* vrmsDataFetch calls sortByDate function and passes vrmsData variable, current page which can either be "events" for the right-col-content.html page or +"project" from the project.html page, and passes the appendMeetingTimes function from projects.js that appends the sorted vrmsData +returned by sortByDate to project.html. AppendMeetingTimes is only called if vrmsDataFetch is being called from project.js for the project.html page +*/ +export const vrmsDataFetch = (currentPage, appendMeetingTimes) => { + return sortByDate(vrmsData, currentPage, appendMeetingTimes) +} + + // Helper function used for project.html and right-col-content.html to sort VRMS data by day of the week from "date" key and meeting time from "startTime" key + function sortByDate(scheduleData, currentPage, appendMeetingTimes) { + const map = { + 'Mon': 1, + 'Tue': 2, + 'Wed': 3, + 'Thu': 4, + 'Fri': 5, + 'Sat': 6, + 'Sun': 7 + }; + + scheduleData.sort(function(a, b) { + const day1 = new Date(a.date).toString().substring(0, 3); + const day2 = new Date(b.date).toString().substring(0, 3); + + return map[day1] - map[day2]; + }); + + scheduleData.sort(function(a, b) { + const day1 = new Date(a.date).toString().substring(0, 3); + const day2 = new Date(b.date).toString().substring(0, 3); + const time1 = new Date(a.startTime).toString().substring(16, 21); + const time2 = new Date(b.startTime).toString().substring(16, 21); + + if (day1 === day2) { + if (time1 > time2) { + return 1; + } else { + return -1; + } + } else { + return 1; + } + }); + + if (currentPage === "events") return scheduleData + else if (currentPage === "project") appendMeetingTimes(scheduleData) +} + +/** + * @param {Date} time - A valid javscript time string. Example: "2020-05-13T02:00:00.000Z" + * @return {String} - A time string formatted in the 12 hour format and converted to your timezone. Example: "10:00 pm" +*/ +// Formats time to be readable for projects.html and right-col-content.html page +export function localeTimeIn12Format(time) { + return new Date(time) + .toLocaleTimeString( + {}, + { + timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone, + hour12: true, + hour: "numeric", + minute: "numeric", + } + ) + .toLowerCase(); + } + diff --git a/pages/events-check.html b/pages/events-check.html new file mode 100644 index 0000000000..27a2881714 --- /dev/null +++ b/pages/events-check.html @@ -0,0 +1,54 @@ +--- +layout: default +title: Events - Hack for LA +permalink: /events-check +--- + + + + + + +
    + {% include events-page/header-container-content.html %} +
    + +
    + +

    Our Events

    +
    +
    + {% include events-page/left-col-content.html %} +
    + +
    + {% include events-page/right-col-content-check.html%} +
    +
    + +

    + Our Locations +

    + +
    +
    +

    + In light of the COVID-19 pandemic, Hack for LA has suspended its in-person + events below. The organization remains fully active, and all events are + now being conducted remotely using Zoom at the days/times listed above. +

    +
    + +
    +

    + + See our Locations +

    +
    +
    + +
    + {% include events-page/our-locations-content.html %} +
    + +
    \ No newline at end of file