Skip to content

Commit

Permalink
favourites working
Browse files Browse the repository at this point in the history
  • Loading branch information
pluvio72 committed Aug 6, 2022
1 parent 9f03080 commit 1ca4175
Show file tree
Hide file tree
Showing 10 changed files with 169 additions and 17 deletions.
Binary file added public/images/cross.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/tick.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Compare from './views/Compare';
import Favourites from './views/Favourites/favourites';
import Pokedex from "./views/Pokedex";

function App() {
Expand All @@ -9,6 +10,7 @@ function App() {
<Routes>
<Route path="/" element={<Pokedex />} />
<Route path="/compare" element={<Compare/>} />
<Route path="/favourites" element={<Favourites/>}/>
</Routes>
</BrowserRouter>
);
Expand Down
13 changes: 7 additions & 6 deletions src/components/Navbar/navbar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@ function NavbarComponent() {
<Container>
<Navbar.Toggle aria-controls="navbar-general" />
<Navbar.Collapse id="navbar-general">
<Nav className="mx-auto align-items-center">
<NavLink to="/" className="nav-link fw-bold fs-4">INDEX</NavLink>
<Navbar.Brand className="mx-3" href="#home">
<img src="/images/logo.png" alt="pokemon logo" height="55"/>
</Navbar.Brand>
<NavLink to="/compare" className="nav-link fw-bold fs-4">COMPARE</NavLink>
<Navbar.Brand>
<img src="/images/logo.png" alt="pokemon logo" height="55"/>
</Navbar.Brand>
<Nav className="me-auto align-items-center">
<NavLink to="/" className="nav-link fw-bold fs-5">HOME</NavLink>
<NavLink to="/compare" className="nav-link fw-bold fs-5">COMPARE</NavLink>
<NavLink to="/favourites" className="nav-link fw-bold fs-5">FAV</NavLink>
</Nav>
</Navbar.Collapse>
</Container>
Expand Down
42 changes: 42 additions & 0 deletions src/services/favourites.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
const KEY = 'saved_pokemon';

function savePokemonToFavourites(name, data) {
const savedItems = JSON.parse(localStorage.getItem(KEY));
if(savedItems === null){
const newObject = {
[name]: data
};
localStorage.setItem(KEY, JSON.stringify(newObject));
} else {
const newObject = {
...savedItems,
[name]: data
};
localStorage.setItem(KEY, JSON.stringify(newObject));
}
}

function removePokemonFromFavourites(name) {
const savedItems = JSON.parse(localStorage.getItem(KEY));
if(savedItems === null) return false;
else {
if(Object.keys(savedItems).includes(name)){
const newObject = {...savedItems};
delete newObject[name];
console.log("DELETED FAVOURITE, New object:", newObject);
localStorage.setItem(KEY, JSON.stringify(newObject));
}
}
}

function getFavourites() {
const savedItems = localStorage.getItem(KEY);
if(savedItems === null) return {};
return JSON.parse(savedItems);
}

export {
getFavourites,
removePokemonFromFavourites,
savePokemonToFavourites
}
53 changes: 53 additions & 0 deletions src/views/Favourites/favourites.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, { useEffect, useState } from "react";
import { getFavourites, removePokemonFromFavourites } from "../../services/favourites";
import Layout from "../../components/Layout";
import { Col, Container, Row } from "react-bootstrap";
import "./favourites.scss";

function Favourites() {
const [favourites, setFavourites] = useState({});

useEffect(() => {
setFavourites(getFavourites());
}, []);

const removeFavourite = (name) => {
removePokemonFromFavourites(name);
setFavourites(prevState => {
const newFavourites = {...prevState};
delete newFavourites[name];
return newFavourites;
})
}

return (
<Layout>
<Container className="p-3">
<h3 className="fs-3 fw-bold text-center mb-4 bg-dark text-light py-2">FAVOURITES</h3>
<Row>
{Object.keys(favourites).length > 0 ? (
Object.keys(favourites).map((favourite) => (
<Col className="col-3">
<div className="favourites-item">
<span>{favourite}</span>
<img
width={16}
height={16}
className="align-self-center ms-auto remove-favourite"
src="/images/cross.png"
alt="remove favourite"
onClick={() => removeFavourite(favourite)}
/>
</div>
</Col>
))
) : (
<span className="fw-bold text-center fs-5">No Favourites</span>
)}
</Row>
</Container>
</Layout>
);
}

export default Favourites;
11 changes: 11 additions & 0 deletions src/views/Favourites/favourites.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.favourites-item{
border: 3px solid black;
background-color: rgb(243,244,245);
border-radius: .5rem;
padding: 10px 14px;
display: flex;
flex-direction: row;
}
.remove-favourite{
cursor: pointer;
}
2 changes: 2 additions & 0 deletions src/views/Favourites/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import Favourites from "./favourites";
export default Favourites;
35 changes: 30 additions & 5 deletions src/views/Pokedex/pokedex.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ import {
} from "../../services/pokemonAPI";
import { formatName, formatPokemonDetails, formatPokemonInfo } from "../../util/formatData";
import "./pokedex.scss";
import { getFavourites, savePokemonToFavourites } from "../../services/favourites";

function Pokedex() {
const { addPokemonToList, getAllPokemon } = useContext(Pokemon);

const [filter, setFilter] = useState('');
const [pokemon, setPokemon] = useState({});

const [favourites, setFavourites] = useState(getFavourites());

// cache first 20 pokemon for index page
useEffect(() => {
if (Object.keys(getAllPokemon()).length === 0) {
Expand Down Expand Up @@ -115,6 +118,16 @@ function Pokedex() {
});
};

const addFavourite = (name, data) => {
savePokemonToFavourites(name, data);
setFavourites(prevState => {
return {
...prevState,
[name]: data
}
})
}

return (
<Layout>
<Container className="py-3">
Expand Down Expand Up @@ -146,12 +159,24 @@ function Pokedex() {
{Object.keys(pokemon).filter(e => e.toLowerCase().indexOf(filter) > -1).map((_name) => (
<Col className="col-3" key={_name}>
<div className="pokemon-card py-2 px-3">
<span className="lead">{formatName(_name)}</span>
<div className="ms-auto">
{pokemon[_name].types.map((_type) => (
<Badge key={_name+_type} className={`${_type} ms-1`}>{_type}</Badge>
))}
<div className="d-flex flex-row align-items-center">
<span className="lead pokemon-card-name">{formatName(_name)}</span>
<div className="ms-auto">
{pokemon[_name].types.map((_type) => (
<Badge key={_name+_type} className={`${_type} ms-1`}>{_type}</Badge>
))}
</div>
</div>
{Object.keys(favourites).includes(_name) ?
<span className="fw-light favourite-text remove">
Remove Favourite
<img className="favourite-icon" src="/images/cross.png" alt="remove favourite"/>
</span>:
<span className="fw-light favourite-text add" onClick={() => addFavourite(_name, pokemon[_name])}>
Add Favourite
<img className="favourite-icon" src="/images/tick.png" alt="add favourite"/>
</span>
}
</div>
</Col>
))}
Expand Down
28 changes: 22 additions & 6 deletions src/views/Pokedex/pokedex.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,28 @@
background-color: rgb(240,241,242);
border-radius: .5rem;
display: flex;
flex-direction: row;
align-items: center;
flex-direction: column;
transition: .2s;
}
.pokemon-card-name{
cursor: pointer;

&:hover{
background-color: rgb(220,221,222);
}
}
.pokemon-card-name:hover{
text-decoration: underline;
}
.favourite-text{
font-size: 14px;
cursor: pointer;
}
.favourite-text.add:hover{
color: green!important;
}
.favourite-text.remove:hover{
color: red!important;
}
.favourite-icon{
width: 12px;
height: 12px;
margin-left: 4px;
margin-bottom: 1px;
}

0 comments on commit 1ca4175

Please sign in to comment.