diff --git a/public/images/fontAwesomeIcons/caret.svg b/public/images/fontAwesomeIcons/caret.svg new file mode 100644 index 00000000..0d59b471 --- /dev/null +++ b/public/images/fontAwesomeIcons/caret.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/js/app/leaderboards.js b/public/js/app/leaderboards.js index 370dbf9c..21988f43 100644 --- a/public/js/app/leaderboards.js +++ b/public/js/app/leaderboards.js @@ -4,8 +4,9 @@ let lastPage = 5; let playerList = []; let timedOutPlayers = []; let currentLeaderboard = '1v1'; -let backgroundColor = 'greyLeaderboard'; -let playerListDivided = playerList.length/100; +const insertPlayer = document.getElementById('insertPlayer'); +const mainLeaderboard = document.getElementById('mainLeaderboard') +let playerListDivided = playerList.length / 100; // This decides the time filter let d = new Date(); let timeFilter = 6; // 6 Months is the default value @@ -13,7 +14,6 @@ let minusTimeFilter = d.setMonth(d.getMonth() - timeFilter); let currentDate = new Date(minusTimeFilter).toISOString(); -//Names of buttons async function leaderboardOneJSON(leaderboardFile) { //Check which category is active const response = await fetch(`js/app/members/${leaderboardFile}.json`); @@ -24,8 +24,8 @@ async function leaderboardOneJSON(leaderboardFile) { //Updates the leaderboard according to what is needed function leaderboardUpdate() { - // We convert playerList into a string to find out how many pages we have. We can find so by checking the first two digits. In other words, if we have 1349 players, then we have 13 pages. However, if we have 834, we have 8 pages (only take the first digit). - playerListDivided = playerList.length/100; + // We convert playerList into a string to find out how many pages we have. We can find so by dividing by a 100 and flooring the results to get an integer. In other words, if we have 1349 players, then we have 13 pages. + playerListDivided = playerList.length / 100; lastPage = Math.floor(playerListDivided); //Deletes everything with the class leaderboardDelete, we do it to delete all the previous leaderboard and add the new one back in. @@ -35,26 +35,54 @@ function leaderboardUpdate() { }); //determines the current page, whether to add or substract the missing players in case we pressed next or previous then it will add or substract players - let playerIndex = (playerList.length - 100) - (pageNumber * 100); //- addNextPlayer; - let next100Players = playerList.length - (pageNumber * 100); + let playerIndex = pageNumber * 100; + let next100Players = (1 + pageNumber) * 100; + + // Function to add player first second and third background + if (playerIndex === 0) { + mainLeaderboard.classList.remove('leaderboardNoAwards'); + mainLeaderboard.classList.add('leaderboardAwards'); + } else { + mainLeaderboard.classList.remove('leaderboardAwards'); + mainLeaderboard.classList.add('leaderboardNoAwards'); + } + + // Actual insertion of HTML for (playerIndex; playerIndex < next100Players; playerIndex++) { if (playerIndex < 0) { playerIndex = 0; - console.log('There are no more players left. Therefore, I come here to relay this message my lord: The bastion of greatness known as the as the for loop of leaderboardUpdate() is unable to be of servitude beyond now. It has broken.'); } - // Gets the player data and inserts it into the li element let rating = playerList[playerIndex][1].rating; let winRate = playerList[playerIndex][1].wonGames / playerList[playerIndex][1].totalgames * 100; - document.getElementById('leaderboardPlayer').insertAdjacentHTML('afterbegin', `
  • ${playerList[playerIndex][0].label}
  • `); - document.getElementById('leaderboardRank').insertAdjacentHTML('afterbegin', `
  • ${-1 * (playerIndex - playerList.length)}
  • `); - document.getElementById('leaderboardRating').insertAdjacentHTML('afterbegin', `
  • ${rating.toFixed(0)}
  • `); - document.getElementById('leaderboardGamesAmount').insertAdjacentHTML('afterbegin', `
  • ${playerList[playerIndex][1].totalgames}
  • `); - document.getElementById('leaderboardWon').insertAdjacentHTML('afterbegin', `
  • ${winRate.toFixed(1)}%
  • `); + insertPlayer.insertAdjacentHTML('beforebegin', `
    +
    +

    ${playerIndex + 1}

    +
    +
    +

    ${playerList[playerIndex][0].label}

    +
    +
    +

    ${rating.toFixed(0)}

    +
    +
    +

    ${winRate.toFixed(1)}%

    +
    +
    +

    ${playerList[playerIndex][1].totalgames}

    +
    +
    ` + ); } + + } + + //This function triggers when the next, previous, first or last button are clicked let pageButton = document.querySelectorAll('.pageButton'); + function pageChange(newPageNumber) { + pageNumber = newPageNumber; pageButton.forEach(element => element.classList.remove(`exhaustedButton`)); if (pageNumber === 0) { @@ -74,7 +102,9 @@ function pageChange(newPageNumber) { } //This function checks the different filters the user has chosen +// It shows as it not being used because it is called by the HTML function timeCheck(timeSelected) { + timeFilter = timeSelected; d = new Date(); minusTimeFilter = d.setMonth(d.getMonth() - timeFilter); @@ -84,7 +114,10 @@ function timeCheck(timeSelected) { for (let i = 0; i < timedOutPlayers.length; i++) { playerList.push(timedOutPlayers[i]); } - playerList.sort((playerA, playerB) => playerA[1].rating - playerB[1].rating); + // Sort players by their rating + playerList.sort((playerA, playerB) => playerB[1].rating - playerA[1].rating); + + //clean slate timedOutPlayers = []; //kick all the players that dont meet the time filter @@ -96,42 +129,83 @@ function timeCheck(timeSelected) { playerList.splice(i, 1); } } + + + pageChange(0); +} + +function filterLeaderboards() { + console.log('Im in progress'); + /* + //Re-insert all players that were kicked, to have a clean slate + for (let i = 0; i < timedOutPlayers.length; i++) { + playerList.push(timedOutPlayers[i]); + } + //Sort players + playerList.sort((playerA, playerB) => (playerB[1].wonGames / playerB[1].totalgames * 100) - (playerA[1].wonGames / playerA[1].totalgames * 100) || playerB[1].totalgames - playerA[1].totalgames); + + //clean slate + timedOutPlayers = []; + + //kick all the players that dont meet the time filter + + for (let i = 0; i < playerList.length; i++) { + + if (50 > playerList[i][1].totalgames) { + timedOutPlayers.push(playerList[i]); + playerList.splice(i, 1); + } + } pageChange(0); + */ + } + // This changes the current leaderboard(newLeaderboard), sets the page to 0 (pageNumber = 0) and resets the next and previous buttons. function changeLeaderboard(newLeaderboard) { leaderboardOneJSON(newLeaderboard) .then(data => { playerList = data; - playerListDivided = playerList.length/100; + playerListDivided = playerList.length / 100; lastPage = Math.floor(playerListDivided); pageChange(0); }); } + //Gets called once so it generates a leaderboard changeLeaderboard('1v1'); - +const insertSearch = document.getElementById('insertSearch'); // SEARCH BAR function findPlayer(playerName) { leaderboardOneJSON(currentLeaderboard) - .then( () => { + .then(() => { //input from the searchbar becomes playerName and then searchPlayer is their index number let searchPlayer = playerList.findIndex(element => element[0].label.toLowerCase() === playerName.toLowerCase()); - if (backgroundColor === 'greyLeaderboard') { - backgroundColor = 'darkGreyLeaderboard'; - } else { - backgroundColor = 'greyLeaderboard'; - } + let rating = playerList[searchPlayer][1].rating; let winRate = playerList[searchPlayer][1].wonGames / playerList[searchPlayer][1].totalgames * 100; - document.getElementById('leaderboardPlayerSearch').insertAdjacentHTML('afterbegin', `
  • ${playerList[searchPlayer][0].label} ${currentLeaderboard}
  • `); - document.getElementById('leaderboardRankSearch').insertAdjacentHTML('afterbegin', `
  • ${-1 * (searchPlayer - playerList.length)}
  • `); - document.getElementById('leaderboardRatingSearch').insertAdjacentHTML('afterbegin', `
  • ${rating.toFixed(0)}
  • `); - document.getElementById('leaderboardGamesAmountSearch').insertAdjacentHTML('afterbegin', `
  • ${playerList[searchPlayer][1].totalgames}
  • `); - document.getElementById('leaderboardWonSearch').insertAdjacentHTML('afterbegin', `
  • ${winRate.toFixed(1)}%
  • `); + insertSearch.insertAdjacentHTML('beforebegin', `
    +
    +

    ${searchPlayer + 1}

    +
    +
    +

    ${playerList[searchPlayer][0].label} ${currentLeaderboard}

    +
    +
    +

    ${rating.toFixed(0)}

    +
    +
    +

    ${winRate.toFixed(1)}%

    +
    +
    +

    ${playerList[searchPlayer][1].totalgames}

    +
    +
    `); + + document.querySelector('#errorLog').innerText = ``; }).catch(() => { document.querySelector('#errorLog').innerText = `Player "${playerName}" couldn't be found in the ${currentLeaderboard} leaderboard.`; diff --git a/public/styles/layout/_navigation.sass b/public/styles/layout/_navigation.sass index 2c59f0c2..89cb8486 100644 --- a/public/styles/layout/_navigation.sass +++ b/public/styles/layout/_navigation.sass @@ -76,6 +76,7 @@ h2 font-family: variables.$family-subtitle font-size: var(--subtitle-font-size) padding: 1em 0.8em + font-weight: 500 h3 , h4, h5, h6 font-size: var(--paragraph-font-size) diff --git a/public/styles/site/leaderboards.sass b/public/styles/site/leaderboards.sass index 4e821884..0f9e8500 100644 --- a/public/styles/site/leaderboards.sass +++ b/public/styles/site/leaderboards.sass @@ -3,12 +3,9 @@ // Background of the whole thing .leaderboardBackground - padding: 7.5vw 11vw - background-image: url("/../../images/fafbgpattern0.5.jpg") - ul - list-style: none - li - padding: 0.5em 0 + padding: 7.5vw 12vw + + // This is the searchbar input form input @@ -21,6 +18,62 @@ input z-index: 2 position: relative + + // This class determines whether the first second and third player will have a different background color +.leaderboardAwards + .newLeaderboardContainer:nth-child(odd) + background-color: mix(variables.$background-tertiary, variables.$background-primary, 25%) + .newLeaderboardContainer:nth-child(even) + background-color: variables.$background-secondary + .newLeaderboardContainer:nth-child(2) + background-color: #594112 + .newLeaderboardContainer:nth-child(3) + background-color: #737373 + .newLeaderboardContainer:nth-child(4) + background-color: #5d351d + +.leaderboardNoAwards + .newLeaderboardContainer:nth-child(odd) + background-color: mix(variables.$background-tertiary, variables.$background-primary, 25%) + .newLeaderboardContainer:nth-child(even) + background-color: variables.$background-secondary + + + +.newLeaderboard + @include mixins.gridMainContainer + border-radius: 20px + + .newLeaderboardCategory + padding: 0.5em + h2 + font-size: 1.2rem + padding: 0 + .categoryFilter + + h2 + padding: 0 + + //transition: 0.4s + //cursor: pointer + //&:hover + transform: scale(1.1) + + + img + display: inline-block + padding: 0 0.1em + height: 0.8em + .newLeaderboardContainer + @include mixins.gridMainContainer + + h3 + font-size: 1rem + padding: 0.75em 0 + + + + .mainLeaderboardContainer @include mixins.gridMainContainer padding: 0 @@ -32,68 +85,59 @@ input padding: 0.2em .leaderboardFilter - border: 1px solid white font-family: variables.$family-paragraph - font-size: var(--paragraph-font-size) + font-size: 1.2rem color: variables.$color-active background-color: variables.$background-tertiary - padding: 0.5em 0 0.5em 0.5em - margin: 0 0.8em + padding: 1em 0.25em + margin: 0 1em + border-radius: 20px text-align: center + select + cursor: pointer + font-size: 1.2rem option + padding: 0 0.25em color: variables.$color-active background-color: variables.$background-secondary -// This is in here for the js since the leaderboard is actually starting from 100 to 1. So it needs to be displayed in reverse. - -.leaderboardBorder - border: 1px solid variables.$color-active - padding: 0px - background-color: variables.$background-primary - -.leaderboardContainer - font-family: variables.$family-paragraph - padding: 0em - ul - font-size: var(--paragraph-font-size) - padding: 1em 0 - li - font-size: var(--paragraph-font-size) - padding: 1em 0 -.leaderboardItem - li:nth-child(odd) - background-color: mix(variables.$background-tertiary, variables.$background-primary, 25%) - li:nth-child(even) - background-color: variables.$background-secondary +//Buttons across the leaderboards .leaderboardCategory + border-radius: 20px padding: 1em 0.25em display: inline-block place-items: start font-family: variables.$family-paragraph - font-size: var(--paragraph-font-size) - letter-spacing: 0em - ul + font-size: 1.2rem + letter-spacing: 0 + .categoryButton:nth-child(odd) + border-radius: 30px 0 0 30px + border-right: 0.1em solid white + + .categoryButton:nth-child(even) + border-radius: 0 30px 30px 0 + .categoryContainer + display: inline-block + margin: 0 padding: 0.5em - li + .categoryButton display: inline-block - padding: 0.6em 1em - border: 0.05em solid variables.$color-inactive + padding: 1em background-color: variables.$background-tertiary cursor: pointer transition: 0.4s &:hover - border: 0.05em solid variables.$color-active filter: brightness(2) .exhaustedButton - border: 0.05em solid variables.$color-inactive background-color: variables.$background-secondary color: variables.$color-inactive-plus pointer-events: none cursor: default + + + -#searchResults - margin: 1em 0 0 0 .appearWhenSearching display: none .centerYourself @@ -126,7 +170,14 @@ input background-color: variables.$color-inactive-plus color: variables.$color-active - +@media (max-width: 600px) + .newLeaderboard + .newLeaderboardCategory + h2 + font-size: 14px + .newLeaderboardContainer + h3 + font-size: 12px @media (max-width: 800px) .leaderboardFilter diff --git a/scripts/extractor.js b/scripts/extractor.js index 3aa73beb..e13fcf39 100644 --- a/scripts/extractor.js +++ b/scripts/extractor.js @@ -5,11 +5,10 @@ process.env.API_URL = process.env.API_URL || 'https://api.faforever.com'; process.env.WP_URL = process.env.WP_URL || 'https:direct.faforever.com'; const fs = require('fs'); -const fetch = require('node-fetch'); const axios = require('axios'); let d = new Date(); -let timeFilter = 6; +let timeFilter = 12; let minusTimeFilter = d.setMonth(d.getMonth() - timeFilter); let currentDate = new Date(minusTimeFilter).toISOString(); @@ -142,7 +141,7 @@ async function contentCreators() { } -//https://api.faforever.com/data/clan?include=memberships.player&filter=tag==FEM + async function getAllClans() { try { let response = await axios.get(`${process.env.API_URL}/data/clan?sort=createTime&include=leader&fields[clan]=name,tag,description,leader,memberships,createTime&fields[player]=login&page[number]=1&page[size]=3000`); @@ -190,7 +189,7 @@ async function getLeaderboards(leaderboardID) { })); const combineArrays = (array1, array2) => array1.map((x, i) => [x, array2[i]]); let leaderboardData = combineArrays(playerLogin, playerValues); - leaderboardData.sort((playerA, playerB) => playerA[1].rating - playerB[1].rating); + leaderboardData.sort((playerA, playerB) => playerB[1].rating - playerA[1].rating); return await leaderboardData; } catch (e) { diff --git a/templates/views/leaderboards.pug b/templates/views/leaderboards.pug index 46254637..2f561b92 100644 --- a/templates/views/leaderboards.pug +++ b/templates/views/leaderboards.pug @@ -16,77 +16,77 @@ block content #placeMe ul#clearSearch.clearButton.appearWhenSearching img(src='/../../images/fontAwesomeIcons/trash.svg' alt='') - .mainLeaderboardContainer.leaderboardBorder#searchResults.appearWhenSearching - .leaderboardContainer.column1 - .leaderboardItem - ul Rank - li#leaderboardRankSearch - .leaderboardContainer.column3 - .leaderboardItem - ul Player - li#leaderboardPlayerSearch - .leaderboardContainer.column3 - .leaderboardItem - ul Rating - li#leaderboardRatingSearch - .leaderboardContainer.column2 - .leaderboardItem - ul Win Rate - li#leaderboardWonSearch - .leaderboardContainer.column3 - .leaderboardItem - ul Total Games - li#leaderboardGamesAmountSearch - .mainLeaderboardContainer + + - .leaderboardContainer.leaderboardCategory.column4 + + + .newLeaderboard.leaderboardBorder.appearWhenSearching#searchResults.leaderboardNoAwards + .newLeaderboardContainer.column12.newLeaderboardCategory + .column1 + h2 Rank + .column4 + h2 Player + .column2 + h2 Rating + + .column2 + h2 Win Rate + + .column3 + h2 Total Games + + #insertSearch + + .mainLeaderboardContainer.leaderboardCategory + .column12.leaderboardSelect select.leaderboardFilter(onchange='changeLeaderboard(this.value)') option(value='1v1') 1v1 option(value='2v2') 2v2 option(value='4v4') 4v4 option(value='global') Global select.leaderboardFilter(onchange='timeCheck(this.value)') + option(value='12') 1 Year option(value='6') 6 Months option(value='3') 3 Months option(value='1') 1 Month + .categoryContainer + .categoryButton(onclick= `pageChange(0)`).pageButton.exhaustedButton First + .categoryButton(onclick= `pageChange(lastPage)`).pageButton Last + .categoryContainer + .categoryButton(onclick= `pageChange(pageNumber - 1)`).pageButton.exhaustedButton Previous + .categoryButton(onclick= `pageChange(pageNumber + 1)`).pageButton Next //DO NOT Change the order of these without changing the js. For them to work, they need to be in this specific order - .leaderboardContainer.leaderboardCategory.column8 - ul - li(onclick= `pageChange(0)`).pageButton.exhaustedButton First - li(onclick= `pageChange(lastPage)`).pageButton Last - ul - li(onclick= `pageChange(pageNumber - 1)`).pageButton.exhaustedButton Previous - li(onclick= `pageChange(pageNumber + 1)`).pageButton Next - .mainLeaderboardContainer.leaderboardBorder - .leaderboardContainer.column1 - .leaderboardItem - ul Rank - li#leaderboardRank - .leaderboardContainer.column4 - .leaderboardItem - ul#spawnPlayer Player - li#leaderboardPlayer - .leaderboardContainer.column2 - .leaderboardItem - ul Rating - li#leaderboardRating - .leaderboardContainer.column2 - .leaderboardItem - ul Win Rate - li#leaderboardWon - .leaderboardContainer.column3 - .leaderboardItem - ul Total Games - li#leaderboardGamesAmount - .mainLeaderboardContainer - .leaderboardContainer.leaderboardCategory.column12 - ul - li(onclick= `pageChange(0)`).pageButton.exhaustedButton First - li(onclick= `pageChange(lastPage)`).pageButton Last - ul - li(onclick= `pageChange(pageNumber - 1)`).pageButton.exhaustedButton Previous - li(onclick= `pageChange(pageNumber + 1)`).pageButton Next + + .newLeaderboard#mainLeaderboard + .newLeaderboardContainer.column12.newLeaderboardCategory + .column1 + h2 Rank + .column4 + h2 Player + .column2.categoryFilter + h2(onclick='filterLeaderboards(1)') Rating + //img.categoryCaret(src='/images/fontAwesomeIcons/caret.svg') + .column2.categoryFilter + h2(onclick='filterLeaderboards(2)') Win Rate + //img.categoryCaret(src='/images/fontAwesomeIcons/caret.svg') + .column3.categoryFilter + h2(onclick='filterLeaderboards(3)') Total Games + //img.categoryCaret(src='/images/fontAwesomeIcons/caret.svg') + + #insertPlayer + + + .mainLeaderboardContainer.leaderboardCategory + .column12.leaderboardSelect + + .categoryContainer + .categoryButton(onclick= `pageChange(0)`).pageButton.exhaustedButton First + .categoryButton(onclick= `pageChange(lastPage)`).pageButton Last + .categoryContainer + .categoryButton(onclick= `pageChange(pageNumber - 1)`).pageButton.exhaustedButton Previous + .categoryButton(onclick= `pageChange(pageNumber + 1)`).pageButton Next block js