diff --git a/_sass/components/_wins-page.scss b/_sass/components/_wins-page.scss
index 84f09280b7..d55e4db567 100644
--- a/_sass/components/_wins-page.scss
+++ b/_sass/components/_wins-page.scss
@@ -245,6 +245,8 @@
height: auto;
}
}
+
+
}
//mobile see more
@@ -266,4 +268,27 @@
.wins-card-content > * {
flex: 0 0 auto;
-}
\ No newline at end of file
+}
+
+
+
+//wins page filter override section begin
+.wins-page-contain > ul.filter-list{
+ grid-template-columns: repeat(2, 1fr);
+ min-width: 216px;
+ width: 46%;
+
+
+}
+
+.wins-page-contain > ul.filter-list li ul {
+ width: 100%;
+}
+
+@media #{$bp-below-tablet}{
+ .wins-page-contain > ul.wins-filter{
+ width: 100%;
+ grid-template-rows: none;
+ }
+}
+//wins page filter override section end
\ No newline at end of file
diff --git a/wins.html b/wins.html
index 775f4458dc..4b24d28f3f 100644
--- a/wins.html
+++ b/wins.html
@@ -2,264 +2,491 @@
layout: default
title: Wins
---
+
{%- include wins-hero.html -%}
-
-
-
-
-
-
-
- Blank
-
-
-
Team(s): Blank
-
Role(s): Blank
-
-
-
+
+
+
+
+
+
+
+ Blank
+
+
+
+ Team(s): Blank
+
+
+ Role(s): Blank
+
+
+
+
\ No newline at end of file
+ //assigning the google form questions to variables for readability
+ //these variables correspond with a question on the google form
+ //these variables can be used as a key to access the data
+ const time = "Timestamp"
+ const email = "Email Address"
+ const name = "Full name"
+ const linkedin_url = "Linkedin URL (optional)"
+ const linkedin_permission = "Could we use your Linkedin profile picture next to your story?"
+ const github_url = "Github URL (optional)"
+ const github_permission = "Could we use your Github profile picture next to your story?"
+ const team = "Select the team(s) you're on"
+ const role = "Select your role(s) on the team"
+ const specific_role = "What is/was your specific role? (optional)"
+ const join_date = "When did you join Hack for LA? (optional)"
+ const win = "What do you want to celebrate (select all that apply)?"
+ const overview = "Give us a brief overview"
+ const display = "Display?"
+
+
+
+ function main() {
+ {% assign localData = site.data.wins-data | jsonify %}
+ let localData = {{ localData }};
+ const rawData = localData.values;
+ //creates an array of objects where each question is the key and the answer is the value
+ //cardData[index][question_str] = answer_str
+ let cardData = []
+ const keys = rawData[0]
+ rawData.slice(1).forEach((data) => {
+ let cardObj = {}
+ for (let i = 0; i < keys.length; i++) {
+ cardObj[keys[i]] = data[i];
+ }
+ cardData.push(cardObj)
+
+
+
+ })
+
+ //createFilter();
+ window.localStorage.setItem('data', JSON.stringify(cardData));
+ makeCards(cardData);
+ ifPageEmpty();
+
+
+
+ }
+
+ //Create The Filters From The Displayed Cards On Page Load
+ document.addEventListener("DOMContentLoaded", createFilter);
+ function createFilter(){
+
+ const roleArr = [];
+ const teamArr = [];
+ const responses = document.querySelector("#responses");
+ responses.querySelectorAll('.wins-card-team:not([style*="display:none"]):not([style*="display: none"]').forEach(item =>{
+ let value = item.textContent.replace("Team(s):","").trim();
+ let team = value.split(",").map(x=>x.trim());
+
+ Array.isArray(team) ? teamArr.push(...team) : teamArr.push(team);
+
+ })
+ responses.querySelectorAll('.wins-card-role:not([style*="display:none"]):not([style*="display: none"]').forEach(item =>{
+ let value = item.textContent.replace("Role(s):","").trim();
+ let role = value.split(",").map(x=>x.trim());
+ Array.isArray(role) ? roleArr.push(...role) : roleArr.push(role);
+
+
+ })
+
+ //Create dropdown key,values where the keys are name of the drops downs and the values are the number of occurences of each key
+ const roleHash = Object.fromEntries([ ...roleArr.reduce((map, key) => map.set(key, (map.get(key) || 0) + 1), new Map()) ]);
+ const teamHash = Object.fromEntries([ ...teamArr.reduce((map, key) => map.set(key, (map.get(key) || 0) + 1), new Map()) ]);
+
+
+ const filterTemplate = document.getElementById("template");
+ var cloneFilterTemplate = filterTemplate.content.cloneNode(true);
+ const roleDropwDown = document.getElementById("role-dropdown");
+ const teamDropDown = document.getElementById("team-dropdown");
+
+
+ for(const [key,value] of Object.entries(roleHash) ){
+ let cloneFilterTemplate = filterTemplate.content.firstElementChild.cloneNode(true);
+ cloneFilterTemplate.querySelector("span").textContent = `${key}`;
+ cloneFilterTemplate.querySelector("span").id=`role_${key.replace(/\s+/g, '')}`
+ cloneFilterTemplate.querySelector("input").value = `role_${key}`;
+ cloneFilterTemplate.querySelector("input").addEventListener("click",checkboxClickHandler)
+ roleDropwDown.append(cloneFilterTemplate);
+
+ }
+ for(const [key,value] of Object.entries(teamHash) ){
+ let cloneFilterTemplate = filterTemplate.content.firstElementChild.cloneNode(true);
+ cloneFilterTemplate.querySelector("span").textContent = `${key}`;
+ cloneFilterTemplate.querySelector("span").id=`team_${key.replace(/\s+/g, '')}`
+ cloneFilterTemplate.querySelector("input").value = `team_${key}`;
+ cloneFilterTemplate.querySelector("input").addEventListener("click",checkboxClickHandler)
+ teamDropDown.append(cloneFilterTemplate);
+
+ }
+
+ }
+
+ //Update History State / URL on checkbox click
+ function checkboxClickHandler(event){
+
+ let incomingFilterData = document.querySelectorAll("input");
+ let queryObj = { };
+
+ //Calculate and Create Updated Query String
+ incomingFilterData.forEach(function(e){
+ //Find boxes that are checked
+ if(e.checked){
+ let data = e.value.split("_");
+
+ if(data[0] == 'role'){
+
+ if(data[0] in queryObj){
+ queryObj[data[0]].push(data[1].trim());
+ }
+ else{
+ queryObj[data[0]] = [];
+ queryObj[data[0]].push(data[1].trim());
+ }
+
+ }
+ if(data[0]=='team'){
+ if(data[0] in queryObj){
+ queryObj[data[0]].push(data[1].trim());
+ }
+ else{
+ queryObj[data[0]] = [];
+ queryObj[data[0]].push(data[1].trim());
+ }
+
+ }
+ }
+ })
+ let questionSymbol = '?';
+ let queryString = Object.keys(queryObj).map(key => key + '=' + queryObj[key]).join('&').replaceAll(" ","+");
+ let urlParameter = `${questionSymbol}${queryString}`;
+
+ //Update URL parameters
+ window.history.replaceState(null, '', urlParameter.replaceAll(" ","+"));
+
+
+
+
+ }
+
+ //Update UI on URL history change and on DomContent loaded
+ window.addEventListener('DOMContentLoaded',updateUI)
+ window.addEventListener('locationchange',updateUI)
+ function updateUI(){
+ const filterParams = Object.fromEntries(new URLSearchParams(window.location.search));
+ const winsCards = document.querySelectorAll("#responses > .wins-card");
+ const checkboxes = document.querySelectorAll("input");
+
+ //If there are no entries in URL display all Cards
+ if(Object.keys(filterParams).length === 0){
+ winsCards.forEach(card=>{card.style.display='flex';})
+ return;
+ }
+
+ //Ensure that checkboxes are marked according to the url query
+ checkboxes.forEach(checkbox =>{
+ let checkboxData = checkbox.value;
+ let checkboxType = checkboxData.split("_")[0];
+ let checkboxValue = checkboxData.split('_')[1];
+ if(checkboxType in filterParams){
+ let args = filterParams[checkboxType].split(',');
+ args.includes(checkboxValue) ? checkbox.checked = true : checkbox.checked = false;
+ }
+ })
+
+
+ //Card Display/Hide Logic
+ winsCards.forEach(card=>{
+ let teamsInCard = (card.querySelector('.wins-card-team').textContent.replace("Team(s):","")).trim();
+ teamsInCard = teamsInCard.split(",").map(x=>x.trim());
+ let rolesInCard = (card.querySelector('.wins-card-role').textContent.replace("Role(s):","")).trim();
+ rolesInCard = rolesInCard.split(",").map(x=>x.trim());
+ let cardUnion = [...rolesInCard,...teamsInCard];
+
+
+ if(('role' in filterParams) && ('team' in filterParams)){
+ let roleInURL = filterParams.role.split(',');
+ let teamInURL = filterParams.team.split(',');
+ let roleIntersection = rolesInCard.filter(x => roleInURL.includes(x));
+ let teamIntersection = teamsInCard.filter(x => teamInURL.includes(x));
+ ((roleIntersection.length == 0) || (teamIntersection.length == 0)) ? card.style.display='none' : card.style.display='flex'
+ }
+ else if('role' in filterParams){
+ let roleInURL = filterParams.role.split(',');
+ let roleIntersection = rolesInCard.filter(x => roleInURL.includes(x));
+ roleIntersection.length == 0 ? card.style.display='none' : card.style.display='flex';
+ }
+ else if('team' in filterParams){
+ let teamInURL = filterParams.team.split(',');
+ let teamIntersection = teamsInCard.filter(x => teamInURL.includes(x));
+ teamIntersection.length == 0 ? card.style.display='none' : card.style.display='flex';
+
+ }
+
+
+ })
+
+ }
+
+ function formatMessage(win) {
+ let str = '';
+ let lastCommaIndex = win.lastIndexOf(",");
+ if (lastCommaIndex != -1) {
+ str += win.slice(0, lastCommaIndex + 1) + " and" + win.slice(lastCommaIndex + 1) + '!';
+ } else {
+ str += win + '!';
+ }
+ return str;
+ }
+
+ function ifPageEmpty() {
+ if (document.querySelectorAll('.wins-card').length == 0) {
+ const page = document.querySelector('.wins-page-contain');
+ const p = document.createElement('p');
+ //p.classList.add("project-card");
+ page.appendChild(p);
+ p.innerHTML = "No one has shared a win yet...be the first!";
+ }
+ }
+
+ function makeElement(elementType, parent, className) {
+ let child = document.createElement(elementType);
+ child.classList.add(className);
+ parent.appendChild(child);
+ return child;
+ }
+ function makeIcon(href, parent, className, src) {
+ let icon = makeElement('a', parent, 'wins-card-icon');
+ icon.setAttribute("href", href);
+ let iconImg = makeElement('img', icon, className);
+ iconImg.setAttribute("src", src);
+ }
+
+ function makeCards(data) {
+ {% assign githubData = site.data.github-data | jsonify %}
+ let githubData = {{ githubData }};
+
+ const list = document.querySelector('#responses');
+ let idNum = 0
+ data.reverse().forEach( (card) => {
+ if (card[display] != "TRUE"){
+ idNum++;
+ return; //checks if Display column is set to true
+ }
+
+ let ghId;
+ if (card[github_url] && card[github_permission] === "Yes") {
+ githubData.slice(1) //first key is a timestamp
+ .forEach(project => {
+
+ /* Exit forEach if githubId is already defined, otherwise
+ iterate through each project (and its contributors) until
+ a matching github_url is found */
+ if (ghId) return;
+ project.contributorsComplete.data.forEach(contrib => {
+ if (contrib.github_url === card[github_url]) {
+ ghId = contrib.id;
+ }
+ });
+ });
+
+ }
+
+ /* if github url is provided in wins-data and permission
+ is granted, ghId is defined & we can use their github avatar
+ otherwise, use default avatar */
+
+ let profileImgSrc = ghId ?
+ `https://avatars1.githubusercontent.com/u/${ghId}?v=4` :
+ "/assets/images/wins-page/avatar-default.svg";
+
+ let cardElement = makeElement('li', list, "project-card");
+ cardElement.classList.add("wins-card");
+
+ let leftDiv = makeElement('div', cardElement, "wins-card-left");
+
+ let profileImg = makeElement('img', leftDiv, "wins-card-profile-img");
+ profileImg.setAttribute("src", profileImgSrc);
+
+ let quote = makeElement('img', leftDiv, "wins-card-big-quote");
+ quote.setAttribute("src", "/assets/images/wins-page/quote-icon.svg");
+ let rightDiv = makeElement('div', cardElement, "wins-card-content");
+ rightDiv.classList.add("project-card-inner");
+
+ //makes the top of thecard name and icons
+ let topDiv = makeElement('div', rightDiv, "project-inner");
+ topDiv.classList.add("wins-card-top");
+ let nameElement = makeElement('span', topDiv, "wins-card-name");
+ nameElement.innerHTML = card[name];
+ let icons = makeElement('span', topDiv, "wins-card-icons");
+ if (card[linkedin_url].length > 0) {
+ makeIcon(card[linkedin_url], icons, 'linkedin-icon', '/assets/images/wins-page/icon-linkedin-small.svg');
+ } if (card[github_url].length > 0) {
+ makeIcon(card[github_url], icons, 'github-icon', '/assets/images/wins-page/icon-github-small.svg');
+ }
+
+ //makes the team and roles portion in the middle
+ let nameDiv = makeElement('div', rightDiv, "project-inner");
+ nameDiv.classList.add("wins-card-team");
+ nameDiv.innerHTML = `Team(s): ${card[team]}`;
+ if (card[role].length > 0) {
+ let roleDiv = makeElement('div', rightDiv, "project-inner");
+ roleDiv.classList.add("wins-card-role");
+ roleDiv.innerHTML = `Role(s): ${card[role]}`;
+ }
+
+ //makes the win and info text on the bottom of the card
+ let winDiv = makeElement('div', rightDiv, "project-inner");
+ winDiv.classList.add("wins__card-text");
+ let overviewElement = makeElement('p', winDiv, "wins-card-overview");
+ overviewElement.innerHTML = card[overview];//description
+ let winElement = makeElement('p', winDiv, "wins-card-info");
+ winElement.innerHTML = formatMessage(card[win]); //win
+
+ let innerHeight = Array.from(rightDiv.childNodes).reduce((acc, el) => el.offsetHeight + acc, 0)
+
+ //makes the see more span on the bottom of the card
+ if(innerHeight > rightDiv.offsetHeight){ //checks if see more is needed.
+ let seeMoreDiv = makeElement('div', rightDiv, "project-inner");
+ seeMoreDiv.classList.add("wins__see-more-div")
+ seeMoreDiv.innerHTML = `...see more`
+ }
+ idNum++
+ })
+ }
+ function seeMore(id){
+ screenWidth = window.innerWidth;
+ if (screenWidth > 960){
+ updateOverlay(id);
+ }else{
+ mobileSeeMore(id);
+ }
+ }
+ function mobileSeeMore(id){
+ let span = document.getElementById(id);
+ let parent = span.parentElement.parentElement
+ parent.classList.toggle('expanded')
+ if (parent.classList.contains('expanded')) {
+ span.innerHTML = "see less"
+ }
+ else {
+ span.innerHTML = "...see more"
+ }
+ }
+ function updateOverlay(i) {
+ let stringData = window.localStorage.getItem("data");
+ let data = JSON.parse(stringData).reverse();
+
+ const overlayIcons = document.querySelector('#overlay-icons');
+ overlayIcons.innerHTML = "";
+
+ if (data[i][linkedin_url].length > 0) {
+ makeIcon(data[i][linkedin_url], overlayIcons, 'linkedin-icon', '/assets/images/wins-page/icon-linkedin-small.svg');
+ } if (data[i][github_url].length > 0) {
+ makeIcon(data[i][github_url], overlayIcons, 'github-icon', '/assets/images/wins-page/icon-github-small.svg');
+ }
+
+ const overlayName = document.querySelector('#overlay-name');
+ overlayName.innerHTML = data[i][name];
+
+ const overlayTeams = document.querySelector('#overlay-teams');
+ overlayTeams.innerHTML = `Team(s): ${data[i][team]}`;
+
+ const overlayRoles = document.querySelector('#overlay-roles');
+ overlayRoles.innerHTML = `Role(s): ${data[i][role]}`;
+
+ const overlayOverview = document.querySelector('#overlay-overview');
+ overlayOverview.innerHTML = data[i][overview];
+
+ const overlayInfo = document.querySelector('#overlay-info');
+ overlayInfo.innerHTML = formatMessage(data[i][win]);
+
+ const overlayProjectCard = document.querySelector('#overlay-project-card');
+ overlayProjectCard.parentNode.classList.add("display-initial");
+ }
+ function hideOverlay(e) {
+ e = e || window.event;
+ if (e.target !== e.currentTarget)
+ return;
+
+ const overlayProjectCard = document.querySelector('#overlay-project-card');
+ overlayProjectCard.parentNode.classList.remove("display-initial");
+ }
+
+ main();
+
+
+
+
+ history.pushState = ( f => function pushState(){
+ var ret = f.apply(this, arguments);
+ window.dispatchEvent(new Event('pushstate'));
+ window.dispatchEvent(new Event('locationchange'));
+ return ret;
+ })(history.pushState);
+
+ history.replaceState = ( f => function replaceState(){
+ var ret = f.apply(this, arguments);
+ window.dispatchEvent(new Event('replacestate'));
+ window.dispatchEvent(new Event('locationchange'));
+ return ret;
+ })(history.replaceState);
+
+ window.addEventListener('popstate',()=>{
+ window.dispatchEvent(new Event('locationchange'))
+ });
+