diff --git a/assets/css/style.css b/assets/css/style.css index b241e27b7e..f2b0d80596 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -1375,6 +1375,28 @@ main { .project-item>a { width: 100%; + position: relative; +} + +.project-item .favouriteIconWrapper { + content: ''; + position: absolute; + top: 0; + right: 0; + width: 2rem; + height: 2rem; + border-radius: 50%; + z-index: 1; + cursor: pointer; +} + +.favorites { + position: fixed; + width: 2rem; + height: 2rem; + top: 1rem; + right: 1rem; + cursor: pointer; } .project-img { diff --git a/assets/images/favorites.png b/assets/images/favorites.png new file mode 100644 index 0000000000..0f6d227ec3 Binary files /dev/null and b/assets/images/favorites.png differ diff --git a/assets/images/favourite-filled.png b/assets/images/favourite-filled.png new file mode 100644 index 0000000000..4c1b63dea0 Binary files /dev/null and b/assets/images/favourite-filled.png differ diff --git a/assets/images/favourite.png b/assets/images/favourite.png new file mode 100644 index 0000000000..431b771023 Binary files /dev/null and b/assets/images/favourite.png differ diff --git a/assets/js/index.js b/assets/js/index.js index 8139dc1022..d3f8fadd39 100644 --- a/assets/js/index.js +++ b/assets/js/index.js @@ -7,6 +7,7 @@ const generateLiTags = gamesData => { if (gameData) { const { gameTitle, gameUrl, thumbnailUrl } = gameData; + const isGameFavourite = JSONParse(getItem('favourites'))?.find(game => game.gameUrl === gameUrl) const liTag = `
  • @@ -20,6 +21,9 @@ const generateLiTags = gamesData => {

    ${tagNumber}. ${gameTitle} 🔗

    Play and have fun!

    +
    + favourite-icon +
  • `; @@ -30,14 +34,21 @@ const generateLiTags = gamesData => { return liTags.join('\n'); }; +let isFavourites = false + // Fetch the game data from the JSON file fetch('./assets/js/gamesData.json') .then(response => response.json()) .then(gamesData => { const projectListContainer = document.querySelector('.project-list'); projectListContainer.innerHTML = generateLiTags(gamesData); + const allIcons = document.getElementsByClassName('favouriteIcon') + for (let i = 0; i < allIcons.length; i++) { + allIcons[i].addEventListener('click', favouriteHandler) + } getPageNumbers(); getProjectsInPage(); + document.querySelector('.favorites').addEventListener('click', fetchFavourites) }) .catch(error => console.error('Error fetching game data:', error)); @@ -61,3 +72,91 @@ searchContainer.addEventListener("click", function () { // Focus on the input field when the div is clicked searchInput.focus(); }); + +const favouriteHandler = (e) => { + fetch('./assets/js/gamesData.json') + .then(response => response.json()) + .then(gamesData => { + const gamesArray = Array.from(Object.values(gamesData)) + + if (!getItem('favourites')) { + const clickedGame = gamesArray.filter(game => game.gameUrl === e.target.id) + setItem(JSONStringify(clickedGame)) + imageSrcUpdate(e.target.id, 'favourite-filled') + } else { + const isGameFavourite = JSONParse(getItem('favourites')).find(game => game.gameUrl === e.target.id) + if (isGameFavourite) { + const clickedGame = JSONParse(getItem('favourites')).filter(game => game.gameUrl !== e.target.id) + setItem(JSONStringify(clickedGame)) + imageSrcUpdate(e.target.id, 'favourite') + } else { + const clickedGame = gamesArray.find(game => game.gameUrl === e.target.id) + setItem(JSONStringify([...JSONParse(getItem('favourites')), clickedGame])) + imageSrcUpdate(e.target.id, 'favourite-filled') + } + } + } + ) +} + +const imageSrcUpdate = (id, type) => { + const newImageUrl = document.getElementById(id).src.split('/') + newImageUrl[5] = `${type}.png` + newImageUrl.join('/') + document.getElementById(id).src = newImageUrl.join('/') +} + +const fetchFavourites = () => { + isFavourites = !isFavourites + fetch('./assets/js/gamesData.json') + .then(response => response.json()) + .then(gamesData => { + const gamesArray = Array.from(Object.values(gamesData)) + if (isFavourites) { + const favorites = JSONParse(getItem('favourites')) + + const finalGamesToRender = Object.assign({}, gamesArray.map(game => { + if (favorites.find(el => el.gameUrl === game.gameUrl)) { + return game + } + }).filter(game => game)) + + // to update the indexing from 0 to 1 + const updatedJSON = {}; + Object.keys(finalGamesToRender).forEach(key => { + const newIndex = parseInt(key) + 1; + updatedJSON[newIndex] = finalGamesToRender[key]; + }); + + favoritesUpdate(updatedJSON) + } else { + favoritesUpdate(gamesData) + } + }) +} + +const favoritesUpdate = (data) => { + const projectListContainer = document.querySelector('.project-list'); + projectListContainer.innerHTML = generateLiTags(data); + getPageNumbers(); + getProjectsInPage(); + + const allIcons = document.getElementsByClassName('favouriteIcon') + for (let i = 0; i < allIcons.length; i++) { + allIcons[i].addEventListener('click', favouriteHandler) + } +} + +const getItem = () => { + return localStorage.getItem('favourites') +} +const setItem = (data) => { + return localStorage.setItem('favourites', data) +} + +const JSONParse = (data) => { + return JSON.parse(data) +} +const JSONStringify = (data) => { + return JSON.stringify(data) +} \ No newline at end of file diff --git a/index.html b/index.html index ee90c5a4e9..d50bc0df7a 100644 --- a/index.html +++ b/index.html @@ -70,6 +70,8 @@ + +